1 This file is enable.def
, from which is created enable.c.
2 It implements the builtin
"enable" in Bash.
4 Copyright (C
) 1987-2003 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
2, 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
, 59 Temple Place
, Suite
330, Boston
, MA
02111 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 without specifying a full pathname. If
-n is used
, the
30 NAMEs become disabled
; otherwise NAMEs are enabled. For example
,
31 to use the `test
' found in $PATH instead of the shell builtin
32 version, type `enable -n test'. On systems supporting dynamic
33 loading
, the
-f option may be used to load new builtins from the
34 shared object FILENAME. The
-d option will delete a builtin
35 previously loaded with
-f. If no non
-option names are given
, or
36 the
-p option is supplied
, a list of builtins is printed. The
37 -a option means to print every builtin with an indication of whether
38 or not it is enabled. The
-s option restricts the output to the POSIX
.2
39 `special
' builtins. The -n option displays a list of all disabled builtins.
44 #if defined (HAVE_UNISTD_H)
46 # include <sys/types.h>
52 #include "../bashansi.h"
53 #include "../bashintl.h"
56 #include "../builtins.h"
59 #include "bashgetopt.h"
61 #if defined (PROGRAMMABLE_COMPLETION)
62 # include "../pcomplete.h"
76 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
77 static int dyn_load_builtin __P((WORD_LIST *, int, char *));
80 #if defined (HAVE_DLCLOSE)
81 static int dyn_unload_builtin __P((char *));
82 static void delete_builtin __P((struct builtin *));
83 static int local_dlclose __P((void *));
86 static void list_some_builtins __P((int));
87 static int enable_shell_command __P((char *, int));
89 /* Enable/disable shell commands present in LIST. If list is not specified,
90 then print out a list of shell commands showing which are enabled and
91 which are disabled. */
98 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
102 result = EXECUTION_SUCCESS;
105 reset_internal_getopt ();
106 while ((opt = internal_getopt (list, "adnpsf:")) != -1)
123 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
125 filename = list_optarg;
128 builtin_error (_("dynamic loading not available"));
131 #if defined (HAVE_DLCLOSE)
136 builtin_error (_("dynamic loading not available"));
138 #endif /* HAVE_DLCLOSE */
147 #if defined (RESTRICTED_SHELL)
148 /* Restricted shells cannot load new builtins. */
149 if (restricted && (flags & (FFLAG|DFLAG)))
151 sh_restricted ((char *)NULL);
152 return (EXECUTION_FAILURE);
156 if (list == 0 || (flags & PFLAG))
158 filter = (flags & AFLAG) ? (ENABLED | DISABLED)
159 : (flags & NFLAG) ? DISABLED : ENABLED;
164 list_some_builtins (filter);
166 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
167 else if (flags & FFLAG)
169 filter = (flags & NFLAG) ? DISABLED : ENABLED;
173 result = dyn_load_builtin (list, filter, filename);
174 #if defined (PROGRAMMABLE_COMPLETION)
175 set_itemlist_dirty (&it_builtins);
179 #if defined (HAVE_DLCLOSE)
180 else if (flags & DFLAG)
184 opt = dyn_unload_builtin (list->word->word);
185 if (opt == EXECUTION_FAILURE)
186 result = EXECUTION_FAILURE;
189 #if defined (PROGRAMMABLE_COMPLETION)
190 set_itemlist_dirty (&it_builtins);
198 opt = enable_shell_command (list->word->word, flags & NFLAG);
200 if (opt == EXECUTION_FAILURE)
202 sh_notbuiltin (list->word->word);
203 result = EXECUTION_FAILURE;
211 /* List some builtins.
212 FILTER is a mask with two slots: ENABLED and DISABLED. */
214 list_some_builtins (filter)
219 for (i = 0; i < num_shell_builtins; i++)
221 if (shell_builtins[i].function == 0 || (shell_builtins[i].flags & BUILTIN_DELETED))
224 if ((filter & SPECIAL) &&
225 (shell_builtins[i].flags & SPECIAL_BUILTIN) == 0)
228 if ((filter & ENABLED) && (shell_builtins[i].flags & BUILTIN_ENABLED))
229 printf ("enable %s\n", shell_builtins[i].name);
230 else if ((filter & DISABLED) &&
231 ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
232 printf ("enable -n %s\n", shell_builtins[i].name);
236 /* Enable the shell command NAME. If DISABLE_P is non-zero, then
237 disable NAME instead. */
239 enable_shell_command (name, disable_p)
245 b = builtin_address_internal (name, 1);
247 return (EXECUTION_FAILURE);
250 b->flags &= ~BUILTIN_ENABLED;
251 #if defined (RESTRICTED_SHELL)
252 else if (restricted && ((b->flags & BUILTIN_ENABLED) == 0))
254 sh_restricted ((char *)NULL);
255 return (EXECUTION_FAILURE);
259 b->flags |= BUILTIN_ENABLED;
261 #if defined (PROGRAMMABLE_COMPLETION)
262 set_itemlist_dirty (&it_enabled);
263 set_itemlist_dirty (&it_disabled);
266 return (EXECUTION_SUCCESS);
269 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
271 #if defined (HAVE_DLFCN_H)
276 dyn_load_builtin (list, flags, filename)
284 int total, size, new, replaced;
285 char *struct_name, *name;
286 struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin;
289 return (EXECUTION_FAILURE);
296 handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL);
298 handle = dlopen (filename, RTLD_LAZY);
303 builtin_error (_("cannot open shared object %s: %s"), filename, dlerror ());
304 return (EXECUTION_FAILURE);
307 for (new = 0, l = list; l; l = l->next, new++)
309 new_builtins = (struct builtin **)xmalloc (new * sizeof (struct builtin *));
311 /* For each new builtin in the shared object, find it and its describing
312 structure. If this is overwriting an existing builtin, do so, otherwise
313 save the loaded struct for creating the new list of builtins. */
314 for (replaced = new = 0; list; list = list->next)
316 name = list->word->word;
318 size = strlen (name);
319 struct_name = (char *)xmalloc (size + 8);
320 strcpy (struct_name, name);
321 strcpy (struct_name + size, "_struct");
323 b = (struct builtin *)dlsym (handle, struct_name);
326 builtin_error (_("cannot find %s in shared object %s: %s"),
327 struct_name, filename, dlerror ());
334 b->flags &= ~STATIC_BUILTIN;
336 b->flags |= SPECIAL_BUILTIN;
339 if (old_builtin = builtin_address_internal (name, 1))
342 FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin));
345 new_builtins[new++] = b;
348 if (replaced == 0 && new == 0)
352 return (EXECUTION_FAILURE);
357 total = num_shell_builtins + new;
358 size = (total + 1) * sizeof (struct builtin);
360 new_shell_builtins = (struct builtin *)xmalloc (size);
361 FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
362 num_shell_builtins * sizeof (struct builtin));
363 for (replaced = 0; replaced < new; replaced++)
364 FASTCOPY ((char *)new_builtins[replaced],
365 (char *)&new_shell_builtins[num_shell_builtins + replaced],
366 sizeof (struct builtin));
368 new_shell_builtins[total].name = (char *)0;
369 new_shell_builtins[total].function = (sh_builtin_func_t *)0;
370 new_shell_builtins[total].flags = 0;
372 if (shell_builtins != static_shell_builtins)
373 free (shell_builtins);
375 shell_builtins = new_shell_builtins;
376 num_shell_builtins = total;
377 initialize_shell_builtins ();
381 return (EXECUTION_SUCCESS);
385 #if defined (HAVE_DLCLOSE)
391 struct builtin *new_shell_builtins;
393 /* XXX - funky pointer arithmetic - XXX */
395 ind = b - shell_builtins;
397 ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin);
399 size = num_shell_builtins * sizeof (struct builtin);
400 new_shell_builtins = (struct builtin *)xmalloc (size);
402 /* Copy shell_builtins[0]...shell_builtins[ind - 1] to new_shell_builtins */
404 FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
405 ind * sizeof (struct builtin));
406 /* Copy shell_builtins[ind+1]...shell_builtins[num_shell_builtins to
407 new_shell_builtins, starting at ind. */
408 FASTCOPY ((char *)(&shell_builtins[ind+1]),
409 (char *)(&new_shell_builtins[ind]),
410 (num_shell_builtins - ind) * sizeof (struct builtin));
412 if (shell_builtins != static_shell_builtins)
413 free (shell_builtins);
415 /* The result is still sorted. */
416 num_shell_builtins--;
417 shell_builtins = new_shell_builtins;
420 /* Tenon's MachTen has a dlclose that doesn
't return a value, so we
421 finesse it with a local wrapper. */
423 local_dlclose (handle)
426 #if !defined (__MACHTEN__)
427 return (dlclose (handle));
428 #else /* __MACHTEN__ */
430 return ((dlerror () != NULL) ? -1 : 0);
431 #endif /* __MACHTEN__ */
435 dyn_unload_builtin (name)
442 b = builtin_address_internal (name, 1);
445 sh_notbuiltin (name);
446 return (EXECUTION_FAILURE);
448 if (b->flags & STATIC_BUILTIN)
450 builtin_error (_("%s: not dynamically loaded"), name);
451 return (EXECUTION_FAILURE);
454 handle = (void *)b->handle;
455 for (ref = i = 0; i < num_shell_builtins; i++)
457 if (shell_builtins[i].handle == b->handle)
461 /* Don't remove the shared object unless the reference count of builtins
462 using it drops to zero.
*/
463 if (ref
== 1 && local_dlclose (handle
) != 0)
465 builtin_error (_("%s: cannot delete: %s"), name
, dlerror ());
466 return (EXECUTION_FAILURE
);
469 /* Now remove this entry from the builtin table and reinitialize.
*/
472 return (EXECUTION_SUCCESS
);