From: Chet Ramey Date: Mon, 13 Dec 2021 14:37:23 +0000 (-0500) Subject: fix to make += work with dynamic integer vars like RANDOM X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=567c0bc2ed4ca24b68f8dd75625275b0e152ae5c;p=thirdparty%2Fbash.git fix to make += work with dynamic integer vars like RANDOM --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 821e85c03..9995e6167 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -2622,3 +2622,21 @@ lib/readline/colors.c - _rl_custom_readline_prefix: use STREQN to check for the extension string in $LS_COLORS, since it's not necessarily null-terminated. From https://savannah.gnu.org/patch/?10158 + + 12/10 + ----- +variables.c + - set_int_value,set_string_value: broke common code for setting int + and string dynamic variable values out into separate functions; + changed all callers to use them where appropriate. set_int_value + takes a flags argument saying whether or not to force the integer + attribute on + - assign_random: store the value assigned as the variable value so + things like RANDOM=42; RANDOM+=7 generate consistent sequences + like in ksh93 + - assign_seconds: store the value assigned as the variable value so + things like SECONDS=42 ; SECONDS+=7 generate what's expected + +doc/Makefile.in + - changes to allow man pages that include others (.so FN) to be built + outside the source tree diff --git a/doc/Makefile.in b/doc/Makefile.in index 4bcd42928..8bf775e14 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -107,11 +107,11 @@ BASHREF_FILES = $(srcdir)/bashref.texi $(srcdir)/fdl.texi $(srcdir)/version.texi .1.ps: $(RM) $@ - -${GROFF} -man $< > $@ + -${GROFF} -I${srcdir} -man $< > $@ .1.0: $(RM) $@ - -${NROFF} -man $< > $@ + -${NROFF} -I${srcdir} -man $< > $@ .1.html: $(RM) $@ @@ -127,11 +127,11 @@ BASHREF_FILES = $(srcdir)/bashref.texi $(srcdir)/fdl.texi $(srcdir)/version.texi .3.ps: $(RM) $@ - -${GROFF} -man $< > $@ + -${GROFF} -I${srcdir} -man $< > $@ .3.0: $(RM) $@ - -${NROFF} -man $< > $@ + -${NROFF} -I${srcdir} -man $< > $@ .3.html: $(RM) $@ diff --git a/doc/bash.0 b/doc/bash.0 index 62e1bab9d..472346063 100644 --- a/doc/bash.0 +++ b/doc/bash.0 @@ -1078,12 +1078,12 @@ PPAARRAAMMEETTEERRSS RREEPPLLYY Set to the line of input read by the rreeaadd builtin command when no arguments are supplied. SSEECCOONNDDSS - Each time this parameter is referenced, the number of seconds - since shell invocation is returned. If a value is assigned to + Each time this parameter is referenced, it expands to the number + of seconds since shell invocation. If a value is assigned to SSEECCOONNDDSS, the value returned upon subsequent references is the number of seconds since the assignment plus the value assigned. The number of seconds at shell invocation and the current time - is always determined by querying the system clock. If SSEECCOONNDDSS + are always determined by querying the system clock. If SSEECCOONNDDSS is unset, it loses its special properties, even if it is subse- quently reset. SSHHEELLLLOOPPTTSS diff --git a/doc/bash.1 b/doc/bash.1 index c3dee17b6..1cf056cc2 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -2014,14 +2014,14 @@ builtin command when no arguments are supplied. .TP .B SECONDS Each time this parameter is -referenced, the number of seconds since shell invocation is returned. If a -value is assigned to +referenced, it expands to the number of seconds since shell invocation. +If a value is assigned to .SM .BR SECONDS , the value returned upon subsequent references is the number of seconds since the assignment plus the value assigned. -The number of seconds at shell invocation and the current time is always +The number of seconds at shell invocation and the current time are always determined by querying the system clock. If .SM diff --git a/doc/bashref.info b/doc/bashref.info index 1361ce7c6..9bd3e92e3 100644 --- a/doc/bashref.info +++ b/doc/bashref.info @@ -5754,7 +5754,7 @@ Variables::). started. Assignment to this variable resets the count to the value assigned, and the expanded value becomes the value assigned plus the number of seconds since the assignment. The number of seconds - at shell invocation and the current time is always determined by + at shell invocation and the current time are always determined by querying the system clock. If 'SECONDS' is unset, it loses its special properties, even if it is subsequently reset. @@ -12476,77 +12476,77 @@ Node: Special Builtins216717 Node: Shell Variables217696 Node: Bourne Shell Variables218133 Node: Bash Variables220237 -Node: Bash Features253052 -Node: Invoking Bash254065 -Node: Bash Startup Files260078 -Node: Interactive Shells265181 -Node: What is an Interactive Shell?265591 -Node: Is this Shell Interactive?266240 -Node: Interactive Shell Behavior267055 -Node: Bash Conditional Expressions270684 -Node: Shell Arithmetic275326 -Node: Aliases278270 -Node: Arrays280883 -Node: The Directory Stack287130 -Node: Directory Stack Builtins287914 -Node: Controlling the Prompt292174 -Node: The Restricted Shell295139 -Node: Bash POSIX Mode297749 -Node: Shell Compatibility Mode309022 -Node: Job Control317051 -Node: Job Control Basics317511 -Node: Job Control Builtins322513 -Node: Job Control Variables327913 -Node: Command Line Editing329069 -Node: Introduction and Notation330740 -Node: Readline Interaction332363 -Node: Readline Bare Essentials333554 -Node: Readline Movement Commands335337 -Node: Readline Killing Commands336297 -Node: Readline Arguments338215 -Node: Searching339259 -Node: Readline Init File341445 -Node: Readline Init File Syntax342706 -Node: Conditional Init Constructs364194 -Node: Sample Init File368390 -Node: Bindable Readline Commands371514 -Node: Commands For Moving372718 -Node: Commands For History374769 -Node: Commands For Text379763 -Node: Commands For Killing383412 -Node: Numeric Arguments386445 -Node: Commands For Completion387584 -Node: Keyboard Macros391775 -Node: Miscellaneous Commands392462 -Node: Readline vi Mode398401 -Node: Programmable Completion399308 -Node: Programmable Completion Builtins407088 -Node: A Programmable Completion Example417783 -Node: Using History Interactively423030 -Node: Bash History Facilities423714 -Node: Bash History Builtins426719 -Node: History Interaction431727 -Node: Event Designators435347 -Node: Word Designators436701 -Node: Modifiers438461 -Node: Installing Bash440272 -Node: Basic Installation441409 -Node: Compilers and Options445131 -Node: Compiling For Multiple Architectures445872 -Node: Installation Names447565 -Node: Specifying the System Type449674 -Node: Sharing Defaults450390 -Node: Operation Controls451063 -Node: Optional Features452021 -Node: Reporting Bugs463239 -Node: Major Differences From The Bourne Shell464514 -Node: GNU Free Documentation License481364 -Node: Indexes506541 -Node: Builtin Index506995 -Node: Reserved Word Index513822 -Node: Variable Index516270 -Node: Function Index532762 -Node: Concept Index546546 +Node: Bash Features253053 +Node: Invoking Bash254066 +Node: Bash Startup Files260079 +Node: Interactive Shells265182 +Node: What is an Interactive Shell?265592 +Node: Is this Shell Interactive?266241 +Node: Interactive Shell Behavior267056 +Node: Bash Conditional Expressions270685 +Node: Shell Arithmetic275327 +Node: Aliases278271 +Node: Arrays280884 +Node: The Directory Stack287131 +Node: Directory Stack Builtins287915 +Node: Controlling the Prompt292175 +Node: The Restricted Shell295140 +Node: Bash POSIX Mode297750 +Node: Shell Compatibility Mode309023 +Node: Job Control317052 +Node: Job Control Basics317512 +Node: Job Control Builtins322514 +Node: Job Control Variables327914 +Node: Command Line Editing329070 +Node: Introduction and Notation330741 +Node: Readline Interaction332364 +Node: Readline Bare Essentials333555 +Node: Readline Movement Commands335338 +Node: Readline Killing Commands336298 +Node: Readline Arguments338216 +Node: Searching339260 +Node: Readline Init File341446 +Node: Readline Init File Syntax342707 +Node: Conditional Init Constructs364195 +Node: Sample Init File368391 +Node: Bindable Readline Commands371515 +Node: Commands For Moving372719 +Node: Commands For History374770 +Node: Commands For Text379764 +Node: Commands For Killing383413 +Node: Numeric Arguments386446 +Node: Commands For Completion387585 +Node: Keyboard Macros391776 +Node: Miscellaneous Commands392463 +Node: Readline vi Mode398402 +Node: Programmable Completion399309 +Node: Programmable Completion Builtins407089 +Node: A Programmable Completion Example417784 +Node: Using History Interactively423031 +Node: Bash History Facilities423715 +Node: Bash History Builtins426720 +Node: History Interaction431728 +Node: Event Designators435348 +Node: Word Designators436702 +Node: Modifiers438462 +Node: Installing Bash440273 +Node: Basic Installation441410 +Node: Compilers and Options445132 +Node: Compiling For Multiple Architectures445873 +Node: Installation Names447566 +Node: Specifying the System Type449675 +Node: Sharing Defaults450391 +Node: Operation Controls451064 +Node: Optional Features452022 +Node: Reporting Bugs463240 +Node: Major Differences From The Bourne Shell464515 +Node: GNU Free Documentation License481365 +Node: Indexes506542 +Node: Builtin Index506996 +Node: Reserved Word Index513823 +Node: Variable Index516271 +Node: Function Index532763 +Node: Concept Index546547  End Tag Table diff --git a/doc/bashref.texi b/doc/bashref.texi index a0b7ce5a9..ec538a384 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -6662,12 +6662,11 @@ with @samp{bind -x} (@pxref{Bash Builtins}). The default variable for the @code{read} builtin. @item SECONDS -This variable expands to the number of seconds since the -shell was started. Assignment to this variable resets -the count to the value assigned, and the expanded value -becomes the value assigned plus the number of seconds +This variable expands to the number of seconds since the shell was started. +Assignment to this variable resets the count to the value assigned, and the +expanded value becomes the value assigned plus the number of seconds since the assignment. -The number of seconds at shell invocation and the current time is always +The number of seconds at shell invocation and the current time are always determined by querying the system clock. If @env{SECONDS} is unset, it loses its special properties, diff --git a/doc/builtins.0 b/doc/builtins.0 index 750128af3..7ecfe91f7 100644 --- a/doc/builtins.0 +++ b/doc/builtins.0 @@ -2071,4 +2071,4 @@ SSEEEE AALLSSOO -GNU Bash 5.1 2021 September 30 BASH_BUILTINS(1) +GNU Bash 5.2 2021 November 22 BASH_BUILTINS(1) diff --git a/doc/builtins.1 b/doc/builtins.1 index 611de93fe..43d92a2fc 100644 --- a/doc/builtins.1 +++ b/doc/builtins.1 @@ -7,7 +7,7 @@ .de FN \fI\|\\$1\|\fP .. -.TH BASH_BUILTINS 1 "2021 September 30" "GNU Bash 5.1" +.TH BASH_BUILTINS 1 "2021 November 22" "GNU Bash 5.2" .SH NAME :, ., [, alias, bg, bind, break, builtin, caller, cd, command, compgen, complete, compopt, diff --git a/doc/rbash.0 b/doc/rbash.0 index eccc5bf8a..96845d0c2 100644 --- a/doc/rbash.0 +++ b/doc/rbash.0 @@ -61,4 +61,4 @@ SSEEEE AALLSSOO -GNU Bash-4.0 2004 Apr 20 RBASH(1) +Bash-5.2 2021 November 22 RBASH(1) diff --git a/doc/rbash.1 b/doc/rbash.1 index 56e38fd03..39309b4cb 100644 --- a/doc/rbash.1 +++ b/doc/rbash.1 @@ -1,4 +1,4 @@ -.TH RBASH 1 "2004 Apr 20" "GNU Bash-4.0" +.TH RBASH 1 "2021 November 22" "Bash-5.2" .SH NAME rbash \- restricted bash, see \fBbash\fR(1) .SH RESTRICTED SHELL diff --git a/examples/loadables/realpath.c b/examples/loadables/realpath.c index 3591e47aa..81c96aa17 100644 --- a/examples/loadables/realpath.c +++ b/examples/loadables/realpath.c @@ -7,6 +7,7 @@ * variable NAME * -c check whether or not each resolved path exists * -s no output, exit status determines whether path is valid + * -S strip . and .. from the pathname only, no symlink resolution * -v produce verbose output * * @@ -63,11 +64,10 @@ extern int errno; extern char *sh_realpath(); int -realpath_builtin(list) -WORD_LIST *list; +realpath_builtin(WORD_LIST *list) { - int opt, cflag, vflag, sflag, aflag, es; - char *r, realbuf[PATH_MAX], *p; + int opt, cflag, vflag, sflag, Sflag, aflag, es; + char *r, realbuf[PATH_MAX], *p, *newpath; struct stat sb; #if defined (ARRAY_VARS) arrayind_t ind; @@ -80,14 +80,14 @@ WORD_LIST *list; return (EX_USAGE); } - vflag = cflag = sflag = aflag = 0; + vflag = cflag = sflag = aflag = Sflag = 0; #if defined (ARRAY_VARS) aname = NULL; v = NULL; ind = 0; #endif reset_internal_getopt(); - while ((opt = internal_getopt (list, "a:csv")) != -1) { + while ((opt = internal_getopt (list, "a:Scsv")) != -1) { switch (opt) { #if defined (ARRAY_VARS) case 'a': @@ -101,6 +101,9 @@ WORD_LIST *list; case 's': sflag = 1; break; + case 'S': + Sflag = 1; + break; case 'v': vflag = 1; break; @@ -143,14 +146,20 @@ WORD_LIST *list; for (es = EXECUTION_SUCCESS; list; list = list->next) { p = list->word->word; - r = sh_realpath(p, realbuf); + if (Sflag) { + /* sh_canonpath doesn't convert to absolute pathnames */ + newpath = make_absolute(p, get_string_value("PWD")); + r = sh_canonpath(newpath, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); + free(newpath); + } else + r = sh_realpath(p, realbuf); if (r == 0) { es = EXECUTION_FAILURE; if (sflag == 0) builtin_error("%s: cannot resolve: %s", p, strerror(errno)); continue; } - if (cflag && (stat(realbuf, &sb) < 0)) { + if (cflag && (stat(r, &sb) < 0)) { es = EXECUTION_FAILURE; if (sflag == 0) builtin_error("%s: %s", p, strerror(errno)); @@ -158,14 +167,16 @@ WORD_LIST *list; } if (sflag == 0) { if (aflag) { - bind_array_element (v, ind, realbuf, 0); + bind_array_element (v, ind, r, 0); ind++; } else { if (vflag) printf ("%s -> ", p); - printf("%s\n", realbuf); + printf("%s\n", r); } } + if (Sflag) + free (r); } return es; } @@ -174,10 +185,14 @@ char *realpath_doc[] = { "Display pathname in canonical form.", "", "Display the canonicalized version of each PATHNAME argument, resolving", - "symbolic links. The -c option checks whether or not each resolved name", - "exists. The -s option produces no output; the exit status determines the", - "validity of each PATHNAME. The -v option produces verbose output. The", - "exit status is 0 if each PATHNAME was resolved; non-zero otherwise.", + "symbolic links.", + "If the -S option is supplied, canonicalize . and .. pathname components", + "without resolving symbolic links.", + "The -c option checks whether or not each resolved name exists.", + "The -s option produces no output; the exit status determines the", + "validity of each PATHNAME.", + "The -v option produces verbose output.", + "The exit status is 0 if each PATHNAME was resolved; non-zero otherwise.", (char *)NULL }; @@ -186,6 +201,6 @@ struct builtin realpath_struct = { realpath_builtin, /* function implementing the builtin */ BUILTIN_ENABLED, /* initial flags for builtin */ realpath_doc, /* array of long documentation strings */ - "realpath [-csv] pathname [pathname...]", /* usage synopsis */ + "realpath [-Scsv] pathname [pathname...]", /* usage synopsis */ 0 /* reserved for internal use */ }; diff --git a/variables.c b/variables.c index 5f216328c..b5bdec201 100644 --- a/variables.c +++ b/variables.c @@ -199,6 +199,9 @@ static SHELL_VAR *init_dynamic_array_var PARAMS((char *, sh_var_value_func_t *, static SHELL_VAR *init_dynamic_assoc_var PARAMS((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int)); #endif +static inline SHELL_VAR *set_int_value (SHELL_VAR *, intmax_t, int); +static inline SHELL_VAR *set_string_value (SHELL_VAR *, const char *, int); + static SHELL_VAR *assign_seconds PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); static SHELL_VAR *get_seconds PARAMS((SHELL_VAR *)); static SHELL_VAR *init_seconds_var PARAMS((void)); @@ -1275,6 +1278,39 @@ init_dynamic_assoc_var (name, getfunc, setfunc, attrs) } #endif +/* Set the string value of VAR to the string representation of VALUE. + Right now this takes an INTMAX_T because that's what itos needs. If + FLAGS&1, we force the integer attribute on. */ +static inline SHELL_VAR * +set_int_value (SHELL_VAR *var, intmax_t value, int flags) +{ + char *p; + + p = itos (value); + FREE (value_cell (var)); + var_setvalue (var, p); + if (flags & 1) + VSETATTR (var, att_integer); + return (var); +} + +static inline SHELL_VAR * +set_string_value (SHELL_VAR *var, const char *value, int flags) +{ + char *p; + + if (value && *value) + p = savestring (value); + else + { + p = (char *)xmalloc (1); + p[0] = '\0'; + } + FREE (value_cell (var)); + var_setvalue (var, p); + return (var); +} + /* The value of $SECONDS. This is the number of seconds since shell invocation, or, the number of seconds since the last assignment + the value of the last assignment. */ @@ -1297,7 +1333,7 @@ assign_seconds (self, value, unused, key) seconds_value_assigned = expok ? nval : 0; gettimeofday (&shellstart, NULL); shell_start_time = shellstart.tv_sec; - return (self); + return (set_int_value (self, nval, integer_p (self) != 0)); } static SHELL_VAR * @@ -1305,18 +1341,11 @@ get_seconds (var) SHELL_VAR *var; { time_t time_since_start; - char *p; struct timeval tv; gettimeofday(&tv, NULL); time_since_start = tv.tv_sec - shell_start_time; - p = itos(seconds_value_assigned + time_since_start); - - FREE (value_cell (var)); - - VSETATTR (var, att_integer); - var_setvalue (var, p); - return (var); + return (set_int_value (var, seconds_value_assigned + time_since_start, 1)); } static SHELL_VAR * @@ -1358,7 +1387,7 @@ assign_random (self, value, unused, key) sbrand (seedval); if (subshell_environment) seeded_subshell = getpid (); - return (self); + return (set_int_value (self, seedval, integer_p (self) != 0)); } int @@ -1386,16 +1415,9 @@ get_random (var) SHELL_VAR *var; { int rv; - char *p; rv = get_random_number (); - p = itos (rv); - - FREE (value_cell (var)); - - VSETATTR (var, att_integer); - var_setvalue (var, p); - return (var); + return (set_int_value (var, rv, 1)); } static SHELL_VAR * @@ -1403,16 +1425,9 @@ get_urandom (var) SHELL_VAR *var; { u_bits32_t rv; - char *p; rv = get_urandom32 (); - p = itos (rv); - - FREE (value_cell (var)); - - VSETATTR (var, att_integer); - var_setvalue (var, p); - return (var); + return (set_int_value (var, rv, 1)); } static SHELL_VAR * @@ -1435,14 +1450,10 @@ static SHELL_VAR * get_lineno (var) SHELL_VAR *var; { - char *p; int ln; ln = executing_line_number (); - p = itos (ln); - FREE (value_cell (var)); - var_setvalue (var, p); - return (var); + return (set_int_value (var, ln, 0)); } static SHELL_VAR * @@ -1464,12 +1475,7 @@ static SHELL_VAR * get_subshell (var) SHELL_VAR *var; { - char *p; - - p = itos (subshell_level); - FREE (value_cell (var)); - var_setvalue (var, p); - return (var); + return (set_int_value (var, subshell_level, 0)); } static SHELL_VAR * @@ -1477,14 +1483,9 @@ get_epochseconds (var) SHELL_VAR *var; { intmax_t now; - char *p; now = NOW; - p = itos (now); - - FREE (value_cell (var)); - var_setvalue (var, p); - return (var); + return (set_int_value (var, now, 0)); } static SHELL_VAR * @@ -1492,7 +1493,6 @@ get_epochrealtime (var) SHELL_VAR *var; { char buf[32]; - char *p; struct timeval tv; gettimeofday (&tv, NULL); @@ -1500,10 +1500,7 @@ get_epochrealtime (var) locale_decpoint (), (unsigned)tv.tv_usec); - p = savestring (buf); - FREE (value_cell (var)); - var_setvalue (var, p); - return (var); + return (set_string_value (var, buf, 0)); } static SHELL_VAR * @@ -1511,27 +1508,16 @@ get_bashpid (var) SHELL_VAR *var; { int pid; - char *p; pid = getpid (); - p = itos (pid); - - FREE (value_cell (var)); - VSETATTR (var, att_integer); /* XXX - was also att_readonly */ - var_setvalue (var, p); - return (var); + return (set_int_value (var, pid, 1)); } static SHELL_VAR * get_bash_argv0 (var) SHELL_VAR *var; { - char *p; - - p = savestring (dollar_vars[0]); - FREE (value_cell (var)); - var_setvalue (var, p); - return var; + return (set_string_value (var, dollar_vars[0], 0)); } static char *static_shell_name = 0; @@ -1576,16 +1562,8 @@ get_bash_command (var) { char *p; - if (the_printed_command_except_trap) - p = savestring (the_printed_command_except_trap); - else - { - p = (char *)xmalloc (1); - p[0] = '\0'; - } - FREE (value_cell (var)); - var_setvalue (var, p); - return (var); + p = the_printed_command_except_trap ? the_printed_command_except_trap : ""; + return (set_string_value (var, p, 0)); } #if defined (HISTORY) @@ -1593,7 +1571,6 @@ static SHELL_VAR * get_histcmd (var) SHELL_VAR *var; { - char *p; int n; /* Do the same adjustment here we do in parse.y:prompt_history_number, @@ -1604,10 +1581,7 @@ get_histcmd (var) already been saved to history and the history number incremented. Right now we use EXECUTING as the determinant. */ n = history_number () - executing; - p = itos (n); - FREE (value_cell (var)); - var_setvalue (var, p); - return (var); + return (set_int_value (var, n, 0)); } #endif @@ -1621,10 +1595,7 @@ get_comp_wordbreaks (var) if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0) enable_hostname_completion (perform_hostname_completion); - FREE (value_cell (var)); - var_setvalue (var, savestring (rl_completer_word_break_characters)); - - return (var); + return (set_string_value (var, rl_completer_word_break_characters, 0)); } /* When this function returns, rl_completer_word_break_characters points to @@ -1860,13 +1831,8 @@ get_funcname (self) SHELL_VAR *self; { #if ! defined (ARRAY_VARS) - char *t; if (variable_context && this_shell_function) - { - FREE (value_cell (self)); - t = savestring (this_shell_function->name); - var_setvalue (self, t); - } + return (set_string_value (self, this_shell_function->name, 0)); #endif return (self); }