From: Chet Ramey Date: Mon, 1 Apr 2019 19:44:20 +0000 (-0400) Subject: commit bash-20190328 snapshot X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=befdddcbf1a23e98352185321021a2d5265510cd;p=thirdparty%2Fbash.git commit bash-20190328 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 398d4abe3..11073450f 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -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 + + 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 diff --git a/MANIFEST b/MANIFEST index d8627af8c..f1661127a 100644 --- 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 diff --git a/Makefile.in b/Makefile.in index 4391c4067..4615ed43d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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) diff --git a/builtins/common.c b/builtins/common.c index 00be24ea0..34ccd8866 100644 --- a/builtins/common.c +++ b/builtins/common.c @@ -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; +} diff --git a/builtins/common.h b/builtins/common.h index bfc294ecc..e18e53567 100644 --- a/builtins/common.h +++ b/builtins/common.h @@ -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; diff --git a/builtins/printf.def b/builtins/printf.def index bc6ef57de..64d1260bb 100644 --- a/builtins/printf.def +++ b/builtins/printf.def @@ -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; -} diff --git a/builtins/read.def b/builtins/read.def index b57c8c398..5d077b986 100644 --- a/builtins/read.def +++ b/builtins/read.def @@ -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)); } diff --git a/builtins/wait.def b/builtins/wait.def index 5deb3735c..a0c3c22cd 100644 --- a/builtins/wait.def +++ b/builtins/wait.def @@ -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); diff --git a/config-bot.h b/config-bot.h index 5563e2a87..0589244f6 100644 --- a/config-bot.h +++ b/config-bot.h @@ -98,6 +98,10 @@ # 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" diff --git a/config-top.h b/config-top.h index 56dbd51e6..bb25adf94 100644 --- a/config-top.h +++ b/config-top.h @@ -173,6 +173,7 @@ /* 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 */ diff --git a/config.h.in b/config.h.in index 8554aecca..8ae4db909 100644 --- a/config.h.in +++ b/config.h.in @@ -746,6 +746,9 @@ /* 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 diff --git a/configure b/configure index b64a650e0..9db96f16a 100755 --- 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 diff --git a/configure.ac b/configure.ac index 9eecf8786..76264adec 100644 --- a/configure.ac +++ b/configure.ac @@ -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 . -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) diff --git a/doc/bash.1 b/doc/bash.1 index 542730a07..7cf5de29c 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -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. diff --git a/doc/bashref.texi b/doc/bashref.texi index 70ab6473b..7678845b9 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -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 diff --git a/examples/loadables/Makefile.in b/examples/loadables/Makefile.in index 05df1d49f..ef2923ced 100644 --- a/examples/loadables/Makefile.in +++ b/examples/loadables/Makefile.in @@ -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 index 000000000..1f7c9ad39 --- /dev/null +++ b/examples/loadables/mktemp.c @@ -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 . +*/ + +#include + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include +#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 */ +}; diff --git a/externs.h b/externs.h index 72df33d16..9e174c082 100644 --- 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 *)); diff --git a/include/posixwait.h b/include/posixwait.h index 815ea2299..63b59c24a 100644 --- a/include/posixwait.h +++ b/include/posixwait.h @@ -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 a3905afba..fae63f07b 100644 --- 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 ddea88b14..d0c646b71 100644 --- 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)); diff --git a/lib/sh/tmpfile.c b/lib/sh/tmpfile.c index e41e45bd7..5c918147d 100644 --- a/lib/sh/tmpfile.c +++ b/lib/sh/tmpfile.c @@ -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 */ +} diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 554f3d6ec..0b0638107 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -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 diff --git a/tests/heredoc.right b/tests/heredoc.right index be68f9b72..27065a7d9 100644 --- a/tests/heredoc.right +++ b/tests/heredoc.right @@ -101,6 +101,6 @@ argv[1] = argv[2] = argv[3] = 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 diff --git a/tests/heredoc.tests b/tests/heredoc.tests index 6cbc4f808..ae3d83930 100644 --- a/tests/heredoc.tests +++ b/tests/heredoc.tests @@ -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 index 000000000..9f070c95a --- /dev/null +++ b/tests/heredoc5.sub @@ -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 diff --git a/tests/run-all b/tests/run-all index 34d3e4c8e..36a3289c1 100644 --- a/tests/run-all +++ b/tests/run-all @@ -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} diff --git a/tests/run-gprof b/tests/run-gprof index a0438ba01..04379864a 100644 --- a/tests/run-gprof +++ b/tests/run-gprof @@ -18,6 +18,9 @@ export PATH : ${THIS_SH:=../bash} export THIS_SH +: ${BUILD_DIR:=..} +export BUILD_DIR + GPROF="gprof" rm -f gmon.sum diff --git a/tests/run-minimal b/tests/run-minimal index bbb9da189..454d579a8 100644 --- a/tests/run-minimal +++ b/tests/run-minimal @@ -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" diff --git a/variables.c b/variables.c index 00118bdaf..2a9753a58 100644 --- a/variables.c +++ b/variables.c @@ -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 }