|
Kamil Dudka |
7e97ff |
From 223ac53797d33b0473323efc0d5a44d1dceaf746 Mon Sep 17 00:00:00 2001
|
|
Kamil Dudka |
7e97ff |
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
|
|
Kamil Dudka |
7e97ff |
Date: Sun, 26 Oct 2014 17:47:42 +0000
|
|
Kamil Dudka |
7e97ff |
Subject: [PATCH 1/2] 33531 with additions: retain status of exited background
|
|
Kamil Dudka |
7e97ff |
jobs.
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
Add linked list of unwaited-for background jobs.
|
|
Kamil Dudka |
7e97ff |
Truncate at value of _SC_CHILD_MAX discarding oldest.
|
|
Kamil Dudka |
7e97ff |
Remove old lastpid_status mechanism for latest exited process only.
|
|
Kamil Dudka |
7e97ff |
Slightly tighten safety of permanently allocated linked lists so
|
|
Kamil Dudka |
7e97ff |
that this doesn't compromise signal handling.
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
Upstream-commit: b4f7ccecd93ca9e64c3c3c774fdaefae83d7204a
|
|
Kamil Dudka |
7e97ff |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
Kamil Dudka |
7e97ff |
---
|
|
Kamil Dudka |
7e97ff |
Doc/Zsh/builtins.yo | 16 ++++++
|
|
Kamil Dudka |
7e97ff |
Doc/Zsh/options.yo | 8 +--
|
|
Kamil Dudka |
5385c4 |
Doc/zshoptions.1 | 8 +--
|
|
Kamil Dudka |
7e97ff |
Src/exec.c | 2 -
|
|
Kamil Dudka |
7e97ff |
Src/init.c | 1 -
|
|
Kamil Dudka |
7e97ff |
Src/jobs.c | 138 ++++++++++++++++++++++++++++++++++++++++++++--------
|
|
Kamil Dudka |
7e97ff |
Src/linklist.c | 4 ++
|
|
Kamil Dudka |
7e97ff |
Src/signals.c | 14 +++---
|
|
Kamil Dudka |
5385c4 |
8 files changed, 152 insertions(+), 39 deletions(-)
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
|
|
Kamil Dudka |
7e97ff |
index 46f40cc..edc335e 100644
|
|
Kamil Dudka |
7e97ff |
--- a/Doc/Zsh/builtins.yo
|
|
Kamil Dudka |
7e97ff |
+++ b/Doc/Zsh/builtins.yo
|
|
Kamil Dudka |
7e97ff |
@@ -2059,6 +2059,22 @@ then all currently active child processes are waited for.
|
|
Kamil Dudka |
7e97ff |
Each var(job) can be either a job specification or the process ID
|
|
Kamil Dudka |
7e97ff |
of a job in the job table.
|
|
Kamil Dudka |
7e97ff |
The exit status from this command is that of the job waited for.
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+It is possible to wait for recent processes (specified by process ID,
|
|
Kamil Dudka |
7e97ff |
+not by job) that were running in the background even if the process has
|
|
Kamil Dudka |
7e97ff |
+exited. Typically the process ID will be recorded by capturing the
|
|
Kamil Dudka |
7e97ff |
+value of the variable tt($!) immediately after the process has been
|
|
Kamil Dudka |
7e97ff |
+started. There is a limit on the number of process IDs remembered by
|
|
Kamil Dudka |
7e97ff |
+the shell; this is given by the value of the system configuration
|
|
Kamil Dudka |
7e97ff |
+parameter tt(CHILD_MAX). When this limit is reached, older process IDs
|
|
Kamil Dudka |
7e97ff |
+are discarded, least recently started processes first.
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+Note there is no protection against the process ID wrapping, i.e. if the
|
|
Kamil Dudka |
7e97ff |
+wait is not executed soon enough there is a chance the process waited
|
|
Kamil Dudka |
7e97ff |
+for is the wrong one. A conflict implies both process IDs have been
|
|
Kamil Dudka |
7e97ff |
+generated by the shell, as other processes are not recorded, and that
|
|
Kamil Dudka |
7e97ff |
+the user is potentially interested in both, so this problem is intrinsic
|
|
Kamil Dudka |
7e97ff |
+to process IDs.
|
|
Kamil Dudka |
7e97ff |
)
|
|
Kamil Dudka |
7e97ff |
findex(whence)
|
|
Kamil Dudka |
7e97ff |
item(tt(whence) [ tt(-vcwfpams) ] var(name) ...)(
|
|
Kamil Dudka |
7e97ff |
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
|
|
Kamil Dudka |
7e97ff |
index 068a253..452b258 100644
|
|
Kamil Dudka |
7e97ff |
--- a/Doc/Zsh/options.yo
|
|
Kamil Dudka |
7e97ff |
+++ b/Doc/Zsh/options.yo
|
|
Kamil Dudka |
7e97ff |
@@ -1434,10 +1434,10 @@ shell is saved for output within a subshell (for example, within a
|
|
Kamil Dudka |
7e97ff |
pipeline). When the option is set, the output of tt(jobs) is empty
|
|
Kamil Dudka |
7e97ff |
until a job is started within the subshell.
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
-When the option is set, it becomes possible to use the tt(wait) builtin to
|
|
Kamil Dudka |
7e97ff |
-wait for the last job started in the background (as given by tt($!)) even
|
|
Kamil Dudka |
7e97ff |
-if that job has already exited. This works even if the option is turned
|
|
Kamil Dudka |
7e97ff |
-on temporarily around the use of the tt(wait) builtin.
|
|
Kamil Dudka |
7e97ff |
+In previous versions of the shell, it was necessary to enable
|
|
Kamil Dudka |
7e97ff |
+tt(POSIX_JOBS) in order for the builtin command tt(wait) to return the
|
|
Kamil Dudka |
7e97ff |
+status of background jobs that had already exited. This is no longer
|
|
Kamil Dudka |
7e97ff |
+the case.
|
|
Kamil Dudka |
7e97ff |
)
|
|
Kamil Dudka |
7e97ff |
enditem()
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
5385c4 |
diff --git a/Doc/zshoptions.1 b/Doc/zshoptions.1
|
|
Kamil Dudka |
5385c4 |
index cc0bd7e..038e259 100644
|
|
Kamil Dudka |
5385c4 |
--- a/Doc/zshoptions.1
|
|
Kamil Dudka |
5385c4 |
+++ b/Doc/zshoptions.1
|
|
Kamil Dudka |
5385c4 |
@@ -892,10 +892,10 @@ shell is saved for output within a subshell (for example, within a
|
|
Kamil Dudka |
5385c4 |
pipeline)\&. When the option is set, the output of \fBjobs\fP is empty
|
|
Kamil Dudka |
5385c4 |
until a job is started within the subshell\&.
|
|
Kamil Dudka |
5385c4 |
.PP
|
|
Kamil Dudka |
5385c4 |
-When the option is set, it becomes possible to use the \fBwait\fP builtin to
|
|
Kamil Dudka |
5385c4 |
-wait for the last job started in the background (as given by \fB$!\fP) even
|
|
Kamil Dudka |
5385c4 |
-if that job has already exited\&. This works even if the option is turned
|
|
Kamil Dudka |
5385c4 |
-on temporarily around the use of the \fBwait\fP builtin\&.
|
|
Kamil Dudka |
5385c4 |
+In previous versions of the shell, it was necessary to enable
|
|
Kamil Dudka |
5385c4 |
+\fBPOSIX_JOBS\fP in order for the builtin command \fBwait\fP to return the
|
|
Kamil Dudka |
5385c4 |
+status of background jobs that had already exited\&. This is no longer
|
|
Kamil Dudka |
5385c4 |
+the case\&.
|
|
Kamil Dudka |
5385c4 |
.RE
|
|
Kamil Dudka |
5385c4 |
.PP
|
|
Kamil Dudka |
5385c4 |
.SS "Prompting"
|
|
Kamil Dudka |
7e97ff |
diff --git a/Src/exec.c b/Src/exec.c
|
|
Kamil Dudka |
7e97ff |
index d0fadd6..a9c4688 100644
|
|
Kamil Dudka |
7e97ff |
--- a/Src/exec.c
|
|
Kamil Dudka |
7e97ff |
+++ b/Src/exec.c
|
|
Kamil Dudka |
7e97ff |
@@ -2941,8 +2941,6 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
|
Kamil Dudka |
7e97ff |
close(synch[0]);
|
|
Kamil Dudka |
7e97ff |
if (how & Z_ASYNC) {
|
|
Kamil Dudka |
7e97ff |
lastpid = (zlong) pid;
|
|
Kamil Dudka |
7e97ff |
- /* indicate it's possible to set status for lastpid */
|
|
Kamil Dudka |
7e97ff |
- lastpid_status = -2L;
|
|
Kamil Dudka |
7e97ff |
} else if (!jobtab[thisjob].stty_in_env && varspc) {
|
|
Kamil Dudka |
7e97ff |
/* search for STTY=... */
|
|
Kamil Dudka |
7e97ff |
Wordcode p = varspc;
|
|
Kamil Dudka |
7e97ff |
diff --git a/Src/init.c b/Src/init.c
|
|
Kamil Dudka |
7e97ff |
index c26d887..6666f98 100644
|
|
Kamil Dudka |
7e97ff |
--- a/Src/init.c
|
|
Kamil Dudka |
7e97ff |
+++ b/Src/init.c
|
|
Kamil Dudka |
7e97ff |
@@ -1036,7 +1036,6 @@ setupvals(void)
|
|
Kamil Dudka |
7e97ff |
bufstack = znewlinklist();
|
|
Kamil Dudka |
7e97ff |
hsubl = hsubr = NULL;
|
|
Kamil Dudka |
7e97ff |
lastpid = 0;
|
|
Kamil Dudka |
7e97ff |
- lastpid_status = -1L;
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
get_usage();
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
diff --git a/Src/jobs.c b/Src/jobs.c
|
|
Kamil Dudka |
7e97ff |
index bd95afb..18bb648 100644
|
|
Kamil Dudka |
7e97ff |
--- a/Src/jobs.c
|
|
Kamil Dudka |
7e97ff |
+++ b/Src/jobs.c
|
|
Kamil Dudka |
7e97ff |
@@ -104,15 +104,6 @@ int prev_errflag, prev_breaks, errbrk_saved;
|
|
Kamil Dudka |
7e97ff |
/**/
|
|
Kamil Dudka |
7e97ff |
int numpipestats, pipestats[MAX_PIPESTATS];
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
-/*
|
|
Kamil Dudka |
7e97ff |
- * The status associated with the process lastpid.
|
|
Kamil Dudka |
7e97ff |
- * -1 if not set and no associated lastpid
|
|
Kamil Dudka |
7e97ff |
- * -2 if lastpid is set and status isn't yet
|
|
Kamil Dudka |
7e97ff |
- * else the value returned by wait().
|
|
Kamil Dudka |
7e97ff |
- */
|
|
Kamil Dudka |
7e97ff |
-/**/
|
|
Kamil Dudka |
7e97ff |
-long lastpid_status;
|
|
Kamil Dudka |
7e97ff |
-
|
|
Kamil Dudka |
7e97ff |
/* Diff two timevals for elapsed-time computations */
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
/**/
|
|
Kamil Dudka |
7e97ff |
@@ -1309,14 +1300,6 @@ addproc(pid_t pid, char *text, int aux, struct timeval *bgtime)
|
|
Kamil Dudka |
7e97ff |
{
|
|
Kamil Dudka |
7e97ff |
Process pn, *pnlist;
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
- if (pid == lastpid && lastpid_status != -2L) {
|
|
Kamil Dudka |
7e97ff |
- /*
|
|
Kamil Dudka |
7e97ff |
- * The status for the previous lastpid is invalid.
|
|
Kamil Dudka |
7e97ff |
- * Presumably process numbers have wrapped.
|
|
Kamil Dudka |
7e97ff |
- */
|
|
Kamil Dudka |
7e97ff |
- lastpid_status = -1L;
|
|
Kamil Dudka |
7e97ff |
- }
|
|
Kamil Dudka |
7e97ff |
-
|
|
Kamil Dudka |
7e97ff |
DPUTS(thisjob == -1, "No valid job in addproc.");
|
|
Kamil Dudka |
7e97ff |
pn = (Process) zshcalloc(sizeof *pn);
|
|
Kamil Dudka |
7e97ff |
pn->pid = pid;
|
|
Kamil Dudka |
7e97ff |
@@ -1940,6 +1923,122 @@ maybeshrinkjobtab(void)
|
|
Kamil Dudka |
7e97ff |
unqueue_signals();
|
|
Kamil Dudka |
7e97ff |
}
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
+/*
|
|
Kamil Dudka |
7e97ff |
+ * Definitions for the background process stuff recorded below.
|
|
Kamil Dudka |
7e97ff |
+ * This would be more efficient as a hash, but
|
|
Kamil Dudka |
7e97ff |
+ * - that's quite heavyweight for something not needed very often
|
|
Kamil Dudka |
7e97ff |
+ * - we need some kind of ordering as POSIX allows us to limit
|
|
Kamil Dudka |
7e97ff |
+ * the size of the list to the value of _SC_CHILD_MAX and clearly
|
|
Kamil Dudka |
7e97ff |
+ * we want to clear the oldest first
|
|
Kamil Dudka |
7e97ff |
+ * - cases with a long list of background jobs where the user doesn't
|
|
Kamil Dudka |
7e97ff |
+ * wait for a large number, and then does wait for one (the only
|
|
Kamil Dudka |
7e97ff |
+ * inefficient case) are rare
|
|
Kamil Dudka |
7e97ff |
+ * - in the context of waiting for an external process, looping
|
|
Kamil Dudka |
7e97ff |
+ * over a list isn't so very inefficient.
|
|
Kamil Dudka |
7e97ff |
+ * Enough excuses already.
|
|
Kamil Dudka |
7e97ff |
+ */
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+/* Data in the link list, a key (process ID) / value (exit status) pair. */
|
|
Kamil Dudka |
7e97ff |
+struct bgstatus {
|
|
Kamil Dudka |
7e97ff |
+ pid_t pid;
|
|
Kamil Dudka |
7e97ff |
+ int status;
|
|
Kamil Dudka |
7e97ff |
+};
|
|
Kamil Dudka |
7e97ff |
+typedef struct bgstatus *Bgstatus;
|
|
Kamil Dudka |
7e97ff |
+/* The list of those entries */
|
|
Kamil Dudka |
7e97ff |
+LinkList bgstatus_list;
|
|
Kamil Dudka |
7e97ff |
+/* Count of entries. Reaches value of _SC_CHILD_MAX and stops. */
|
|
Kamil Dudka |
7e97ff |
+long bgstatus_count;
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+/*
|
|
Kamil Dudka |
7e97ff |
+ * Remove and free a bgstatus entry.
|
|
Kamil Dudka |
7e97ff |
+ */
|
|
Kamil Dudka |
7e97ff |
+static void rembgstatus(LinkNode node)
|
|
Kamil Dudka |
7e97ff |
+{
|
|
Kamil Dudka |
7e97ff |
+ zfree(remnode(bgstatus_list, node), sizeof(struct bgstatus));
|
|
Kamil Dudka |
7e97ff |
+ bgstatus_count--;
|
|
Kamil Dudka |
7e97ff |
+}
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+/*
|
|
Kamil Dudka |
7e97ff |
+ * Record the status of a background process that exited so we
|
|
Kamil Dudka |
7e97ff |
+ * can execute the builtin wait for it.
|
|
Kamil Dudka |
7e97ff |
+ *
|
|
Kamil Dudka |
7e97ff |
+ * We can't execute the wait builtin for something that exited in the
|
|
Kamil Dudka |
7e97ff |
+ * foreground as it's not visible to the user, so don't bother recording.
|
|
Kamil Dudka |
7e97ff |
+ */
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+/**/
|
|
Kamil Dudka |
7e97ff |
+void
|
|
Kamil Dudka |
7e97ff |
+addbgstatus(pid_t pid, int status)
|
|
Kamil Dudka |
7e97ff |
+{
|
|
Kamil Dudka |
7e97ff |
+ static long child_max;
|
|
Kamil Dudka |
7e97ff |
+ Bgstatus bgstatus_entry;
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+ if (!child_max) {
|
|
Kamil Dudka |
7e97ff |
+#ifdef _SC_CHILD_MAX
|
|
Kamil Dudka |
7e97ff |
+ child_max = sysconf(_SC_CHILD_MAX);
|
|
Kamil Dudka |
7e97ff |
+ if (!child_max) /* paranoia */
|
|
Kamil Dudka |
7e97ff |
+#endif
|
|
Kamil Dudka |
7e97ff |
+ {
|
|
Kamil Dudka |
7e97ff |
+ /* Be inventive */
|
|
Kamil Dudka |
7e97ff |
+ child_max = 1024L;
|
|
Kamil Dudka |
7e97ff |
+ }
|
|
Kamil Dudka |
7e97ff |
+ }
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+ if (!bgstatus_list) {
|
|
Kamil Dudka |
7e97ff |
+ bgstatus_list = znewlinklist();
|
|
Kamil Dudka |
7e97ff |
+ /*
|
|
Kamil Dudka |
7e97ff |
+ * We're not always robust about memory failures, but
|
|
Kamil Dudka |
7e97ff |
+ * this is pretty deep in the shell basics to be failing owing
|
|
Kamil Dudka |
7e97ff |
+ * to memory, and a failure to wait is reported loudly, so test
|
|
Kamil Dudka |
7e97ff |
+ * and fail silently here.
|
|
Kamil Dudka |
7e97ff |
+ */
|
|
Kamil Dudka |
7e97ff |
+ if (!bgstatus_list)
|
|
Kamil Dudka |
7e97ff |
+ return;
|
|
Kamil Dudka |
7e97ff |
+ }
|
|
Kamil Dudka |
7e97ff |
+ if (bgstatus_count == child_max) {
|
|
Kamil Dudka |
7e97ff |
+ /* Overflow. List is in order, remove first */
|
|
Kamil Dudka |
7e97ff |
+ rembgstatus(firstnode(bgstatus_list));
|
|
Kamil Dudka |
7e97ff |
+ }
|
|
Kamil Dudka |
7e97ff |
+ bgstatus_entry = (Bgstatus)zalloc(sizeof(*bgstatus_entry));
|
|
Kamil Dudka |
7e97ff |
+ if (!bgstatus_entry) {
|
|
Kamil Dudka |
7e97ff |
+ /* See note above */
|
|
Kamil Dudka |
7e97ff |
+ return;
|
|
Kamil Dudka |
7e97ff |
+ }
|
|
Kamil Dudka |
7e97ff |
+ bgstatus_entry->pid = pid;
|
|
Kamil Dudka |
7e97ff |
+ bgstatus_entry->status = status;
|
|
Kamil Dudka |
7e97ff |
+ if (!zaddlinknode(bgstatus_list, bgstatus_entry)) {
|
|
Kamil Dudka |
7e97ff |
+ zfree(bgstatus_entry, sizeof(*bgstatus_entry));
|
|
Kamil Dudka |
7e97ff |
+ return;
|
|
Kamil Dudka |
7e97ff |
+ }
|
|
Kamil Dudka |
7e97ff |
+ bgstatus_count++;
|
|
Kamil Dudka |
7e97ff |
+}
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+/*
|
|
Kamil Dudka |
7e97ff |
+ * See if pid has a recorded exit status.
|
|
Kamil Dudka |
7e97ff |
+ * Note we make no guarantee that the PIDs haven't wrapped, so this
|
|
Kamil Dudka |
7e97ff |
+ * may not be the right process.
|
|
Kamil Dudka |
7e97ff |
+ *
|
|
Kamil Dudka |
7e97ff |
+ * This is only used by wait, which must only work on each
|
|
Kamil Dudka |
7e97ff |
+ * pid once, so we need to remove the entry if we find it.
|
|
Kamil Dudka |
7e97ff |
+ */
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+static int getbgstatus(pid_t pid)
|
|
Kamil Dudka |
7e97ff |
+{
|
|
Kamil Dudka |
7e97ff |
+ LinkNode node;
|
|
Kamil Dudka |
7e97ff |
+ Bgstatus bgstatus_entry;
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+ if (!bgstatus_list)
|
|
Kamil Dudka |
7e97ff |
+ return -1;
|
|
Kamil Dudka |
7e97ff |
+ for (node = firstnode(bgstatus_list); node; incnode(node)) {
|
|
Kamil Dudka |
7e97ff |
+ bgstatus_entry = (Bgstatus)getdata(node);
|
|
Kamil Dudka |
7e97ff |
+ if (bgstatus_entry->pid == pid) {
|
|
Kamil Dudka |
7e97ff |
+ int status = bgstatus_entry->status;
|
|
Kamil Dudka |
7e97ff |
+ rembgstatus(node);
|
|
Kamil Dudka |
7e97ff |
+ return status;
|
|
Kamil Dudka |
7e97ff |
+ }
|
|
Kamil Dudka |
7e97ff |
+ }
|
|
Kamil Dudka |
7e97ff |
+ return -1;
|
|
Kamil Dudka |
7e97ff |
+}
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
/* bg, disown, fg, jobs, wait: most of the job control commands are *
|
|
Kamil Dudka |
7e97ff |
* here. They all take the same type of argument. Exception: wait can *
|
|
Kamil Dudka |
7e97ff |
@@ -2085,10 +2184,7 @@ bin_fg(char *name, char **argv, Options ops, int func)
|
|
Kamil Dudka |
7e97ff |
}
|
|
Kamil Dudka |
7e97ff |
if (retval == 0)
|
|
Kamil Dudka |
7e97ff |
retval = lastval2;
|
|
Kamil Dudka |
7e97ff |
- } else if (isset(POSIXJOBS) &&
|
|
Kamil Dudka |
7e97ff |
- pid == lastpid && lastpid_status >= 0L) {
|
|
Kamil Dudka |
7e97ff |
- retval = (int)lastpid_status;
|
|
Kamil Dudka |
7e97ff |
- } else {
|
|
Kamil Dudka |
7e97ff |
+ } else if ((retval = getbgstatus(pid)) < 0) {
|
|
Kamil Dudka |
7e97ff |
zwarnnam(name, "pid %d is not a child of this shell", pid);
|
|
Kamil Dudka |
7e97ff |
/* presumably lastval2 doesn't tell us a heck of a lot? */
|
|
Kamil Dudka |
7e97ff |
retval = 1;
|
|
Kamil Dudka |
7e97ff |
diff --git a/Src/linklist.c b/Src/linklist.c
|
|
Kamil Dudka |
7e97ff |
index 1e364fb..3aa8125 100644
|
|
Kamil Dudka |
7e97ff |
--- a/Src/linklist.c
|
|
Kamil Dudka |
7e97ff |
+++ b/Src/linklist.c
|
|
Kamil Dudka |
7e97ff |
@@ -118,6 +118,8 @@ znewlinklist(void)
|
|
Kamil Dudka |
7e97ff |
LinkList list;
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
list = (LinkList) zalloc(sizeof *list);
|
|
Kamil Dudka |
7e97ff |
+ if (!list)
|
|
Kamil Dudka |
7e97ff |
+ return NULL;
|
|
Kamil Dudka |
7e97ff |
list->list.first = NULL;
|
|
Kamil Dudka |
7e97ff |
list->list.last = &list->node;
|
|
Kamil Dudka |
7e97ff |
list->list.flags = 0;
|
|
Kamil Dudka |
7e97ff |
@@ -152,6 +154,8 @@ zinsertlinknode(LinkList list, LinkNode node, void *dat)
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
tmp = node->next;
|
|
Kamil Dudka |
7e97ff |
node->next = new = (LinkNode) zalloc(sizeof *tmp);
|
|
Kamil Dudka |
7e97ff |
+ if (!new)
|
|
Kamil Dudka |
7e97ff |
+ return NULL;
|
|
Kamil Dudka |
7e97ff |
new->prev = node;
|
|
Kamil Dudka |
7e97ff |
new->dat = dat;
|
|
Kamil Dudka |
7e97ff |
new->next = tmp;
|
|
Kamil Dudka |
7e97ff |
diff --git a/Src/signals.c b/Src/signals.c
|
|
Kamil Dudka |
7e97ff |
index 2df69f9..e728505 100644
|
|
Kamil Dudka |
7e97ff |
--- a/Src/signals.c
|
|
Kamil Dudka |
7e97ff |
+++ b/Src/signals.c
|
|
Kamil Dudka |
7e97ff |
@@ -522,14 +522,14 @@ wait_for_processes(void)
|
|
Kamil Dudka |
7e97ff |
get_usage();
|
|
Kamil Dudka |
7e97ff |
}
|
|
Kamil Dudka |
7e97ff |
/*
|
|
Kamil Dudka |
7e97ff |
- * Remember the status associated with $!, so we can
|
|
Kamil Dudka |
7e97ff |
- * wait for it even if it's exited. This value is
|
|
Kamil Dudka |
7e97ff |
- * only used if we can't find the PID in the job table,
|
|
Kamil Dudka |
7e97ff |
- * so it doesn't matter that the value we save here isn't
|
|
Kamil Dudka |
7e97ff |
- * useful until the process has exited.
|
|
Kamil Dudka |
7e97ff |
+ * Accumulate a list of older jobs. We only do this for
|
|
Kamil Dudka |
7e97ff |
+ * background jobs, which is something in the job table
|
|
Kamil Dudka |
7e97ff |
+ * that's not marked as in the current shell or as shell builtin
|
|
Kamil Dudka |
7e97ff |
+ * and is not equal to the current foreground job.
|
|
Kamil Dudka |
7e97ff |
*/
|
|
Kamil Dudka |
7e97ff |
- if (pn != NULL && pid == lastpid && lastpid_status != -1L)
|
|
Kamil Dudka |
7e97ff |
- lastpid_status = lastval2;
|
|
Kamil Dudka |
7e97ff |
+ if (jn && !(jn->stat & (STAT_CURSH|STAT_BUILTIN)) &&
|
|
Kamil Dudka |
7e97ff |
+ jn - jobtab != thisjob)
|
|
Kamil Dudka |
7e97ff |
+ addbgstatus(pid, (int)lastval2);
|
|
Kamil Dudka |
7e97ff |
}
|
|
Kamil Dudka |
7e97ff |
}
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
--
|
|
Kamil Dudka |
7e97ff |
2.1.0
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
From 2d59469450ba80b69449dc2777f0fc0673e0fbd6 Mon Sep 17 00:00:00 2001
|
|
Kamil Dudka |
7e97ff |
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
|
|
Kamil Dudka |
7e97ff |
Date: Sun, 26 Oct 2014 19:04:47 +0000
|
|
Kamil Dudka |
7e97ff |
Subject: [PATCH 2/2] 33542: test logic for waiting for already exited
|
|
Kamil Dudka |
7e97ff |
processes
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
Upstream-commit: 9a551ca85999ff329714fd2cca138ce2f7d3c3d9
|
|
Kamil Dudka |
7e97ff |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
Kamil Dudka |
7e97ff |
---
|
|
Kamil Dudka |
7e97ff |
Test/A05execution.ztst | 29 +++++++++++++++++++++++++++--
|
|
Kamil Dudka |
7e97ff |
1 file changed, 27 insertions(+), 2 deletions(-)
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst
|
|
Kamil Dudka |
7e97ff |
index ca97f4f..589815f 100644
|
|
Kamil Dudka |
7e97ff |
--- a/Test/A05execution.ztst
|
|
Kamil Dudka |
7e97ff |
+++ b/Test/A05execution.ztst
|
|
Kamil Dudka |
7e97ff |
@@ -190,9 +190,9 @@
|
|
Kamil Dudka |
7e97ff |
print "${pipestatus[@]}")
|
|
Kamil Dudka |
7e97ff |
ZTST_hashmark
|
|
Kamil Dudka |
7e97ff |
done | sort | uniq -c | sed 's/^ *//'
|
|
Kamil Dudka |
7e97ff |
-0:Check whether `$pipestatus[]' behaves.
|
|
Kamil Dudka |
7e97ff |
+0:Check whether '$pipestatus[]' behaves.
|
|
Kamil Dudka |
7e97ff |
>2048 2 1 0
|
|
Kamil Dudka |
7e97ff |
-F:This test checks for a bug in `$pipestatus[]' handling. If it breaks then
|
|
Kamil Dudka |
7e97ff |
+F:This test checks for a bug in '$pipestatus[]' handling. If it breaks then
|
|
Kamil Dudka |
7e97ff |
F:the bug is still there or it reappeared. See workers-29973 for details.
|
|
Kamil Dudka |
7e97ff |
|
|
Kamil Dudka |
7e97ff |
{ setopt MONITOR } 2>/dev/null
|
|
Kamil Dudka |
7e97ff |
@@ -244,3 +244,28 @@ F:anonymous function, and a descriptor leak when backgrounding a pipeline
|
|
Kamil Dudka |
7e97ff |
>autoload_redir () {
|
|
Kamil Dudka |
7e97ff |
> print Autoloaded ksh style
|
|
Kamil Dudka |
7e97ff |
>} > autoload.log
|
|
Kamil Dudka |
7e97ff |
+
|
|
Kamil Dudka |
7e97ff |
+# This tests that we record the status of processes that have already exited
|
|
Kamil Dudka |
7e97ff |
+# for when we wait for them.
|
|
Kamil Dudka |
7e97ff |
+#
|
|
Kamil Dudka |
7e97ff |
+# Actually, we don't guarantee here that the jobs have already exited, but
|
|
Kamil Dudka |
7e97ff |
+# the order of the waits means it's highly likely we do need to recall a
|
|
Kamil Dudka |
7e97ff |
+# previous status, barring accidents which shouldn't happen very often. In
|
|
Kamil Dudka |
7e97ff |
+# other words, we rely on the test working repeatedly rather than just
|
|
Kamil Dudka |
7e97ff |
+# once. The monitor option is irrelevant to the logic, so we'll make
|
|
Kamil Dudka |
7e97ff |
+# our job easier by turning it off.
|
|
Kamil Dudka |
7e97ff |
+ unsetopt monitor
|
|
Kamil Dudka |
7e97ff |
+ (exit 1) &
|
|
Kamil Dudka |
7e97ff |
+ one=$!
|
|
Kamil Dudka |
7e97ff |
+ (exit 2) &
|
|
Kamil Dudka |
7e97ff |
+ two=$!
|
|
Kamil Dudka |
7e97ff |
+ (exit 3) &
|
|
Kamil Dudka |
7e97ff |
+ three=$!
|
|
Kamil Dudka |
7e97ff |
+ wait $three
|
|
Kamil Dudka |
7e97ff |
+ print $?
|
|
Kamil Dudka |
7e97ff |
+ wait $two
|
|
Kamil Dudka |
7e97ff |
+ print $?
|
|
Kamil Dudka |
7e97ff |
+ wait $one
|
|
Kamil Dudka |
7e97ff |
+1:The status of recently exited background jobs is recorded
|
|
Kamil Dudka |
7e97ff |
+>3
|
|
Kamil Dudka |
7e97ff |
+>2
|
|
Kamil Dudka |
7e97ff |
--
|
|
Kamil Dudka |
7e97ff |
2.1.0
|
|
Kamil Dudka |
7e97ff |
|