zsh-workers
 help / color / mirror / code / Atom feed
* Re: pws-22: killing the ZSH loops problem
@ 1999-06-21 11:29 Sven Wischnowsky
  0 siblings, 0 replies; 13+ messages in thread
From: Sven Wischnowsky @ 1999-06-21 11:29 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> On Jun 18, 10:55am, Sven Wischnowsky wrote:
> } Subject: Re: pws-22: killing the ZSH loops problem
> }
> } Unless I'm missing something obvious, we can't simply execute
> } processes in a loop (or other shell construct) in the same pgrp as the 
> } shell. Sure, this would give us the SIGINT, but it would also give us
> } the SIGSTOP -- suspending the shell.
> 
> Strictly speaking, it would give us SIGTSTP -- ^Z does not generate STOP.
> Since TSTP is catchable (unlike STOP), the parent shell simply has to have
> a TSTP handler or ignore TSTP -- which zsh already does.

Oh, yes. Oops. I had tried implementing that and got a SIGSTOP --
without further thinking I wrote the above. Seems like the stuff I had 
hacked together caused update_job() to send a SIGSTOP to the parent
shell.
Hm. So there might be a way...

Bye
 Sven


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


^ permalink raw reply	[flat|nested] 13+ messages in thread
* Re: pws-22: killing the ZSH loops problem
@ 1999-06-18  8:55 Sven Wischnowsky
  1999-06-18 15:33 ` Andrej Borsenkow
  0 siblings, 1 reply; 13+ messages in thread
From: Sven Wischnowsky @ 1999-06-18  8:55 UTC (permalink / raw)
  To: zsh-workers


I wrote:

> Bart Schaefer wrote:
> 
> > One possibility is to not permit job control of individual external jobs
> > run within a shell construct; that is, force ^Z to stop the entire shell
> > loop and restart it.  As has been mentioned before, this is easy in other
> > shells because they typically fork off the tails of pipelines whereas zsh
> > always forks off the heads -- but some of the new list_pipe code that was
> > added recently may give us the necessary hooks to manage it.  Given that,
> > we can stop using new pgrps for subjobs of a shell construct, and then
> > zsh can get the terminal signals directly again.
> 
> I think, this is the way to go. I'll have a look at it, but probably not
> before the weekend.

I was to hasty to agree with this...

Unless I'm missing something obvious, we can't simply execute
processes in a loop (or other shell construct) in the same pgrp as the 
shell. Sure, this would give us the SIGINT, but it would also give us
the SIGSTOP -- suspending the shell.

So the patch below at least makes loops suspendable as a whole, even
if they are not part of a pipeline (it was strange that we could do it 
for `foo | while ...' but not for `while ...'). For the ^C'ing of such 
loops I don't see a good solution any more -- other than this: with the
patch you can ^Z the loop, fg it and then you can ^C it if the next
external command has been started, because then the sub-shell created
when the loop was suspended gets the SIGINT, too, and terminates.

(Btw. `foo | while ...' can be ^C'ed because we have the `foo' to find 
that out. This means that we could make normal loops be ^C'able by
forking of a sub-shell for every loop and let the sub-shell do
nothing. Then ^C would SIGINT the sub-shell and the parent shell would 
be notified about this -- but this is really ugly isn't it? Or should
we? But that would be an extra fork on every shell construct...)

And another `btw.': comparison with bash shows that it has the same
problem ^C'ing such commands in loops and behaves like zsh. But it
can't even correctly stop such loops.


Bye
 Sven

diff -u oos/exec.c Src/exec.c
--- oos/exec.c	Fri Jun 18 08:50:07 1999
+++ Src/exec.c	Fri Jun 18 08:50:23 1999
@@ -919,7 +919,7 @@
 	    }
 
 	    for (; !nowait;) {
-		if (list_pipe_child) {
+		if (list_pipe_child || pline_level) {
 		    jn->stat |= STAT_NOPRINT;
 		    makerunning(jn);
 		}
@@ -930,8 +930,8 @@
 		    jn->stat & STAT_DONE &&
 		    lastval2 & 0200)
 		    killpg(mypgrp, lastval2 & ~0200);
-		if ((list_pipe || last1) && !list_pipe_child &&
-		    jn->stat & STAT_STOPPED) {
+		if ((list_pipe || last1 || pline_level) &&
+		    !list_pipe_child && jn->stat & STAT_STOPPED) {
 		    pid_t pid;
 		    int synch[2];
 
@@ -961,7 +961,8 @@
 			jobtab[list_pipe_job].stat |= STAT_SUPERJOB;
 			jn->stat |= STAT_SUBJOB | STAT_NOPRINT;
 			jn->other = pid;
-			killpg(jobtab[list_pipe_job].gleader, SIGSTOP);
+			if (list_pipe || last1)
+			    killpg(jobtab[list_pipe_job].gleader, SIGSTOP);
 			break;
 		    }
 		    else {
@@ -988,7 +989,8 @@
 		jn->stat |= STAT_NOPRINT;
 		killjb(jobtab + pj, lastval & ~0200);
 	    }
-	    if (list_pipe_child || (list_pipe && (jn->stat & STAT_DONE)))
+	    if (list_pipe_child || ((list_pipe || pline_level) &&
+				    (jn->stat & STAT_DONE)))
 		deletejob(jn);
 	    thisjob = pj;
 

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


^ permalink raw reply	[flat|nested] 13+ messages in thread
* Re: pws-22: killing the ZSH loops problem
@ 1999-06-17  9:23 Sven Wischnowsky
  0 siblings, 0 replies; 13+ messages in thread
From: Sven Wischnowsky @ 1999-06-17  9:23 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> One possibility is to not permit job control of individual external jobs
> run within a shell construct; that is, force ^Z to stop the entire shell
> loop and restart it.  As has been mentioned before, this is easy in other
> shells because they typically fork off the tails of pipelines whereas zsh
> always forks off the heads -- but some of the new list_pipe code that was
> added recently may give us the necessary hooks to manage it.  Given that,
> we can stop using new pgrps for subjobs of a shell construct, and then
> zsh can get the terminal signals directly again.

I think, this is the way to go. I'll have a look at it, but probably not
before the weekend.

Bye
 Sven


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


^ permalink raw reply	[flat|nested] 13+ messages in thread
* RE: pws-22: killing the ZSH loops problem
@ 1999-06-16  9:09 Andrej Borsenkow
  0 siblings, 0 replies; 13+ messages in thread
From: Andrej Borsenkow @ 1999-06-16  9:09 UTC (permalink / raw)
  To: Andrej Borsenkow, ZSH workers mailing list


>
> It does not happen, if I use 'zsh -c "read line"' (that is, the whole
> loop is killed), but as it stays with every external command I tried.
>


Sorry for all these followups. It looks, like the problem happens with programs,
that catch SIGINT (sh, gzip, gzcat) but not with programs, that leave it default
(cat, zsh). In the latter case, Zsh gets information about child being
interraupted by SIGINT and reacts correctly. In the former case, Zsh only knows,
that program (normally) exited for whatever reason.

Looks, like Zsh cannot rely on child info and must handle INT itself. I wonder,
how 3.0.5 behaves in this case.

/andrej


^ permalink raw reply	[flat|nested] 13+ messages in thread
* RE: pws-22: killing the ZSH loops problem
@ 1999-06-16  8:43 Andrej Borsenkow
  0 siblings, 0 replies; 13+ messages in thread
From: Andrej Borsenkow @ 1999-06-16  8:43 UTC (permalink / raw)
  To: Andrej Borsenkow, ZSH workers mailing list


 The easy way to reproduce it is
>
> bor@itsrm2:~%> while true
> while> do
> while> echo $((i++))
> while> sh -c "read line"
> while> done
> 0
> ^C
> 1
> ^C
> 2
>


It does not happen, if I use 'zsh -c "read line"' (that is, the whole loop is
killed), but as it stays with every external command I tried.

/andrej


^ permalink raw reply	[flat|nested] 13+ messages in thread
* pws-22: killing the ZSH loops problem
@ 1999-06-15 16:45 Andrej Borsenkow
  1999-06-16 15:14 ` Peter Stephenson
  0 siblings, 1 reply; 13+ messages in thread
From: Andrej Borsenkow @ 1999-06-15 16:45 UTC (permalink / raw)
  To: ZSH workers mailing list

I wanted to gzip a bunch of files, so I did

for i in *.txt
do
gzip $i
done

I overlooked that I had (plenty of) already gzipped versions, so after I hitted
a couple of times "n" (as a reply to gzip, if I want to overwrite it) the next
time I just hitted ^C to stop the whole story.  It did not. It just killed the
current gzip and for loop happily ran the next one. The easy way to reproduce it
is

bor@itsrm2:~%> while true
while> do
while> echo $((i++))
while> sh -c "read line"
while> done
0
^C
1
^C
2

Note, that hitting ^C simply kills started command instead of killing the whole
loop. The same happens with pws-19. ^Z does not help either - it stops the
current inner command.

Compare it with shell:

bor@itsrm2:~%> sh
$ i=0
$ while true
> do
> i=`expr "$i + 1"`
> echo $i
> sh -c "read line"
> done
0 + 1

0 + 1 + 1

0 + 1 + 1 + 1
^C
$

(sorry, expr was wrong, but I have not used it for quite a long time). Note,
that in shell it kills the whole loop.

/andrej


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~1999-06-21 16:16 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-06-21 11:29 pws-22: killing the ZSH loops problem Sven Wischnowsky
  -- strict thread matches above, loose matches on Subject: below --
1999-06-18  8:55 Sven Wischnowsky
1999-06-18 15:33 ` Andrej Borsenkow
1999-06-18 16:44   ` Bart Schaefer
1999-06-21  7:08     ` Andrej Borsenkow
1999-06-21 15:55       ` Bart Schaefer
1999-06-21 16:14         ` Andrej Borsenkow
1999-06-17  9:23 Sven Wischnowsky
1999-06-16  9:09 Andrej Borsenkow
1999-06-16  8:43 Andrej Borsenkow
1999-06-15 16:45 Andrej Borsenkow
1999-06-16 15:14 ` Peter Stephenson
1999-06-16 17:16   ` Bart Schaefer

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).