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);