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)
49 #include "../bashansi.h"
51 #include "../builtins.h"
54 #include "bashgetopt.h"
56 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
57 static int dyn_load_builtin ();
60 #if defined (HAVE_DLCLOSE)
61 static int dyn_unload_builtin ();
75 static int enable_shell_command ();
76 static void list_some_builtins ();
78 /* Enable/disable shell commands present in LIST. If list is not specified,
79 then print out a list of shell commands showing which are enabled and
80 which are disabled. */
87 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
91 result = EXECUTION_SUCCESS;
94 reset_internal_getopt ();
95 while ((opt = internal_getopt (list, "adnpsf:")) != -1)
112 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
114 filename = list_optarg;
117 builtin_error ("dynamic loading not available");
120 #if defined (HAVE_DLCLOSE)
125 builtin_error ("dynamic loading not available");
127 #endif /* HAVE_DLCLOSE */
136 #if defined (RESTRICTED_SHELL)
137 /* Restricted shells cannot load new builtins. */
138 if (restricted && (flags & (FFLAG|DFLAG)))
140 builtin_error ("restricted");
141 return (EXECUTION_FAILURE);
145 if (list == 0 || (flags & PFLAG))
147 filter = (flags & AFLAG) ? (ENABLED | DISABLED)
148 : (flags & NFLAG) ? DISABLED : ENABLED;
153 list_some_builtins (filter);
155 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
156 else if (flags & FFLAG)
158 filter = (flags & NFLAG) ? DISABLED : ENABLED;
162 result = dyn_load_builtin (list, filter, filename);
165 #if defined (HAVE_DLCLOSE)
166 else if (flags & DFLAG)
170 opt = dyn_unload_builtin (list->word->word);
171 if (opt == EXECUTION_FAILURE)
172 result = EXECUTION_FAILURE;
181 opt = enable_shell_command (list->word->word, flags & NFLAG);
183 if (opt == EXECUTION_FAILURE)
185 builtin_error ("%s: not a shell builtin", list->word->word);
186 result = EXECUTION_FAILURE;
194 /* List some builtins.
195 FILTER is a mask with two slots: ENABLED and DISABLED. */
197 list_some_builtins (filter)
202 for (i = 0; i < num_shell_builtins; i++)
204 if (shell_builtins[i].function == 0 || (shell_builtins[i].flags & BUILTIN_DELETED))
207 if ((filter & SPECIAL) &&
208 (shell_builtins[i].flags & SPECIAL_BUILTIN) == 0)
211 if ((filter & ENABLED) && (shell_builtins[i].flags & BUILTIN_ENABLED))
212 printf ("enable %s\n", shell_builtins[i].name);
213 else if ((filter & DISABLED) &&
214 ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
215 printf ("enable -n %s\n", shell_builtins[i].name);
219 /* Enable the shell command NAME. If DISABLE_P is non-zero, then
220 disable NAME instead. */
222 enable_shell_command (name, disable_p)
228 b = builtin_address_internal (name, 1);
230 return (EXECUTION_FAILURE);
233 b->flags &= ~BUILTIN_ENABLED;
235 b->flags |= BUILTIN_ENABLED;
237 return (EXECUTION_SUCCESS);
240 #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
244 dyn_load_builtin (list, flags, filename)
252 int total, size, new, replaced;
253 char *struct_name, *name;
254 struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin;
257 return (EXECUTION_FAILURE);
264 handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL);
266 handle = dlopen (filename, RTLD_LAZY);
271 builtin_error ("cannot open shared object %s: %s", filename, dlerror ());
272 return (EXECUTION_FAILURE);
275 for (new = 0, l = list; l; l = l->next, new++)
277 new_builtins = (struct builtin **)xmalloc (new * sizeof (struct builtin *));
279 /* For each new builtin in the shared object, find it and its describing
280 structure. If this is overwriting an existing builtin, do so, otherwise
281 save the loaded struct for creating the new list of builtins. */
282 for (replaced = new = 0; list; list = list->next)
284 name = list->word->word;
286 size = strlen (name);
287 struct_name = xmalloc (size + 8);
288 strcpy (struct_name, name);
289 strcpy (struct_name + size, "_struct");
291 b = (struct builtin *)dlsym (handle, struct_name);
294 builtin_error ("cannot find %s in shared object %s: %s", struct_name,
295 filename, dlerror ());
302 b->flags &= ~STATIC_BUILTIN;
304 b->flags |= SPECIAL_BUILTIN;
307 if (old_builtin = builtin_address_internal (name, 1))
310 FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin));
313 new_builtins[new++] = b;
316 if (replaced == 0 && new == 0)
320 return (EXECUTION_FAILURE);
325 total = num_shell_builtins + new;
326 size = (total + 1) * sizeof (struct builtin);
328 new_shell_builtins = (struct builtin *)xmalloc (size);
329 FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
330 num_shell_builtins * sizeof (struct builtin));
331 for (replaced = 0; replaced < new; replaced++)
332 FASTCOPY ((char *)new_builtins[replaced],
333 (char *)&new_shell_builtins[num_shell_builtins + replaced],
334 sizeof (struct builtin));
336 new_shell_builtins[total].name = (char *)0;
337 new_shell_builtins[total].function = (Function *)0;
338 new_shell_builtins[total].flags = 0;
340 if (shell_builtins != static_shell_builtins)
341 free (shell_builtins);
343 shell_builtins = new_shell_builtins;
344 num_shell_builtins = total;
345 initialize_shell_builtins ();
349 return (EXECUTION_SUCCESS);
353 #if defined (HAVE_DLCLOSE)
359 struct builtin *new_shell_builtins;
361 /* XXX - funky pointer arithmetic - XXX */
362 ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin);
363 size = num_shell_builtins * sizeof (struct builtin);
364 new_shell_builtins = (struct builtin *)xmalloc (size);
366 /* Copy shell_builtins[0]...shell_builtins[ind - 1] to new_shell_builtins */
368 FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins,
369 ind * sizeof (struct builtin));
370 /* Copy shell_builtins[ind+1]...shell_builtins[num_shell_builtins to
371 new_shell_builtins, starting at ind. */
372 FASTCOPY ((char *)(&shell_builtins[ind+1]),
373 (char *)(&new_shell_builtins[ind]),
374 (num_shell_builtins - ind) * sizeof (struct builtin));
376 if (shell_builtins != static_shell_builtins)
377 free (shell_builtins);
379 /* The result is still sorted. */
380 num_shell_builtins--;
381 shell_builtins = new_shell_builtins;
385 dyn_unload_builtin (name)
392 b = builtin_address_internal (name, 1);
395 builtin_error ("%s: not a shell builtin", name);
396 return (EXECUTION_FAILURE);
398 if (b->flags & STATIC_BUILTIN)
400 builtin_error ("%s: not dynamically loaded", name);
401 return (EXECUTION_FAILURE);
404 handle = (void *)b->handle;
405 for (ref = i = 0; i < num_shell_builtins; i++)
407 if (shell_builtins[i].handle == b->handle)
411 /* Don't remove the shared object unless the reference count of builtins
412 using it drops to zero. */
413 if (ref == 1 && dlclose (handle) != 0)
415 builtin_error ("cannot delete %s: %s", name, dlerror ());
416 return (EXECUTION_FAILURE);
419 /* Now remove this entry from the builtin table and reinitialize. */
422 return (EXECUTION_SUCCESS);