301 lines
7.2 KiB
Diff
301 lines
7.2 KiB
Diff
---
|
|
execute_cmd.c | 4 ++
|
|
jobs.c | 45 +++++++++++++++++++------
|
|
nojobs.c | 5 ++
|
|
subst.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
subst.h | 8 ++++
|
|
5 files changed, 154 insertions(+), 10 deletions(-)
|
|
|
|
--- execute_cmd.c
|
|
+++ execute_cmd.c 2019-06-05 09:19:06.362106086 +0000
|
|
@@ -722,6 +722,10 @@ execute_command_internal (command, async
|
|
stdin_redir = stdin_redirects (command->redirects);
|
|
|
|
#if defined (PROCESS_SUBSTITUTION)
|
|
+# if !defined (HAVE_DEV_FD)
|
|
+ reap_procsubs ();
|
|
+# endif
|
|
+
|
|
if (variable_context != 0)
|
|
{
|
|
ofifo = num_fifos ();
|
|
--- jobs.c
|
|
+++ jobs.c 2019-06-05 09:42:13.056119389 +0000
|
|
@@ -72,6 +72,8 @@
|
|
#include "execute_cmd.h"
|
|
#include "flags.h"
|
|
|
|
+#include "typemax.h"
|
|
+
|
|
#include "builtins/builtext.h"
|
|
#include "builtins/common.h"
|
|
|
|
@@ -92,7 +94,7 @@ extern int killpg __P((pid_t, int));
|
|
#endif
|
|
|
|
#if !MAX_CHILD_MAX
|
|
-# define MAX_CHILD_MAX 8192
|
|
+# define MAX_CHILD_MAX 32768
|
|
#endif
|
|
|
|
#if !defined (DEBUG)
|
|
@@ -751,7 +753,7 @@ stop_pipeline (async, deferred)
|
|
static void
|
|
bgp_resize ()
|
|
{
|
|
- ps_index_t nsize;
|
|
+ ps_index_t nsize, nsize_cur, nsize_max;
|
|
ps_index_t psi;
|
|
|
|
if (bgpids.nalloc == 0)
|
|
@@ -765,10 +767,19 @@ bgp_resize ()
|
|
else
|
|
nsize = bgpids.nalloc;
|
|
|
|
- while (nsize < js.c_childmax)
|
|
- nsize *= 2;
|
|
+ nsize_max = TYPE_MAXIMUM (ps_index_t);
|
|
+ nsize_cur = (ps_index_t)js.c_childmax;
|
|
+ if (nsize_cur < 0) /* overflow */
|
|
+ nsize_cur = MAX_CHILD_MAX;
|
|
+
|
|
+ while (nsize > 0 && nsize < nsize_cur) /* > 0 should catch overflow */
|
|
+ nsize <<= 1;
|
|
+ if (nsize > nsize_max || nsize <= 0) /* overflow? */
|
|
+ nsize = nsize_max;
|
|
+ if (nsize > MAX_CHILD_MAX)
|
|
+ nsize = nsize_max = MAX_CHILD_MAX; /* hard cap */
|
|
|
|
- if (bgpids.nalloc < js.c_childmax)
|
|
+ if (bgpids.nalloc < nsize_cur && bgpids.nalloc < nsize_max)
|
|
{
|
|
bgpids.storage = (struct pidstat *)xrealloc (bgpids.storage, nsize * sizeof (struct pidstat));
|
|
|
|
@@ -785,9 +796,7 @@ bgp_resize ()
|
|
static ps_index_t
|
|
bgp_getindex ()
|
|
{
|
|
- ps_index_t psi;
|
|
-
|
|
- if (bgpids.nalloc < js.c_childmax || bgpids.head >= bgpids.nalloc)
|
|
+ if (bgpids.nalloc < (ps_index_t)js.c_childmax || bgpids.head >= bgpids.nalloc)
|
|
bgp_resize ();
|
|
|
|
pshash_delindex (bgpids.head); /* XXX - clear before reusing */
|
|
@@ -1010,6 +1019,7 @@ cleanup_dead_jobs ()
|
|
{
|
|
register int i;
|
|
int os;
|
|
+ PROCESS *discard;
|
|
|
|
if (js.j_jobslots == 0 || jobs_list_frozen)
|
|
return;
|
|
@@ -1034,8 +1044,9 @@ cleanup_dead_jobs ()
|
|
if (last_procsub_child && last_procsub_child->running == PS_DONE)
|
|
{
|
|
bgp_add (last_procsub_child->pid, process_exit_status (last_procsub_child->status)); /* XXX */
|
|
- discard_pipeline (last_procsub_child);
|
|
+ discard = last_procsub_child;
|
|
last_procsub_child = (PROCESS *)NULL;
|
|
+ discard_pipeline (discard);
|
|
}
|
|
#endif
|
|
|
|
@@ -2475,6 +2486,13 @@ wait_for_background_pids ()
|
|
waited_for++;
|
|
}
|
|
|
|
+#if defined (PROCESS_SUBSTITUTION)
|
|
+ if (last_procsub_child && last_procsub_child->pid != NO_PID)
|
|
+ r = wait_for (last_procsub_child->pid);
|
|
+ wait_procsubs ();
|
|
+ reap_procsubs ();
|
|
+#endif
|
|
+
|
|
/* POSIX.2 says the shell can discard the statuses of all completed jobs if
|
|
`wait' is called with no arguments. */
|
|
mark_dead_jobs_as_notified (1);
|
|
@@ -3498,6 +3516,7 @@ waitchld (wpid, block)
|
|
WAIT status;
|
|
PROCESS *child;
|
|
pid_t pid;
|
|
+ int ind;
|
|
|
|
int call_set_current, last_stopped_job, job, children_exited, waitpid_flags;
|
|
static int wcontinued = WCONTINUED; /* run-time fix for glibc problem */
|
|
@@ -3604,6 +3623,13 @@ itrace("waitchld: waitpid returns %d blo
|
|
coproc_pidchk (pid, WSTATUS(status));
|
|
#endif
|
|
|
|
+#if defined (PROCESS_SUBSTITUTION)
|
|
+ /* Only manipulate the list of process substitutions while SIGCHLD
|
|
+ is blocked. */
|
|
+ if ((ind = find_procsub_child (pid)) >= 0)
|
|
+ set_procsub_status (ind, pid, WSTATUS (status));
|
|
+#endif
|
|
+
|
|
/* It is not an error to have a child terminate that we did
|
|
not have a record of. This child could have been part of
|
|
a pipeline in backquote substitution. Even so, I'm not
|
|
@@ -4838,5 +4864,4 @@ restore_pgrp_pipe (p)
|
|
pgrp_pipe[0] = p[0];
|
|
pgrp_pipe[1] = p[1];
|
|
}
|
|
-
|
|
#endif /* PGRP_PIPE */
|
|
--- nojobs.c
|
|
+++ nojobs.c 2019-06-05 09:28:29.891549557 +0000
|
|
@@ -273,6 +273,11 @@ set_pid_status (pid, status)
|
|
coproc_pidchk (pid, status);
|
|
#endif
|
|
|
|
+#if defined (PROCESS_SUBSTITUTION)
|
|
+ if ((slot = find_procsub_child (pid)) >= 0)
|
|
+ set_procsub_status (slot, pid, WSTATUS (status));
|
|
+#endif
|
|
+
|
|
slot = find_index_by_pid (pid);
|
|
if (slot == NO_PID)
|
|
return;
|
|
--- subst.c
|
|
+++ subst.c 2019-06-05 09:34:35.696693909 +0000
|
|
@@ -5506,6 +5506,55 @@ close_new_fifos (list, lsize)
|
|
}
|
|
|
|
int
|
|
+find_procsub_child (pid)
|
|
+ pid_t pid;
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < nfifo; i++)
|
|
+ if (fifo_list[i].proc == pid)
|
|
+ return i;
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+void
|
|
+set_procsub_status (ind, pid, status)
|
|
+ int ind;
|
|
+ pid_t pid;
|
|
+ int status;
|
|
+{
|
|
+ if (ind >= 0 && ind < nfifo)
|
|
+ fifo_list[ind].proc = (pid_t)-1; /* sentinel */
|
|
+}
|
|
+
|
|
+/* If we've marked the process for this procsub as dead, close the
|
|
+ associated file descriptor and delete the FIFO. */
|
|
+void
|
|
+reap_procsubs ()
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < nfifo; i++)
|
|
+ if (fifo_list[i].proc == (pid_t)-1) /* reaped */
|
|
+ unlink_fifo (i);
|
|
+}
|
|
+
|
|
+void
|
|
+wait_procsubs ()
|
|
+{
|
|
+ int i, r;
|
|
+
|
|
+ for (i = 0; i < nfifo; i++)
|
|
+ {
|
|
+ if (fifo_list[i].proc != (pid_t)-1 && fifo_list[i].proc > 0)
|
|
+ {
|
|
+ r = wait_for (fifo_list[i].proc);
|
|
+ fifo_list[i].proc = (pid_t)-1;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+int
|
|
fifos_pending ()
|
|
{
|
|
return nfifo;
|
|
@@ -5674,6 +5723,59 @@ close_new_fifos (list, lsize)
|
|
unlink_fifo (i);
|
|
}
|
|
|
|
+int
|
|
+find_procsub_child (pid)
|
|
+ pid_t pid;
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (nfds == 0)
|
|
+ return -1;
|
|
+
|
|
+ for (i = 0; i < totfds; i++)
|
|
+ if (dev_fd_list[i] == pid)
|
|
+ return i;
|
|
+
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+void
|
|
+set_procsub_status (ind, pid, status)
|
|
+ int ind;
|
|
+ pid_t pid;
|
|
+ int status;
|
|
+{
|
|
+ if (ind >= 0 && ind < totfds)
|
|
+ dev_fd_list[ind] = (pid_t)-1; /* sentinel */
|
|
+}
|
|
+
|
|
+/* If we've marked the process for this procsub as dead, close the
|
|
+ associated file descriptor. */
|
|
+void
|
|
+reap_procsubs ()
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; nfds > 0 && i < totfds; i++)
|
|
+ if (dev_fd_list[i] == (pid_t)-1)
|
|
+ unlink_fifo (i);
|
|
+}
|
|
+
|
|
+void
|
|
+wait_procsubs ()
|
|
+{
|
|
+ int i, r;
|
|
+
|
|
+ for (i = 0; nfds > 0 && i < totfds; i++)
|
|
+ {
|
|
+ if (dev_fd_list[i] != (pid_t)-1 && dev_fd_list[i] > 0)
|
|
+ {
|
|
+ r = wait_for (dev_fd_list[i]);
|
|
+ dev_fd_list[i] = (pid_t)-1;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
#if defined (NOTDEF)
|
|
print_dev_fd_list ()
|
|
{
|
|
--- subst.h
|
|
+++ subst.h 2019-06-05 09:15:36.846029324 +0000
|
|
@@ -261,6 +261,7 @@ extern WORD_LIST *expand_words_shellexp
|
|
extern WORD_DESC *command_substitute __P((char *, int));
|
|
extern char *pat_subst __P((char *, char *, char *, int));
|
|
|
|
+#if defined (PROCESS_SUBSTITUTION)
|
|
extern int fifos_pending __P((void));
|
|
extern int num_fifos __P((void));
|
|
extern void unlink_fifo_list __P((void));
|
|
@@ -272,6 +273,13 @@ extern void close_new_fifos __P((char *,
|
|
|
|
extern void clear_fifo_list __P((void));
|
|
|
|
+extern int find_procsub_child __P((pid_t));
|
|
+extern void set_procsub_status __P((int, pid_t, int));
|
|
+
|
|
+extern void wait_procsubs __P((void));
|
|
+extern void reap_procsubs __P((void));
|
|
+#endif
|
|
+
|
|
extern WORD_LIST *list_string_with_quotes __P((char *));
|
|
|
|
#if defined (ARRAY_VARS)
|