- _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
.1.ps:
$(RM) $@
- -${GROFF} -man $< > $@
+ -${GROFF} -I${srcdir} -man $< > $@
.1.0:
$(RM) $@
- -${NROFF} -man $< > $@
+ -${NROFF} -I${srcdir} -man $< > $@
.1.html:
$(RM) $@
.3.ps:
$(RM) $@
- -${GROFF} -man $< > $@
+ -${GROFF} -I${srcdir} -man $< > $@
.3.0:
$(RM) $@
- -${NROFF} -man $< > $@
+ -${NROFF} -I${srcdir} -man $< > $@
.3.html:
$(RM) $@
R\bRE\bEP\bPL\bLY\bY Set to the line of input read by the r\bre\bea\bad\bd builtin command when
no arguments are supplied.
S\bSE\bEC\bCO\bON\bND\bDS\bS
- 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
S\bSE\bEC\bCO\bON\bND\bDS\bS, 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 S\bSE\bEC\bCO\bON\bND\bDS\bS
+ are always determined by querying the system clock. If S\bSE\bEC\bCO\bON\bND\bDS\bS
is unset, it loses its special properties, even if it is subse-
quently reset.
S\bSH\bHE\bEL\bLL\bLO\bOP\bPT\bTS\bS
.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
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.
Node: Shell Variables\7f217696
Node: Bourne Shell Variables\7f218133
Node: Bash Variables\7f220237
-Node: Bash Features\7f253052
-Node: Invoking Bash\7f254065
-Node: Bash Startup Files\7f260078
-Node: Interactive Shells\7f265181
-Node: What is an Interactive Shell?\7f265591
-Node: Is this Shell Interactive?\7f266240
-Node: Interactive Shell Behavior\7f267055
-Node: Bash Conditional Expressions\7f270684
-Node: Shell Arithmetic\7f275326
-Node: Aliases\7f278270
-Node: Arrays\7f280883
-Node: The Directory Stack\7f287130
-Node: Directory Stack Builtins\7f287914
-Node: Controlling the Prompt\7f292174
-Node: The Restricted Shell\7f295139
-Node: Bash POSIX Mode\7f297749
-Node: Shell Compatibility Mode\7f309022
-Node: Job Control\7f317051
-Node: Job Control Basics\7f317511
-Node: Job Control Builtins\7f322513
-Node: Job Control Variables\7f327913
-Node: Command Line Editing\7f329069
-Node: Introduction and Notation\7f330740
-Node: Readline Interaction\7f332363
-Node: Readline Bare Essentials\7f333554
-Node: Readline Movement Commands\7f335337
-Node: Readline Killing Commands\7f336297
-Node: Readline Arguments\7f338215
-Node: Searching\7f339259
-Node: Readline Init File\7f341445
-Node: Readline Init File Syntax\7f342706
-Node: Conditional Init Constructs\7f364194
-Node: Sample Init File\7f368390
-Node: Bindable Readline Commands\7f371514
-Node: Commands For Moving\7f372718
-Node: Commands For History\7f374769
-Node: Commands For Text\7f379763
-Node: Commands For Killing\7f383412
-Node: Numeric Arguments\7f386445
-Node: Commands For Completion\7f387584
-Node: Keyboard Macros\7f391775
-Node: Miscellaneous Commands\7f392462
-Node: Readline vi Mode\7f398401
-Node: Programmable Completion\7f399308
-Node: Programmable Completion Builtins\7f407088
-Node: A Programmable Completion Example\7f417783
-Node: Using History Interactively\7f423030
-Node: Bash History Facilities\7f423714
-Node: Bash History Builtins\7f426719
-Node: History Interaction\7f431727
-Node: Event Designators\7f435347
-Node: Word Designators\7f436701
-Node: Modifiers\7f438461
-Node: Installing Bash\7f440272
-Node: Basic Installation\7f441409
-Node: Compilers and Options\7f445131
-Node: Compiling For Multiple Architectures\7f445872
-Node: Installation Names\7f447565
-Node: Specifying the System Type\7f449674
-Node: Sharing Defaults\7f450390
-Node: Operation Controls\7f451063
-Node: Optional Features\7f452021
-Node: Reporting Bugs\7f463239
-Node: Major Differences From The Bourne Shell\7f464514
-Node: GNU Free Documentation License\7f481364
-Node: Indexes\7f506541
-Node: Builtin Index\7f506995
-Node: Reserved Word Index\7f513822
-Node: Variable Index\7f516270
-Node: Function Index\7f532762
-Node: Concept Index\7f546546
+Node: Bash Features\7f253053
+Node: Invoking Bash\7f254066
+Node: Bash Startup Files\7f260079
+Node: Interactive Shells\7f265182
+Node: What is an Interactive Shell?\7f265592
+Node: Is this Shell Interactive?\7f266241
+Node: Interactive Shell Behavior\7f267056
+Node: Bash Conditional Expressions\7f270685
+Node: Shell Arithmetic\7f275327
+Node: Aliases\7f278271
+Node: Arrays\7f280884
+Node: The Directory Stack\7f287131
+Node: Directory Stack Builtins\7f287915
+Node: Controlling the Prompt\7f292175
+Node: The Restricted Shell\7f295140
+Node: Bash POSIX Mode\7f297750
+Node: Shell Compatibility Mode\7f309023
+Node: Job Control\7f317052
+Node: Job Control Basics\7f317512
+Node: Job Control Builtins\7f322514
+Node: Job Control Variables\7f327914
+Node: Command Line Editing\7f329070
+Node: Introduction and Notation\7f330741
+Node: Readline Interaction\7f332364
+Node: Readline Bare Essentials\7f333555
+Node: Readline Movement Commands\7f335338
+Node: Readline Killing Commands\7f336298
+Node: Readline Arguments\7f338216
+Node: Searching\7f339260
+Node: Readline Init File\7f341446
+Node: Readline Init File Syntax\7f342707
+Node: Conditional Init Constructs\7f364195
+Node: Sample Init File\7f368391
+Node: Bindable Readline Commands\7f371515
+Node: Commands For Moving\7f372719
+Node: Commands For History\7f374770
+Node: Commands For Text\7f379764
+Node: Commands For Killing\7f383413
+Node: Numeric Arguments\7f386446
+Node: Commands For Completion\7f387585
+Node: Keyboard Macros\7f391776
+Node: Miscellaneous Commands\7f392463
+Node: Readline vi Mode\7f398402
+Node: Programmable Completion\7f399309
+Node: Programmable Completion Builtins\7f407089
+Node: A Programmable Completion Example\7f417784
+Node: Using History Interactively\7f423031
+Node: Bash History Facilities\7f423715
+Node: Bash History Builtins\7f426720
+Node: History Interaction\7f431728
+Node: Event Designators\7f435348
+Node: Word Designators\7f436702
+Node: Modifiers\7f438462
+Node: Installing Bash\7f440273
+Node: Basic Installation\7f441410
+Node: Compilers and Options\7f445132
+Node: Compiling For Multiple Architectures\7f445873
+Node: Installation Names\7f447566
+Node: Specifying the System Type\7f449675
+Node: Sharing Defaults\7f450391
+Node: Operation Controls\7f451064
+Node: Optional Features\7f452022
+Node: Reporting Bugs\7f463240
+Node: Major Differences From The Bourne Shell\7f464515
+Node: GNU Free Documentation License\7f481365
+Node: Indexes\7f506542
+Node: Builtin Index\7f506996
+Node: Reserved Word Index\7f513823
+Node: Variable Index\7f516271
+Node: Function Index\7f532763
+Node: Concept Index\7f546547
\1f
End Tag Table
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,
-GNU Bash 5.1 2021 September 30 BASH_BUILTINS(1)
+GNU Bash 5.2 2021 November 22 BASH_BUILTINS(1)
.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,
-GNU Bash-4.0 2004 Apr 20 RBASH(1)
+Bash-5.2 2021 November 22 RBASH(1)
-.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
* 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
*
*
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;
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':
case 's':
sflag = 1;
break;
+ case 'S':
+ Sflag = 1;
+ break;
case 'v':
vflag = 1;
break;
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));
}
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;
}
"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
};
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 */
};
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));
}
#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. */
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 *
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 *
sbrand (seedval);
if (subshell_environment)
seeded_subshell = getpid ();
- return (self);
+ return (set_int_value (self, seedval, integer_p (self) != 0));
}
int
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 *
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 *
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 *
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 *
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 *
SHELL_VAR *var;
{
char buf[32];
- char *p;
struct timeval tv;
gettimeofday (&tv, NULL);
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 *
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;
{
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)
get_histcmd (var)
SHELL_VAR *var;
{
- char *p;
int n;
/* Do the same adjustment here we do in parse.y:prompt_history_number,
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
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
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);
}