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 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"
54 #include "../builtins.h"
57 #include "bashgetopt.h"
59 #if defined (PROGRAMMABLE_COMPLETION)
60 # include "../pcomplete.h"
74 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
75 static int dyn_load_builtin __P((WORD_LIST *, int, char *));
78 #if defined (HAVE_DLCLOSE)
79 static int dyn_unload_builtin __P((char *));
80 static void delete_builtin __P((struct builtin *));
81 static int local_dlclose __P((void *));
84 static void list_some_builtins __P((int));
85 static int enable_shell_command __P((char *, int));
87 /* Enable/disable shell commands present in LIST. If list is not specified,
88 then print out a list of shell commands showing which are enabled and
89 which are disabled. */
96 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
100 result = EXECUTION_SUCCESS;
103 reset_internal_getopt ();
104 while ((opt = internal_getopt (list, "adnpsf:")) != -1)
121 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
123 filename = list_optarg;
126 builtin_error ("dynamic loading not available");
129 #if defined (HAVE_DLCLOSE)
134 builtin_error ("dynamic loading not available");
136 #endif /* HAVE_DLCLOSE */
145 #if defined (RESTRICTED_SHELL)
146 /* Restricted shells cannot load new builtins. */
147 if (restricted && (flags & (FFLAG|DFLAG)))
149 builtin_error ("restricted");
150 return (EXECUTION_FAILURE);
154 if (list == 0 || (flags & PFLAG))
156 filter = (flags & AFLAG) ? (ENABLED | DISABLED)
157 : (flags & NFLAG) ? DISABLED : ENABLED;
162 list_some_builtins (filter);
164 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
165 else if (flags & FFLAG)
167 filter = (flags & NFLAG) ? DISABLED : ENABLED;
171 result = dyn_load_builtin (list, filter, filename);
172 #if defined (PROGRAMMABLE_COMPLETION)
173 set_itemlist_dirty (&it_builtins);
177 #if defined (HAVE_DLCLOSE)
178 else if (flags & DFLAG)
182 opt = dyn_unload_builtin (list->word->word);
183 if (opt == EXECUTION_FAILURE)
184 result = EXECUTION_FAILURE;
187 #if defined (PROGRAMMABLE_COMPLETION)
188 set_itemlist_dirty (&it_builtins);
196 opt = enable_shell_command (list->word->word, flags & NFLAG);
198 if (opt == EXECUTION_FAILURE)
200 builtin_error ("%s: not a shell builtin", list->word->word);
201 result = EXECUTION_FAILURE;
209 /* List some builtins.
210 FILTER is a mask with two slots: ENABLED and DISABLED. */
212 list_some_builtins (filter)
217 for (i = 0; i < num_shell_builtins; i++)
219 if (shell_builtins[i].function == 0 || (shell_builtins[i].flags & BUILTIN_DELETED))
222 if ((filter & SPECIAL) &&
223 (shell_builtins[i].flags & SPECIAL_BUILTIN) == 0)
226 if ((filter & ENABLED) && (shell_builtins[i].flags & BUILTIN_ENABLED))
227 printf ("enable %s\n", shell_builtins[i].name);
228 else if ((filter & DISABLED) &&
229 ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
230 printf ("enable -n %s\n", shell_builtins[i].name);
234 /* Enable the shell command NAME. If DISABLE_P is non-zero, then
235 disable NAME instead. */
237 enable_shell_command (name, disable_p)
243 b = builtin_address_internal (name, 1);
245 return (EXECUTION_FAILURE);
248 b->flags &= ~BUILTIN_ENABLED;
250 b->flags |= BUILTIN_ENABLED;
252 #if defined (PROGRAMMABLE_COMPLETION)
253 set_itemlist_dirty (&it_enabled);
254 set_itemlist_dirty (&it_disabled);
257 return (EXECUTION_SUCCESS);
260 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
262 #if defined (HAVE_DLFCN_H)
267 dyn_load_builtin (list, flags, filename)
275 int total, size, new, replaced;
276 char *struct_name, *name;
277 struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin;
280 return (EXECUTION_FAILURE);
287 handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL);
289 handle = dlopen (filename, RTLD_LAZY);
294 builtin_error ("cannot open shared object %s: %s", filename, dlerror ());
295 return (EXECUTION_FAILURE);
298 for (new = 0, l = list; l; l = l->next, new++)
300 new_builtins = (struct builtin **)xmalloc (new * sizeof (struct builtin *));
302 /* For each new builtin in the shared object, find it and its describing
303 structure. If this is overwriting an existing builtin, do so, otherwise
304 save the loaded struct for creating the new list of builtins. */
305 for (replaced = new = 0; list; list = list->next)
307 name = list->word->word;
309 size = strlen (name);
310 struct_name = (char *)xmalloc (size + 8);
311 strcpy (struct_name, name);
312 strcpy (struct_name + size, "_struct");
314 b = (struct builtin *)dlsym (handle, struct_name);
317 builtin_error ("cannot find %s in shared object %s: %s", struct_name,
318 filename, dlerror ());
325 b->flags &= ~STATIC_BUILTIN;
327 b->flags |= SPECIAL_BUILTIN;
330 if (old_builtin = builtin_address_internal (name, 1))
333 FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin));
336 new_builtins[new++] = b;
339 if (replaced == 0 && new == 0)
343 return (EXECUTION_FAILURE);
348 total = num_shell_builtins + new;
349 size = (total + 1) * sizeof (struct builtin);
351 new_shell_builtins = (struct builtin *)xmalloc (size);
352 FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
353 num_shell_builtins * sizeof (struct builtin));
354 for (replaced = 0; replaced < new; replaced++)
355 FASTCOPY ((char *)new_builtins[replaced],
356 (char *)&new_shell_builtins[num_shell_builtins + replaced],
357 sizeof (struct builtin));
359 new_shell_builtins[total].name = (char *)0;
360 new_shell_builtins[total].function = (sh_builtin_func_t *)0;
361 new_shell_builtins[total].flags = 0;
363 if (shell_builtins != static_shell_builtins)
364 free (shell_builtins);
366 shell_builtins = new_shell_builtins;
367 num_shell_builtins = total;
368 initialize_shell_builtins ();
372 return (EXECUTION_SUCCESS);
376 #if defined (HAVE_DLCLOSE)
382 struct builtin *new_shell_builtins;
384 /* XXX - funky pointer arithmetic - XXX */
386 ind = b - shell_builtins;
388 ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin);
390 size = num_shell_builtins * sizeof (struct builtin);
391 new_shell_builtins = (struct builtin *)xmalloc (size);
393 /* Copy shell_builtins[0]...shell_builtins[ind - 1] to new_shell_builtins */
395 FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
396 ind * sizeof (struct builtin));
397 /* Copy shell_builtins[ind+1]...shell_builtins[num_shell_builtins to
398 new_shell_builtins, starting at ind. */
399 FASTCOPY ((char *)(&shell_builtins[ind+1]),
400 (char *)(&new_shell_builtins[ind]),
401 (num_shell_builtins - ind) * sizeof (struct builtin));
403 if (shell_builtins != static_shell_builtins)
404 free (shell_builtins);
406 /* The result is still sorted. */
407 num_shell_builtins--;
408 shell_builtins = new_shell_builtins;
411 /* Tenon's MachTen has a dlclose that doesn't return a value, so we
412 finesse it with a local wrapper. */
414 local_dlclose (handle)
417 #if !defined (__MACHTEN__)
418 return (dlclose (handle));
419 #else /* __MACHTEN__ */
421 return ((dlerror () != NULL) ? -1 : 0);
422 #endif /* __MACHTEN__ */
426 dyn_unload_builtin (name)
433 b = builtin_address_internal (name, 1);
436 builtin_error ("%s: not a shell builtin", name);
437 return (EXECUTION_FAILURE);
439 if (b->flags & STATIC_BUILTIN)
441 builtin_error ("%s: not dynamically loaded", name);
442 return (EXECUTION_FAILURE);
445 handle = (void *)b->handle;
446 for (ref = i = 0; i < num_shell_builtins; i++)
448 if (shell_builtins[i].handle == b->handle)
452 /* Don't remove the shared object unless the reference count of builtins
453 using it drops to zero. */
454 if (ref == 1 && local_dlclose (handle) != 0)
456 builtin_error ("cannot delete %s: %s", name, dlerror ());
457 return (EXECUTION_FAILURE);
460 /* Now remove this entry from the builtin table and reinitialize. */
463 return (EXECUTION_SUCCESS);