From f7ec6b1a00821939cf6bb18b588683ae33714a70 Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Mon, 7 Oct 2019 11:02:34 -0400 Subject: [PATCH] commit bash-20191004 snapshot --- CWRU/CWRU.chlog | 72 ++++++++++++++++++++++++- MANIFEST | 3 +- bashline.c | 4 +- builtins/shopt.def | 8 +++ execute_cmd.c | 55 ++++++++----------- general.h | 1 + jobs.c | 4 -- lib/glob/glob.c | 11 ++-- lib/glob/glob_loop.c | 6 ++- lib/glob/xmbsrtowcs.c | 116 +++++++++++++++++++++++++++++++++++++++- lib/readline/complete.c | 39 ++++---------- pathexp.c | 25 ++++----- pathexp.h | 7 +-- subst.c | 2 +- tests/glob.right | 16 +++--- tests/shopt.tests | 2 + tests/shopt1.sub | 52 ++++++++++++++++++ variables.c | 8 ++- 18 files changed, 329 insertions(+), 102 deletions(-) create mode 100644 tests/shopt1.sub diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 2df28fc64..515836f76 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -6655,4 +6655,74 @@ doc/{bash.1,bashref.texi} - mark_dead_jobs_as_notified: call set_maxchild to set js.c_childmax if it hasn't been set yet - + 9/30 + ---- +lib/glob/xmbsrtowcs.c + - xwcsrtombs: implementation of wcsrtombs from gnulib, modified to + treat invalid wide characters (or wide characters that can't be + converted to multibyte character sequences) as bytes. Should be + used only in unusual circumstances where wcsrtombs fails. + +lib/glob/glob.c + - wdequote_pathname: if wcsrtombs fails to convert the dequoted wide + character pathname back to a sequence of multibyte characters, call + xwcsrtombs to try to treat the invalid wide characters as bytes -- + the call to xdupmbstowcs treats bytes that don't convert to wide + characters as just bytes, which kind of causes this problem in the + first place. Inspired by report from Geoff Kuenning + +lib/readline/complete.c + - compute_lcd_of_matches: use the case-folding code (which performs + character-by-character checking and compares invalid multibyte + sequences as bytes) instead of the old case-sensitive code (which + used _rl_compare_chars), converting characters to lowercase as + needed. Fixes bug with invalid sequences in common filename prefixes + reported by Grisha Levit + + 10/1 + ---- +builtins/shopt.def + - reset_shopt_options: add in resets for some missing shopt options. + Report and fix from Grisha Levit + +execute_cmd.c + - execute_command_internal: make sure a failed attempt to define a + shell function causes the shell to exit if -e is enabled. Report + from Andreas Kusalananda Kähäri + - execute_command_internal: combine cm_function_def, cm_arith, and + cm_cond cases into one switch case, since the code is virtually + identical across all three + + 10/3 + ---- +pathexp.[ch],lib/glob/glob.c,lib/glob/glob_loop.c + - remove all references to posix_glob_backslash in preparation for + implementing austin group interpretation #1234 + +pathexp.c + - unquoted_glob_pattern_p: revert to bash-4.4 behavior of returning 1 + only if there is an unquoted `*', `?', or bracket expression, as + per austin group interpretation #1234 + +lib/glob/glob_loop.c + - INTERNAL_GLOB_PATTERN_P: revert to bash-4.4 behavior of returning 1 + only if there is an unquoted `*', `?', or bracket expression, as + per austin group interpretation #1234 + + 10/4 + ---- +variables.c + - assign_seconds,get_seconds: use the tv_sec value returned from + gettimeofday() instead of time() to get a better approximation of + the number of seconds since the epoch for future calculations. + From a report by Stephane Chazelas + +pathexp.[ch],{bashline,subst}.c + - shell_glob_filename: now takes an additional flags argument to pass + to quote_string_for_globbing + + 10/6 + ---- +subst.c + - glob_expand_word_list: call shell_glob_filename with QGLOB_CTLESC + because quote removal hasn't been performed yet diff --git a/MANIFEST b/MANIFEST index 60c15381b..1c90c6a85 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1383,7 +1383,8 @@ tests/set-e.right f tests/set-x.tests f tests/set-x1.sub f tests/set-x.right f -tests/shopt.tests f +tests/shopt.tests f +tests/shopt1.sub f tests/shopt.right f tests/strip.tests f tests/strip.right f diff --git a/bashline.c b/bashline.c index 209389786..e992c64ba 100644 --- a/bashline.c +++ b/bashline.c @@ -2140,7 +2140,7 @@ globword: if (state == 0) { glob_ignore_case = igncase; - glob_matches = shell_glob_filename (hint); + glob_matches = shell_glob_filename (hint, 0); glob_ignore_case = old_glob_ignore_case; if (GLOB_FAILED (glob_matches) || glob_matches == 0) @@ -3891,7 +3891,7 @@ glob_complete_word (text, state) if (ttext != text) free (ttext); - matches = shell_glob_filename (globtext); + matches = shell_glob_filename (globtext, 0); if (GLOB_FAILED (matches)) matches = (char **)NULL; ind = 0; diff --git a/builtins/shopt.def b/builtins/shopt.def index 7e3d4d085..eae44481d 100644 --- a/builtins/shopt.def +++ b/builtins/shopt.def @@ -347,6 +347,7 @@ reset_shopt_options () inherit_errexit = 0; interactive_comments = 1; lastpipe_opt = 0; + localvar_inherit = localvar_unset = 0; mail_warning = 0; glob_ignore_case = match_ignore_case = 0; print_shift_error = 0; @@ -360,6 +361,10 @@ reset_shopt_options () extended_glob = EXTGLOB_DEFAULT; #endif +#if defined (ARRAY_VARS) + assoc_expand_once = 0; +#endif + #if defined (HISTORY) literal_history = 0; force_append_history = 0; @@ -390,6 +395,9 @@ reset_shopt_options () #if defined (PROGRAMMABLE_COMPLETION) prog_completion_enabled = 1; +# if defined (ALIAS) + progcomp_alias = 0; +# endif #endif #if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX) diff --git a/execute_cmd.c b/execute_cmd.c index 0def61664..f6423e5b2 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -1002,40 +1002,35 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, #if defined (DPAREN_ARITHMETIC) case cm_arith: - was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0; - if (ignore_return) - command->value.Arith->flags |= CMD_IGNORE_RETURN; - line_number_for_err_trap = save_line_number = line_number; - exec_result = execute_arith_command (command->value.Arith); - line_number = save_line_number; - - if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS) - { - last_command_exit_value = exec_result; - save_line_number = line_number; - line_number = line_number_for_err_trap; - run_error_trap (); - line_number = save_line_number; - } - - if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS) - { - last_command_exit_value = exec_result; - run_pending_traps (); - jump_to_top_level (ERREXIT); - } - - break; #endif - #if defined (COND_COMMAND) case cm_cond: +#endif + case cm_function_def: was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0; - if (ignore_return) +#if defined (DPAREN_ARITHMETIC) + if (ignore_return && command->type == cm_arith) + command->value.Arith->flags |= CMD_IGNORE_RETURN; +#endif +#if defined (COND_COMMAND) + if (ignore_return && command->type == cm_cond) command->value.Cond->flags |= CMD_IGNORE_RETURN; +#endif line_number_for_err_trap = save_line_number = line_number; - exec_result = execute_cond_command (command->value.Cond); +#if defined (DPAREN_ARITHMETIC) + if (command->type == cm_arith) + exec_result = execute_arith_command (command->value.Arith); + else +#endif +#if defined (COND_COMMAND) + if (command->type == cm_cond) + exec_result = execute_cond_command (command->value.Cond); + else +#endif + if (command->type == cm_function_def) + exec_result = execute_intern_function (command->value.Function_def->name, + command->value.Function_def); line_number = save_line_number; if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS) @@ -1055,12 +1050,6 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, } break; -#endif - - case cm_function_def: - exec_result = execute_intern_function (command->value.Function_def->name, - command->value.Function_def); - break; default: command_error ("execute_command", CMDERR_BADTYPE, command->type, 0); diff --git a/general.h b/general.h index d87310ee3..a9f67ee3e 100644 --- a/general.h +++ b/general.h @@ -246,6 +246,7 @@ typedef int sh_builtin_func_t __P((WORD_LIST *)); /* sh_wlist_func_t */ #endif /* SH_FUNCTION_TYPEDEF */ #define NOW ((time_t) time ((time_t *) 0)) +#define GETTIME(tv) gettimeofday(&(tv), NULL) /* Some defines for calling file status functions. */ #define FS_EXISTS 0x1 diff --git a/jobs.c b/jobs.c index 3779e4ae6..f9079dd2d 100644 --- a/jobs.c +++ b/jobs.c @@ -2834,11 +2834,7 @@ raw_job_exit_status (job) int fail; WAIT ret; -#if 0 - if (pipefail_opt) -#else if (jobs[job]->flags & J_PIPEFAIL) -#endif { fail = 0; p = jobs[job]->pipe; diff --git a/lib/glob/glob.c b/lib/glob/glob.c index b7f2d8307..4c7e8b959 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -91,7 +91,6 @@ extern int signal_is_pending __P((int)); extern void run_pending_traps __P((void)); extern int extended_glob; -extern int posix_glob_backslash; /* Global variable which controls whether or not * matches .*. Non-zero means don't match .*. */ @@ -475,6 +474,12 @@ wdequote_pathname (pathname) /* Convert the wide character string into unibyte character set. */ memset (&ps, '\0', sizeof(mbstate_t)); n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps); + if (n == (size_t)-1 || *wpathname != 0) /* what? now you tell me? */ + { + wpathname = orig_wpathname; + memset (&ps, '\0', sizeof(mbstate_t)); + n = xwcsrtombs (pathname, (const wchar_t **)&wpathname, len, &ps); + } pathname[len] = '\0'; /* Can't just free wpathname here; wcsrtombs changes it in many cases. */ @@ -1421,7 +1426,6 @@ only_filename: if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) == 0) { -#if 1 dequote_pathname (directory_name); if (glob_testdir (directory_name, 0) < 0) { @@ -1429,9 +1433,6 @@ only_filename: free (directory_name); return ((char **)&glob_error_return); } -#else - return ((char **)&glob_error_return); -#endif } /* Handle GX_MARKDIRS here. */ diff --git a/lib/glob/glob_loop.c b/lib/glob/glob_loop.c index 92329b3ea..1900996d2 100644 --- a/lib/glob/glob_loop.c +++ b/lib/glob/glob_loop.c @@ -70,7 +70,11 @@ INTERNAL_GLOB_PATTERN_P (pattern) return 0; } - return ((bsquote && posix_glob_backslash) ? 2 : 0); +#if 0 + return bsquote ? 2 : 0; +#else + return (0); +#endif } #undef INTERNAL_GLOB_PATTERN_P diff --git a/lib/glob/xmbsrtowcs.c b/lib/glob/xmbsrtowcs.c index 11a4d1b94..d00ed413e 100644 --- a/lib/glob/xmbsrtowcs.c +++ b/lib/glob/xmbsrtowcs.c @@ -1,6 +1,6 @@ /* xmbsrtowcs.c -- replacement function for mbsrtowcs */ -/* Copyright (C) 2002-2013 Free Software Foundation, Inc. +/* Copyright (C) 2002-2019 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -35,6 +35,11 @@ #if HANDLE_MULTIBYTE +#include +#if !defined (errno) +extern int errno; +#endif + #define WSBUF_INC 32 #ifndef FREE @@ -406,4 +411,113 @@ xdupmbstowcs (destp, indicesp, src) return (wcnum - 1); } +/* Convert wide character string to multibyte character string. Treat invalid + wide characters as bytes. Used only in unusual circumstances. + + Written by Bruno Haible , 2008, adapted by Chet Ramey + for use in Bash. */ + +/* Convert wide character string *SRCP to a multibyte character string and + store the result in DEST. Store at most LEN bytes in DEST. */ +size_t +xwcsrtombs (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) +{ + const wchar_t *src; + size_t cur_max; /* XXX - locale_cur_max */ + char buf[64], *destptr, *tmp_dest; + unsigned char uc; + mbstate_t prev_state; + + cur_max = MB_CUR_MAX; + if (cur_max > sizeof (buf)) /* Holy cow. */ + return (size_t)-1; + + src = *srcp; + + if (dest != NULL) + { + destptr = dest; + + for (; len > 0; src++) + { + wchar_t wc; + size_t ret; + + wc = *src; + /* If we have room, store directly into DEST. */ + tmp_dest = destptr; + ret = wcrtomb (len >= cur_max ? destptr : buf, wc, ps); + + if (ret == (size_t)(-1)) /* XXX */ + { + /* Since this is used for globbing and other uses of filenames, + treat invalid wide character sequences as bytes. This is + intended to be symmetric with xdupmbstowcs2. */ +handle_byte: + destptr = tmp_dest; /* in case wcrtomb modified it */ + uc = wc; + ret = 1; + if (len >= cur_max) + *destptr = uc; + else + buf[0] = uc; + if (ps) + memset (ps, 0, sizeof (mbstate_t)); + } + + if (ret > cur_max) /* Holy cow */ + goto bad_input; + + if (len < ret) + break; + + if (len < cur_max) + memcpy (destptr, buf, ret); + + if (wc == 0) + { + src = NULL; + /* Here mbsinit (ps). */ + break; + } + destptr += ret; + len -= ret; + } + *srcp = src; + return destptr - dest; + } + else + { + /* Ignore dest and len, don't store *srcp at the end, and + don't clobber *ps. */ + mbstate_t state = *ps; + size_t totalcount = 0; + + for (;; src++) + { + wchar_t wc; + size_t ret; + + wc = *src; + ret = wcrtomb (buf, wc, &state); + + if (ret == (size_t)(-1)) + goto bad_input2; + if (wc == 0) + { + /* Here mbsinit (&state). */ + break; + } + totalcount += ret; + } + return totalcount; + } + +bad_input: + *srcp = src; +bad_input2: + errno = EILSEQ; + return (size_t)(-1); +} + #endif /* HANDLE_MULTIBYTE */ diff --git a/lib/readline/complete.c b/lib/readline/complete.c index bd82ab9ff..cbddb6f63 100644 --- a/lib/readline/complete.c +++ b/lib/readline/complete.c @@ -1335,12 +1335,13 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text) memset (&ps2, 0, sizeof (mbstate_t)); } #endif - if (_rl_completion_case_fold) + for (si = 0; (c1 = match_list[i][si]) && (c2 = match_list[i + 1][si]); si++) { - for (si = 0; - (c1 = _rl_to_lower(match_list[i][si])) && - (c2 = _rl_to_lower(match_list[i + 1][si])); - si++) + if (_rl_completion_case_fold) + { + c1 = _rl_to_lower (c1); + c2 = _rl_to_lower (c2); + } #if defined (HANDLE_MULTIBYTE) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) { @@ -1352,35 +1353,17 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text) break; continue; } - wc1 = towlower (wc1); - wc2 = towlower (wc2); + if (_rl_completion_case_fold) + { + wc1 = towlower (wc1); + wc2 = towlower (wc2); + } if (wc1 != wc2) break; else if (v1 > 1) si += v1 - 1; } else -#endif - if (c1 != c2) - break; - } - else - { - for (si = 0; - (c1 = match_list[i][si]) && - (c2 = match_list[i + 1][si]); - si++) -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) - { - mbstate_t ps_back; - ps_back = ps1; - if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2)) - break; - else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1) - si += v - 1; - } - else #endif if (c1 != c2) break; diff --git a/pathexp.c b/pathexp.c index 0c2ab273c..572db7530 100644 --- a/pathexp.c +++ b/pathexp.c @@ -1,6 +1,6 @@ /* pathexp.c -- The shell interface to the globbing library. */ -/* Copyright (C) 1995-2014 Free Software Foundation, Inc. +/* Copyright (C) 1995-2019 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -58,9 +58,6 @@ int extended_glob = EXTGLOB_DEFAULT; /* Control enabling special handling of `**' */ int glob_star = 0; -/* Do we handle backslashes in patterns the way Posix specifies? */ -int posix_glob_backslash = 1; - /* Return nonzero if STRING has any unquoted special globbing chars in it. This is supposed to be called when pathname expansion is performed, so it implements the rules in Posix 2.13.3, specifically that an unquoted @@ -107,8 +104,8 @@ unquoted_glob_pattern_p (string) continue; /* A pattern can't end with a backslash, but a backslash in the pattern - can be removed by the matching engine, so we have to run it through - globbing. */ + can be special to the matching engine, so we note it in case we + need it later. */ case '\\': if (*string != '\0' && *string != '/') { @@ -140,7 +137,11 @@ unquoted_glob_pattern_p (string) #endif } - return ((bsquote && posix_glob_backslash) ? 2 : 0); +#if 0 + return (bsquote ? 2 : 0); +#else + return (0); +#endif } /* Return 1 if C is a character that is `special' in a POSIX ERE and needs to @@ -343,7 +344,7 @@ quote_string_for_globbing (pathname, qflags) else if (pathname[i] == '\\' && (qflags & QGLOB_REGEXP) == 0) { /* XXX - if not quoting regexp, use backslash as quote char. Should - we just pass it through without treating it as special? That is + We just pass it through without treating it as special? That is what ksh93 seems to do. */ /* If we want to pass through backslash unaltered, comment out these @@ -396,8 +397,9 @@ quote_globbing_chars (string) /* Call the glob library to do globbing on PATHNAME. */ char ** -shell_glob_filename (pathname) +shell_glob_filename (pathname, qflags) const char *pathname; + int qflags; { #if defined (USE_POSIX_GLOB_LIBRARY) register int i; @@ -405,7 +407,7 @@ shell_glob_filename (pathname) glob_t filenames; int glob_flags; - temp = quote_string_for_globbing (pathname, QGLOB_FILENAME); + temp = quote_string_for_globbing (pathname, QGLOB_FILENAME|qflags); filenames.gl_offs = 0; @@ -452,8 +454,7 @@ shell_glob_filename (pathname) noglob_dot_filenames = glob_dot_filenames == 0; - temp = quote_string_for_globbing (pathname, QGLOB_FILENAME); - quoted_pattern = STREQ (pathname, temp) == 0; + temp = quote_string_for_globbing (pathname, QGLOB_FILENAME|qflags); gflags = glob_star ? GX_GLOBSTAR : 0; results = glob_filename (temp, gflags); free (temp); diff --git a/pathexp.h b/pathexp.h index d72d99a3e..119fd65aa 100644 --- a/pathexp.h +++ b/pathexp.h @@ -51,7 +51,6 @@ extern int glob_dot_filenames; extern int extended_glob; extern int glob_star; extern int match_ignore_case; /* doesn't really belong here */ -extern int posix_glob_backslash; extern int unquoted_glob_pattern_p __P((char *)); @@ -70,8 +69,10 @@ extern char *quote_string_for_globbing __P((const char *, int)); extern int glob_char_p __P((const char *)); extern char *quote_globbing_chars __P((const char *)); -/* Call the glob library to do globbing on PATHNAME. */ -extern char **shell_glob_filename __P((const char *)); +/* Call the glob library to do globbing on PATHNAME. FLAGS is additional + flags to pass to QUOTE_STRING_FOR_GLOBBING, mostly having to do with + whether or not we've already performed quote removal. */ +extern char **shell_glob_filename __P((const char *, int)); /* Filename completion ignore. Used to implement the "fignore" facility of tcsh, GLOBIGNORE (like ksh-93 FIGNORE), and EXECIGNORE. diff --git a/subst.c b/subst.c index 9a0c9cc09..0fd33a6f1 100644 --- a/subst.c +++ b/subst.c @@ -11251,7 +11251,7 @@ glob_expand_word_list (tlist, eflags) if ((tlist->word->flags & W_NOGLOB) == 0 && unquoted_glob_pattern_p (tlist->word->word)) { - glob_array = shell_glob_filename (tlist->word->word); + glob_array = shell_glob_filename (tlist->word->word, QGLOB_CTLESC); /* XXX */ /* Handle error cases. I don't think we should report errors like "No such file diff --git a/tests/glob.right b/tests/glob.right index 469822d8b..82ed3d8ae 100644 --- a/tests/glob.right +++ b/tests/glob.right @@ -57,10 +57,10 @@ ok 3 ok 4 ok 5 argv[1] = -a? +a\? argv[1] = -a? -aa +a\? +a\a ./tmp/a/b/c ./tmp/a/b/c ./tmp/a/b/c @@ -79,8 +79,8 @@ argv[1] = <./t\mp/a/*> argv[1] = <./tmp/a/b/c> argv[1] = <./tmp/a/> argv[1] = <./tmp/a/b/> -argv[1] = <./tmp/a/> -argv[1] = <./tmp/a/b/> +argv[1] = <./t\mp/a/> +argv[1] = <./t\mp/a/b/> argv[1] = <./tmp/a/*> argv[1] = <./tmp/a/b/c> argv[1] = <./tmp/a> @@ -92,10 +92,10 @@ argv[1] = <\$foo> argv[2] = <\$foo> argv[1] = -<.> +<\.> *abc.c -searchable/. -searchable/./. +searchable/\. +searchable/\./. readable/\. readable/\./. searchable/\. diff --git a/tests/shopt.tests b/tests/shopt.tests index 601da537d..fb7652094 100644 --- a/tests/shopt.tests +++ b/tests/shopt.tests @@ -105,3 +105,5 @@ shopt -u -o builtin printf -- "--\n" shopt -p xyz1 shopt -o -p xyz1 + +${THIS_SH} ./shopt1.sub diff --git a/tests/shopt1.sub b/tests/shopt1.sub new file mode 100644 index 000000000..8c1150fb9 --- /dev/null +++ b/tests/shopt1.sub @@ -0,0 +1,52 @@ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# verify all shopt options are reset properly when the shell is reinitialized + +: ${TMPDIR:=/var/tmp} ${THIS_SH:=$PWD/bash} + +t1=$(mktemp) +t2=$(mktemp) + +if [ ! -e "$t1" ] ; then + S1=$RANDOM + S2=$RANDOM + t1=$TMPDIR/s-$S1 + t2=$TMPDIR/s-$S2 + touch "$t1" "$t2" +fi + +chmod +x "$t1" "$t2" + +echo "shopt" > "$t1" + +echo "#!${THIS_SH}" > "$t2" +echo "shopt" >> "$t2" + +for o in $(compgen -A shopt) +do + case $o in + extdebug) ;; + *) shopt -s $o ;; + esac +done +diff <("$t1") <("$t2") + +for o in $(compgen -A shopt) +do + shopt -u $o; +done +diff <("$t1") <("$t2") + +rm "$t1" "$t2" diff --git a/variables.c b/variables.c index db3ccab60..21ee34d45 100644 --- a/variables.c +++ b/variables.c @@ -1294,9 +1294,11 @@ assign_seconds (self, value, unused, key) arrayind_t unused; char *key; { + struct timeval tv; if (legal_number (value, &seconds_value_assigned) == 0) seconds_value_assigned = 0; - shell_start_time = NOW; + gettimeofday (&tv, NULL); + shell_start_time = tv.tv_sec; return (self); } @@ -1306,8 +1308,10 @@ get_seconds (var) { time_t time_since_start; char *p; + struct timeval tv; - time_since_start = NOW - shell_start_time; + gettimeofday(&tv, NULL); + time_since_start = tv.tv_sec - shell_start_time; p = itos(seconds_value_assigned + time_since_start); FREE (value_cell (var)); -- 2.47.2