Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: 5.0.8 regression when waiting for suspended jobs



On Aug 12,  5:09pm, Peter Stephenson wrote:
} Subject: Re: 5.0.8 regression when waiting for suspended jobs
}
} On Wed, 12 Aug 2015 07:58:58 -0700
} Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
} > We could special-case the SIGTT* signals, we obviously know (from the
} > status that's printed) which signal stopped the job.
} 
} That kind of makes sense, since very few if any(?) other signals have
} this retry-and-fail-again-immediately behaviour.  Many other IO-related
} signals are permanent failures, anyway.

This is a bit ugly, suggestions welcome.  In the "is a child but has no
job table entry" case, this won't SIGCONT the child where previous it
would have, so there's that.

diff --git a/Src/jobs.c b/Src/jobs.c
index ed647b8..ef2bbf0 100644
--- a/Src/jobs.c
+++ b/Src/jobs.c
@@ -1379,16 +1379,26 @@ int
 waitforpid(pid_t pid, int wait_cmd)
 {
     int first = 1, q = queue_signal_level();
+    Process pn;
 
     /* child_block() around this loop in case #ifndef WNOHANG */
     dont_queue_signals();
     child_block();		/* unblocked in signal_suspend() */
     queue_traps(wait_cmd);
     while (!errflag && (kill(pid, 0) >= 0 || errno != ESRCH)) {
-	if (first)
-	    first = 0;
-	else
-	    kill(pid, SIGCONT);
+	if (first) {
+	    Job jn;
+	    /* We may be waiting for a pid that is a child
+	     * but does not have a job table entry? */
+	    first = !findproc(pid, &jn, &pn, 0);
+	}
+	else if (!WIFSTOPPED(pn->status) ||
+		 (WSTOPSIG(pn->status) != SIGTTIN &&
+		  WSTOPSIG(pn->status) != SIGTTOU))
+	    kill(pid, SIGCONT);		/* Harmless if not stopped */
+	/*
+	  else break;  This is bash behavior, just give up when stopped
+	*/
 
 	last_signal = -1;
 	signal_suspend(SIGCHLD, wait_cmd);



Messages sorted by: Reverse Date, Date, Thread, Author