zsh-workers
 help / color / mirror / code / Atom feed
From: Sven Wischnowsky <wischnow@informatik.hu-berlin.de>
To: zsh-workers@sunsite.auc.dk
Subject: PATCH: job-control
Date: Tue, 18 Jan 2000 12:36:47 +0100 (MET)	[thread overview]
Message-ID: <200001181136.MAA00399@beta.informatik.hu-berlin.de> (raw)


Here is the fix for the problem mentioned in 9332. This:

  # Try
  #   ^Z
  #   fg
  #   ^Z
  #   fg
  fn() {
    local a
    while read a; do :; done
    less "$@"
  }
  cat foo | fn bar

didn't work.

The first problem was that at the time the sub-shell was created, the
cat wasn't running anymore. So the sub-shell was put in its own process
group and the gleader field for the job was set to that. Then bin_fg()
didn't realise that the gleader only referred to the sub-shell and
attached that to the terminal instead of the less, as it should
have. I've solved this by adding another STAT_* flag (STAT_SUBLEADER)
that gets set if a job's gleader is set to a sub-shell's pgrp because
the other commands in the pipe have finished already and bin_fg()
tests this flag to find out which pgrp to attach.

The second problem turned out to be two problems. If one hit ^Z early
enough to suspend the cat, the then-sub-shelled loop wasn't continued
and the less wasn't executed. First, the sub-shell had simply returned 
from too many functions, waiting in the execpline() for the whole loop 
instead one of those in the loop. This was because at the time of the
inner waitjobs() child_block() was active so it found out that the
pipe-leader was suspended too late. This is fixed by the hunk that
adds a child_block/unblock() before the waitjobs(). This is the hunk
I'm least happy about. Bart, can you think of any problems with this?
The second sub-problem was that update_job() set errflag and breaks to 
tell the parent shell to leave the loop. But since the sub-shell
inherits these, it left the loop, too, even though it should have
continued it. So I made them be restored to their previous values in 
the sub-shell.

Bye
 Sven

diff -ru ../z.old/Src/exec.c Src/exec.c
--- ../z.old/Src/exec.c	Tue Jan 18 11:04:15 2000
+++ Src/exec.c	Tue Jan 18 12:20:16 2000
@@ -949,9 +949,10 @@
 
 		    /* If the super-job contains only the sub-shell, the
 		       sub-shell is the group leader. */
-		    if (!jn->procs->next || lpforked == 2)
+		    if (!jn->procs->next || lpforked == 2) {
 			jn->gleader = list_pipe_pid;
-
+			jn->stat |= STAT_SUBLEADER;
+		    }
 		    for (pn = jobtab[jn->other].procs; pn; pn = pn->next)
 			if (WIFSTOPPED(pn->status))
 			    break;
@@ -971,14 +972,17 @@
 		    lastwj = -1;
 	    }
 
+	    errbrk_saved = 0;
 	    for (; !nowait;) {
 		if (list_pipe_child) {
 		    jn->stat |= STAT_NOPRINT;
 		    makerunning(jn);
 		}
-		if (!(jn->stat & STAT_LOCKED))
+		if (!(jn->stat & STAT_LOCKED)) {
+		    child_unblock();
+		    child_block();
 		    waitjobs();
-
+		}
 		if (list_pipe_child &&
 		    jn->stat & STAT_DONE &&
 		    lastval2 & 0200)
@@ -1042,6 +1046,10 @@
 			list_pipe = 0;
 			list_pipe_child = 1;
 			opts[INTERACTIVE] = 0;
+			if (errbrk_saved) {
+			    errflag = prev_errflag;
+			    breaks = prev_breaks;
+			}
 			break;
 		    }
 		}
diff -ru ../z.old/Src/jobs.c Src/jobs.c
--- ../z.old/Src/jobs.c	Tue Jan 18 11:04:16 2000
+++ Src/jobs.c	Tue Jan 18 11:53:47 2000
@@ -64,7 +64,13 @@
  
 /**/
 int ttyfrozen;
- 
+
+/* Previous values of errflag and breaks if the signal handler had to
+ * change them. And a flag saying if it did that. */
+
+/**/
+int prev_errflag, prev_breaks, errbrk_saved;
+
 static struct timeval dtimeval, now;
 
 /* Diff two timevals for elapsed-time computations */
@@ -311,6 +317,11 @@
 		/* If we have `foo|while true; (( x++ )); done', and hit
 		 * ^C, we have to stop the loop, too. */
 		if ((val & 0200) && inforeground == 1) {
+		    if (!errbrk_saved) {
+			errbrk_saved = 1;
+			prev_breaks = breaks;
+			prev_errflag = errflag;
+		    }
 		    breaks = loops;
 		    errflag = 1;
 		    inerrflush();
@@ -322,6 +333,11 @@
 	    }
 	}
     } else if (list_pipe && (val & 0200) && inforeground == 1) {
+	if (!errbrk_saved) {
+	    errbrk_saved = 1;
+	    prev_breaks = breaks;
+	    prev_errflag = errflag;
+	}
 	breaks = loops;
 	errflag = 1;
 	inerrflush();
@@ -1296,6 +1312,7 @@
 		    thisjob = job;
 		    if ((jobtab[job].stat & STAT_SUPERJOB) &&
 			((!jobtab[job].procs->next ||
+			  (jobtab[job].stat & STAT_SUBLEADER) ||
 			  killpg(jobtab[job].gleader, 0) == -1)) &&
 			jobtab[jobtab[job].other].gleader)
 			attachtty(jobtab[jobtab[job].other].gleader);
diff -ru ../z.old/Src/zsh.h Src/zsh.h
--- ../z.old/Src/zsh.h	Tue Jan 18 11:04:19 2000
+++ Src/zsh.h	Tue Jan 18 11:10:00 2000
@@ -636,6 +636,7 @@
 #define STAT_NOSTTY	(1<<11)	/* the tty settings are not inherited   */
 				/* from this job when it exits.         */
 #define STAT_ATTACH	(1<<12)	/* delay reattaching shell to tty       */
+#define STAT_SUBLEADER  (1<<13) /* is super-job, but leader is sub-shell */
 
 #define SP_RUNNING -1		/* fake status for jobs currently running */
 

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


             reply	other threads:[~2000-01-18 11:37 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-01-18 11:36 Sven Wischnowsky [this message]
2000-01-29 18:13 ` Bart Schaefer
2000-01-31 10:00 Sven Wischnowsky
2000-01-31 10:47 ` Bart Schaefer
2000-01-31 11:52 ` Bart Schaefer
2000-01-31 12:53 Sven Wischnowsky
2000-02-01 10:58 Sven Wischnowsky
2000-02-01 16:35 ` Bart Schaefer
2000-02-02  8:25 Sven Wischnowsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200001181136.MAA00399@beta.informatik.hu-berlin.de \
    --to=wischnow@informatik.hu-berlin.de \
    --cc=zsh-workers@sunsite.auc.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).