"enable name" when name is not a shell builtin attempts to load it from a shared object

This commit is contained in:
Chet Ramey
2021-08-02 12:07:40 -04:00
parent 6c84d09c19
commit 0edd0a9183
9 changed files with 9275 additions and 9197 deletions
+25 -9177
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+43 -10
View File
@@ -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
@@ -188,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
@@ -213,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);
@@ -261,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;
@@ -340,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++)
@@ -370,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);
+7 -2
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
.\" Last Change: Wed Jun 16 09:50:34 EDT 2021
.\" Last Change: Fri Jul 30 15:05:43 EDT 2021
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2021 June 16" "GNU Bash 5.1"
.TH BASH 1 "2021 July 30" "GNU Bash 5.1"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -8451,6 +8451,11 @@ If \fB\-a\fP is supplied, the list printed includes all builtins, with an
indication of whether or not each is enabled.
If \fB\-s\fP is supplied, the output is restricted to the POSIX
\fIspecial\fP builtins.
If no options are supplied and a \fIname\fP is not a shell builtin,
\fBenable\fP will attempt to load \fIname\fP from a shared object named
\fIname\fP, as if the command were
.if t \f(CWenable \-f\fP \fIname name\fP .
.if n ``enable -f \fIname name\fP .
The return value is 0 unless a
.I name
is not a shell builtin or there is an error loading a new builtin
+5
View File
@@ -4532,6 +4532,11 @@ The @option{-s} option restricts @code{enable} to the @sc{posix} special
builtins. If @option{-s} is used with @option{-f}, the new builtin becomes
a special builtin (@pxref{Special Builtins}).
If no options are supplied and a @var{name} is not a shell builtin,
@code{enable} will attempt to load @var{name} from a shared object named
@var{name}, as if the command were
@samp{enable -f @var{name} @var{name}}.
The return status is zero unless a @var{name} is not a shell builtin
or there is an error loading a new builtin from a shared object.
+3 -3
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2021 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Wed Jun 16 09:50:57 EDT 2021
@set LASTCHANGE Fri Jul 30 15:04:53 EDT 2021
@set EDITION 5.1
@set VERSION 5.1
@set UPDATED 16 June 2021
@set UPDATED-MONTH June 2021
@set UPDATED 30 July 2021
@set UPDATED-MONTH July 2021
+10 -3
View File
@@ -74,12 +74,19 @@ WORD_LIST *list;
r = uconvert(list->word->word, &sec, &usec, &ep);
/* Maybe postprocess conversion failures here based on EP */
if (r) {
if (r) {
fsleep(sec, usec);
QUIT;
return(EXECUTION_SUCCESS);
}
}
/*
* A heuristic: if the conversion failed, but the argument appears to
* contain a GNU-like interval specifier (e.g. "1m30s"), return the
* right exit code to tell execute_builtin to try and execute a disk
* command instead.
*/
if (strpbrk (list->word->word, "dhms"))
return(EX_DISKFALLBACK);
builtin_error("%s: bad sleep interval", list->word->word);
return (EXECUTION_FAILURE);
}
+4 -1
View File
@@ -4740,7 +4740,10 @@ run_builtin:
executing_builtin = old_builtin;
executing_command_builtin = old_command_builtin;
builtin = 0;
/* XXX - redirections will have to be performed again */
/* The redirections have already been `undone', so this
will have to do them again. But piping is forever. */
pipe_in = pipe_out = -1;
goto execute_from_filesystem;
}
result = builtin_status (result);
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/bash/bash-current
BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR