]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
commit bash-20190328 snapshot
authorChet Ramey <chet.ramey@case.edu>
Mon, 1 Apr 2019 19:44:20 +0000 (15:44 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 1 Apr 2019 19:44:20 +0000 (15:44 -0400)
30 files changed:
CWRU/CWRU.chlog
MANIFEST
Makefile.in
builtins/common.c
builtins/common.h
builtins/printf.def
builtins/read.def
builtins/wait.def
config-bot.h
config-top.h
config.h.in
configure
configure.ac
doc/bash.1
doc/bashref.texi
examples/loadables/Makefile.in
examples/loadables/mktemp.c [new file with mode: 0644]
externs.h
include/posixwait.h
jobs.c
jobs.h
lib/sh/tmpfile.c
tests/RUN-ONE-TEST
tests/heredoc.right
tests/heredoc.tests
tests/heredoc5.sub [new file with mode: 0644]
tests/run-all
tests/run-gprof
tests/run-minimal
variables.c

index 398d4abe37598823754e93185609e4640d396a94..11073450f13bf5dfd8f01da7242c568844184e1f 100644 (file)
@@ -5658,3 +5658,49 @@ builtins/enable.def
        - dyn_load_builtin: add warning if dynamic builtin with a load function
          is loaded more than once, before running the load function a second
          time. From a suggestion by Stan Marsh <gazelle@xmission.com>
+
+                                  3/25
+                                  ----
+jobs.[ch]
+       - wait_for_any_job: takes a new argument, a struct procstat * that
+         gets the PID of the exited job's process leader (the one that
+         contributes the status) and the same status we return from the
+         function
+
+builtins/wait.def
+       - wait_builtin: pass a struct procstat * to wait_for_any_job to get
+         the pid of the job's process leader (and the same status the
+         function returns). We don't do anything with it yet
+
+                                  3/28
+                                  ----
+variable.c
+       - seedrand: add a couple more variables to the random seed
+
+lib/sh/tmpfile.c
+       - sh_mktmpdir: new function, makes a temporary directory using
+         mkdtemp if it's available, and generates a filename using
+         sh_mktmpname (which uses mktemp, if available) and makes a
+         directory with it if not
+
+config-{top,bot}.h
+       - set up to use mkdtemp if available
+
+externs.h
+       - sh_mktmpdir: extern declaration
+       - MT_TEMPFILE: new flag for the tempfile functions; means to use the
+         value in the NAMEROOT argument as a template for the mktemp/mkstemp/
+         mkdtemp functions. Not used in mainline shell code
+
+examples/loadables/mktemp.c
+       - mktemp: new loadable builtin, with BSD options and basic semantics
+
+                                  3/29
+                                  ----
+builtins/common.c,builtins/printf.def
+       - builtin_bind_variable: moved bind_printf_variable to common.c from
+         printf.def, renamed to builtin_bind_variable, made global for other
+         builtins to use
+
+builtins/read.def
+       - bind_read_variable: now uses builtin_bind_variable
index d8627af8ce06b37bf9dcb39321b1f18d8192636d..f1661127ac69c212d5d5a8f2338b13b48731f977 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -737,6 +737,7 @@ examples/loadables/whoami.c f
 examples/loadables/uname.c     f
 examples/loadables/sync.c      f
 examples/loadables/mkdir.c     f
+examples/loadables/mktemp.c    f
 examples/loadables/ln.c                f
 examples/loadables/mypid.c     f
 examples/loadables/unlink.c    f
@@ -1109,6 +1110,7 @@ tests/heredoc1.sub        f
 tests/heredoc2.sub     f
 tests/heredoc3.sub     f
 tests/heredoc4.sub     f
+tests/heredoc5.sub     f
 tests/herestr.tests    f
 tests/herestr.right    f
 tests/herestr1.sub     f
index 4391c40671174cecdee2f800bcaeb7f7c075e0b6..4615ed43d0878f1396c6e7c2f695ed1862e5090c 100644 (file)
@@ -1,4 +1,4 @@
-# Makefile for bash-5.0, version 4.27
+# Makefile for bash-5.0, version 4.28
 #
 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
 
@@ -618,7 +618,7 @@ asan-tests: asan  $(TESTS_SUPPORT)
        @-test -d tests || mkdir tests
        @cp $(TESTS_SUPPORT) tests
        @( cd $(srcdir)/tests && \
-               PATH=$(BUILD_DIR)/tests:$$PATH THIS_SH=$(THIS_SH) $(SHELL) ${TESTSCRIPT} )
+               BUILD_DIR=$(BUILD_DIR) PATH=$(BUILD_DIR)/tests:$$PATH THIS_SH=$(THIS_SH) $(SHELL) ${TESTSCRIPT} )
 
 profiling-tests:       ${PROGRAM}
        @test "X$$PROFILE_FLAGS" == "X" && { echo "profiling-tests: must be built with profiling enabled" >&2; exit 1; }
@@ -950,7 +950,7 @@ test tests check:   force $(Program) $(TESTS_SUPPORT)
        @-test -d tests || mkdir tests
        @cp $(TESTS_SUPPORT) tests
        @( cd $(srcdir)/tests && \
-               PATH=$(BUILD_DIR)/tests:$$PATH THIS_SH=$(THIS_SH) $(SHELL) ${TESTSCRIPT} )
+               BUILD_DIR=$(BUILD_DIR) PATH=$(BUILD_DIR)/tests:$$PATH THIS_SH=$(THIS_SH) $(SHELL) ${TESTSCRIPT} )
 
 symlinks:
        $(SHELL) $(SUPPORT_SRC)fixlinks -s $(srcdir)
index 00be24ea0029911f48273cf666f79206f78e3812..34ccd88661fedbee425736f36138c8cc15607a12 100644 (file)
@@ -908,3 +908,32 @@ builtin_help ()
   printf ("%s: %s\n", this_command_name, _("help not available in this version"));
 }
 #endif
+
+/* **************************************************************** */
+/*                                                                 */
+/*         Variable assignments during builtin commands            */
+/*                                                                 */
+/* **************************************************************** */
+
+SHELL_VAR *
+builtin_bind_variable (name, value, flags)
+     char *name;
+     char *value;
+     int flags;
+{
+  SHELL_VAR *v;
+
+#if defined (ARRAY_VARS)
+  if (valid_array_reference (name, assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0) == 0)
+    v = bind_variable (name, value, flags);
+  else
+    v = assign_array_element (name, value, flags | (assoc_expand_once ? ASS_NOEXPAND : 0));
+#else /* !ARRAY_VARS */
+  v = bind_variable (name, value, flags);
+#endif /* !ARRAY_VARS */
+
+  if (v && readonly_p (v) == 0 && noassign_p (v) == 0)
+    VUNSETATTR (v, att_invisible);
+
+  return v;
+}
index bfc294eccdee5057f833af7c8321bd28875b2992..e18e53567f9e9f77e6364acb43da552b8b4d1b6b 100644 (file)
@@ -217,6 +217,8 @@ extern int fc_execute_file __P((const char *));
 extern sh_builtin_func_t *this_shell_builtin;
 extern sh_builtin_func_t *last_shell_builtin;
 
+extern SHELL_VAR *builtin_bind_variable __P((char *, char *, int));
+
 /* variables from evalfile.c */
 extern int sourcelevel;
 
index bc6ef57deca1a495485242d71bdc83d3d3b5efe0..64d1260bb211f09dd5a345ecfe94aa164c920b87 100644 (file)
@@ -149,7 +149,7 @@ extern int errno;
       if (vflag) \
        { \
          SHELL_VAR *v; \
-         v = bind_printf_variable  (vname, vbuf, 0); \
+         v = builtin_bind_variable  (vname, vbuf, 0); \
          stupidly_hack_special_variables (vname); \
          if (v == 0 || readonly_p (v) || noassign_p (v)) \
            return (EXECUTION_FAILURE); \
@@ -206,7 +206,6 @@ static char *getstr __P((void));
 static int  getint __P((void));
 static intmax_t getintmax __P((void));
 static uintmax_t getuintmax __P((void));
-static SHELL_VAR *bind_printf_variable __P((char *, char *, int));
 
 #if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN)
 typedef long double floatmax_t;
@@ -301,7 +300,7 @@ printf_builtin (list)
   if (vflag && list->word->word && list->word->word[0] == '\0')
     {
       SHELL_VAR *v;
-      v = bind_printf_variable (vname, "", 0);
+      v = builtin_bind_variable (vname, "", 0);
       stupidly_hack_special_variables (vname);
       return ((v == 0 || readonly_p (v) || noassign_p (v)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
     }
@@ -1271,26 +1270,3 @@ asciicode ()
   garglist = garglist->next;
   return (ch);
 }
-
-static SHELL_VAR *
-bind_printf_variable (name, value, flags)
-     char *name;
-     char *value;
-     int flags;
-{
-  SHELL_VAR *v;
-
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name, assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0) == 0)
-    v = bind_variable (name, value, flags);
-  else
-    v = assign_array_element (name, value, flags | (assoc_expand_once ? ASS_NOEXPAND : 0));
-#else /* !ARRAY_VARS */
-  v = bind_variable (name, value, flags);
-#endif /* !ARRAY_VARS */
-
-  if (v && readonly_p (v) == 0 && noassign_p (v) == 0)
-    VUNSETATTR (v, att_invisible);
-
-  return v;
-}
index b57c8c398e18f4ffd1de627274cc24e80c834b9d..5d077b986ceecba672804440087518cdadaeb8c7 100644 (file)
@@ -966,14 +966,7 @@ bind_read_variable (name, value)
 {
   SHELL_VAR *v;
 
-#if defined (ARRAY_VARS)
-  if (valid_array_reference (name, assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0) == 0)
-    v = bind_variable (name, value, 0);
-  else
-    v = assign_array_element (name, value, assoc_expand_once ? ASS_NOEXPAND : 0);
-#else /* !ARRAY_VARS */
-  v = bind_variable (name, value, 0);
-#endif /* !ARRAY_VARS */
+  v = builtin_bind_variable (name, value, 0);
   return (v == 0 ? v
                 : ((readonly_p (v) || noassign_p (v)) ? (SHELL_VAR *)NULL : v));
 }
index 5deb3735c40ceb717e980e2e8f2b290f349423dd..a0c3c22cdaf6c8f2e3ad04738edb70a85a1187d6 100644 (file)
@@ -102,6 +102,9 @@ wait_builtin (list)
 {
   int status, code, opt, nflag, wflags;
   volatile int old_interrupt_immediately;
+#if defined (JOB_CONTROL)
+  struct procstat pstat;
+#endif
 
   USE_VAR(list);
 
@@ -157,7 +160,7 @@ wait_builtin (list)
 #if defined (JOB_CONTROL)
   if (nflag)
     {
-      status = wait_for_any_job (wflags);
+      status = wait_for_any_job (wflags, &pstat);
       if (status < 0)
        status = 127;
       WAIT_RETURN (status);
index 5563e2a87f9c702ac5de02b473cc6b662816bd8f..0589244f688840b9fab5f632185299e34609ac72 100644 (file)
 #  undef USE_MKSTEMP
 #endif
 
+#if !HAVE_MKDTEMP
+#  undef USE_MKDTMP
+#endif
+
 /* If the shell is called by this name, it will become restricted. */
 #if defined (RESTRICTED_SHELL)
 #  define RESTRICTED_SHELL_NAME "rbash"
index 56dbd51e61ad5baf4ac53da0907dba9de93c1d45..bb25adf94093cdfa02ac3ff5b52de316c24bd1c9 100644 (file)
 /* Define to use libc mktemp/mkstemp instead of replacements in lib/sh/tmpfile.c */
 #define USE_MKTEMP
 #define USE_MKSTEMP
+#define USE_MKDTEMP
 
 /* Define to force the value of OLDPWD inherited from the environment to be a
    directory */
index 8554aecca12a1ffa92b6da74d0e7e758b2b46f33..8ae4db909a3f7b8c9711fa75b8bee6446d8f2ef5 100644 (file)
 /* Define if you have the memset function.  */
 #undef HAVE_MEMSET
 
+/* Define if you have the mkdtemp function.  */
+#undef HAVE_MKDTEMP
+
 /* Define if you have the mkfifo function.  */
 #undef HAVE_MKFIFO
 
index b64a650e0d44dfb4757d275155c94640ec0135fe..9db96f16afa3587d6cc6921ebe278534d5017940 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.ac for Bash 5.0, version 5.008.
+# From configure.ac for Bash 5.0, version 5.009.
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.69 for bash 5.0-maint.
 #
@@ -13892,12 +13892,13 @@ _ACEOF
 fi
 done
 
-for ac_func in mkstemp
+for ac_func in mkstemp mkdtemp
 do :
-  ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp"
-if test "x$ac_cv_func_mkstemp" = xyes; then :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
-#define HAVE_MKSTEMP 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
 fi
index 9eecf8786a26176ba32b3b73ee69f83a6a200eff..76264adec972f152d8384d5f5799bb20dfef9a20 100644 (file)
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
 #   You should have received a copy of the GNU General Public License
 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-AC_REVISION([for Bash 5.0, version 5.008])dnl
+AC_REVISION([for Bash 5.0, version 5.009])dnl
 
 define(bashvers, 5.0)
 define(relstatus, maint)
@@ -833,7 +833,7 @@ AC_CHECK_FUNCS(bcopy bzero confstr faccessat fnmatch \
 AC_CHECK_FUNCS(vasprintf asprintf)
 AC_CHECK_FUNCS(isascii isblank isgraph isprint isspace isxdigit)
 AC_CHECK_FUNCS(getpwent getpwnam getpwuid)
-AC_CHECK_FUNCS(mkstemp)
+AC_CHECK_FUNCS(mkstemp mkdtemp)
 AC_REPLACE_FUNCS(getcwd memset)
 AC_REPLACE_FUNCS(strcasecmp strcasestr strerror strftime strnlen strpbrk strstr)
 AC_REPLACE_FUNCS(strtod strtol strtoul strtoll strtoull strtoimax strtoumax)
index 542730a07b85f7465e49efa20af47de7c83cd6d0..7cf5de29c2423303e26f545b4b5dcae0af8389eb 100644 (file)
@@ -10759,8 +10759,8 @@ in that job's pipeline are waited for.  If
 .I id
 is not given, all currently active child processes
 are waited for, and the return status is zero.
-If the \fB\-n\fP option is supplied, \fBwait\fP waits for any job to
-terminate and returns its exit status.
+If the \fB\-n\fP option is supplied, \fBwait\fP waits for a single job
+to terminate and returns its exit status.
 Supplying the \fB\-f\fP option, when job control is enabled,
 forces \fBwait\fP to wait for \fIid\fP to terminate before returning
 its status, instead of returning when it changes status.
index 70ab6473b6c9f4d36b65dd1180076a67c6ddd7a7..7678845b968eea89dab5eaea2ea4fb1d38976a01 100644 (file)
@@ -8096,8 +8096,8 @@ last command waited for.
 If a job spec is given, all processes in the job are waited for.
 If no arguments are given, all currently active child processes are
 waited for, and the return status is zero.
-If the @option{-n} option is supplied, @code{wait} waits for any job to
-terminate and returns its exit status.
+If the @option{-n} option is supplied, @code{wait} waits for a single job
+to terminate and returns its exit status.
 Supplying the @option{-f} option, when job control is enabled,
 forces @code{wait} to wait for each @var{pid} or @var{jobspec} to
 terminate before returning its status, intead of returning when it changes
index 05df1d49f3b3d86fdd2d1eeee91c60a13e12b6c2..ef2923ced9ecb037c6859462b45aab0c06634032 100644 (file)
@@ -101,7 +101,7 @@ INC = -I. -I.. -I$(topdir) -I$(topdir)/lib -I$(topdir)/builtins -I${srcdir} \
 
 
 ALLPROG = print truefalse sleep finfo logname basename dirname fdflags \
-         tty pathchk tee head mkdir rmdir printenv id whoami \
+         tty pathchk tee head mkdir rmdir mktemp printenv id whoami \
          uname sync push ln unlink realpath strftime mypid setpgid seq
 OTHERPROG = necho hello cat pushd stat rm
 
@@ -175,6 +175,9 @@ mkdir:      mkdir.o
 rmdir: rmdir.o
        $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ rmdir.o $(SHOBJ_LIBS)
 
+mktemp:        mktemp.o
+       $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ mktemp.o $(SHOBJ_LIBS)
+
 head:  head.o
        $(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ head.o $(SHOBJ_LIBS)
 
@@ -292,6 +295,7 @@ uname.o: uname.c
 sync.o: sync.c
 push.o: push.c
 mkdir.o: mkdir.c
+mktemp.o: mktemp.c
 realpath.o: realpath.c
 strftime.o: strftime.c
 setpgid.o: setpgid.c
diff --git a/examples/loadables/mktemp.c b/examples/loadables/mktemp.c
new file mode 100644 (file)
index 0000000..1f7c9ad
--- /dev/null
@@ -0,0 +1,212 @@
+/* mktemp - create temporary file or directory */
+
+/*
+   Copyright (C) 2019 Free Software Foundation, Inc.
+
+   This file is part of GNU Bash.
+   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 3 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include "bashansi.h"
+
+#include "loadables.h"
+
+#define DEFAULT_PREFIX "shtmp"
+
+int
+mktemp_builtin (list)
+     WORD_LIST *list;
+{
+  WORD_LIST *l;
+  int rval, opt, fd, mflags, base_mflags;
+  int dflag, qflag, tflag, uflag, onetime;
+  char *prefix, *varname, *filename, *template;
+  SHELL_VAR *v;
+
+  dflag = qflag = uflag = tflag = onetime = 0;
+  prefix = varname = 0;
+  rval = EXECUTION_SUCCESS;
+
+  reset_internal_getopt ();
+  while ((opt = internal_getopt (list, "dqut:v:")) != -1)
+    {
+      switch (opt)
+       {
+       case 'd':
+         dflag = 1;
+         break;
+       case 'q':
+         qflag = 1;
+         break;
+       case 't':
+         tflag = 1;
+         prefix = list_optarg;
+         break;
+       case 'u':
+         uflag = 1;
+         break;
+       case 'v':
+         varname = list_optarg;
+         break;
+       CASE_HELPOPT;
+       default:
+         builtin_usage ();
+         return (EX_USAGE);
+       }
+    }
+  list = loptend;
+
+  if (varname)                 /* check for validity, not readonly */
+    {
+      if (legal_identifier (varname) == 0)
+       {
+         if (qflag == 0)
+           sh_invalidid (varname);
+         return (EXECUTION_FAILURE);
+       }
+      v = find_variable (varname);
+      if (v && readonly_p (v))
+       {
+         if (qflag == 0)
+           sh_readonly (varname);
+         return (EXECUTION_FAILURE);
+       }
+    }
+
+  onetime = (list == 0);       /* once through the loop, $TMPDIR/prefix.XXXXXX */
+
+  if (prefix == 0)
+    prefix = DEFAULT_PREFIX;
+  base_mflags = MT_USETMPDIR|MT_USERANDOM;     /* USERANDOM not strictly needed */
+
+  while (list || onetime)
+    {
+      mflags = base_mflags;
+      onetime = 0;
+#if defined (USE_MKTEMP) && defined (USE_MKSTEMP)
+      if (list)
+       {
+         template = list->word->word;
+         mflags |= MT_TEMPLATE;
+       }
+#else
+      /* This is sub-optimal. */
+      if (list)
+       {
+         /* Treat the basename as a prefix */
+         template = strrchr (list->word->word, '/');
+         if (template)
+           template++;
+         else
+           template = list->word->word;
+       }
+#endif
+      else
+       template = prefix;
+
+      if (dflag)
+       {
+         filename = sh_mktmpdir (template, mflags);
+         if (filename == 0)
+           {
+             if (qflag == 0)
+               builtin_error ("%s: cannot create directory", template);
+             rval = EXECUTION_FAILURE;
+           }
+         else
+           {
+             if (uflag)
+               rmdir (filename);
+             printf ("%s\n", filename);
+           }
+       }
+      else             /* filename */
+       {
+         fd = sh_mktmpfd (template, mflags, &filename);
+         if (fd < 0)
+           {
+             if (qflag == 0)
+               builtin_error ("%s: cannot create file", template);
+             rval = EXECUTION_FAILURE;
+           }
+         else
+           {
+             close (fd);
+             if (uflag)
+               unlink (filename);
+             printf ("%s\n", filename);
+           }
+       }
+
+      /* Assign variable if requested */
+      if (filename && varname)
+       {
+         v = builtin_bind_variable (varname, filename, 0);
+         if (v == 0 || readonly_p (v) || noassign_p (v))
+           {
+             builtin_error ("%s: cannot set variable", varname);
+             rval = EXECUTION_FAILURE;
+           }
+       }
+
+      FREE (filename);
+
+      if (list)
+        list = list->next;
+    }
+
+  return (rval);
+}
+
+char *mktemp_doc[] = {
+       "Make unique temporary file name",
+       "",
+       "Take each supplied filename template and overwrite a portion of it",
+       "to create a filename, which is unique and may be used by the calling",
+       "script. TEMPLATE is a string ending in some number of 'X's. If",
+       "TEMPLATE is not supplied, shtmp.XXXXXX is used and $TMPDIR is used as",
+       "the name of the containing directory. Files are created u+rw; directories",
+       "are created u+rwx.",
+       "",
+       "Options, if supplied, have the following meanings:",
+       "",
+       "    -d    Create a directory instead of a file",
+       "    -q    Do not print error messages about file creation failure",
+       "    -t PREFIX Use PREFIX as the directory in which to create files",
+       "    -u    Do not create anything; simply print a name",
+       "    -v VAR    Store the generated name into shell variable VAR",
+       "",
+       "Any PREFIX supplied with -t is ignored if TEMPLATE is supplied.",
+       "",
+       "The return status is true if the file or directory was created successfully;",
+       "false if an error occurs or VAR is invalid or readonly.",
+
+       (char *)NULL
+};
+
+struct builtin mktemp_struct = {
+       "mktemp",               /* builtin name */
+       mktemp_builtin,         /* function implementing the builtin */
+       BUILTIN_ENABLED,        /* initial flags for builtin */
+       mktemp_doc,             /* array of long documentation strings. */
+       "mktemp [-d] [-q] [-t prefix] [-u] [-v varname] [template] ...",
+       0                       /* reserved for internal use */
+};
index 72df33d1627657ea6d45720fc394dcb68d5f375e..9e174c0820c51f0a56e567e6bcd3d550747795f8 100644 (file)
--- a/externs.h
+++ b/externs.h
@@ -470,10 +470,12 @@ extern void print_timeval ();
 #define MT_USETMPDIR           0x0001
 #define MT_READWRITE           0x0002
 #define MT_USERANDOM           0x0004
+#define MT_TEMPLATE            0x0008
 
 extern char *sh_mktmpname __P((char *, int));
 extern int sh_mktmpfd __P((char *, int, char **));
 /* extern FILE *sh_mktmpfp __P((char *, int, char **)); */
+extern char *sh_mktmpdir __P((char *, int));
 
 /* declarations for functions defined in lib/sh/uconvert.c */
 extern int uconvert __P((char *, long *, long *));
index 815ea22992478370c33213261bc78f362daf5690..63b59c24a8814ca94cd1f6b66d87d90905c14234 100644 (file)
@@ -77,7 +77,11 @@ typedef int WAIT;
 #  endif /* !WIFSIGNALED */
 
 #  if !defined (WIFCORED)
-#    define WIFCORED(s)       ((s) & 0200)
+#    if defined (WCOREDUMP)
+#      define WIFCORED(s)      (WCOREDUMP(s))
+#    else
+#      define WIFCORED(s)       ((s) & 0200)
+#    endif
 #  endif /* !WIFCORED */
 
 #else /* !_POSIX_VERSION */
diff --git a/jobs.c b/jobs.c
index a3905afbac1c2a3ebc0f07d095d2d8dedde5ede1..fae63f07b3357e751bf53e074223eef585c905f0 100644 (file)
--- a/jobs.c
+++ b/jobs.c
@@ -3085,10 +3085,12 @@ wait_for_job (job, flags)
 /* Wait for any background job started by this shell to finish.  Very
    similar to wait_for_background_pids().  Returns the exit status of
    the next exiting job, -1 if there are no background jobs.  The caller
-   is responsible for translating -1 into the right return value. */
+   is responsible for translating -1 into the right return value. RPID,
+   if non-null, gets the pid of the job's process leader. */
 int
-wait_for_any_job (flags)
+wait_for_any_job (flags, ps)
      int flags;
+     struct procstat *ps;
 {
   pid_t pid;
   int i, r;
@@ -3105,6 +3107,12 @@ wait_for_any_job (flags)
        {
 return_job:
          r = job_exit_status (i);
+         pid = find_last_pid (i, 0);
+         if (ps)
+           {
+             ps->pid = pid;
+             ps->status = r;
+           }
          notify_of_job_status ();              /* XXX */
          delete_job (i, 0);
 #if defined (COPROCESS_SUPPORT)
diff --git a/jobs.h b/jobs.h
index ddea88b1413cd20ed2bad4f1716a9494c528916d..d0c646b71407fe4c37a2a0215234cffb54753248 100644 (file)
--- a/jobs.h
+++ b/jobs.h
@@ -169,6 +169,12 @@ struct bgpids {
 
 #define NO_PIDSTAT (ps_index_t)-1
 
+/* standalone process status struct, without bgpids indexes */
+struct procstat {
+  pid_t pid;
+  bits16_t status;
+};
+
 #define NO_JOB  -1     /* An impossible job array index. */
 #define DUP_JOB -2     /* A possible return value for get_job_spec (). */
 #define BAD_JOBSPEC -3 /* Bad syntax for job spec. */
@@ -245,7 +251,7 @@ extern int wait_for_single_pid __P((pid_t, int));
 extern void wait_for_background_pids __P((void));
 extern int wait_for __P((pid_t));
 extern int wait_for_job __P((int, int));
-extern int wait_for_any_job __P((int));
+extern int wait_for_any_job __P((int, struct procstat *));
 
 extern void wait_sigint_cleanup __P((void));
 
index e41e45bd7cac237b51dd13a22d268046bdf18324..5c918147d4d625501c39fdae64b44b1436395cf6 100644 (file)
@@ -2,7 +2,7 @@
  * tmpfile.c - functions to create and safely open temp files for the shell.
  */
 
-/* Copyright (C) 2000-2015 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2019 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -146,9 +146,17 @@ sh_mktmpname (nameroot, flags)
   tdlen = strlen (tdir);
 
   lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
+  if (nameroot == 0)
+    flags &= ~MT_TEMPLATE;
+
+  if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX)
+    flags &= ~MT_TEMPLATE;
 
 #ifdef USE_MKTEMP
-  sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+  if (flags & MT_TEMPLATE)
+    strcpy (filename, nameroot);
+  else
+    sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
   if (mktemp (filename) == 0)
     {
       free (filename);
@@ -192,9 +200,17 @@ sh_mktmpfd (nameroot, flags, namep)
   tdlen = strlen (tdir);
 
   lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
+  if (nameroot == 0)
+    flags &= ~MT_TEMPLATE;
+
+  if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX)
+    flags &= ~MT_TEMPLATE;
 
 #ifdef USE_MKSTEMP
-  sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+  if (flags & MT_TEMPLATE)
+    strcpy (filename, nameroot);
+  else
+    sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
   fd = mkstemp (filename);
   if (fd < 0 || namep == 0)
     {
@@ -245,3 +261,51 @@ sh_mktmpfp (nameroot, flags, namep)
     close (fd);
   return fp;
 }
+
+char *
+sh_mktmpdir (nameroot, flags)
+     char *nameroot;
+     int flags;
+{
+  char *filename, *tdir, *lroot, *dirname;
+  int fd, tdlen;
+  
+#ifdef USE_MKDTEMP
+  filename = (char *)xmalloc (PATH_MAX + 1);
+  tdir = get_tmpdir (flags);
+  tdlen = strlen (tdir);
+
+  lroot = nameroot ? nameroot : DEFAULT_NAMEROOT;
+  if (nameroot == 0)
+    flags &= ~MT_TEMPLATE;
+
+  if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX)
+    flags &= ~MT_TEMPLATE;
+
+  if (flags & MT_TEMPLATE)
+    strcpy (filename, nameroot);
+  else
+    sprintf (filename, "%s/%s.XXXXXX", tdir, lroot);
+  dirname = mkdtemp (filename);
+  if (dirname == 0)
+    {
+      free (filename);
+      filename = NULL;
+    }
+  return dirname;
+#else /* !USE_MKDTEMP */
+  filename = (char *)NULL;
+  do
+    {
+      filename = sh_mktmpname (nameroot, flags);
+      fd = mkdir (filename, 0700);
+      if (fd == 0)
+       break;
+      free (filename);
+      filename = (char *)NULL;
+    }
+  while (fd < 0 && errno == EEXIST);
+
+  return (filename);
+#endif /* !USE_MKDTEMP */
+}
index 554f3d6ecc09d7149b13daa2d36a6bab1480269f..0b06381072414283266cf5d055a42ac14b9b6da6 100755 (executable)
@@ -1,8 +1,8 @@
-BUILD_DIR=/usr/local/build/bash/bash-current
+BUILD_DIR=/usr/local/build/chet/bash/bash-current
 THIS_SH=$BUILD_DIR/bash
 PATH=$PATH:$BUILD_DIR
 
-export THIS_SH PATH
+export THIS_SH PATH BUILD_DIR
 
 : ${TMPDIR:=/tmp}
 export TMPDIR
index be68f9b72e36c587a4eed3e735895861bb20e2e4..27065a7d9d96c2867e430f5d05986f020a68c964 100644 (file)
@@ -101,6 +101,6 @@ argv[1] = <two>
 argv[2] = <threefi>
 argv[3] = <ve>
 comsub here-string
-./heredoc.tests: line 133: warning: here-document at line 131 delimited by end-of-file (wanted `EOF')
+./heredoc.tests: line 136: warning: here-document at line 134 delimited by end-of-file (wanted `EOF')
 hi
 there
index 6cbc4f8087ce391f7e4010260d9b6cec9e827ad6..ae3d83930a7d2a75a111c01f7c052f7b1503fe44 100644 (file)
@@ -121,6 +121,9 @@ ${THIS_SH} ./heredoc2.sub
 ${THIS_SH} ./heredoc3.sub
 ${THIS_SH} ./heredoc4.sub
 
+# heredoc tests that use different size documents to test pipe implementation
+${THIS_SH} ./heredoc5.sub
+
 echo $(
        cat <<< "comsub here-string"
 )
diff --git a/tests/heredoc5.sub b/tests/heredoc5.sub
new file mode 100644 (file)
index 0000000..9f070c9
--- /dev/null
@@ -0,0 +1,28 @@
+# test here documents for sizes > 65536 (max pipe capacity I've seen),
+# 4096 < size < 65536 (for smaller pipe capacities)
+# 512 < size < 4096 (PIPE_BUF)
+#
+# There are tests in other scripts for here documents shorter than 512 bytes
+#
+# This should return the same results regardless of the pipe capacity
+
+: ${TMPDIR:=/tmp}
+FILENAME=${TMPDIR}/catfile-$$
+
+catfile()
+{
+       cat <<- EOF > $FILENAME
+               $(cat $1)
+EOF
+       cmp $FILENAME $1
+       rm -f $FILENAME
+}
+
+
+if [ -f $BUILD_DIR/y.tab.c ]; then
+       catfile $BUILD_DIR/y.tab.c
+else
+       catfile ../y.tab.c
+fi
+catfile ${BUILD_DIR}/config.h
+catfile ${BUILD_DIR}/version.h
index 34d3e4c8ebbe645f92acb40a2f4a019855db67ce..36a3289c16bab0f92b8c59b10db32296baf4dc78 100644 (file)
@@ -14,6 +14,7 @@ trap 'rm -f $BASH_TSTOUT' 0 1 2 3 15
 PATH=.:$PATH   # just to get recho/zecho/printenv if not run via `make tests'
 export PATH
 
+
 # unset BASH_ENV only if it is set
 [ "${BASH_ENV+set}" = "set" ] && unset BASH_ENV
 # can't reliably do it for SHELLOPTS; SHELLOPTS is readonly in bash
@@ -28,6 +29,9 @@ fi
 : ${THIS_SH:=../bash}
 export THIS_SH
 
+: ${BUILD_DIR:=..}
+export BUILD_DIR
+
 ${THIS_SH} ./version
 
 rm -f ${BASH_TSTOUT}
index a0438ba01983dde3ce84f386030b90c9aaf83366..04379864a79da9fcca8c1095e71a622e3a30b590 100644 (file)
@@ -18,6 +18,9 @@ export PATH
 : ${THIS_SH:=../bash}
 export THIS_SH
 
+: ${BUILD_DIR:=..}
+export BUILD_DIR
+
 GPROF="gprof"
 
 rm -f gmon.sum
index bbb9da189c21252b9568f795ad526e54815cf173..454d579a86d338bf4d76ac8320de8e39d7b972ec 100644 (file)
@@ -26,6 +26,9 @@ export PATH
 : ${THIS_SH:=../bash}
 export THIS_SH
 
+: ${BUILD_DIR:=..}
+export BUILD_DIR
+
 ${THIS_SH} ./version.mini
 
 rm -f "$BASH_TSTOUT"
index 00118bdafd2d4851d4477dbbc39baa32a05aa8c6..2a9753a58b9b181e56f287582cb3e3ea72e92029 100644 (file)
@@ -1376,7 +1376,7 @@ seedrand ()
   v = find_variable ("BASH_VERSION");
   sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid () ^ ((u_bits32_t)&v & 0x7fffffff));
 #else
-  sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid ());
+  sbrand (tv.tv_sec ^ tv.tv_usec ^ getpid () ^ getppid () ^ current_user.uid ^ current_user.gid);
 #endif
 }