From 0568080fce102531efc26ab49b023818fefca67a Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Fri, 20 Mar 2015 16:58:28 -0400 Subject: [PATCH] commit bash-20150313 snapshot --- CWRU/CWRU.chlog | 31 +++++++++++++++++++++++++++++++ arrayfunc.c | 4 ++-- jobs.c | 33 +++++++++++++++++++++++++++++---- jobs.h | 3 ++- subst.c | 11 ++++++++++- 5 files changed, 74 insertions(+), 8 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 33571f711..cc3261401 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -8103,3 +8103,34 @@ pathexp.c closing right bracket, rescan it from just after the opening bracket without treating it as a bracket expression. Bug report from Stephane Chazelas + + 3/9 + --- +subst.c + - process_substitute: keep the last pipeline created to run a process + substitution in LAST_PROCSUB_CHILD; discard it when another one is + created + +jobs.[ch] + - discard_pipeline: now global, so process_substitute can call it + +jobs.c + - last_procsub_child: new variable, set and modified only by the process + substitution code + - find_pipeline: if the requested pid is in LAST_PROCSUB_CHILD, return it; + analogous to the way this code handles the_pipeline + - waitchld: if we find a child via find_pipeline that is a part of the + last process substitution child, mark that child appropriately. If + the child is dead, add it to the bgp list. This and the previous change + allow waiting for the most recent process substitution (the one + corresponding to $!). Original report from Stephane Chazelas + + + 3/10 + ---- +arrayfunc.c + - unbind_array_element: make sure skipsubscript() doesn't try to parse + embedded quotes in the subscript, since this has already been through + one round of word expansion before calling the unset builtin. (This + function is only called by the unset builtin). Fixes bug reported by + diff --git a/arrayfunc.c b/arrayfunc.c index cb7333939..d917bad88 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -1,6 +1,6 @@ /* arrayfunc.c -- High-level array functions used by other parts of the shell. */ -/* Copyright (C) 2001-2011 Free Software Foundation, Inc. +/* Copyright (C) 2001-2015 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -737,7 +737,7 @@ unbind_array_element (var, sub) char *akey; ARRAY_ELEMENT *ae; - len = skipsubscript (sub, 0, 0); + len = skipsubscript (sub, 0, (var && assoc_p(var))); if (sub[len] != ']' || len == 0) { builtin_error ("%s[%s: %s", var->name, sub, _(bash_badsub_errmsg)); diff --git a/jobs.c b/jobs.c index 5db74ee94..3ce9d2d4e 100644 --- a/jobs.c +++ b/jobs.c @@ -233,6 +233,8 @@ int already_making_children = 0; exits from get_tty_state(). */ int check_window_size = CHECKWINSIZE_DEFAULT; +PROCESS *last_procsub_child = (PROCESS *)NULL; + /* Functions local to this file. */ static sighandler wait_sigint_handler __P((int)); @@ -273,7 +275,6 @@ static void cleanup_dead_jobs __P((void)); static int processes_in_job __P((int)); static void realloc_jobs_list __P((void)); static int compact_jobs_list __P((int)); -static int discard_pipeline __P((PROCESS *)); static void add_process __P((char *, pid_t)); static void print_pipeline __P((PROCESS *, int, int, FILE *)); static void pretty_print_job __P((int, int, FILE *)); @@ -445,7 +446,7 @@ save_pipeline (clear) UNBLOCK_CHILD (oset); } -void +PROCESS * restore_pipeline (discard) int discard; { @@ -459,7 +460,11 @@ restore_pipeline (discard) UNBLOCK_CHILD (oset); if (discard && old_pipeline) - discard_pipeline (old_pipeline); + { + discard_pipeline (old_pipeline); + return ((PROCESS *)NULL); + } + return old_pipeline; } /* Start building a pipeline. */ @@ -1090,7 +1095,7 @@ nohup_job (job_index) } /* Get rid of the data structure associated with a process chain. */ -static int +int discard_pipeline (chain) register PROCESS *chain; { @@ -1345,6 +1350,20 @@ find_pipeline (pid, alive_only, jobp) } while (p != the_pipeline); } + /* Now look in the last process substitution pipeline, since that sets $! */ + if (last_procsub_child) + { + p = last_procsub_child; + do + { + /* Return it if we found it. Don't ever return a recycled pid. */ + if (p->pid == pid && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p))) + return (p); + + p = p->next; + } + while (p != last_procsub_child); + } job = find_job (pid, alive_only, &p); if (jobp) @@ -3363,6 +3382,12 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc js.c_reaped++; } +#if defined (PROCESS_SUBSTITUTION) + /* XXX - should we make this unconditional and not depend on last procsub? */ + if (child && child == last_procsub_child && child->running == PS_DONE) + bgp_add (child->pid, process_exit_status (child->status)); /* XXX */ +#endif + if (job == NO_JOB) continue; diff --git a/jobs.h b/jobs.h index e19ca0947..abbeb7e91 100644 --- a/jobs.h +++ b/jobs.h @@ -176,9 +176,10 @@ extern void making_children __P((void)); extern void stop_making_children __P((void)); extern void cleanup_the_pipeline __P((void)); extern void save_pipeline __P((int)); -extern void restore_pipeline __P((int)); +extern PROCESS *restore_pipeline __P((int)); extern void start_pipeline __P((void)); extern int stop_pipeline __P((int, COMMAND *)); +extern int discard_pipeline __P((PROCESS *)); extern void append_process __P((char *, pid_t, int, int)); extern void delete_job __P((int, int)); diff --git a/subst.c b/subst.c index 1b12fd733..7f6528495 100644 --- a/subst.c +++ b/subst.c @@ -174,6 +174,10 @@ extern int expanding_redir; extern int tempenv_assign_error; extern int builtin_ignoring_errexit; +#if defined (JOB_CONTROL) && defined (PROCESS_SUBSTITUTION) +extern PROCESS *last_procsub_child; +#endif + #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE) extern wchar_t *wcsdup __P((const wchar_t *)); #endif @@ -5459,7 +5463,12 @@ process_substitute (string, open_for_read_in_child) if (pid > 0) { #if defined (JOB_CONTROL) - restore_pipeline (1); + if (last_procsub_child) + { + discard_pipeline (last_procsub_child); + last_procsub_child = (PROCESS *)NULL; + } + last_procsub_child = restore_pipeline (0); #endif #if !defined (HAVE_DEV_FD) -- 2.47.2