From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21361 invoked from network); 22 Jun 1999 09:36:05 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 22 Jun 1999 09:36:05 -0000 Received: (qmail 10620 invoked by alias); 22 Jun 1999 09:35:59 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 6778 Received: (qmail 10613 invoked from network); 22 Jun 1999 09:35:58 -0000 Date: Tue, 22 Jun 1999 11:35:56 +0200 (MET DST) Message-Id: <199906220935.LAA24578@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: "Andrej Borsenkow"'s message of Mon, 21 Jun 1999 20:14:52 +0400 Subject: RE: pws-22: killing the ZSH loops problem (with PATCH) Andrej Borsenkow wrote: > > } > } We need it only if MONITOR is set > > } > > > } > Not true! MONITOR only affects handling of ^Z, not of ^C. We need to be > > } > able to properly interrupt such loops in any shell. > > } > > } Ahem ... yes. What about "only in interactive shells?" > > > > What about "kill -INT"? What about a shell script that isn't interactive > > but that's running in the foreground? > > > > The shell script running in foreground will get INT from tty because it is in > TTY group and can do anything with it. The same, if I do kill -INT. The problem > only ever happens with loops started as part of shells with MIONITOR option set, > because it runs part of command (loop) in other process group as loop itself. > That prevents it from seeing this INT. Please remember that the program sees the INT all right. The problem is that some programs fail to allow the shell to see that they terminated because of a signal. With well-behaved programs the shell shouldn't need to see the INT. > > } If don't miss something again: we have to fork only for the loop as whole. > > > > That's right, but the reason we don't do this now is so that parameter > > assignments inside the loop are visible after the loop terminates. That > > doesn't work in most other shells. > > As I understand, the last part of pipeline runs in current shell, and Sven's > suggestion was basically to run while ... done loop as | while > ... loop. May be, I was wrong. That's right -- only that we don't even need to use a pipe. We would just create a (well-behaved but never ending) dummy process with it's own pgrp and put the command from the shell construct in that group. That way we can see the signals by looking at the dummy. > And another way is to run commands in the process group as shell and catch INT. > Is it even remotely possible? It's what you get after `unsetopt MONITOR'. The problem with this is that we would have to implement those parts of job control directly that we get for free when we can use process groups. > > } ... so, it seems, execution time penalty is acceptable. After all, you > > } don't use loops on every prompt. > > > > The execution time isn't as much at issue as is the process table space. > > If it is needed (as I still believe) only for loops, started at PS1 when MONITOR > is set - it hardly happens too often. And having to kill your login shell to get > out of loop is not as nice For every shell construct, not only loops. And you don't have to kill the shell even now (since you can always ^Z it -- and then kill or fg/^C). When thinking about implementations I would certainly prefer the solution using the dummy process because most of what should be needed for it is already there (the existing super/sub-job code). But we would also need it for every shell construct in a function that is called from the command line... If you try that last one you'll notice that suspending such functions does not work. Well, the function stops all right but you don't get a job table entry for it. The patch below fixes this -- the job was deleted on the way up the call chain. Bye Sven diff -u os/exec.c Src/exec.c --- os/exec.c Tue Jun 22 08:59:14 1999 +++ Src/exec.c Tue Jun 22 11:31:51 1999 @@ -914,8 +914,10 @@ jn->stat |= STAT_STOPPED | STAT_CHANGED; printjob(jn, !!isset(LONGLISTJOBS), 1); } - else + else if (newjob != list_pipe_job) deletejob(jn); + else + lastwj = -1; } for (; !nowait;) { -- Sven Wischnowsky wischnow@informatik.hu-berlin.de