summaryrefslogtreecommitdiff
path: root/builtins/enable.def
diff options
context:
space:
mode:
Diffstat (limited to 'builtins/enable.def')
-rw-r--r--builtins/enable.def54
1 files changed, 44 insertions, 10 deletions
diff --git a/builtins/enable.def b/builtins/enable.def
index 9d9010b7..27d341a6 100644
--- a/builtins/enable.def
+++ b/builtins/enable.def
@@ -1,7 +1,7 @@
This file is enable.def, from which is created enable.c.
It implements the builtin "enable" in Bash.
-Copyright (C) 1987-2020 Free Software Foundation, Inc.
+Copyright (C) 1987-2021 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -75,6 +75,7 @@ $END
#define ENABLED 1
#define DISABLED 2
#define SPECIAL 4
+#define SILENT 8 /* affects dyn_load_builtin behavior */
#define AFLAG 0x01
#define DFLAG 0x02
@@ -110,6 +111,7 @@ enable_builtin (list)
{
int result, flags;
int opt, filter;
+ WORD_LIST *next;
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
char *filename;
#endif
@@ -178,6 +180,7 @@ enable_builtin (list)
filter |= SPECIAL;
list_some_builtins (filter);
+ result = sh_chkwrite (EXECUTION_SUCCESS);
}
#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
else if (flags & FFLAG)
@@ -187,6 +190,8 @@ enable_builtin (list)
filter |= SPECIAL;
result = dyn_load_builtin (list, filter, filename);
+ if (result != EXECUTION_SUCCESS)
+ result = EXECUTION_FAILURE; /* normalize return value */
#if defined (PROGRAMMABLE_COMPLETION)
set_itemlist_dirty (&it_builtins);
#endif
@@ -212,13 +217,37 @@ enable_builtin (list)
while (list)
{
opt = enable_shell_command (list->word->word, flags & NFLAG);
+ next = list->next;
- if (opt == EXECUTION_FAILURE)
+#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM)
+ /* If we try to enable a non-existent builtin, and we have dynamic
+ loading, try the equivalent of `enable -f name name'. */
+ if (opt == EX_NOTFOUND)
+ {
+ int dflags, r;
+
+ dflags = ENABLED|SILENT|((flags & SFLAG) ? SPECIAL : 0);
+
+ list->next = 0;
+ r = dyn_load_builtin (list, dflags, list->word->word);
+ list->next = next;
+ if (r == EXECUTION_SUCCESS)
+ opt = r;
+#if defined (PROGRAMMABLE_COMPLETION)
+ set_itemlist_dirty (&it_builtins);
+#endif
+ }
+#endif
+
+ if (opt == EX_NOTFOUND)
{
sh_notbuiltin (list->word->word);
result = EXECUTION_FAILURE;
}
- list = list->next;
+ else if (opt != EXECUTION_SUCCESS)
+ result = EXECUTION_FAILURE;
+
+ list = next;
}
}
return (result);
@@ -260,7 +289,7 @@ enable_shell_command (name, disable_p)
b = builtin_address_internal (name, 1);
if (b == 0)
- return (EXECUTION_FAILURE);
+ return (EX_NOTFOUND);
if (disable_p)
b->flags &= ~BUILTIN_ENABLED;
@@ -339,11 +368,16 @@ dyn_load_builtin (list, flags, filename)
if (handle == 0)
{
- name = printable_filename (filename, 0);
- builtin_error (_("cannot open shared object %s: %s"), name, dlerror ());
- if (name != filename)
- free (name);
- return (EXECUTION_FAILURE);
+ /* If we've been told to be quiet, don't complain about not finding the
+ specified shared object. */
+ if ((flags & SILENT) == 0)
+ {
+ name = printable_filename (filename, 0);
+ builtin_error (_("cannot open shared object %s: %s"), name, dlerror ());
+ if (name != filename)
+ free (name);
+ }
+ return (EX_NOTFOUND);
}
for (new = 0, l = list; l; l = l->next, new++)
@@ -369,7 +403,7 @@ dyn_load_builtin (list, flags, filename)
{
name = printable_filename (filename, 0);
builtin_error (_("cannot find %s in shared object %s: %s"),
- struct_name, name, dlerror ());
+ struct_name, name, dlerror ());
if (name != filename)
free (name);
free (struct_name);