1 This file is enable.def, from which is created enable.c.
2 It implements the builtin "enable" in Bash.
4 Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 1, or (at your option) any later
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 $FUNCTION enable_builtin
26 $SHORT_DOC enable [-pnds] [-a] [-f filename] [name ...]
27 Enable and disable builtin shell commands. This allows
28 you to use a disk command which has the same name as a shell
29 builtin. If -n is used, the NAMEs become disabled; otherwise
30 NAMEs are enabled. For example, to use the `test' found on your
31 path instead of the shell builtin version, type `enable -n test'.
32 On systems supporting dynamic loading, the -f option may be used
33 to load new builtins from the shared object FILENAME. The -d
34 option will delete a builtin previously loaded with -f. If no
35 non-option names are given, or the -p option is supplied, a list
36 of builtins is printed. The -a option means to print every builtin
37 with an indication of whether or not it is enabled. The -s option
38 restricts the output to the Posix.2 `special' builtins. The -n
39 option displays a list of all disabled builtins.
44 #if defined (HAVE_UNISTD_H)
46 # include <sys/types.h>
52 #include "../bashansi.h"
54 #include "../builtins.h"
57 #include "bashgetopt.h"
59 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
60 static int dyn_load_builtin ();
63 #if defined (HAVE_DLCLOSE)
64 static int dyn_unload_builtin ();
78 static int enable_shell_command ();
79 static void list_some_builtins ();
81 /* Enable/disable shell commands present in LIST. If list is not specified,
82 then print out a list of shell commands showing which are enabled and
83 which are disabled. */
90 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
94 result = EXECUTION_SUCCESS;
97 reset_internal_getopt ();
98 while ((opt = internal_getopt (list, "adnpsf:")) != -1)
115 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
117 filename = list_optarg;
120 builtin_error ("dynamic loading not available");
123 #if defined (HAVE_DLCLOSE)
128 builtin_error ("dynamic loading not available");
130 #endif /* HAVE_DLCLOSE */
139 #if defined (RESTRICTED_SHELL)
140 /* Restricted shells cannot load new builtins. */
141 if (restricted && (flags & (FFLAG|DFLAG)))
143 builtin_error ("restricted");
144 return (EXECUTION_FAILURE);
148 if (list == 0 || (flags & PFLAG))
150 filter = (flags & AFLAG) ? (ENABLED | DISABLED)
151 : (flags & NFLAG) ? DISABLED : ENABLED;
156 list_some_builtins (filter);
158 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
159 else if (flags & FFLAG)
161 filter = (flags & NFLAG) ? DISABLED : ENABLED;
165 result = dyn_load_builtin (list, filter, filename);
168 #if defined (HAVE_DLCLOSE)
169 else if (flags & DFLAG)
173 opt = dyn_unload_builtin (list->word->word);
174 if (opt == EXECUTION_FAILURE)
175 result = EXECUTION_FAILURE;
184 opt = enable_shell_command (list->word->word, flags & NFLAG);
186 if (opt == EXECUTION_FAILURE)
188 builtin_error ("%s: not a shell builtin", list->word->word);
189 result = EXECUTION_FAILURE;
197 /* List some builtins.
198 FILTER is a mask with two slots: ENABLED and DISABLED. */
200 list_some_builtins (filter)
205 for (i = 0; i < num_shell_builtins; i++)
207 if (shell_builtins[i].function == 0 || (shell_builtins[i].flags & BUILTIN_DELETED))
210 if ((filter & SPECIAL) &&
211 (shell_builtins[i].flags & SPECIAL_BUILTIN) == 0)
214 if ((filter & ENABLED) && (shell_builtins[i].flags & BUILTIN_ENABLED))
215 printf ("enable %s\n", shell_builtins[i].name);
216 else if ((filter & DISABLED) &&
217 ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
218 printf ("enable -n %s\n", shell_builtins[i].name);
222 /* Enable the shell command NAME. If DISABLE_P is non-zero, then
223 disable NAME instead. */
225 enable_shell_command (name, disable_p)
231 b = builtin_address_internal (name, 1);
233 return (EXECUTION_FAILURE);
236 b->flags &= ~BUILTIN_ENABLED;
238 b->flags |= BUILTIN_ENABLED;
240 return (EXECUTION_SUCCESS);
243 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
245 #if defined (HAVE_DLFCN_H)
250 dyn_load_builtin (list, flags, filename)
258 int total, size, new, replaced;
259 char *struct_name, *name;
260 struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin;
263 return (EXECUTION_FAILURE);
270 handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL);
272 handle = dlopen (filename, RTLD_LAZY);
277 builtin_error ("cannot open shared object %s: %s", filename, dlerror ());
278 return (EXECUTION_FAILURE);
281 for (new = 0, l = list; l; l = l->next, new++)
283 new_builtins = (struct builtin **)xmalloc (new * sizeof (struct builtin *));
285 /* For each new builtin in the shared object, find it and its describing
286 structure. If this is overwriting an existing builtin, do so, otherwise
287 save the loaded struct for creating the new list of builtins. */
288 for (replaced = new = 0; list; list = list->next)
290 name = list->word->word;
292 size = strlen (name);
293 struct_name = xmalloc (size + 8);
294 strcpy (struct_name, name);
295 strcpy (struct_name + size, "_struct");
297 b = (struct builtin *)dlsym (handle, struct_name);
300 builtin_error ("cannot find %s in shared object %s: %s", struct_name,
301 filename, dlerror ());
308 b->flags &= ~STATIC_BUILTIN;
310 b->flags |= SPECIAL_BUILTIN;
313 if (old_builtin = builtin_address_internal (name, 1))
316 FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin));
319 new_builtins[new++] = b;
322 if (replaced == 0 && new == 0)
326 return (EXECUTION_FAILURE);
331 total = num_shell_builtins + new;
332 size = (total + 1) * sizeof (struct builtin);
334 new_shell_builtins = (struct builtin *)xmalloc (size);
335 FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
336 num_shell_builtins * sizeof (struct builtin));
337 for (replaced = 0; replaced < new; replaced++)
338 FASTCOPY ((char *)new_builtins[replaced],
339 (char *)&new_shell_builtins[num_shell_builtins + replaced],
340 sizeof (struct builtin));
342 new_shell_builtins[total].name = (char *)0;
343 new_shell_builtins[total].function = (Function *)0;
344 new_shell_builtins[total].flags = 0;
346 if (shell_builtins != static_shell_builtins)
347 free (shell_builtins);
349 shell_builtins = new_shell_builtins;
350 num_shell_builtins = total;
351 initialize_shell_builtins ();
355 return (EXECUTION_SUCCESS);
359 #if defined (HAVE_DLCLOSE)
365 struct builtin *new_shell_builtins;
367 /* XXX - funky pointer arithmetic - XXX */
369 ind = b - shell_builtins;
371 ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin);
373 size = num_shell_builtins * sizeof (struct builtin);
374 new_shell_builtins = (struct builtin *)xmalloc (size);
376 /* Copy shell_builtins[0]...shell_builtins[ind - 1] to new_shell_builtins */
378 FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
379 ind * sizeof (struct builtin));
380 /* Copy shell_builtins[ind+1]...shell_builtins[num_shell_builtins to
381 new_shell_builtins, starting at ind. */
382 FASTCOPY ((char *)(&shell_builtins[ind+1]),
383 (char *)(&new_shell_builtins[ind]),
384 (num_shell_builtins - ind) * sizeof (struct builtin));
386 if (shell_builtins != static_shell_builtins)
387 free (shell_builtins);
389 /* The result is still sorted. */
390 num_shell_builtins--;
391 shell_builtins = new_shell_builtins;
395 dyn_unload_builtin (name)
402 b = builtin_address_internal (name, 1);
405 builtin_error ("%s: not a shell builtin", name);
406 return (EXECUTION_FAILURE);
408 if (b->flags & STATIC_BUILTIN)
410 builtin_error ("%s: not dynamically loaded", name);
411 return (EXECUTION_FAILURE);
414 handle = (void *)b->handle;
415 for (ref = i = 0; i < num_shell_builtins; i++)
417 if (shell_builtins[i].handle == b->handle)
421 /* Don't remove the shared object unless the reference count of builtins
422 using it drops to zero. */
423 if (ref == 1 && dlclose (handle) != 0)
425 builtin_error ("cannot delete %s: %s", name, dlerror ());
426 return (EXECUTION_FAILURE);
429 /* Now remove this entry from the builtin table and reinitialize. */
432 return (EXECUTION_SUCCESS);