]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20061130 snapshot
authorChet Ramey <chet.ramey@case.edu>
Wed, 7 Dec 2011 14:00:59 +0000 (09:00 -0500)
committerChet Ramey <chet.ramey@case.edu>
Wed, 7 Dec 2011 14:00:59 +0000 (09:00 -0500)
37 files changed:
CWRU/CWRU.chlog
CWRU/CWRU.chlog~
CWRU/devfd.c
MANIFEST
Makefile.in
builtins/declare.def
builtins/declare.def~ [new file with mode: 0644]
builtins/evalfile.c
builtins/exec.def
builtins/exec.def~ [new file with mode: 0644]
builtins/reserved.def
builtins/reserved.def~
builtins/source.def
doc/bash.1
doc/bashref.texi
doc/version.texi
externs.h
lib/readline/readline.c
lib/sh/Makefile.in
lib/sh/snprintf.c
lib/sh/snprintf.c~
lib/sh/zmapfd.c [new file with mode: 0644]
tests/RUN-ONE-TEST
tests/comsub.right [new file with mode: 0644]
tests/comsub.tests [new file with mode: 0644]
tests/dbg-support.right
tests/dstack.right
tests/errors.right
tests/history.right
tests/intl.tests
tests/new-exp.right
tests/new-exp6.sub
tests/printf.right
tests/printf.tests
tests/printf.tests~
tests/rsh.right
tests/run-comsub [new file with mode: 0644]

index 1d2f877ab924c8bedb8f4f94f3a06f61f0303150..173e876c541673f8f45bca32354783bc78ce8ed2 100644 (file)
@@ -13981,3 +13981,32 @@ lib/readline/readline.c
          variable _rl_revert_all_at_newline is non-zero
        - declare _rl_revert_all_lines initially 0
 
+                                  11/27
+                                  -----
+doc/{bash.1,bashref.texi}
+       - make sure to be explicit that `typeset +r' cannot remove the readonly
+         attribute from a variable
+
+                                  11/28
+                                  -----
+lib/sh/zmapfd.c
+       - new file, implements zmapfd(), which takes a file and returns its
+         contents in a string
+
+externs.h
+       - extern declaration for zmapfd
+
+                                  11/29
+                                  -----
+builtins/evalfile.c
+       - in _evalfile, use zmapfd to read the contents of the file into a
+         string, rather than using the size reported by stat and reading that
+         many characters, if the file is not a regular file (for things like
+         named pipes, stat reports the size as 0)
+
+                                  12/3
+                                  ----
+lib/sh/snprintf.c
+       - make sure number() sets the FL_UNSIGNED flag for %x and %X, so
+         fmtulong treats them as unsigned numbers.  Fixes bug reported by
+         James Botte <James.M.Botte@lowes.com>
index 21a0c1ce828125342beb9b30d50889170586db2c..6ec5722ba8241a2add2868a6de9c37cfc7021c01 100644 (file)
@@ -13979,3 +13979,33 @@ rldefs.h
 lib/readline/readline.c
        - call _rl_revert_all_lines from readline_internal_teardown if the
          variable _rl_revert_all_at_newline is non-zero
+       - declare _rl_revert_all_lines initially 0
+
+                                  11/27
+                                  -----
+doc/{bash.1,bashref.texi}
+       - make sure to be explicit that `typeset +r' cannot remove the readonly
+         attribute from a variable
+
+                                  11/28
+                                  -----
+lib/sh/zmapfd.c
+       - new file, implements zmapfd(), which takes a file and returns its
+         contents in a string
+
+externs.h
+       - extern declaration for zmapfd
+
+                                  11/29
+                                  -----
+builtins/evalfile.c
+       - in _evalfile, use zmapfd to read the contents of the file into a
+         string, rather than using the size reported by stat and reading that
+         many characters, if the file is not a regular file (for things like
+         named pipes, stat reports the size as 0)
+
+                                  12/3
+                                  ----
+lib/sh/snprintf.c
+       - make sure number() sets the FL_UNSIGNED flag for %x and %X, so
+         fmtulong treats them as unsigned numbers
index db443a617862558a16fb45bbd6fcb394250911a0..e5a35748781f8f3655cd99c21ba11154e03a9873 100644 (file)
@@ -31,7 +31,7 @@ char  **v;
        fd = open("/dev/null", O_RDONLY, 0666);
        if (fd == -1)
                exit (2);
-       if (dup2(fd, 3) == -1)
+       if (fd != 3 && (dup2(fd, 3) == -1))
                exit (1);
        /* test -r /dev/fd/3 */
        r = access("/dev/fd/3", R_OK);
index 195c3f380054cc2c8a9488796406c18e2397faa7..69c36c3f63585c93ed630439505e87452a538741 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -426,6 +426,7 @@ lib/sh/wcsdup.c             f
 lib/sh/winsize.c       f
 lib/sh/xstrchr.c       f
 lib/sh/zcatfd.c                f
+lib/sh/zmapfd.c                f
 lib/sh/zread.c         f
 lib/sh/zwrite.c                f
 lib/termcap/Makefile.in        f
@@ -712,6 +713,8 @@ tests/source2.sub   f
 tests/source3.sub      f
 tests/source4.sub      f
 tests/source5.sub      f
+tests/comsub.tests     f
+tests/comsub.right     f
 tests/cond.tests       f
 tests/cond.right       f
 tests/cprint.tests     f
@@ -859,6 +862,7 @@ tests/run-array             f
 tests/run-array2       f
 tests/run-braces       f
 tests/run-builtins     f
+tests/run-comsub       f
 tests/run-cond         f
 tests/run-cprint       f
 tests/run-dbg-support  f
index b5339b72bb0a18bd7d6c2d5e7786fb4dafedbe54..e89181814da3bf9f75a100ff09f04aee1119add3 100644 (file)
@@ -204,7 +204,8 @@ SHLIB_SOURCE =      ${SH_LIBSRC}/clktck.c ${SH_LIBSRC}/getcwd.c \
                ${SH_LIBSRC}/memset.c ${SH_LIBSRC}/xstrchr.c \
                ${SH_LIBSRC}/zcatfd.c ${SH_LIBSRC}/shmatch.c \
                ${SH_LIBSRC}/strnlen.c ${SH_LIBSRC}/winsize.c \
-               ${SH_LIBSRC}/eaccess.c ${SH_LIBSRC}/wcsdup.c
+               ${SH_LIBSRC}/eaccess.c ${SH_LIBSRC}/wcsdup.c \
+               ${SH_LIBSRC}/zmapfd.c
 
 SHLIB_LIB = -lsh
 SHLIB_LIBNAME = libsh.a
index 4d94face666ef5147f9b940c361a72154cec82b6..c472a86c48283e25c32442c38700613fbaf9c2e5 100644 (file)
@@ -24,30 +24,29 @@ $PRODUCES declare.c
 $BUILTIN declare
 $FUNCTION declare_builtin
 $SHORT_DOC declare [-afFirtx] [-p] [name[=value] ...]
-Declare variables and/or give them attributes.  If no NAMEs are
-given, then display the values of variables instead.  The -p option
-will display the attributes and values of each NAME.
+Declare variables and give them attributes.  If no NAMEs are
+given, then display the values of variables instead.  When
+displaying variable values, the -f option restricts the display
+to function names and definitions; the -F option restricts the
+display to function names only (plus line number and source file
+when debugging).  The -p option will display the attributes and
+values of each NAME. 
 
-The flags are:
+The options which set attributes are:
 
   -a   to make NAMEs arrays (if supported)
-  -f   to select from among function names only
-  -F   to display function names (and line number and source file name if
-       debugging) without definitions 
   -i   to make NAMEs have the `integer' attribute
   -r   to make NAMEs readonly
   -t   to make NAMEs have the `trace' attribute
   -x   to make NAMEs export
 
-Variables with the integer attribute have arithmetic evaluation (see
-`let') done when the variable is assigned to.
+Using `+' instead of `-' turns off the given attribute.
 
-When displaying values of variables, -f displays a function's name
-and definition.  The -F option restricts the display to function
-name only.
+Variables with the integer attribute have arithmetic evaluation (see
+the `let' command) done when the variable is assigned a value.
 
-Using `+' instead of `-' turns off the given attribute instead.  When
-used in a function, makes NAMEs local, as with the `local' command.
+When used in a function, `declare' makes NAMEs local, as with the `local'
+command.
 $END
 
 $BUILTIN typeset
diff --git a/builtins/declare.def~ b/builtins/declare.def~
new file mode 100644 (file)
index 0000000..4d94fac
--- /dev/null
@@ -0,0 +1,475 @@
+This file is declare.def, from which is created declare.c.
+It implements the builtins "declare" and "local" in Bash.
+
+Copyright (C) 1987-2004 Free Software Foundation, Inc.
+
+This file is part of GNU Bash, the Bourne Again SHell.
+
+Bash 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 2, or (at your option) any later
+version.
+
+Bash 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 Bash; see the file COPYING.  If not, write to the Free Software
+Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
+
+$PRODUCES declare.c
+
+$BUILTIN declare
+$FUNCTION declare_builtin
+$SHORT_DOC declare [-afFirtx] [-p] [name[=value] ...]
+Declare variables and/or give them attributes.  If no NAMEs are
+given, then display the values of variables instead.  The -p option
+will display the attributes and values of each NAME.
+
+The flags are:
+
+  -a   to make NAMEs arrays (if supported)
+  -f   to select from among function names only
+  -F   to display function names (and line number and source file name if
+       debugging) without definitions 
+  -i   to make NAMEs have the `integer' attribute
+  -r   to make NAMEs readonly
+  -t   to make NAMEs have the `trace' attribute
+  -x   to make NAMEs export
+
+Variables with the integer attribute have arithmetic evaluation (see
+`let') done when the variable is assigned to.
+
+When displaying values of variables, -f displays a function's name
+and definition.  The -F option restricts the display to function
+name only.
+
+Using `+' instead of `-' turns off the given attribute instead.  When
+used in a function, makes NAMEs local, as with the `local' command.
+$END
+
+$BUILTIN typeset
+$FUNCTION declare_builtin
+$SHORT_DOC typeset [-afFirtx] [-p] name[=value] ...
+Obsolete.  See `declare'.
+$END
+
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+#  ifdef _MINIX
+#    include <sys/types.h>
+#  endif
+#  include <unistd.h>
+#endif
+
+#include <stdio.h>
+
+#include "../bashansi.h"
+#include "../bashintl.h"
+
+#include "../shell.h"
+#include "common.h"
+#include "builtext.h"
+#include "bashgetopt.h"
+
+extern int array_needs_making;
+extern int posixly_correct;
+
+static int declare_internal __P((register WORD_LIST *, int));
+
+/* Declare or change variable attributes. */
+int
+declare_builtin (list)
+     register WORD_LIST *list;
+{
+  return (declare_internal (list, 0));
+}
+
+$BUILTIN local
+$FUNCTION local_builtin
+$SHORT_DOC local name[=value] ...
+Create a local variable called NAME, and give it VALUE.  LOCAL
+can only be used within a function; it makes the variable NAME
+have a visible scope restricted to that function and its children.
+$END
+int
+local_builtin (list)
+     register WORD_LIST *list;
+{
+  if (variable_context)
+    return (declare_internal (list, 1));
+  else
+    {
+      builtin_error (_("can only be used in a function"));
+      return (EXECUTION_FAILURE);
+    }
+}
+
+#if defined (ARRAY_VARS)
+#  define DECLARE_OPTS "+afiprtxF"
+#else
+#  define DECLARE_OPTS "+fiprtxF"
+#endif
+
+/* The workhorse function. */
+static int
+declare_internal (list, local_var)
+     register WORD_LIST *list;
+     int local_var;
+{
+  int flags_on, flags_off, *flags, any_failed, assign_error, pflag, nodefs, opt;
+  char *t, *subscript_start;
+  SHELL_VAR *var;
+  FUNCTION_DEF *shell_fn;
+
+  flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0;
+  reset_internal_getopt ();
+  while ((opt = internal_getopt (list, DECLARE_OPTS)) != EOF)
+    {
+      flags = list_opttype == '+' ? &flags_off : &flags_on;
+
+      switch (opt)
+       {
+       case 'a':
+#if defined (ARRAY_VARS)
+         *flags |= att_array;
+#endif
+         break;
+       case 'p':
+         if (local_var == 0)
+           pflag++;
+         break;
+        case 'F':
+         nodefs++;
+         *flags |= att_function;
+         break;
+       case 'f':
+         *flags |= att_function;
+         break;
+       case 'i':
+         *flags |= att_integer;
+         break;
+       case 'r':
+         *flags |= att_readonly;
+         break;
+       case 't':
+         *flags |= att_trace;
+         break;
+       case 'x':
+         *flags |= att_exported;
+         array_needs_making = 1;
+         break;
+       default:
+         builtin_usage ();
+         return (EX_USAGE);
+       }
+    }
+
+  list = loptend;
+
+  /* If there are no more arguments left, then we just want to show
+     some variables. */
+  if (list == 0)       /* declare -[afFirtx] */
+    {
+      /* Show local variables defined at this context level if this is
+        the `local' builtin. */
+      if (local_var)
+       {
+         register SHELL_VAR **vlist;
+         register int i;
+
+         vlist = all_local_variables ();
+
+         if (vlist)
+           {
+             for (i = 0; vlist[i]; i++)
+               print_assignment (vlist[i]);
+
+             free (vlist);
+           }
+       }
+      else
+       {
+         if (flags_on == 0)
+           set_builtin ((WORD_LIST *)NULL);
+         else
+           set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs);
+       }
+
+      fflush (stdout);
+      return (EXECUTION_SUCCESS);
+    }
+
+  if (pflag)   /* declare -p [-afFirtx] name [name...] */
+    {
+      for (any_failed = 0; list; list = list->next)
+       {
+         pflag = show_name_attributes (list->word->word, nodefs);
+         if (pflag)
+           {
+             sh_notfound (list->word->word);
+             any_failed++;
+           }
+       }
+      return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
+    }
+
+#define NEXT_VARIABLE() free (name); list = list->next; continue
+
+  /* There are arguments left, so we are making variables. */
+  while (list)         /* declare [-afFirx] name [name ...] */
+    {
+      char *value, *name;
+      int offset, aflags;
+#if defined (ARRAY_VARS)
+      int making_array_special, compound_array_assign, simple_array_assign;
+#endif
+
+      name = savestring (list->word->word);
+      offset = assignment (name, 0);
+      aflags = 0;
+
+      if (offset)      /* declare [-afFirx] name=value */
+       {
+         name[offset] = '\0';
+         value = name + offset + 1;
+         if (name[offset - 1] == '+')
+           {
+             aflags |= ASS_APPEND;
+             name[offset - 1] = '\0';
+           }
+       }
+      else
+       value = "";
+
+#if defined (ARRAY_VARS)
+      compound_array_assign = simple_array_assign = 0;
+      subscript_start = (char *)NULL;
+      if (t = strchr (name, '['))      /* ] */
+       {
+         subscript_start = t;
+         *t = '\0';
+         making_array_special = 1;
+       }
+      else
+       making_array_special = 0;
+#endif
+
+      /* If we're in posix mode or not looking for a shell function (since
+        shell function names don't have to be valid identifiers when the
+        shell's not in posix mode), check whether or not the argument is a
+        valid, well-formed shell identifier. */
+      if ((posixly_correct || (flags_on & att_function) == 0) && legal_identifier (name) == 0)
+       {
+         sh_invalidid (name);
+         assign_error++;
+         NEXT_VARIABLE ();
+       }
+
+      /* If VARIABLE_CONTEXT has a non-zero value, then we are executing
+        inside of a function.  This means we should make local variables,
+        not global ones. */
+
+      /* XXX - this has consequences when we're making a local copy of a
+              variable that was in the temporary environment.  Watch out
+              for this. */
+      if (variable_context && ((flags_on & att_function) == 0))
+       {
+#if defined (ARRAY_VARS)
+         if ((flags_on & att_array) || making_array_special)
+           var = make_local_array_variable (name);
+         else
+#endif
+         var = make_local_variable (name);
+         if (var == 0)
+           {
+             any_failed++;
+             NEXT_VARIABLE ();
+           }
+       }
+      else
+       var = (SHELL_VAR *)NULL;
+
+      /* If we are declaring a function, then complain about it in some way.
+        We don't let people make functions by saying `typeset -f foo=bar'. */
+
+      /* There should be a way, however, to let people look at a particular
+        function definition by saying `typeset -f foo'. */
+
+      if (flags_on & att_function)
+       {
+         if (offset)   /* declare -f [-rix] foo=bar */
+           {
+             builtin_error (_("cannot use `-f' to make functions"));
+             free (name);
+             return (EXECUTION_FAILURE);
+           }
+         else          /* declare -f [-rx] name [name...] */
+           {
+             var = find_function (name);
+
+             if (var)
+               {
+                 if (readonly_p (var) && (flags_off & att_readonly))
+                   {
+                     builtin_error (_("%s: readonly function"), name);
+                     any_failed++;
+                     NEXT_VARIABLE ();
+                   }
+
+                 /* declare -[Ff] name [name...] */
+                 if (flags_on == att_function && flags_off == 0)
+                   {
+#if defined (DEBUGGER)
+                     if (nodefs && debugging_mode)
+                       {
+                         shell_fn = find_function_def (var->name);
+                         if (shell_fn)
+                           printf ("%s %d %s\n", var->name, shell_fn->line, shell_fn->source_file);
+                         else
+                           printf ("%s\n", var->name);
+                       }
+                     else
+#endif /* DEBUGGER */
+                       {       
+                         t = nodefs ? var->name
+                                    : named_function_string (name, function_cell (var), 1);
+                         printf ("%s\n", t);
+                       }
+                   }
+                 else          /* declare -[fF] -[rx] name [name...] */
+                   {
+                     VSETATTR (var, flags_on);
+                     VUNSETATTR (var, flags_off);
+                   }
+               }
+             else
+               any_failed++;
+             NEXT_VARIABLE ();
+           }
+       }
+      else             /* declare -[airx] name [name...] */
+       {
+         /* Non-null if we just created or fetched a local variable. */
+         if (var == 0)
+           var = find_variable (name);
+
+         if (var == 0)
+           {
+#if defined (ARRAY_VARS)
+             if ((flags_on & att_array) || making_array_special)
+               var = make_new_array_variable (name);
+             else
+#endif
+             var = bind_variable (name, "", 0);
+           }
+
+         /* Cannot use declare +r to turn off readonly attribute. */ 
+         if (readonly_p (var) && (flags_off & att_readonly))
+           {
+             sh_readonly (name);
+             any_failed++;
+             NEXT_VARIABLE ();
+           }
+
+         /* Cannot use declare to assign value to readonly or noassign
+            variable. */
+         if ((readonly_p (var) || noassign_p (var)) && offset)
+           {
+             if (readonly_p (var))
+               sh_readonly (name);
+             assign_error++;
+             NEXT_VARIABLE ();
+           }
+
+#if defined (ARRAY_VARS)
+         if ((making_array_special || (flags_on & att_array) || array_p (var)) && offset)
+           {
+             int vlen;
+             vlen = STRLEN (value);
+#if 0
+             if (value[0] == '(' && strchr (value, ')'))
+#else
+             if (value[0] == '(' && value[vlen-1] == ')')
+#endif
+               compound_array_assign = 1;
+             else
+               simple_array_assign = 1;
+           }
+
+         /* Cannot use declare +a name to remove an array variable. */
+         if ((flags_off & att_array) && array_p (var))
+           {
+             builtin_error (_("%s: cannot destroy array variables in this way"), name);
+             any_failed++;
+             NEXT_VARIABLE ();
+           }
+
+         /* declare -a name makes name an array variable. */
+         if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0)
+           var = convert_var_to_array (var);
+#endif /* ARRAY_VARS */
+
+         VSETATTR (var, flags_on);
+         VUNSETATTR (var, flags_off);
+
+#if defined (ARRAY_VARS)
+         if (offset && compound_array_assign)
+           assign_array_var_from_string (var, value, aflags);
+         else if (simple_array_assign && subscript_start)
+           {
+             /* declare [-a] name[N]=value */
+             *subscript_start = '[';   /* ] */
+             var = assign_array_element (name, value, 0);      /* XXX - not aflags */
+             *subscript_start = '\0';
+           }
+         else if (simple_array_assign)
+           /* let bind_array_variable take care of this. */
+           bind_array_variable (name, 0, value, aflags);
+         else
+#endif
+         /* bind_variable_value duplicates the essential internals of
+            bind_variable() */
+         if (offset)
+           bind_variable_value (var, value, aflags);
+
+         /* If we found this variable in the temporary environment, as with
+            `var=value declare -x var', make sure it is treated identically
+            to `var=value export var'.  Do the same for `declare -r' and
+            `readonly'.  Preserve the attributes, except for att_tempvar. */
+         /* XXX -- should this create a variable in the global scope, or
+            modify the local variable flags?  ksh93 has it modify the
+            global scope.
+            Need to handle case like in set_var_attribute where a temporary
+            variable is in the same table as the function local vars. */
+         if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var))
+           {
+             SHELL_VAR *tv;
+             char *tvalue;
+
+             tv = find_tempenv_variable (var->name);
+             if (tv)
+               {
+                 tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring ("");
+                 tv = bind_variable (var->name, tvalue, 0);
+                 tv->attributes |= var->attributes & ~att_tempvar;
+                 if (tv->context > 0)
+                   VSETATTR (tv, att_propagate);
+                 free (tvalue);
+               }
+             VSETATTR (var, att_propagate);
+           }
+       }
+
+      stupidly_hack_special_variables (name);
+
+      NEXT_VARIABLE ();
+    }
+
+  return (assign_error ? EX_BADASSIGN
+                      : ((any_failed == 0) ? EXECUTION_SUCCESS
+                                           : EXECUTION_FAILURE));
+}
index d05bc7bb369d854014024b75d5bf29b66c69a4d5..89d39e0423e2b760970dd4876a26e5546e978b81 100644 (file)
@@ -147,9 +147,14 @@ file_error_and_exit:
   setmode (fd, O_TEXT);
 #endif
 
-  string = (char *)xmalloc (1 + file_size);
-  result = read (fd, string, file_size);
-  string[result] = '\0';
+  if (S_ISREG (finfo.st_mode))
+    {
+      string = (char *)xmalloc (1 + file_size);
+      result = read (fd, string, file_size);
+      string[result] = '\0';
+    }
+  else
+    result = zmapfd (fd, &string, 0);
 
   return_val = errno;
   close (fd);
index 0818a25e21cb6b9fad071e8c6ba055cc61b4410a..dd34ad53a40ce8f7a7d8405d551d765664ec2472 100644 (file)
@@ -24,12 +24,12 @@ $PRODUCES exec.c
 $BUILTIN exec
 $FUNCTION exec_builtin
 $SHORT_DOC exec [-cl] [-a name] file [redirection ...]
-Exec FILE, replacing this shell with the specified program.
+Execute FILE, replacing this shell with the specified program.
 If FILE is not specified, the redirections take effect in this
 shell.  If the first argument is `-l', then place a dash in the
 zeroth arg passed to FILE, as login does.  If the `-c' option
 is supplied, FILE is executed with a null environment.  The `-a'
-option means to make set argv[0] of the executed process to NAME.
+option means set argv[0] of the executed process to NAME.
 If the file cannot be executed and the shell is not interactive,
 then the shell exits, unless the shell option `execfail' is set.
 $END
diff --git a/builtins/exec.def~ b/builtins/exec.def~
new file mode 100644 (file)
index 0000000..0818a25
--- /dev/null
@@ -0,0 +1,229 @@
+This file is exec.def, from which is created exec.c.
+It implements the builtin "exec" in Bash.
+
+Copyright (C) 1987-2003 Free Software Foundation, Inc.
+
+This file is part of GNU Bash, the Bourne Again SHell.
+
+Bash 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 2, or (at your option) any later
+version.
+
+Bash 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 Bash; see the file COPYING.  If not, write to the Free Software
+Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
+
+$PRODUCES exec.c
+
+$BUILTIN exec
+$FUNCTION exec_builtin
+$SHORT_DOC exec [-cl] [-a name] file [redirection ...]
+Exec FILE, replacing this shell with the specified program.
+If FILE is not specified, the redirections take effect in this
+shell.  If the first argument is `-l', then place a dash in the
+zeroth arg passed to FILE, as login does.  If the `-c' option
+is supplied, FILE is executed with a null environment.  The `-a'
+option means to make set argv[0] of the executed process to NAME.
+If the file cannot be executed and the shell is not interactive,
+then the shell exits, unless the shell option `execfail' is set.
+$END
+
+#include <config.h>
+
+#include "../bashtypes.h"
+#include "posixstat.h"
+#include <signal.h>
+#include <errno.h>
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+
+#include "../bashansi.h"
+#include "../bashintl.h"
+
+#include "../shell.h"
+#include "../execute_cmd.h"
+#include "../findcmd.h"
+#if defined (JOB_CONTROL)
+#  include "../jobs.h"
+#endif
+#include "../flags.h"
+#include "../trap.h"
+#if defined (HISTORY)
+#  include "../bashhist.h"
+#endif
+#include "common.h"
+#include "bashgetopt.h"
+
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+extern int subshell_environment;
+extern REDIRECT *redirection_undo_list;
+
+int no_exit_on_failed_exec;
+
+/* If the user wants this to look like a login shell, then
+   prepend a `-' onto NAME and return the new name. */
+static char *
+mkdashname (name)
+     char *name;
+{
+  char *ret;
+
+  ret = (char *)xmalloc (2 + strlen (name));
+  ret[0] = '-';
+  strcpy (ret + 1, name);
+  return ret;
+}
+
+int
+exec_builtin (list)
+     WORD_LIST *list;
+{
+  int exit_value = EXECUTION_FAILURE;
+  int cleanenv, login, opt;
+  char *argv0, *command, **args, **env, *newname, *com2;
+
+  cleanenv = login = 0;
+  argv0 = (char *)NULL;
+
+  reset_internal_getopt ();
+  while ((opt = internal_getopt (list, "cla:")) != -1)
+    {
+      switch (opt)
+       {
+       case 'c':
+         cleanenv = 1;
+         break;
+       case 'l':
+         login = 1;
+         break;
+       case 'a':
+         argv0 = list_optarg;
+         break;
+       default:
+         builtin_usage ();
+         return (EX_USAGE);
+       }
+    }
+  list = loptend;
+
+  /* First, let the redirections remain. */
+  dispose_redirects (redirection_undo_list);
+  redirection_undo_list = (REDIRECT *)NULL;
+
+  if (list == 0)
+    return (EXECUTION_SUCCESS);
+
+#if defined (RESTRICTED_SHELL)
+  if (restricted)
+    {
+      sh_restricted ((char *)NULL);
+      return (EXECUTION_FAILURE);
+    }
+#endif /* RESTRICTED_SHELL */
+
+  args = strvec_from_word_list (list, 1, 0, (int *)NULL);
+
+  /* A command with a slash anywhere in its name is not looked up in $PATH. */
+  command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
+
+  if (command == 0)
+    {
+      sh_notfound (args[0]);
+      exit_value = EX_NOTFOUND;        /* As per Posix.2, 3.14.6 */
+      goto failed_exec;
+    }
+
+  com2 = full_pathname (command);
+  if (com2)
+    {
+      if (command != args[0])
+       free (command);
+      command = com2;
+    }
+
+  if (argv0)
+    {
+      free (args[0]);
+      args[0] = login ? mkdashname (argv0) : savestring (argv0);
+    }
+  else if (login)
+    {
+      newname = mkdashname (args[0]);
+      free (args[0]);
+      args[0] = newname;
+    }
+
+  /* Decrement SHLVL by 1 so a new shell started here has the same value,
+     preserving the appearance.  After we do that, we need to change the
+     exported environment to include the new value. */
+  if (cleanenv == 0)
+    adjust_shell_level (-1);
+
+  if (cleanenv)
+    env = (char **)NULL;
+  else
+    {  
+      maybe_make_export_env ();
+      env = export_env;
+    }
+
+#if defined (HISTORY)
+  if (interactive_shell && subshell_environment == 0)
+    maybe_save_shell_history ();
+#endif /* HISTORY */
+
+  restore_original_signals ();
+
+#if defined (JOB_CONTROL)
+  if (subshell_environment == 0)
+    end_job_control ();
+#endif /* JOB_CONTROL */
+
+  shell_execve (command, args, env);
+
+  /* We have to set this to NULL because shell_execve has called realloc()
+     to stuff more items at the front of the array, which may have caused
+     the memory to be freed by realloc().  We don't want to free it twice. */
+  args = (char **)NULL;
+  if (cleanenv == 0)
+    adjust_shell_level (1);
+
+  if (executable_file (command) == 0)
+    {
+      builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
+      exit_value = EX_NOEXEC;  /* As per Posix.2, 3.14.6 */
+    }
+  else
+    file_error (command);
+
+failed_exec:
+  FREE (command);
+
+  if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0))
+    exit_shell (exit_value);
+
+  if (args)
+    strvec_dispose (args);
+
+  initialize_traps ();
+  initialize_signals (1);
+
+#if defined (JOB_CONTROL)
+  if (interactive_shell || job_control)
+    restart_job_control ();
+#endif /* JOB_CONTROL */
+
+  return (exit_value);
+}
index 28b48d0b5599c1b74e9e093dd3d190348c70f45e..584b944b0bb0f7d14cb575a1f721763394bda7fb 100644 (file)
@@ -61,8 +61,8 @@ $SHORT_DOC time [-p] pipeline
 Execute PIPELINE and print a summary of the real time, user CPU time,
 and system CPU time spent executing PIPELINE when it terminates.
 The return status is the return status of PIPELINE.  The `-p' option
-prints the timing summary in a slightly different format.  This uses
-the value of the TIMEFORMAT variable as the output format.
+prints the timing summary in the portable Posix format; otherwise, the
+the value of the TIMEFORMAT variable is used as the output format.
 $END
 
 $BUILTIN case
index e968ec7cf52931a49c3aa66528401d52f81d6b4b..2ef303b3c19a599fc6f8a9cdbe935a9e0f252770 100644 (file)
@@ -57,12 +57,12 @@ until a break command is executed.
 $END
 
 $BUILTIN time
-$SHORT_DOC time [-p] PIPELINE
+$SHORT_DOC time [-p] pipeline
 Execute PIPELINE and print a summary of the real time, user CPU time,
 and system CPU time spent executing PIPELINE when it terminates.
 The return status is the return status of PIPELINE.  The `-p' option
-prints the timing summary in a slightly different format.  This uses
-the value of the TIMEFORMAT variable as the output format.
+prints the timing summary in the standard Posix format; otherwise, the
+the value of the TIMEFORMAT variable is used as the output format.
 $END
 
 $BUILTIN case
@@ -110,7 +110,7 @@ $END
 
 $BUILTIN %
 $DOCNAME fg_percent
-$SHORT_DOC JOB_SPEC [&]
+$SHORT_DOC job_spec [&]
 Equivalent to the JOB_SPEC argument to the `fg' command.  Resume a
 stopped or background job.  JOB_SPEC can specify either a job name
 or a job number.  Following JOB_SPEC with a `&' places the job in
index 9576f09e1f0f8e267dfe0aaa78acfcdeab41ffb5..0a8eb0ffa2516cd91ca890be529def35b34cfc06 100644 (file)
@@ -38,7 +38,6 @@ in $PATH are used to find the directory containing FILENAME.  If any
 ARGUMENTS are supplied, they become the positional parameters when
 FILENAME is executed.
 $END
-/* source.c - Implements the `.' and `source' builtins. */
 
 #include <config.h>
 
index 8116270f88654e105f7866be921deb099a56b661..bd29b8aac22d535b7c25b4e849add8e16ece74bc 100644 (file)
@@ -6,12 +6,12 @@
 .\"    Case Western Reserve University
 .\"    chet@po.cwru.edu
 .\"
-.\"    Last Change: Tue Nov 21 10:50:26 EST 2006
+.\"    Last Change: Mon Nov 27 12:02:01 EST 2006
 .\"
 .\" bash_builtins, strip all but Built-Ins section
 .if \n(zZ=1 .ig zZ
 .if \n(zY=1 .ig zY
-.TH BASH 1 "2006 November 21" "GNU Bash-3.2"
+.TH BASH 1 "2006 November 27" "GNU Bash-3.2"
 .\"
 .\" There's some problem with having a `@'
 .\" in a tagged paragraph with the BSD man macros.
@@ -6499,8 +6499,11 @@ Mark \fIname\fPs for export to subsequent commands via the environment.
 .PD
 .PP
 Using `+' instead of `\-'
-turns off the attribute instead, with the exception that \fB+a\fP
-may not be used to destroy an array variable.  When used in a function,
+turns off the attribute instead,
+with the exceptions that \fB+a\fP
+may not be used to destroy an array variable and \fB+r\fB will not
+remove the readonly attribute.
+When used in a function,
 makes each
 \fIname\fP local, as with the 
 .B local
index 0f8094706cd47e4d1931bf190762b1e7a1f92954..2460df768b614ae0ec64235fffed960d5d801b32 100644 (file)
@@ -3287,7 +3287,10 @@ Mark each @var{name} for export to subsequent commands via
 the environment.
 @end table
 
-Using @samp{+} instead of @samp{-} turns off the attribute instead.
+Using @samp{+} instead of @samp{-} turns off the attribute instead,
+with the exceptions that @samp{+a}
+may not be used to destroy an array variable and @samp{+r} will not
+remove the readonly attribute.
 When used in a function, @code{declare} makes each @var{name} local,
 as with the @code{local} command.  If a variable name is followed by
 =@var{value}, the value of the variable is set to @var{value}.
index 1f386b4c1179ffdd36a1fb5f0dca2a71d8fae6cb..530e495b7f60f4c4211fd827dd9b4739e156e840 100644 (file)
@@ -2,9 +2,9 @@
 Copyright (C) 1988-2006 Free Software Foundation, Inc.
 @end ignore
 
-@set LASTCHANGE Tue Nov 21 10:50:07 EST 2006
+@set LASTCHANGE Mon Nov 27 12:02:15 EST 2006
 
 @set EDITION 3.2
 @set VERSION 3.2
-@set UPDATED 21 November 2006
+@set UPDATED 27 November 2006
 @set UPDATED-MONTH November 2006
index bc28eda2fc839eff5ac69c78a5accc80bd8ca853..834b767b6ba1b225e5333b569b9033762bb36f22 100644 (file)
--- a/externs.h
+++ b/externs.h
@@ -383,6 +383,9 @@ extern char *xstrchr __P((const char *, int));
 /* declarations for functions defined in lib/sh/zcatfd.c */
 extern int zcatfd __P((int, int, char *));
 
+/* declarations for functions defined in lib/sh/zmapfd.c */
+extern int zmapfd __P((int, char **, char *));
+
 /* declarations for functions defined in lib/sh/zread.c */
 extern ssize_t zread __P((int, char *, size_t));
 extern ssize_t zreadintr __P((int, char *, size_t));
index e0f76b1d4d9cda93451d8f5be7e783afff23e34d..8b1ad7d0da84f2810e4b5b4740f41eb50a9423bb 100644 (file)
@@ -314,11 +314,14 @@ readline (prompt)
       return ((char *)NULL);
     }
 
+#if 0
   /* If readline() is called after installing a callback handler, temporarily
      turn off the callback state to avoid ensuing messiness.  Patch supplied
-     by the gdb folks. */
+     by the gdb folks.  XXX -- disabled.  This can be fooled and readline
+     left in a strange state by a poorly-timed longjmp. */
   if (in_callback = RL_ISSTATE (RL_STATE_CALLBACK))
     RL_UNSETSTATE (RL_STATE_CALLBACK);
+#endif
 
   rl_set_prompt (prompt);
 
@@ -338,8 +341,10 @@ readline (prompt)
   rl_clear_signals ();
 #endif
 
+#if 0
   if (in_callback)
     RL_SETSTATE (RL_STATE_CALLBACK);
+#endif
 
   return (value);
 }
index bf95d19226df0e44a52a3c6533e241aa5e2a64a2..53e5ca5d1f5665a22c5025551645848bdfabf6d7 100644 (file)
@@ -88,7 +88,7 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \
           shquote.c strtrans.c strindex.c snprintf.c mailstat.c \
           fmtulong.c fmtullong.c fmtumax.c shmatch.c strnlen.c \
           strtoll.c strtoull.c strtoimax.c strtoumax.c memset.c strstr.c \
-          mktime.c strftime.c xstrchr.c zcatfd.c winsize.c eaccess.c \
+          mktime.c strftime.c xstrchr.c zcatfd.c zmapfd.c winsize.c eaccess.c \
           wcsdup.c
 
 # The header files for this library.
@@ -101,7 +101,7 @@ OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \
          netconn.o netopen.o timeval.o makepath.o pathcanon.o \
          pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.o \
          strtrans.o strindex.o snprintf.o mailstat.o fmtulong.o \
-         fmtullong.o fmtumax.o xstrchr.o zcatfd.o winsize.o wcsdup.o \
+         fmtullong.o fmtumax.o xstrchr.o zcatfd.o zmapfd.o winsize.o wcsdup.o \
          ${LIBOBJS}
 
 SUPPORT = Makefile
@@ -182,6 +182,7 @@ vprint.o: vprint.c
 wcsdup.o: wcsdup.c
 xstrchr.o: xstrchr.c
 zcatfd.o: zcatfd.c
+zmapfd.o: zmapfd.c
 zread.o: zread.c
 zwrite.o: zwrite.c
 
@@ -241,6 +242,7 @@ vprint.o: ${BUILD_DIR}/config.h
 wcsdup.o: ${BUILD_DIR}/config.h
 xstrchr.o: ${BUILD_DIR}/config.h
 zcatfd.o: ${BUILD_DIR}/config.h
+zmapfd.o: ${BUILD_DIR}/config.h
 zread.o: ${BUILD_DIR}/config.h
 zwrite.o: ${BUILD_DIR}/config.h
 
index 7bbf2c3597aaa242b4f6ae06e46c21c46d346cce..d05523e6a7f0a9e730b1bdf718a7f5f26cd7fc8b 100644 (file)
@@ -674,6 +674,8 @@ number(p, d, base)
 
   sd = d;      /* signed for ' ' padding in base 10 */
   flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
+  if (*p->pf == 'x' || *p->pf == 'X')
+    flags |= FL_UNSIGNED;      /* %x, %X treated as unsigned */
   if (*p->pf == 'X')
     flags |= FL_HEXUPPER;
 
index 95e191b410222614dfffdd5ec478895e1b79561f..7bbf2c3597aaa242b4f6ae06e46c21c46d346cce 100644 (file)
@@ -406,7 +406,7 @@ static void xfree __P((void *));
              } \
        } while (0)
 
-#if defined (HAVE_LOCALE_H)
+#if defined (HAVE_LOCALE_H) && defined (HAVE_LOCALECONV)
 #  define GETLOCALEDATA(d, t, g) \
       do \
        { \
diff --git a/lib/sh/zmapfd.c b/lib/sh/zmapfd.c
new file mode 100644 (file)
index 0000000..9add065
--- /dev/null
@@ -0,0 +1,88 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+   This file is part of GNU Bash, the Bourne Again SHell.
+
+   Bash 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 2, or (at your option) any later
+   version.
+
+   Bash 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 Bash; see the file COPYING.  If not, write to the Free Software
+   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+
+#include <errno.h>
+
+#include "bashansi.h"
+#include "command.h"
+#include "general.h"
+
+#if !defined (errno)
+extern int errno;
+#endif
+
+extern ssize_t zread __P((int, char *, size_t));
+
+/* Dump contents of file descriptor FD to *OSTR.  FN is the filename for
+   error messages (not used right now). */
+int
+zmapfd (fd, ostr, fn)
+     int fd;
+     char **ostr;
+     char *fn;
+{
+  ssize_t nr;
+  int rval;
+  char lbuf[128];
+  char *result;
+  int rsize, rind;
+
+  rval = 0;
+  result = (char *)xmalloc (rsize = 64);
+  rind = 0;
+
+  while (1)
+    {
+      nr = zread (fd, lbuf, sizeof (lbuf));
+      if (nr == 0)
+       {
+         rval = rind;
+         break;
+       }
+      else if (nr < 0)
+       {
+         rval = -1;
+         free (result);
+         if (ostr)
+           *ostr = (char *)NULL;
+         break;
+       }
+
+      RESIZE_MALLOCED_BUFFER (result, rind, nr, rsize, 128);
+      memcpy (result+rind, lbuf, nr);
+      rind += nr;
+    }
+
+  RESIZE_MALLOCED_BUFFER (result, rind, 1, rsize, 128);
+  result[rind] = '\0';
+
+  if (ostr)
+    *ostr = result;
+  else
+    free (result);
+
+  return rval;
+}
index 3efcf32d68e9722024b6ca9d67f9e81b2aa5ac04..72ec06a2c1fd8dde92acea5e8ac773e35f1d061b 100755 (executable)
@@ -1,4 +1,4 @@
-BUILD_DIR=/usr/local/build/chet/bash/bash-current
+BUILD_DIR=/usr/local/build/bash/bash-current
 THIS_SH=$BUILD_DIR/bash
 PATH=$PATH:$BUILD_DIR
 
diff --git a/tests/comsub.right b/tests/comsub.right
new file mode 100644 (file)
index 0000000..a4aed2f
--- /dev/null
@@ -0,0 +1,21 @@
+./comsub.tests: line 7: hijkl: command not found
+argv[1] = <ab>
+argv[2] = <cd>
+argv[1] = <abmn>
+argv[2] = <opyz>
+argv[1] = <b>
+argv[1] = <a\>
+argv[2] = <b>
+argv[1] = <$>
+argv[2] = <bab>
+argv[1] = <`>
+argv[2] = <ab>
+argv[1] = <\>
+argv[2] = <ab>
+argv[1] = <foo \\^Jbar>
+argv[1] = <foo \^Jbar>
+argv[1] = <sed> argv[2] = <-e> argv[3] = <s/[^I:]/\^J/g>
+argv[1] = <sed> argv[2] = <-e> argv[3] = <s/[^I:]//g>
+argv[1] = <foo\^Jbar>
+argv[1] = <foobar>
+argv[1] = <foo\^Jbar>
diff --git a/tests/comsub.tests b/tests/comsub.tests
new file mode 100644 (file)
index 0000000..d481dc3
--- /dev/null
@@ -0,0 +1,42 @@
+# command substution parsing tests
+
+TABSIZE=`grep -v '^[ #]' $CAPS </dev/null | grep -v "^$" | grep -v "^capalias"| grep -v "^infoalias" | wc -l`
+
+recho `echo ab cd #efg
+hijkl`
+
+recho ab$(echo mn; echo op)yz
+
+a=`echo 'a b c' | sed 's/ /\\
+/g' | grep 'b'`
+recho $a
+
+recho `echo 'a\' b`
+
+recho `echo '\$' bab`
+
+recho `echo '\`' ab`
+
+recho `echo '\\' ab`
+
+# old-style command substitution parsing compatibility tests -- post bash-3.1
+recho 'foo \\
+bar'
+
+recho 'foo \
+bar'
+
+echo `recho sed -e 's/[        :]/\\
+/g'`
+
+echo `recho sed -e 's/[        :]/\
+/g'`
+
+echo `recho 'foo\\
+bar'`
+
+echo `recho 'foo\
+bar'`  
+
+echo $(recho 'foo\
+bar')
index eb7d3c3ac290f7e2ba9b0697e2f4986041516a97..63a86f2c81869f9c635b4d8a6c3adac3f64f4437 100644 (file)
@@ -19,7 +19,7 @@ debug lineno: 24 fn1
 debug lineno: 24 fn1
 debug lineno: 25 fn1
 ./dbg-support.tests: line 25: caller: foo: invalid number
-caller: usage: caller [EXPR]
+caller: usage: caller [expr]
 debug lineno: 25 fn1
 debug lineno: 17 fn1
 debug lineno: 12 print_return_trap
@@ -48,7 +48,7 @@ debug lineno: 24 fn1
 debug lineno: 24 fn1 71 main ./dbg-support.tests
 debug lineno: 25 fn1
 ./dbg-support.tests: line 25: caller: foo: invalid number
-caller: usage: caller [EXPR]
+caller: usage: caller [expr]
 debug lineno: 25 fn1
 debug lineno: 17 fn1
 debug lineno: 12 print_return_trap
@@ -190,7 +190,7 @@ FUNCNAME[0] fn1
 79 main ./dbg-support.tests
 
 ./dbg-support.tests: line 25: caller: foo: invalid number
-caller: usage: caller [EXPR]
+caller: usage: caller [expr]
 
 debug lineno: 80 main
 fn2 here. Calling fn1...
@@ -202,7 +202,7 @@ FUNCNAME[0] fn1
 30 fn2 ./dbg-support.tests
 80 main ./dbg-support.tests
 ./dbg-support.tests: line 25: caller: foo: invalid number
-caller: usage: caller [EXPR]
+caller: usage: caller [expr]
 
 debug lineno: 81 main
 LINENO 34
index 73a006ceb0e44daaf92e5321a322d748f596785e..8f27d28bb7cacae2cdeafd8a027d8e33791fdf1d 100644 (file)
@@ -2,9 +2,9 @@
 ./dstack.tests: line 9: pushd: no other directory
 ./dstack.tests: line 10: popd: directory stack empty
 ./dstack.tests: line 13: pushd: -m: invalid number
-pushd: usage: pushd [dir | +N | -N] [-n]
+pushd: usage: pushd [-n] [+N | -N | dir]
 ./dstack.tests: line 14: popd: -m: invalid number
-popd: usage: popd [+N | -N] [-n]
+popd: usage: popd [-n] [+N | -N]
 ./dstack.tests: line 15: dirs: -m: invalid number
 dirs: usage: dirs [-clpv] [+N] [-N]
 ./dstack.tests: line 16: dirs: 7: invalid option
index ac987fbdd5035c2cff45093426c6715f039cb6b3..abef9e1ad6ee3a1ca8c9f15469cba479ebf37a1c 100644 (file)
@@ -68,7 +68,7 @@ source: usage: source filename [arguments]
 ./errors.tests: line 184: .: -i: invalid option
 .: usage: . filename [arguments]
 ./errors.tests: line 187: set: -q: invalid option
-set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
+set: usage: set [--abefhkmnptuvxBCHP] [-o option-name] [arg ...]
 ./errors.tests: line 190: enable: sh: not a shell builtin
 ./errors.tests: line 190: enable: bash: not a shell builtin
 ./errors.tests: line 193: shopt: cannot set and unset shell options simultaneously
index 556a3129b36bf81836ae2171fd6712ca6d328726..edd2777b89e4544f02b2cb581b2506c4abc52903 100644 (file)
@@ -2,7 +2,7 @@
 history: usage: history [-c] [-d offset] [n] or history -awrn [filename] or history -ps arg [arg...]
 ./history.tests: line 6: history: cannot use more than one of -anrw
 ./history.tests: line 9: fc: -v: invalid option
-fc: usage: fc [-e ename] [-nlr] [first] [last] or fc -s [pat=rep] [cmd]
+fc: usage: fc [-e ename] [-nlr] [first] [last] or fc -s [pat=rep] [command]
     1  for i in one two three; do echo $i; done
     2  /bin/sh -c 'echo this is $0'
     3  ls
index 0dc33cbb0912b1e601955b1ae33cbf732a706154..d4c2373eb168b11ad6fa914a49ce0d0f020eece3 100644 (file)
@@ -1,4 +1,4 @@
-export LANG=en_US.UTF-8
+export LC_ALL=en_US.UTF-8
 
 a=$'\303\251'
 
index bff3dd4b075fa504febcd0ec16e9618a367497a2..4509570528adb68898b60438d005e63f58430677 100644 (file)
@@ -515,4 +515,7 @@ argv[1] = <>
 argv[1] = <>
 argv[1] = <>
 argv[1] = <12>
+argv[1] = <>
+argv[1] = <>
+argv[1] = </tmp/test/TEST>
 ./new-exp.tests: line 560: ABXD: parameter unset
index c2fbd73c937f8971e3c02be4b8d0d60510169cf3..532ec1af78973d1a43226763146d5756620c350c 100644 (file)
@@ -20,3 +20,10 @@ recho "${str/$str/}"
 recho "${snul##$snul}"
 recho "${str##$str}"
 recho "${str##$nul}"
+
+A=""
+B="${A:0}"
+
+recho "$B"
+recho "${A:0}"
+recho "/tmp/test/TEST${A:0}"
index 43c0574155d102fcaa4074e17fec3ccca62d7d3b..5a8749ef162ac464abd76bb60fe75e678ddd1465 100644 (file)
Binary files a/tests/printf.right and b/tests/printf.right differ
index bd3bcc10e6df27b5c562ac6f2bdbe1ae9417d3c1..7cfeebd02dc9e878bd27675243e9402653938341 100644 (file)
@@ -285,3 +285,18 @@ printf "%E\n" 4
 printf "%e\n" 4
 printf "%4.2E\n" 4
 printf "%4.2e\n" 4
+
+printf "%08X\n" 2604292517
+
+# make sure these format specifiers all output '' for empty string arguments
+echo q
+printf "%q\n" ""
+printf "%q\n"
+
+echo s
+printf "%s\n" ''
+printf "%s\n"
+
+echo b
+printf "%b\n" ''
+printf "%b\n"
index 60928d6bbe15524b06aca42d186919f3d28998c1..04241085fdb4a4b79a7a8eadf0335aee49824f6d 100644 (file)
@@ -253,3 +253,48 @@ printf '%0.5d\n' 1
 printf '%05d\n' 1
 printf '%5d\n' 1
 printf '%0d\n' 1
+
+# failures with various floating point formats and 0 after bash-3.2
+
+printf "%G\n" 0
+printf "%g\n" 0
+printf "%4.2G\n" 0
+printf "%4.2g\n" 0
+
+printf "%G\n" 4
+printf "%g\n" 4
+printf "%4.2G\n" 4
+printf "%4.2g\n" 4
+
+printf "%F\n" 0
+printf "%f\n" 0
+printf "%4.2F\n" 0
+printf "%4.2f\n" 0
+
+printf "%F\n" 4
+printf "%f\n" 4
+printf "%4.2F\n" 4
+printf "%4.2f\n" 4
+
+printf "%E\n" 0
+printf "%e\n" 0
+printf "%4.2E\n" 0
+printf "%4.2e\n" 0
+
+printf "%E\n" 4
+printf "%e\n" 4
+printf "%4.2E\n" 4
+printf "%4.2e\n" 4
+
+# make sure these format specifiers all output '' for empty string arguments
+echo q
+printf "%q\n" ""
+printf "%q\n"
+
+echo s
+printf "%s\n" ''
+printf "%s\n"
+
+echo b
+printf "%b\n" ''
+printf "%b\n"
index e673b94d494c73411ffbef6f3282c883727dbb31..04c6971086d4a651562c29c5d6de01cc9c0d3636 100644 (file)
@@ -7,7 +7,7 @@
 ./rsh.tests: line 21: /tmp/restricted: restricted: cannot redirect output
 ./rsh.tests: line 26: command: -p: restricted
 ./rsh.tests: line 28: set: +r: invalid option
-set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
+set: usage: set [--abefhkmnptuvxBCHP] [-o option-name] [arg ...]
 ./rsh.tests: line 29: set: restricted: invalid option name
 ./rsh.tests: line 31: exec: restricted
 ./rsh.tests: after exec
diff --git a/tests/run-comsub b/tests/run-comsub
new file mode 100644 (file)
index 0000000..0bbcad5
--- /dev/null
@@ -0,0 +1,2 @@
+${THIS_SH} ./comsub.tests > /tmp/xx 2>&1
+diff /tmp/xx comsub.right && rm -f /tmp/xx