mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-26 23:33:08 +02:00
fix for %P in TIMEFORMAT; make updating variables that aren't subject to allexport smoother; fix spurious compiler warning about realloc; efficiency improvement for command timing; fix issue with read builtin and failure to set terminal attributes
This commit is contained in:
@@ -11862,3 +11862,52 @@ parse.y
|
||||
- reset_parser: reset shell_eof_token to 0, rely on callers to restore
|
||||
it if they need to
|
||||
Report from Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
execute_cmd.c
|
||||
- print_formatted_time: when processing %P, sum_frac should be in
|
||||
microseconds; missed when making max precision 6 back in 6/2023
|
||||
Report from pourko2@tutamail.com
|
||||
|
||||
9/30
|
||||
----
|
||||
subst.h
|
||||
- ASS_NOEXPORT: don't export the variable being assigned even if
|
||||
`allexport' is enabled
|
||||
|
||||
builtins/set.def
|
||||
- set_shellopts: pass ASS_NOEXPORT so we don't have to mess with
|
||||
unsetting the export attribute
|
||||
|
||||
builtins/shopt.def
|
||||
- set_bashopts: pass ASS_NOEXPORT so we don't have to mess with
|
||||
unsetting the export attribute
|
||||
|
||||
variables.c
|
||||
- bind_variable_internal,bind_variable_value: if ASS_NOEXPORT is set in
|
||||
the flags argument, don't export the variable even if `allexport'
|
||||
(mark_modified_vars) is set.
|
||||
Patch from Martin D Kealey <martin@kurahaupo.gen.nz>
|
||||
|
||||
10/1
|
||||
----
|
||||
include/typemax.h
|
||||
- PTRDIFF_MAX: add default max value for ptrdiff_t if the system
|
||||
doesn't provide one
|
||||
|
||||
parse.y
|
||||
- SIZE_MAX -> PTRDIFF_MAX to avoid spurious compiler warning
|
||||
Patch from Martin D Kealey <martin@kurahaupo.gen.nz> and
|
||||
Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
execute_cmd.c
|
||||
- time_command: don't bother with time zone info in gettimeofday()
|
||||
- time_command: don't bother trying to execute a null command in
|
||||
posix mode, since we just want timing information since the shell
|
||||
started
|
||||
|
||||
10/3
|
||||
----
|
||||
builtins/read.def
|
||||
- read_builtin: don't use i as a return value for functions and then
|
||||
as an index into input_string without resetting it
|
||||
Report and patch from Grisha Levit <grishalevit@gmail.com>
|
||||
|
||||
+2
-4
@@ -622,8 +622,7 @@ read_builtin (WORD_LIST *list)
|
||||
termsave.attrs = ttattrs;
|
||||
|
||||
ttset = ttattrs;
|
||||
i = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset);
|
||||
if (i < 0)
|
||||
if ((silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset)) < 0)
|
||||
sh_ttyerror (1);
|
||||
tty_modified = 1;
|
||||
add_unwind_protect (uw_ttyrestore, &termsave);
|
||||
@@ -639,8 +638,7 @@ read_builtin (WORD_LIST *list)
|
||||
termsave.attrs = ttattrs;
|
||||
|
||||
ttset = ttattrs;
|
||||
i = ttfd_noecho (fd, &ttset); /* ttnoecho (); */
|
||||
if (i < 0)
|
||||
if (ttfd_noecho (fd, &ttset) < 0)
|
||||
sh_ttyerror (1);
|
||||
|
||||
tty_modified = 1;
|
||||
|
||||
+5
-14
@@ -532,7 +532,7 @@ set_shellopts (void)
|
||||
{
|
||||
char *value;
|
||||
char tflag[N_O_OPTIONS];
|
||||
int i, *ip, exported;
|
||||
int i, *ip;
|
||||
size_t vsize, vptr;
|
||||
SHELL_VAR *v;
|
||||
|
||||
@@ -571,21 +571,12 @@ set_shellopts (void)
|
||||
vptr--; /* cut off trailing colon */
|
||||
value[vptr] = '\0';
|
||||
|
||||
v = find_variable ("SHELLOPTS");
|
||||
/* ASS_FORCE so we don't have to temporarily turn off readonly; ASS_NOEXPORT
|
||||
so we don't have to work around allexport. */
|
||||
v = bind_variable ("SHELLOPTS", value, ASS_FORCE|ASS_NOEXPORT);
|
||||
|
||||
/* Note whether or not the variable was exported so we can adjust after the
|
||||
assignment. */
|
||||
exported = v ? exported_p (v) : 0;
|
||||
|
||||
/* ASS_FORCE so we don't have to temporarily turn off readonly */
|
||||
v = bind_variable ("SHELLOPTS", value, ASS_FORCE);
|
||||
|
||||
/* Turn the read-only attribute back on, and turn off the export attribute
|
||||
if it was set implicitly by mark_modified_vars and SHELLOPTS was not
|
||||
exported before we bound the new value. */
|
||||
/* Turn the read-only attribute back on. */
|
||||
VSETATTR (v, att_readonly);
|
||||
if (mark_modified_vars && exported == 0 && exported_p (v))
|
||||
VUNSETATTR (v, att_exported);
|
||||
|
||||
free (value);
|
||||
}
|
||||
|
||||
+4
-11
@@ -823,7 +823,7 @@ set_bashopts (void)
|
||||
{
|
||||
char *value;
|
||||
char tflag[N_SHOPT_OPTIONS];
|
||||
int i, exported;
|
||||
int i;
|
||||
size_t vsize, vptr;
|
||||
SHELL_VAR *v;
|
||||
|
||||
@@ -853,21 +853,14 @@ set_bashopts (void)
|
||||
vptr--; /* cut off trailing colon */
|
||||
value[vptr] = '\0';
|
||||
|
||||
v = find_variable ("BASHOPTS");
|
||||
|
||||
/* Note whether or not the variable was exported so we can adjust after the
|
||||
assignment. */
|
||||
exported = v ? exported_p (v) : 0;
|
||||
|
||||
/* ASS_FORCE so we don't have to temporarily turn off readonly */
|
||||
v = bind_variable ("BASHOPTS", value, ASS_FORCE);
|
||||
/* ASS_FORCE so we don't have to temporarily turn off readonly; ASS_NOEXPORT
|
||||
so we don't have to work around allexport. */
|
||||
v = bind_variable ("BASHOPTS", value, ASS_FORCE|ASS_NOEXPORT);
|
||||
|
||||
/* Turn the read-only attribute back on, and turn off the export attribute
|
||||
if it was set implicitly by mark_modified_vars and SHELLOPTS was not
|
||||
exported before we bound the new value. */
|
||||
VSETATTR (v, att_readonly);
|
||||
if (mark_modified_vars && exported == 0 && exported_p (v))
|
||||
VUNSETATTR (v, att_exported);
|
||||
|
||||
free (value);
|
||||
}
|
||||
|
||||
@@ -2513,6 +2513,10 @@ A filename whose suffix matches one of the entries in
|
||||
is excluded from the list of matched filenames.
|
||||
A sample value is
|
||||
.Q .o:\*~ .
|
||||
Since tilde expansion takes place after
|
||||
.Q :
|
||||
in assignment statements,
|
||||
make sure to quote assignments appropriately to avoid it as appropriate.
|
||||
.TP
|
||||
.B FUNCNEST
|
||||
If set to a numeric value greater than 0, defines a maximum function
|
||||
|
||||
+7
-2
@@ -7174,8 +7174,13 @@ A colon-separated list of suffixes to ignore when performing
|
||||
filename completion.
|
||||
A filename whose suffix matches one of the entries in
|
||||
@env{FIGNORE}
|
||||
is excluded from the list of matched filenames. A sample
|
||||
value is @samp{.o:~}
|
||||
is excluded from the list of matched filenames.
|
||||
A sample value is
|
||||
@samp{.o:~}.
|
||||
Since tilde expansion takes place after
|
||||
@samp{:}
|
||||
in assignment statements,
|
||||
make sure to quote assignments appropriately to avoid it as appropriate.
|
||||
|
||||
@item FUNCNAME
|
||||
An array variable containing the names of all shell functions
|
||||
|
||||
+31
-38
@@ -1408,7 +1408,7 @@ print_formatted_time (FILE *fp, char *format,
|
||||
cpu = 10000;
|
||||
#endif
|
||||
sum = cpu / 100;
|
||||
sum_frac = (cpu % 100) * 10;
|
||||
sum_frac = (cpu % 100) * 10000; /* convert to microseconds */
|
||||
len = mkfmt (ts, 2, 0, sum, sum_frac);
|
||||
RESIZE_MALLOCED_BUFFER (str, sindex, len, ssize, 64);
|
||||
strcpy (str + sindex, ts);
|
||||
@@ -1468,9 +1468,6 @@ time_command (COMMAND *command, int asynchronous, int pipe_in, int pipe_out, str
|
||||
#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
|
||||
struct timeval real, user, sys;
|
||||
struct timeval before, after;
|
||||
# if defined (HAVE_STRUCT_TIMEZONE)
|
||||
struct timezone dtz; /* posix doesn't define this */
|
||||
# endif
|
||||
struct rusage selfb, selfa, kidsb, kidsa; /* a = after, b = before */
|
||||
#else
|
||||
# if defined (HAVE_TIMES)
|
||||
@@ -1479,24 +1476,28 @@ time_command (COMMAND *command, int asynchronous, int pipe_in, int pipe_out, str
|
||||
# endif
|
||||
#endif
|
||||
|
||||
rv = EXECUTION_SUCCESS; /* suppress uninitialized use warnings */
|
||||
|
||||
rs = us = ss = 0;
|
||||
rsf = usf = ssf = 0;
|
||||
cpu = 0;
|
||||
|
||||
old_subshell = subshell_environment;
|
||||
posix_time = command && (command->flags & CMD_TIME_POSIX);
|
||||
nullcmd = (command == 0) || (command->type == cm_simple && command->value.Simple->words == 0 && command->value.Simple->redirects == 0);
|
||||
|
||||
#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
|
||||
# if defined (HAVE_STRUCT_TIMEZONE)
|
||||
gettimeofday (&before, &dtz);
|
||||
# else
|
||||
gettimeofday (&before, NULL);
|
||||
# endif /* !HAVE_STRUCT_TIMEZONE */
|
||||
getrusage (RUSAGE_SELF, &selfb);
|
||||
getrusage (RUSAGE_CHILDREN, &kidsb);
|
||||
gettimeofday (&before, NULL);
|
||||
#else
|
||||
# if defined (HAVE_TIMES)
|
||||
tbefore = times (&before);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
old_subshell = subshell_environment;
|
||||
posix_time = command && (command->flags & CMD_TIME_POSIX);
|
||||
|
||||
nullcmd = (command == 0) || (command->type == cm_simple && command->value.Simple->words == 0 && command->value.Simple->redirects == 0);
|
||||
/* In posix mode, `time' without argument is equivalent to `times', but
|
||||
obeys TIMEFORMAT. This is from POSIX interp 267 */
|
||||
if (posixly_correct && nullcmd)
|
||||
{
|
||||
#if defined (HAVE_GETRUSAGE)
|
||||
@@ -1508,35 +1509,27 @@ time_command (COMMAND *command, int asynchronous, int pipe_in, int pipe_out, str
|
||||
tbefore = shell_start_time * get_clk_tck ();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
old_flags = command->flags;
|
||||
COPY_PROCENV (top_level, save_top_level);
|
||||
command->flags &= ~(CMD_TIME_PIPELINE|CMD_TIME_POSIX);
|
||||
code = setjmp_nosigs (top_level);
|
||||
if (code == NOT_JUMPED)
|
||||
rv = execute_command_internal (command, asynchronous, pipe_in, pipe_out, fds_to_close);
|
||||
COPY_PROCENV (save_top_level, top_level);
|
||||
if (code == NOT_JUMPED)
|
||||
command->flags = old_flags;
|
||||
|
||||
rv = EXECUTION_SUCCESS; /* suppress uninitialized use warnings */
|
||||
old_flags = command->flags;
|
||||
COPY_PROCENV (top_level, save_top_level);
|
||||
command->flags &= ~(CMD_TIME_PIPELINE|CMD_TIME_POSIX);
|
||||
code = setjmp_nosigs (top_level);
|
||||
if (code == NOT_JUMPED)
|
||||
rv = execute_command_internal (command, asynchronous, pipe_in, pipe_out, fds_to_close);
|
||||
COPY_PROCENV (save_top_level, top_level);
|
||||
|
||||
if (code == NOT_JUMPED)
|
||||
command->flags = old_flags;
|
||||
|
||||
/* If we're jumping in a different subshell environment than we started,
|
||||
don't bother printing timing stats, just keep longjmping back to the
|
||||
original top level. */
|
||||
if (code != NOT_JUMPED && subshell_environment && subshell_environment != old_subshell)
|
||||
sh_longjmp (top_level, code);
|
||||
|
||||
rs = us = ss = 0;
|
||||
rsf = usf = ssf = 0;
|
||||
cpu = 0;
|
||||
/* If we're jumping in a different subshell environment than we started,
|
||||
don't bother printing timing stats, just keep longjmping back to the
|
||||
original top level. */
|
||||
if (code != NOT_JUMPED && subshell_environment && subshell_environment != old_subshell)
|
||||
sh_longjmp (top_level, code);
|
||||
}
|
||||
|
||||
#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY)
|
||||
# if defined (HAVE_STRUCT_TIMEZONE)
|
||||
gettimeofday (&after, &dtz);
|
||||
# else
|
||||
gettimeofday (&after, NULL);
|
||||
# endif /* !HAVE_STRUCT_TIMEZONE */
|
||||
getrusage (RUSAGE_SELF, &selfa);
|
||||
getrusage (RUSAGE_CHILDREN, &kidsa);
|
||||
|
||||
|
||||
@@ -119,6 +119,10 @@ static const unsigned long long int maxquad = ULLONG_MAX;
|
||||
# define SIZE_MAX ((size_t) ~(size_t)0)
|
||||
#endif
|
||||
|
||||
#ifndef PTRDIFF_MAX
|
||||
# define PTRDIFF_MAX TYPE_MAXIMUM(ptrdiff_t)
|
||||
#endif
|
||||
|
||||
#ifndef sh_imaxabs
|
||||
# define sh_imaxabs(x) (((x) >= 0) ? (x) : -(x))
|
||||
#endif
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
#include "shell.h"
|
||||
#include "execute_cmd.h"
|
||||
#include "typemax.h" /* SIZE_MAX if needed */
|
||||
#include "typemax.h" /* PTRDIFF_MAX if needed */
|
||||
#include "trap.h"
|
||||
#include "flags.h"
|
||||
#include "parser.h"
|
||||
@@ -2579,21 +2579,21 @@ shell_getc (int remove_quoted_newline)
|
||||
/* If we can't put 256 bytes more into the buffer, allocate
|
||||
everything we can and fill it as full as we can. */
|
||||
/* XXX - we ignore rest of line using `truncating' flag */
|
||||
if (shell_input_line_size > (SIZE_MAX - 256))
|
||||
if (shell_input_line_size > (PTRDIFF_MAX - 256))
|
||||
{
|
||||
size_t n;
|
||||
|
||||
n = SIZE_MAX - i; /* how much more can we put into the buffer? */
|
||||
n = PTRDIFF_MAX - i; /* how much more can we put into the buffer? */
|
||||
if (n <= 2) /* we have to save 1 for the newline added below */
|
||||
{
|
||||
if (truncating == 0)
|
||||
internal_warning(_("shell_getc: shell_input_line_size (%zu) exceeds SIZE_MAX (%lu): line truncated"), shell_input_line_size, (unsigned long)SIZE_MAX);
|
||||
internal_warning(_("shell_getc: shell_input_line_size (%zu) exceeds PTRDIFF_MAX (%lu): line truncated"), shell_input_line_size, (unsigned long)PTRDIFF_MAX);
|
||||
shell_input_line[i] = '\0';
|
||||
truncating = 1;
|
||||
}
|
||||
if (shell_input_line_size < SIZE_MAX)
|
||||
if (shell_input_line_size < PTRDIFF_MAX)
|
||||
{
|
||||
shell_input_line_size = SIZE_MAX;
|
||||
shell_input_line_size = PTRDIFF_MAX;
|
||||
shell_input_line = xrealloc (shell_input_line, shell_input_line_size);
|
||||
}
|
||||
}
|
||||
@@ -2735,7 +2735,7 @@ shell_getc (int remove_quoted_newline)
|
||||
not already end in an EOF character. */
|
||||
if (shell_input_line_terminator != EOF && shell_input_line_terminator != READERR)
|
||||
{
|
||||
if (shell_input_line_size + 3 < SIZE_MAX && (shell_input_line_len+3 > shell_input_line_size))
|
||||
if (shell_input_line_size + 3 < PTRDIFF_MAX && (shell_input_line_len+3 > shell_input_line_size))
|
||||
shell_input_line = (char *)xrealloc (shell_input_line,
|
||||
1 + (shell_input_line_size += 2));
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
/* Flag values controlling how assignment statements are treated. */
|
||||
#define ASS_APPEND 0x0001 /* a+=b */
|
||||
#define ASS_MKLOCAL 0x0002
|
||||
#define ASS_MKLOCAL 0x0002 /* make a local variable */
|
||||
#define ASS_MKASSOC 0x0004
|
||||
#define ASS_MKGLOBAL 0x0008 /* force global assignment */
|
||||
#define ASS_NAMEREF 0x0010 /* assigning to nameref variable */
|
||||
@@ -59,6 +59,7 @@
|
||||
#define ASS_ONEWORD 0x1000 /* don't check array subscripts, assume higher level has done that */
|
||||
#define ASS_NOTEMPENV 0x2000 /* don't assign into temporary environment */
|
||||
#define ASS_XTRACE 0x4000 /* print trace after compound assignment expansion */
|
||||
#define ASS_NOEXPORT 0x8000 /* don't export even if allexport is set */
|
||||
|
||||
/* Flags for the string extraction functions. */
|
||||
#define SX_NOALLOC 0x0001 /* just skip; don't return substring */
|
||||
|
||||
+3
-3
@@ -3166,7 +3166,7 @@ assign_value:
|
||||
INVALIDATE_EXPORTSTR (entry);
|
||||
optimized_assignment (entry, value, aflags);
|
||||
|
||||
if (mark_modified_vars)
|
||||
if (mark_modified_vars && (aflags & ASS_NOEXPORT) == 0)
|
||||
VSETATTR (entry, att_exported);
|
||||
|
||||
if (exported_p (entry))
|
||||
@@ -3208,7 +3208,7 @@ assign_value:
|
||||
}
|
||||
}
|
||||
|
||||
if (mark_modified_vars)
|
||||
if (mark_modified_vars && (aflags & ASS_NOEXPORT) == 0)
|
||||
VSETATTR (entry, att_exported);
|
||||
|
||||
if (exported_p (entry))
|
||||
@@ -3363,7 +3363,7 @@ bind_variable_value (SHELL_VAR *var, char *value, int aflags)
|
||||
|
||||
INVALIDATE_EXPORTSTR (var);
|
||||
|
||||
if (mark_modified_vars)
|
||||
if (mark_modified_vars && (aflags & ASS_NOEXPORT) == 0)
|
||||
VSETATTR (var, att_exported);
|
||||
|
||||
if (exported_p (var))
|
||||
|
||||
Reference in New Issue
Block a user