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

Re: Bug#593426: zsh: Status of background jobs not updated



On Wed, 18 Aug 2010 18:29:59 +0000
Clint Adams <schizo@xxxxxxxxxx> wrote:
> On Wed, Aug 18, 2010 at 02:51:48PM +1200, Victor Villa wrote:
> > After running a process in the background (by putting "&" at the end
> > of the command line) the output of "jobs" correctly shows the
> > process as "running". If I send the process a STOP signal with "kill
> > -STOP", the process stops and "jobs" shows the process as "suspended
> > (signal)".  The problem is that after sending a CONT signal to the
> > process (with kill -CONT), "jobs" still shows the process as
> > suspended, even though the process resumes (if it's a media file I
> > can hear it playing, for example.

Part of the problem is that we don't update the process status properly
when sending a SIGCONT.  That's fairly easy to fix, and it sounds like
it addresses the immediate issue.

However, we ought to be cleverer, since we don't get a signal when a
child gets a SIGCONT from outside the shell, which is perfectly
possible.  To handle that we'd need to use wait3() or waitpid() with
WNOHANG to see if the job was still stopped.  That's still fairly
straightforward, the problem is that if the job has just exited we then
need to update the job status as if we were in the SIGCHLD handler, and
that needs more thought to do it properly.  Probably not *that*
difficult.  I don't suppose anyone has an urge to learn about the signal
code?

Index: Src/jobs.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/jobs.c,v
retrieving revision 1.77
diff -p -u -r1.77 jobs.c
--- Src/jobs.c	31 Jul 2010 22:03:41 -0000	1.77
+++ Src/jobs.c	18 Aug 2010 19:58:50 -0000
@@ -2217,7 +2217,7 @@ bin_kill(char *nam, char **argv, UNUSED(
 	    signal. */
 	    if (jobtab[p].stat & STAT_STOPPED) {
 		if (sig == SIGCONT)
-		    jobtab[p].stat &= ~STAT_STOPPED;
+		    makerunning(jobtab + p);
 		if (sig != SIGKILL && sig != SIGCONT && sig != SIGTSTP
 		    && sig != SIGTTOU && sig != SIGTTIN && sig != SIGSTOP)
 		    killjb(jobtab + p, SIGCONT);
@@ -2225,9 +2225,19 @@ bin_kill(char *nam, char **argv, UNUSED(
 	} else if (!isanum(*argv)) {
 	    zwarnnam("kill", "illegal pid: %s", *argv);
 	    returnval++;
-	} else if (kill(atoi(*argv), sig) == -1) {
-	    zwarnnam("kill", "kill %s failed: %e", *argv, errno);
-	    returnval++;
+	} else {
+	    int pid = atoi(*argv);
+	    if (kill(pid, sig) == -1) {
+		zwarnnam("kill", "kill %s failed: %e", *argv, errno);
+		returnval++;
+	    } else if (sig == SIGCONT) {
+		Job jn;
+		Process pn;
+		if (findproc(pid, &jn, &pn, 0)) {
+		    if (WIFSTOPPED(pn->status))
+			pn->status = SP_RUNNING;
+		}
+	    }
 	}
     }
     unqueue_signals();

-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



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