Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: subtle `echo' bug
- X-seq: zsh-workers 21345
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxx
- Subject: Re: subtle `echo' bug
- Date: Wed, 15 Jun 2005 15:32:14 +0000
- In-reply-to: <200506151356.j5FDunra015702@xxxxxxxxxxxxxx>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- References: <20050614172738.GL4685@xxxxxxxxxxxxxxxxxxx> <200506142212.24133.arvidjaar@xxxxxxxxxx> <1050615002844.ZM7767@xxxxxxxxxxxxxxxxxxxxxxx> <200506150910.j5F9AEFa009630@xxxxxxxxxxxxxx> <200506151356.j5FDunra015702@xxxxxxxxxxxxxx>
On Jun 15, 2:56pm, Peter Stephenson wrote:
}
} This is rather garbled: the error message shown was a write error which
} you certainly wouldn't see if the process that failed to write received
} a SIGPIPE.
SIGPIPE is one of those signals that causes a process to exit if it is
not trapped, and zsh does not trap it. So there's no opportunity for
the error message to be printed.
} Experimentation suggests a SIGPIPE to a subprocess in a pipeline in
} other shells doesn't cause the shell to abort execution. I'm not sure
} where the logic in zsh is that's causing this.
Since SIGPIPE is causing the child process to exit, it's the SIGCHLD
handler in the parent that's at issue. Ultimately I believe it's this
code in update_job():
/* 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();
}
I've verified that (val & 0200) == 128 in this instance, which is not
distinguishable from the child having received a SIGINT.
Related may be this comment in zwaitjob():
/* Commenting this out makes ^C-ing a job started by a function
stop the whole function again. But I guess it will stop
something else from working properly, we have to find out
what this might be. --oberon
errflag = 0; */
(Golly, I'd completely forgotten about Oberon. That comment goes back a
decade at least.)
So, we could try this patch:
Index: Src/jobs.c
===================================================================
RCS file: /extra/cvsroot/zsh/zsh-4.0/Src/jobs.c,v
retrieving revision 1.15
diff -c -r1.15 jobs.c
--- Src/jobs.c 26 Mar 2005 16:14:05 -0000 1.15
+++ Src/jobs.c 15 Jun 2005 15:26:07 -0000
@@ -383,7 +383,8 @@
}
/* If we have `foo|while true; (( x++ )); done', and hit
* ^C, we have to stop the loop, too. */
- if ((val & 0200) && inforeground == 1) {
+ if ((val & 0200) && inforeground == 1 &&
+ (val - 128 != SIGPIPE)) {
if (!errbrk_saved) {
errbrk_saved = 1;
prev_breaks = breaks;
@@ -399,7 +400,8 @@
adjustwinsize(0);
}
}
- } else if (list_pipe && (val & 0200) && inforeground == 1) {
+ } else if (list_pipe && (val & 0200) && inforeground == 1 &&
+ (val - 128 != SIGPIPE)) {
if (!errbrk_saved) {
errbrk_saved = 1;
prev_breaks = breaks;
Messages sorted by:
Reverse Date,
Date,
Thread,
Author