]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20191004 snapshot
authorChet Ramey <chet.ramey@case.edu>
Mon, 7 Oct 2019 15:02:34 +0000 (11:02 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 7 Oct 2019 15:02:34 +0000 (11:02 -0400)
18 files changed:
CWRU/CWRU.chlog
MANIFEST
bashline.c
builtins/shopt.def
execute_cmd.c
general.h
jobs.c
lib/glob/glob.c
lib/glob/glob_loop.c
lib/glob/xmbsrtowcs.c
lib/readline/complete.c
pathexp.c
pathexp.h
subst.c
tests/glob.right
tests/shopt.tests
tests/shopt1.sub [new file with mode: 0644]
variables.c

index 2df28fc6473469cfa4c97e174d172cf7de01f5be..515836f76652b4953fc6a89b1c909ce39834c36a 100644 (file)
@@ -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 <geoff@cs.hmc.edu>
+
+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 <grishalevit@gmail.com>
+
+                                  10/1
+                                  ----
+builtins/shopt.def
+       - reset_shopt_options: add in resets for some missing shopt options.
+         Report and fix from Grisha Levit <grishalevit@gmail.com>
+
+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 <andreas.kahari@abc.se>
+       - 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 <stephane.chazelas@gmail.com>
+
+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
index 60c15381bb44ff40a917a7b3a27360393e284045..1c90c6a85009b895b0fa97ff551c4a056517b0bd 100644 (file)
--- 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
index 209389786e6dfd079b7e729f92ac612c38b404ce..e992c64ba6ef63174a22c78d1d5cd557ac7b6489 100644 (file)
@@ -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;
index 7e3d4d085e11b16f4dc3511c8c5807ad5282d863..eae44481d58f7ffc3369f545143adeefaa54f3e4 100644 (file)
@@ -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)
index 0def616643286f9a9c3a037a6de140a7e5eabeed..f6423e5b2f967dc56e0730c57bdd274b0468c809 100644 (file)
@@ -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);
index d87310ee3d8d1e571366b19cce928f5aa669b298..a9f67ee3e0ff61c2d947ea489c9dec5122b861a8 100644 (file)
--- 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 3779e4ae67c21eeb9cb0d218c74347497c478a38..f9079dd2db13d462ebd7c74064e53b376c570dbd 100644 (file)
--- 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;
index b7f2d830727b07e1f8185ee64c9187ec2bdd17de..4c7e8b95959bd53167a26814e05e7546e5beeaee 100644 (file)
@@ -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. */
index 92329b3ea0f00a88f6185d376e85b91ef5c6b0ee..1900996d25826a4154d8effc70328c6d2a7a6e86 100644 (file)
@@ -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
index 11a4d1b94cef98db63bd0d0c6b9fae368b7bce23..d00ed413e70e1086e39675db2c34d7b0c98bc78f 100644 (file)
@@ -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.
 
 
 #if HANDLE_MULTIBYTE
 
+#include <errno.h>
+#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 <bruno@clisp.org>, 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 */
index bd82ab9ff32aa810a2611548c41f681ced058635..cbddb6f63ff0bf53b9d318d3e90c336c63d62639 100644 (file)
@@ -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;
index 0c2ab273c0caad2d5cb6d5e281757b38c873f4a4..572db75301f3e65a03b9593f36a459fcaa9b7aa0 100644 (file)
--- 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);
index d72d99a3e49099318400c5f8ff07580e575036e7..119fd65aa5fb213dafee74973f12a21790f6e710 100644 (file)
--- 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 9a0c9cc09be4bb0adf83a3dd6786450edb7ee200..0fd33a6f16738ff4946ebcf00bd87da0e33bab92 100644 (file)
--- 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
index 469822d8b43414a141ec28aabc70083647fe093d..82ed3d8ae81b198f19c242445e98d072adb68af8 100644 (file)
@@ -57,10 +57,10 @@ ok 3
 ok 4
 ok 5
 argv[1] = <a\?>
-a?
+a\?
 argv[1] = <a\?>
-a?
-aa
+a\?
+a\a
 <define\/\
 />
 ./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] = <mixed\$foo/>
 <abcdefg>
-<.>
+<\.>
 *abc.c
-searchable/.
-searchable/./.
+searchable/\.
+searchable/\./.
 readable/\.
 readable/\./.
 searchable/\.
index 601da537db2826a2009bb4236e253b07f10300b1..fb76520941a0040b922239e12fb4de7ab012a96d 100644 (file)
@@ -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 (file)
index 0000000..8c1150f
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+#
+
+# 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"
index db3ccab60c2bfc98239696d700fadddb48155d70..21ee34d456ad9b1eba663ddc9749ea1e22ba25f0 100644 (file)
@@ -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));