1 This file is enable.def, from which is created enable.c.
2 It implements the builtin "enable" in Bash.
4 Copyright (C) 1987-2009 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
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
24 $FUNCTION enable_builtin
25 $SHORT_DOC enable [-a] [-dnps] [-f filename] [name ...]
26 Enable and disable shell builtins.
28 Enables and disables builtin shell commands. Disabling allows you to
29 execute a disk command which has the same name as a shell builtin
30 without using a full pathname.
33 -a print a list of builtins showing whether or not each is enabled
34 -n disable each NAME or display a list of disabled builtins
35 -p print the list of builtins in a reusable format
36 -s print only the names of Posix `special' builtins
38 Options controlling dynamic loading:
39 -f Load builtin NAME from shared object FILENAME
40 -d Remove a builtin loaded with -f
42 Without options, each NAME is enabled.
44 To use the `test' found in $PATH instead of the shell builtin
45 version, type `enable -n test'.
48 Returns success unless NAME is not a shell builtin or an error occurs.
53 #if defined (HAVE_UNISTD_H)
55 # include <sys/types.h>
61 #include "../bashansi.h"
62 #include "../bashintl.h"
65 #include "../builtins.h"
68 #include "bashgetopt.h"
70 #if defined (PROGRAMMABLE_COMPLETION)
71 # include "../pcomplete.h"
85 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
86 static int dyn_load_builtin __P((WORD_LIST *, int, char *));
89 #if defined (HAVE_DLCLOSE)
90 static int dyn_unload_builtin __P((char *));
91 static void delete_builtin __P((struct builtin *));
92 static int local_dlclose __P((void *));
95 static void list_some_builtins __P((int));
96 static int enable_shell_command __P((char *, int));
98 /* Enable/disable shell commands present in LIST. If list is not specified,
99 then print out a list of shell commands showing which are enabled and
100 which are disabled. */
102 enable_builtin (list)
107 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
111 result = EXECUTION_SUCCESS;
114 reset_internal_getopt ();
115 while ((opt = internal_getopt (list, "adnpsf:")) != -1)
132 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
134 filename = list_optarg;
137 builtin_error (_("dynamic loading not available"));
140 #if defined (HAVE_DLCLOSE)
145 builtin_error (_("dynamic loading not available"));
147 #endif /* HAVE_DLCLOSE */
156 #if defined (RESTRICTED_SHELL)
157 /* Restricted shells cannot load new builtins. */
158 if (restricted && (flags & (FFLAG|DFLAG)))
160 sh_restricted ((char *)NULL);
161 return (EXECUTION_FAILURE);
165 if (list == 0 || (flags & PFLAG))
167 filter = (flags & AFLAG) ? (ENABLED | DISABLED)
168 : (flags & NFLAG) ? DISABLED : ENABLED;
173 list_some_builtins (filter);
175 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
176 else if (flags & FFLAG)
178 filter = (flags & NFLAG) ? DISABLED : ENABLED;
182 result = dyn_load_builtin (list, filter, filename);
183 #if defined (PROGRAMMABLE_COMPLETION)
184 set_itemlist_dirty (&it_builtins);
188 #if defined (HAVE_DLCLOSE)
189 else if (flags & DFLAG)
193 opt = dyn_unload_builtin (list->word->word);
194 if (opt == EXECUTION_FAILURE)
195 result = EXECUTION_FAILURE;
198 #if defined (PROGRAMMABLE_COMPLETION)
199 set_itemlist_dirty (&it_builtins);
207 opt = enable_shell_command (list->word->word, flags & NFLAG);
209 if (opt == EXECUTION_FAILURE)
211 sh_notbuiltin (list->word->word);
212 result = EXECUTION_FAILURE;
220 /* List some builtins.
221 FILTER is a mask with two slots: ENABLED and DISABLED. */
223 list_some_builtins (filter)
228 for (i = 0; i < num_shell_builtins; i++)
230 if (shell_builtins[i].function == 0 || (shell_builtins[i].flags & BUILTIN_DELETED))
233 if ((filter & SPECIAL) &&
234 (shell_builtins[i].flags & SPECIAL_BUILTIN) == 0)
237 if ((filter & ENABLED) && (shell_builtins[i].flags & BUILTIN_ENABLED))
238 printf ("enable %s\n", shell_builtins[i].name);
239 else if ((filter & DISABLED) &&
240 ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
241 printf ("enable -n %s\n", shell_builtins[i].name);
245 /* Enable the shell command NAME. If DISABLE_P is non-zero, then
246 disable NAME instead. */
248 enable_shell_command (name, disable_p)
254 b = builtin_address_internal (name, 1);
256 return (EXECUTION_FAILURE);
259 b->flags &= ~BUILTIN_ENABLED;
260 #if defined (RESTRICTED_SHELL)
261 else if (restricted && ((b->flags & BUILTIN_ENABLED) == 0))
263 sh_restricted ((char *)NULL);
264 return (EXECUTION_FAILURE);
268 b->flags |= BUILTIN_ENABLED;
270 #if defined (PROGRAMMABLE_COMPLETION)
271 set_itemlist_dirty (&it_enabled);
272 set_itemlist_dirty (&it_disabled);
275 return (EXECUTION_SUCCESS);
278 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
280 #if defined (HAVE_DLFCN_H)
285 dyn_load_builtin (list, flags, filename)
293 int total, size, new, replaced;
294 char *struct_name, *name;
295 struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin;
298 return (EXECUTION_FAILURE);
305 handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL);
307 handle = dlopen (filename, RTLD_LAZY);
312 builtin_error (_("cannot open shared object %s: %s"), filename, dlerror ());
313 return (EXECUTION_FAILURE);
316 for (new = 0, l = list; l; l = l->next, new++)
318 new_builtins = (struct builtin **)xmalloc (new * sizeof (struct builtin *));
320 /* For each new builtin in the shared object, find it and its describing
321 structure. If this is overwriting an existing builtin, do so, otherwise
322 save the loaded struct for creating the new list of builtins. */
323 for (replaced = new = 0; list; list = list->next)
325 name = list->word->word;
327 size = strlen (name);
328 struct_name = (char *)xmalloc (size + 8);
329 strcpy (struct_name, name);
330 strcpy (struct_name + size, "_struct");
332 b = (struct builtin *)dlsym (handle, struct_name);
335 builtin_error (_("cannot find %s in shared object %s: %s"),
336 struct_name, filename, dlerror ());
343 b->flags &= ~STATIC_BUILTIN;
345 b->flags |= SPECIAL_BUILTIN;
348 if (old_builtin = builtin_address_internal (name, 1))
351 FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin));
354 new_builtins[new++] = b;
357 if (replaced == 0 && new == 0)
361 return (EXECUTION_FAILURE);
366 total = num_shell_builtins + new;
367 size = (total + 1) * sizeof (struct builtin);
369 new_shell_builtins = (struct builtin *)xmalloc (size);
370 FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
371 num_shell_builtins * sizeof (struct builtin));
372 for (replaced = 0; replaced < new; replaced++)
373 FASTCOPY ((char *)new_builtins[replaced],
374 (char *)&new_shell_builtins[num_shell_builtins + replaced],
375 sizeof (struct builtin));
377 new_shell_builtins[total].name = (char *)0;
378 new_shell_builtins[total].function = (sh_builtin_func_t *)0;
379 new_shell_builtins[total].flags = 0;
381 if (shell_builtins != static_shell_builtins)
382 free (shell_builtins);
384 shell_builtins = new_shell_builtins;
385 num_shell_builtins = total;
386 initialize_shell_builtins ();
390 return (EXECUTION_SUCCESS);
394 #if defined (HAVE_DLCLOSE)
400 struct builtin *new_shell_builtins;
402 /* XXX - funky pointer arithmetic - XXX */
404 ind = b - shell_builtins;
406 ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin);
408 size = num_shell_builtins * sizeof (struct builtin);
409 new_shell_builtins = (struct builtin *)xmalloc (size);
411 /* Copy shell_builtins[0]...shell_builtins[ind - 1] to new_shell_builtins */
413 FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
414 ind * sizeof (struct builtin));
415 /* Copy shell_builtins[ind+1]...shell_builtins[num_shell_builtins to
416 new_shell_builtins, starting at ind. */
417 FASTCOPY ((char *)(&shell_builtins[ind+1]),
418 (char *)(&new_shell_builtins[ind]),
419 (num_shell_builtins - ind) * sizeof (struct builtin));
421 if (shell_builtins != static_shell_builtins)
422 free (shell_builtins);
424 /* The result is still sorted. */
425 num_shell_builtins--;
426 shell_builtins = new_shell_builtins;
429 /* Tenon's MachTen has a dlclose that doesn't return a value, so we
430 finesse it with a local wrapper. */
432 local_dlclose (handle)
435 #if !defined (__MACHTEN__)
436 return (dlclose (handle));
437 #else /* __MACHTEN__ */
439 return ((dlerror () != NULL) ? -1 : 0);
440 #endif /* __MACHTEN__ */
444 dyn_unload_builtin (name)
451 b = builtin_address_internal (name, 1);
454 sh_notbuiltin (name);
455 return (EXECUTION_FAILURE);
457 if (b->flags & STATIC_BUILTIN)
459 builtin_error (_("%s: not dynamically loaded"), name);
460 return (EXECUTION_FAILURE);
463 handle = (void *)b->handle;
464 for (ref = i = 0; i < num_shell_builtins; i++)
466 if (shell_builtins[i].handle == b->handle)
470 /* Don't remove the shared object unless the reference count of builtins
471 using it drops to zero. */
472 if (ref == 1 && local_dlclose (handle) != 0)
474 builtin_error (_("%s: cannot delete: %s"), name, dlerror ());
475 return (EXECUTION_FAILURE);
478 /* Now remove this entry from the builtin table and reinitialize. */
481 return (EXECUTION_SUCCESS);