zsh-workers
 help / color / mirror / code / Atom feed
* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
@ 2009-07-22 18:18 Martin Cracauer
  2009-07-25 18:58 ` Bart Schaefer
  0 siblings, 1 reply; 28+ messages in thread
From: Martin Cracauer @ 2009-07-22 18:18 UTC (permalink / raw)
  To: zsh-workers


Hi, a friend pointed me to this discussion and I took it as an
opportunity to fix some minor issues with my SIGINT page.

I'd like to comment on this one:

Bart Schaefer wrote:
> Further I think Cracauer is very wrong here:
> 
>   Do nothing special when SIGINT appears while you wait for a
>   child. You
>   don't even have to remember that one happened.
>   ...
>   Look at WIFSIGNALED(status) and WTERMSIG(status) to tell whether the
>   child says "I exited on SIGINT: in my opinion the user wants the
>   shellscript to be discontinued".
> 
> This is plain nonsense.
> 
> Not only does this potentially contradict a caller's explicit request
> to ignore SIGINT, but the script should not exit 130 every time any
> child exits 130.  It should exit only when SIGINT was received *by the
> script*.  "kill -INT ..." of the child should not cause the shell to
> behave as if it was interrupted.  Try it with bash.

You are correct (except that the numeric exit of 130 means nothing,
you have to use WIFSIGNALED but I assume you know that and just
shortcut it for the message).

There would be two ways of dealing with this:

1) when a child got killed with SIGINT, always abort the script
2) do that only when the shell itself also had received a SIGINT while
   that child was executing in the foreground

I have actually implemented 2) in FreeBSD's shell and bash also does
2).  However, I had skipped over that detail when writing the webpage.
The have has been corrected.

(let me know if you want credit on the page)

%%

More bits from the discussion:
>> BTW, I wonder why typing Ctrl-g in emacs sends SIGINT to the parent
>> under Mac OS X, but not under Linux.
>
> Some ancestry of BSD vs. SYSV tty process group semantics, I expect.

Looks like it's more complicated.

Both FreeBSD and Linux place both the shell and emacs in the same
progress group.

However, using strace on Linux you can see the SIGINT delivered to the
shell if you do

#! /bin/sh
cat
echo survived

And Control-C out of the cat.

And not when the callee is emacs.

On first sight it looks like the Linux kernel changes semantics based
on whether the terminal is in cooked mode or not.  Possibly in an
attempt to help a bit with the "what to do on SIGINT in interactive
programs" mess we are dealing with here.

If so, that explains why Linux users never flamed about the
wrong-exit-after-emacs problem.  If the kernel never tells the shell
anything about the SIGINT when the foreground program is in curses
mode the problem won't appear.

If so, that would be bad news for shellscripts calling programs that
do curses but just exit on SIGINT (lynx comes to mind).

Thanks
Martin
-- 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Martin Cracauer <cracauer@cons.org>   http://www.cons.org/cracauer/
FreeBSD - where you want to go, today.      http://www.freebsd.org/


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-22 18:18 zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X Martin Cracauer
@ 2009-07-25 18:58 ` Bart Schaefer
  2009-07-26  6:24   ` Philippe Troin
  2009-07-27 23:10   ` Martin Cracauer
  0 siblings, 2 replies; 28+ messages in thread
From: Bart Schaefer @ 2009-07-25 18:58 UTC (permalink / raw)
  To: Martin Cracauer, zsh-workers

On Jul 22,  2:18pm, Martin Cracauer wrote:
} 
} Hi, a friend pointed me to this discussion and I took it as an
} opportunity to fix some minor issues with my SIGINT page.
} 
} There would be two ways of dealing with this:
} 
} 1) when a child got killed with SIGINT, always abort the script
} 2) do that only when the shell itself also had received a SIGINT while
}    that child was executing in the foreground
} 
} I have actually implemented 2) in FreeBSD's shell and bash also does
} 2).  However, I had skipped over that detail when writing the webpage.
} The have has been corrected.
} 
} (let me know if you want credit on the page)

Credit me if you like, but it's not necessary.

Did you also see Eric Blake's assertion that the shell must not un-ignore
a signal if it "starts life" with the signal ignored?  That's a "trap"
command restriction I'd never discovered before (and one I'm not very
happy about).
 
} On first sight it looks like the Linux kernel changes semantics based
} on whether the terminal is in cooked mode or not.  Possibly in an
} attempt to help a bit with the "what to do on SIGINT in interactive
} programs" mess we are dealing with here.

I suspect it's more subtle than that ... e.g., it may be that on linux,
the SIGINT isn't coming from the terminal driver at all.


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-25 18:58 ` Bart Schaefer
@ 2009-07-26  6:24   ` Philippe Troin
  2009-07-26 21:14     ` Bart Schaefer
  2009-07-27 23:10   ` Martin Cracauer
  1 sibling, 1 reply; 28+ messages in thread
From: Philippe Troin @ 2009-07-26  6:24 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Martin Cracauer, zsh-workers

I've missed the beginning of the discussion, so excuse me if I restate
some points...

Bart Schaefer <schaefer@brasslantern.com> writes:

> Did you also see Eric Blake's assertion that the shell must not un-ignore
> a signal if it "starts life" with the signal ignored?  That's a "trap"
> command restriction I'd never discovered before (and one I'm not very
> happy about).

I would agree with that for non-interactive shells (that is zsh
interpreting a script).  However not resetting at least the terminal
signals (INT, QUIT, TTIN, TTOU, TSTP, CONT, HUP) to their default
settings (SIG_IGN) for interactive sessions could expose you to a lot
of trouble.  

> } On first sight it looks like the Linux kernel changes semantics based
> } on whether the terminal is in cooked mode or not.  Possibly in an
> } attempt to help a bit with the "what to do on SIGINT in interactive
> } programs" mess we are dealing with here.
> 
> I suspect it's more subtle than that ... e.g., it may be that on linux,
> the SIGINT isn't coming from the terminal driver at all.

Please enligthen me on this one...

Phil.


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-26  6:24   ` Philippe Troin
@ 2009-07-26 21:14     ` Bart Schaefer
  0 siblings, 0 replies; 28+ messages in thread
From: Bart Schaefer @ 2009-07-26 21:14 UTC (permalink / raw)
  To: zsh-workers; +Cc: Martin Cracauer

On Jul 25, 11:24pm, Philippe Troin wrote:
}
} > } On first sight it looks like the Linux kernel changes semantics based
} > } on whether the terminal is in cooked mode or not.  Possibly in an
} > } attempt to help a bit with the "what to do on SIGINT in interactive
} > } programs" mess we are dealing with here.
} > 
} > I suspect it's more subtle than that ... e.g., it may be that on linux,
} > the SIGINT isn't coming from the terminal driver at all.
} 
} Please enligthen me on this one...

Well, I'm speculating because I don't really know what emacs does with
the terminal on different architectures, but for example it might put
the terminal in raw mode and do its own I/O, then send the emacs process
group a signal when emacs reads a character that matches in interrupt
character definition.

That sure seems more sensible to me than trapping SIGINT and treating
it as the input of a ^C when doing keymap processing.


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-25 18:58 ` Bart Schaefer
  2009-07-26  6:24   ` Philippe Troin
@ 2009-07-27 23:10   ` Martin Cracauer
  2009-07-28  4:29     ` Bart Schaefer
  1 sibling, 1 reply; 28+ messages in thread
From: Martin Cracauer @ 2009-07-27 23:10 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Martin Cracauer, zsh-workers

Bart Schaefer wrote on Sat, Jul 25, 2009 at 11:58:11AM -0700: 
> On Jul 22,  2:18pm, Martin Cracauer wrote:
> } 
> } Hi, a friend pointed me to this discussion and I took it as an
> } opportunity to fix some minor issues with my SIGINT page.
> } 
> } There would be two ways of dealing with this:
> } 
> } 1) when a child got killed with SIGINT, always abort the script
> } 2) do that only when the shell itself also had received a SIGINT while
> }    that child was executing in the foreground
> } 
> } I have actually implemented 2) in FreeBSD's shell and bash also does
> } 2).  However, I had skipped over that detail when writing the webpage.
> } The have has been corrected.
> } 
> } (let me know if you want credit on the page)
> 
> Credit me if you like, but it's not necessary.
> 
> Did you also see Eric Blake's assertion that the shell must not un-ignore
> a signal if it "starts life" with the signal ignored?  That's a "trap"
> command restriction I'd never discovered before (and one I'm not very
> happy about).

I think that goes without saying but I can as well include it.

In fact this would be useful if somebody want to change a
shellscript's behavior to not abort more than the current program on
SIGINT and go forward with the next statement in the script.

Martin
-- 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Martin Cracauer <cracauer@cons.org>   http://www.cons.org/cracauer/
FreeBSD - where you want to go, today.      http://www.freebsd.org/


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-27 23:10   ` Martin Cracauer
@ 2009-07-28  4:29     ` Bart Schaefer
  0 siblings, 0 replies; 28+ messages in thread
From: Bart Schaefer @ 2009-07-28  4:29 UTC (permalink / raw)
  To: Martin Cracauer; +Cc: zsh-workers

On Jul 27,  7:10pm, Martin Cracauer wrote:
} Subject: Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in em
}
} Bart Schaefer wrote on Sat, Jul 25, 2009 at 11:58:11AM -0700: 
} > Did you also see Eric Blake's assertion that the shell must not
} > un-ignore a signal if it "starts life" with the signal ignored?
} 
} In fact this would be useful if somebody want to change a
} shellscript's behavior to not abort more than the current program on
} SIGINT and go forward with the next statement in the script.

No; if the shell doesn't un-ignore the signal, then any program that
is started from the script will also still have SIGINT ignored, and
(unless *that* program re-handles the signal) neither the script nor
its children will be interruptible.


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-22  2:58                       ` Eric Blake
@ 2009-07-22  8:16                         ` Vincent Lefevre
  0 siblings, 0 replies; 28+ messages in thread
From: Vincent Lefevre @ 2009-07-22  8:16 UTC (permalink / raw)
  To: zsh-workers

On 2009-07-22 02:58:37 +0000, Eric Blake wrote:
> POSIX requires that if a shell starts life with a signal ignored,
> that the shell should silently reject attempts to alter the fact
> that the signal is ignored (either back to a default, or to a
> user-specified handler). Which is very annoying if your shell ever
> gets started with SIGPIPE ignored, but that's life. In other words,
> if you start bash with SIGINT ignored, you can't undo that from
> within the bash shell.

OK, thanks for the explanations. So, the following script shows a bug
in zsh (typing Ctrl-C immediately interrupts the sleep and the script
and SIGINT is output):

#!/bin/sh

trap ''  INT
zsh -fc "emulate sh; trap 'echo SIGINT; exit' INT; sleep 6"

I wonder whether zsh should behave in the same way without
"emulate sh".

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-20  8:31                     ` Vincent Lefevre
@ 2009-07-22  2:58                       ` Eric Blake
  2009-07-22  8:16                         ` Vincent Lefevre
  0 siblings, 1 reply; 28+ messages in thread
From: Eric Blake @ 2009-07-22  2:58 UTC (permalink / raw)
  To: zsh-workers

Vincent Lefevre <vincent <at> vinc17.org> writes:

> 
> Sorry, I was not enough clear. I meant that bash restores the trap
> to the behavior at the time that bash was called. But it seems to
> be something different, something like if SIGINT is ignored when
> bash is executed, a "trap command INT" has no effect unless both
> bash and its child receive a SIGINT. Now, this behavior is a bit
> strange, maybe a bug.

POSIX requires that if a shell starts life with a signal ignored, that the shell
should silently reject attempts to alter the fact that the signal is ignored
(either back to a default, or to a user-specified handler).  Which is very
annoying if your shell ever gets started with SIGPIPE ignored, but that's life.
 In other words, if you start bash with SIGINT ignored, you can't undo that from
within the bash shell.

-- 
Eric Blake



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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-19 18:31                   ` Bart Schaefer
@ 2009-07-20  8:31                     ` Vincent Lefevre
  2009-07-22  2:58                       ` Eric Blake
  0 siblings, 1 reply; 28+ messages in thread
From: Vincent Lefevre @ 2009-07-20  8:31 UTC (permalink / raw)
  To: zsh-workers

On 2009-07-19 11:31:47 -0700, Bart Schaefer wrote:
> On Jul 19,  1:09am, Vincent Lefevre wrote:
> } Subject: Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in em
> }
> } > } [bash] ignores SIGINT if the caller chose to ignore it; also when
> } > } executing a process, it restores the trap to the default behavior,
> } > } in case it was ignored (that's another difference with zsh).
> } > 
> } > And that's a case where I think the zsh behavior is in fact preferable.
> } 
> } Is there any reason?
> 
> If bash really "restores the trap to the default behavior, in case it was
> ignored" then I think bash is wrong because "the default behavior" is to
> exit on the signal.

Sorry, I was not enough clear. I meant that bash restores the trap
to the behavior at the time that bash was called. But it seems to
be something different, something like if SIGINT is ignored when
bash is executed, a "trap command INT" has no effect unless both
bash and its child receive a SIGINT. Now, this behavior is a bit
strange, maybe a bug.

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-19 16:32                     ` Bart Schaefer
@ 2009-07-19 22:24                       ` Vincent Lefevre
  0 siblings, 0 replies; 28+ messages in thread
From: Vincent Lefevre @ 2009-07-19 22:24 UTC (permalink / raw)
  To: zsh-workers

On 2009-07-19 09:32:31 -0700, Bart Schaefer wrote:
> On Jul 19, 11:51am, Vincent Lefevre wrote:
> }
> } In fact, it seems that zsh implements some form of WCE in
> } interactive scripts, whereas bash implements it in any case.
> 
> I think you'll find that if you "setopt restricted" you'll get yet
> another set of behaviors.

I don't find any difference.

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-19 20:14                     ` Bart Schaefer
@ 2009-07-19 20:41                       ` Peter Stephenson
  0 siblings, 0 replies; 28+ messages in thread
From: Peter Stephenson @ 2009-07-19 20:41 UTC (permalink / raw)
  To: zsh-workers

Bart Schaefer wrote:
> On Jul 19, 12:15pm, Bart Schaefer wrote:
> }
> } The only way I can see to fix this is to re-introduce the wait_cmd second
> } argument to signal_suspend().  PWS?  Any thoughts?
> 
> Here's a patch in case there's agreement this is the right approach.

If it fixes both problems, it'll certainly do for now, until we work out
what it breaks.

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


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-19 19:15                   ` Bart Schaefer
@ 2009-07-19 20:14                     ` Bart Schaefer
  2009-07-19 20:41                       ` Peter Stephenson
  0 siblings, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2009-07-19 20:14 UTC (permalink / raw)
  To: zsh-workers

On Jul 19, 12:15pm, Bart Schaefer wrote:
}
} The only way I can see to fix this is to re-introduce the wait_cmd second
} argument to signal_suspend().  PWS?  Any thoughts?

Here's a patch in case there's agreement this is the right approach.
Apply *instead of* zsh-workers/27165.  Line numbers may be wonky in
the jobs.c patch.

Index: Src/jobs.c
===================================================================
--- Src/jobs.c	17 Apr 2009 18:57:22 -0000	1.27
+++ Src/jobs.c	19 Jul 2009 19:19:10 -0000
@@ -1178,7 +1191,7 @@
 	    kill(pid, SIGCONT);
 
 	last_signal = -1;
-	signal_suspend(SIGCHLD);
+	signal_suspend(SIGCHLD, wait_cmd);
 	if (last_signal != SIGCHLD && wait_cmd && last_signal >= 0 &&
 	    (sigtrapped[last_signal] & ZSIG_TRAPPED)) {
 	    /* wait command interrupted, but no error: return */
@@ -1217,7 +1230,7 @@
 	while (!errflag && jn->stat &&
 	       !(jn->stat & STAT_DONE) &&
 	       !(interact && (jn->stat & STAT_STOPPED))) {
-	    signal_suspend(SIGCHLD);
+	    signal_suspend(SIGCHLD, wait_cmd);
 	    if (last_signal != SIGCHLD && wait_cmd && last_signal >= 0 &&
 		(sigtrapped[last_signal] & ZSIG_TRAPPED))
 	    {

Index: Src/signals.c
===================================================================
--- Src/signals.c	28 Feb 2009 07:13:37 -0000	1.22
+++ Src/signals.c	19 Jul 2009 20:07:04 -0000
@@ -342,29 +342,32 @@
 
 /**/
 int
-signal_suspend(UNUSED(int sig))
+signal_suspend(UNUSED(int sig), int wait_cmd)
 {
     int ret;
- 
-#ifdef POSIX_SIGNALS
+
+#if defined(POSIX_SIGNALS) || defined(BSD_SIGNALS)
     sigset_t set;
-#ifdef BROKEN_POSIX_SIGSUSPEND
+# if defined(POSIX_SIGNALS) && defined(BROKEN_POSIX_SIGSUSPEND)
     sigset_t oset;
-#endif /* BROKEN_POSIX_SIGSUSPEND */
+# endif
 
     sigemptyset(&set);
-#ifdef BROKEN_POSIX_SIGSUSPEND
+    if (!(wait_cmd || isset(TRAPSASYNC) ||
+	  (sigtrapped[SIGINT] & ~ZSIG_IGNORED)))
+	sigaddset(&set, SIGINT);
+#endif /* POSIX_SIGNALS || BSD_SIGNALS */
+
+#ifdef POSIX_SIGNALS
+# ifdef BROKEN_POSIX_SIGSUSPEND
     sigprocmask(SIG_SETMASK, &set, &oset);
     pause();
     sigprocmask(SIG_SETMASK, &oset, NULL);
-#else /* not BROKEN_POSIX_SIGSUSPEND */
+# else /* not BROKEN_POSIX_SIGSUSPEND */
     ret = sigsuspend(&set);
-#endif /* BROKEN_POSIX_SIGSUSPEND */
+# endif /* BROKEN_POSIX_SIGSUSPEND */
 #else /* not POSIX_SIGNALS */
 # ifdef BSD_SIGNALS
-    sigset_t set;
-
-    sigemptyset(&set);
     ret = sigpause(set);
 # else
 #  ifdef SYSV_SIGNALS


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-19 18:03                 ` Bart Schaefer
@ 2009-07-19 19:15                   ` Bart Schaefer
  2009-07-19 20:14                     ` Bart Schaefer
  0 siblings, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2009-07-19 19:15 UTC (permalink / raw)
  To: zsh-workers

On Jul 19, 11:03am, Bart Schaefer wrote:
}
} The following small change appears to restore the old behavior for SIGINT.

Unfortunately it does so too well.  It makes "wait" uninterruptible again,
which was the problem in the original thread at zsh-workers/23053.

The only way I can see to fix this is to re-introduce the wait_cmd second
argument to signal_suspend().  PWS?  Any thoughts?

} Hmm, looking at the #ifdef flow and considering that this affects MacOS,
} maybe the change in my patch needs to be in the BSD_SIGNALS section,
} either instead or as well.

I checked config.h on my iMac at work and it does not have BSD_SIGNALS,
so this isn't necessary for that reason, but it still might be a good
idea to have it in both branches.


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-18 23:09                 ` Vincent Lefevre
  2009-07-19  9:51                   ` Vincent Lefevre
@ 2009-07-19 18:31                   ` Bart Schaefer
  2009-07-20  8:31                     ` Vincent Lefevre
  1 sibling, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2009-07-19 18:31 UTC (permalink / raw)
  To: zsh-workers

On Jul 19,  1:09am, Vincent Lefevre wrote:
} Subject: Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in em
}
} > } [bash] ignores SIGINT if the caller chose to ignore it; also when
} > } executing a process, it restores the trap to the default behavior,
} > } in case it was ignored (that's another difference with zsh).
} > 
} > And that's a case where I think the zsh behavior is in fact preferable.
} 
} Is there any reason?

If bash really "restores the trap to the default behavior, in case it was
ignored" then I think bash is wrong because "the default behavior" is to
exit on the signal.  It should instead continue to ignore it, as requested
by the caller, as would have happened if the caller directly exec'd the
process instead of passing through bash along the way.

The patch I just sent for Src/signals.c sidesteps the issue in the way I
previously mentioned: without changing the eventual handling, it holds
SIGINT undelivered until some other signal interrupts signal_suspend().

Hmm, looking at the #ifdef flow and considering that this affects MacOS,
maybe the change in my patch needs to be in the BSD_SIGNALS section,
either instead or as well.


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-18 18:16               ` Bart Schaefer
@ 2009-07-19 18:03                 ` Bart Schaefer
  2009-07-19 19:15                   ` Bart Schaefer
  0 siblings, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2009-07-19 18:03 UTC (permalink / raw)
  To: zsh-workers

On Jul 18, 11:16am, Bart Schaefer wrote:
}
} This was changed in this patch ...
} 
}         * 23067: Doc/Zsh/builtins.yo, Src/jobs.c, Src/signals.c:
}         queue traps but handle signals when waiting for jobs or processes,
}         unless TRAPSASYNC is set or the wait builtin is in use, so as
}         to handle untrapped signals in a timely fashion; document that
}         negative or zero process IDs after kill may be handled specially
}         by the OS.

The following small change appears to restore the old behavior for SIGINT.
The question is whether this should be applied to other signals that are
known to cause process termination, such as SIGQUIT.

I'm also not sure whether it's really necessary to test sigtrapped[], or
whether I've got the sense of that test right.

Index: Src/signals.c
===================================================================
diff -c -r1.22 signals.c
--- Src/signals.c	28 Feb 2009 07:13:37 -0000	1.22
+++ Src/signals.c	19 Jul 2009 17:52:28 -0000
@@ -353,6 +353,8 @@
 #endif /* BROKEN_POSIX_SIGSUSPEND */
 
     sigemptyset(&set);
+    if (!(isset(TRAPSASYNC) || (sigtrapped[SIGINT] & ~ZSIG_IGNORED)))
+	sigaddset(&set, SIGINT);
 #ifdef BROKEN_POSIX_SIGSUSPEND
     sigprocmask(SIG_SETMASK, &set, &oset);
     pause();


-- 


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-19  9:51                   ` Vincent Lefevre
@ 2009-07-19 16:32                     ` Bart Schaefer
  2009-07-19 22:24                       ` Vincent Lefevre
  0 siblings, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2009-07-19 16:32 UTC (permalink / raw)
  To: zsh-workers

On Jul 19, 11:51am, Vincent Lefevre wrote:
}
} In fact, it seems that zsh implements some form of WCE in
} interactive scripts, whereas bash implements it in any case.

I think you'll find that if you "setopt restricted" you'll get yet
another set of behaviors.

This really all comes down to what I said in zsh-workers/27159.


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-18 23:09                 ` Vincent Lefevre
@ 2009-07-19  9:51                   ` Vincent Lefevre
  2009-07-19 16:32                     ` Bart Schaefer
  2009-07-19 18:31                   ` Bart Schaefer
  1 sibling, 1 reply; 28+ messages in thread
From: Vincent Lefevre @ 2009-07-19  9:51 UTC (permalink / raw)
  To: zsh-workers

In fact, it seems that zsh implements some form of WCE in
interactive scripts, whereas bash implements it in any case.
Consider the following shell script:

sigint() { echo "SIGINT (sh)"; }
for i in 0 1 2 3
do
  trap - INT
  [ "$i" -eq 1 ] && trap sigint INT
  perl -e $i' or $SIG{"INT"} = sub { print "SIGINT (perl)\n" }; print "'$i' - $$\n"; sleep 30; $SIG{"INT"} = "DEFAULT"; kill "INT", $$'
done

Under Linux, whether this script is run in an interactive shell
or not (zsh or another one), I always get something like:

0 - 7387
^CSIGINT (perl)

and the script is immediately interrupted. Now, remove the

  $SIG{"INT"} = "DEFAULT"; kill "INT", $$

so that in the case i = 0, the Perl script is no longer killed
by SIGINT. Now, depending on the shell and how the script is
started, the script is interrupted either for i = 0 or i = 2
(the latter more of less corresponds to WCE, i.e. the sh script
is interrupted only if the Perl script is killed by SIGINT).

I considered the following two cases:
  1. "<shell> script.sh"
  2. ". script.sh" from the interactive shell

and I get the following results with:

  bash 3.2-5 (whether executed as bash or sh)
  dash 0.5.5.1-2
  ksh 93t+-2 (ksh93)
  pdksh 5.2.14-23
  posh 0.6.18
  zsh 4.3.10-3

under Debian/unstable.

* bash[1], dash[2], ksh93[1], pdksh[2], zsh[2]

0 - 7062
^CSIGINT (perl)
1 - 7063
^CSIGINT (sh)
2 - 7066
^C

* bash[2]

0 - 7241
^CSIGINT (perl)
1 - 7242
^C
2 - 7243
^C

* dash[1], ksh93[2], pdksh[1], posh[1], posh[2], zsh[1]

0 - 7387
^CSIGINT (perl)

Note that ksh93 does the opposite to pdksh and zsh!

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-18 18:35               ` Bart Schaefer
@ 2009-07-18 23:09                 ` Vincent Lefevre
  2009-07-19  9:51                   ` Vincent Lefevre
  2009-07-19 18:31                   ` Bart Schaefer
  0 siblings, 2 replies; 28+ messages in thread
From: Vincent Lefevre @ 2009-07-18 23:09 UTC (permalink / raw)
  To: zsh-workers

On 2009-07-18 11:35:09 -0700, Bart Schaefer wrote:
> On Jul 18, 12:16pm, Vincent Lefevre wrote:
> } On 2009-07-17 22:29:36 -0700, Bart Schaefer wrote:
> } > The point I believe Cracauer is overlooking is that the CALLER of the
> } > shell script may have specified that SIGINT is to be ignored.  SIG_IGN
> } > is supposed to be inherited by child processes; but to implement WUE
> } > or WCE, the shell must itself either ignore or handle SIGINT, which
> } > may contradict what the caller has requested.
> } 
> } I don't think that the caller should enforce what its children should
> } do. Many programs will set their own SIGINT handler, even if the caller
> } chose to ignore this signal.
> 
> You've missed the point.  SIG_IGN is by definition been inherited from
> parent to child, and this is deliberately preserved across exec.  The
> parent doesn't *enforce* this -- the child is *allowed* to set up a
> handler of its own once it gets control -- but the mere fact that the
> execv'd program is a shell should not void the inherited signal settings.
> The shell might merely be an intermediary that's going to exec itself
> out of existence, and the programmer of the parent should be able to
> expect that the inherited signal settings make it through.

I didn't miss anything: the shell can still restore the previous
status before an exec.

> } Anyway, even though bash implements WCE,
> 
> Except that bash *DOESN'T* implement WCE, at least not the way that it
> is defined in Cracauer's web page.  See below.

According to my tests, bash *does* implement WCE. See below.

> } it ignores SIGINT if the caller chose to ignore it; also when executing
> } a process, it restores the trap to the default behavior, in case it was
> } ignored (that's another difference with zsh).
> 
> And that's a case where I think the zsh behavior is in fact preferable.

Is there any reason?

> } > Further I think Cracauer is very wrong here:
> } > 
> } >   Do nothing special when SIGINT appears while you wait for a child. You
> } >   don't even have to remember that one happened.
> } >   ...
> } >   Look at WIFSIGNALED(status) and WTERMSIG(status) to tell whether the
> } >   child says "I exited on SIGINT: in my opinion the user wants the
> } >   shellscript to be discontinued".
> } > 
> } > This is plain nonsense.
> } > 
> } > Not only does this potentially contradict a caller's explicit request
> } > to ignore SIGINT, but the script should not exit 130 every time any
> } > child exits 130.  It should exit only when SIGINT was received *by the
> } > script*.  "kill -INT ..." of the child should not cause the shell to
> } > behave as if it was interrupted.  Try it with bash.
> } 
> } It seems that bash behaves correctly in all those cases.
> 
> Exactly -- which it would not if it followed Cracauer's advice; he's
> wrong, and I'm not going to advocate that zsh adopt the behavior that
> he describes.

Well, after re-reading, I agree Cracauer's advice is wrong here.
But it is fixable and I think that the other parts of his page are
correct. At least, IUE/WUE/WCE are defined under the context "There
are several ways to handle abortion of shell scripts when SIGINT is
received while a foreground child runs", so it is clear that the shell
*must* receive a SIGINT (this is also said near the beginning of the
page).

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-18 10:16             ` Vincent Lefevre
  2009-07-18 18:16               ` Bart Schaefer
@ 2009-07-18 18:35               ` Bart Schaefer
  2009-07-18 23:09                 ` Vincent Lefevre
  1 sibling, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2009-07-18 18:35 UTC (permalink / raw)
  To: zsh-workers

Part 2 of my reply, in which I argue philosophy rather than address the
specific shell problem.

On Jul 18, 12:16pm, Vincent Lefevre wrote:
} Subject: Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in em
}
} On 2009-07-17 22:29:36 -0700, Bart Schaefer wrote:
} > The point I believe Cracauer is overlooking is that the CALLER of the
} > shell script may have specified that SIGINT is to be ignored.  SIG_IGN
} > is supposed to be inherited by child processes; but to implement WUE
} > or WCE, the shell must itself either ignore or handle SIGINT, which
} > may contradict what the caller has requested.
} 
} I don't think that the caller should enforce what its children should
} do. Many programs will set their own SIGINT handler, even if the caller
} chose to ignore this signal.

You've missed the point.  SIG_IGN is by definition been inherited from
parent to child, and this is deliberately preserved across exec.  The
parent doesn't *enforce* this -- the child is *allowed* to set up a
handler of its own once it gets control -- but the mere fact that the
execv'd program is a shell should not void the inherited signal settings.
The shell might merely be an intermediary that's going to exec itself
out of existence, and the programmer of the parent should be able to
expect that the inherited signal settings make it through.

} Anyway, even though bash implements WCE,

Except that bash *DOESN'T* implement WCE, at least not the way that it
is defined in Cracauer's web page.  See below.

} it ignores SIGINT if the caller chose to ignore it; also when executing
} a process, it restores the trap to the default behavior, in case it was
} ignored (that's another difference with zsh).

And that's a case where I think the zsh behavior is in fact preferable.
 
} > Further I think Cracauer is very wrong here:
} > 
} >   Do nothing special when SIGINT appears while you wait for a child. You
} >   don't even have to remember that one happened.
} >   ...
} >   Look at WIFSIGNALED(status) and WTERMSIG(status) to tell whether the
} >   child says "I exited on SIGINT: in my opinion the user wants the
} >   shellscript to be discontinued".
} > 
} > This is plain nonsense.
} > 
} > Not only does this potentially contradict a caller's explicit request
} > to ignore SIGINT, but the script should not exit 130 every time any
} > child exits 130.  It should exit only when SIGINT was received *by the
} > script*.  "kill -INT ..." of the child should not cause the shell to
} > behave as if it was interrupted.  Try it with bash.
} 
} It seems that bash behaves correctly in all those cases.

Exactly -- which it would not if it followed Cracauer's advice; he's
wrong, and I'm not going to advocate that zsh adopt the behavior that
he describes.

} > Having said all that, I also looked at what it would take to implement
} > WCE as an option.  There are two complications here:
} > 
} > (1) There's a race condition as to whether the shell receives SIGINT
} > or SIGCHLD first.  With enough trials I can get it to happen either
} > way, though the vast majority of the time the SIGINT wins.
} 
} How does bash handle that?

It must handle it the way zsh 4.2.6 NO_TRAPS_ASYNC does, that is, by
blocking SIGINT (without changing the handler behavior) while waiting for
a child, then unblocking so the signal comes through after the waited-
for child exits.  This resolves the race in favor of always getting the
SIGCHLD first, and therefore the shell can always exit when it receives
the SIGINT (or never exit when it does not receive it).

} BTW, I wonder why typing Ctrl-g in emacs sends SIGINT to the parent
} under Mac OS X, but not under Linux.

Some ancestry of BSD vs. SYSV tty process group semantics, I expect.


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-18 10:16             ` Vincent Lefevre
@ 2009-07-18 18:16               ` Bart Schaefer
  2009-07-19 18:03                 ` Bart Schaefer
  2009-07-18 18:35               ` Bart Schaefer
  1 sibling, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2009-07-18 18:16 UTC (permalink / raw)
  To: zsh-workers

I'm going to send two replies to this part of the thread for different
subsets of Vincent's remarks, so that neither message gets too long.
This first one has a bunch of strace output in it.  Jump towards the
end for the punchline.

On Jul 18, 12:16pm, Vincent Lefevre wrote:
} Subject: Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in em
}
} On 2009-07-17 22:29:36 -0700, Bart Schaefer wrote:
} > When running a shell script (not interactively), zsh does NO HANDLING
} > of SIGINT whatsoever.  It's implementing IUE, not WUE.  Or to be more
} > precise, it's implementing the default behavior on SIGINT, which is
} > usually to exit.
} 
} Yes, this is what I can see with zsh 4.3.10 (but zsh 4.2.3 implemented
} WUE).

Let's look at that a bit more closely.

Here's 4.2.6 (slight difference in OS version may account for the
missing RT_1 in the sigprocmask):

pipe([3, 4])                            = 0
gettimeofday({1247938636, 336849}, {480, 0}) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0xb75e4868) = 27231
close(4)                                = 0
read(3, "", 1)                          = 0
close(3)                                = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
rt_sigsuspend(~[HUP CHLD RTMIN] <unfinished ...>
--- SIGCHLD (Child exited) @ 0 (0) ---
<... rt_sigsuspend resumed> )           = -1 EINTR (Interrupted system call)
rt_sigprocmask(SIG_BLOCK, ~[RTMIN], ~[HUP KILL STOP RTMIN], 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[HUP KILL STOP RTMIN], ~[KILL STOP RTMIN], 8) = 0
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WUNTRACED,
{ru_utime={0, 0}, ru_stime={0, 0}, ...}) = 27231
gettimeofday({1247938666, 347837}, {480, 0}) = 0
wait4(-1, 0xbfffd14c, WNOHANG|WUNTRACED, 0xbfffd154) = -1 ECHILD (No child
processes)
sigreturn()                             = ? (mask now [CHLD])
--- SIGINT (Interrupt) @ 0 (0) ---

Now here's 4.2.6 with the TRAPS_ASYNC option set:

pipe([3, 4])                            = 0
gettimeofday({1247939573, 896574}, {480, 0}) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0xb75e0868) = 27252
close(4)                                = 0
read(3, "", 1)                          = 0
close(3)                                = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
rt_sigsuspend([] <unfinished ...>
--- SIGINT (Interrupt) @ 0 (0) ---

And finally 4.3.10-dev-1, doesn't matter whether TRAPS_ASYNC is set:

pipe([3, 4])                            = 0
gettimeofday({1247938336, 854096}, {420, 0}) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0xb7f6c708) = 10263
close(4)                                = 0
read(3, "", 1)                          = 0
close(3)                                = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
rt_sigsuspend([] <unfinished ...>
--- SIGINT (Interrupt) @ 0 (0) ---

This was changed in this patch ...

        * 23067: Doc/Zsh/builtins.yo, Src/jobs.c, Src/signals.c:
        queue traps but handle signals when waiting for jobs or processes,
        unless TRAPSASYNC is set or the wait builtin is in use, so as
        to handle untrapped signals in a timely fashion; document that
        negative or zero process IDs after kill may be handled specially
        by the OS.

... when the signal_suspend_setup() function was removed from signals.c
because of a problem with interrupting "wait".  This began in 23053 as
a MacOS bug report and relevant dicussion continues in 23055 and 23061.

Apparently you darn Mac users can't make up your mind. :-)


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-18  5:29           ` Bart Schaefer
@ 2009-07-18 10:16             ` Vincent Lefevre
  2009-07-18 18:16               ` Bart Schaefer
  2009-07-18 18:35               ` Bart Schaefer
  0 siblings, 2 replies; 28+ messages in thread
From: Vincent Lefevre @ 2009-07-18 10:16 UTC (permalink / raw)
  To: zsh-workers

On 2009-07-17 22:29:36 -0700, Bart Schaefer wrote:
> When running a shell script (not interactively), zsh does NO HANDLING
> of SIGINT whatsoever.  It's implementing IUE, not WUE.  Or to be more
> precise, it's implementing the default behavior on SIGINT, which is
> usually to exit.

Yes, this is what I can see with zsh 4.3.10 (but zsh 4.2.3 implemented
WUE).

> The point I believe Cracauer is overlooking is that the CALLER of the
> shell script may have specified that SIGINT is to be ignored.  SIG_IGN
> is supposed to be inherited by child processes; but to implement WUE
> or WCE, the shell must itself either ignore or handle SIGINT, which
> may contradict what the caller has requested.

I don't think that the caller should enforce what its children should
do. Many programs will set their own SIGINT handler, even if the caller
chose to ignore this signal. Anyway, even though bash implements WCE,
it ignores SIGINT if the caller chose to ignore it; also when executing
a process, it restores the trap to the default behavior, in case it was
ignored (that's another difference with zsh).

For instance, you can try with the following script with both bash
and zsh:

------------------------------------------------------------
echo "Caller: $$"
cmd="echo \"Callee: \$\$ ($SHELL)\"; sleep 6; echo OK"
trp="trap 'echo SIGINT; exit' INT; $cmd"

echo "Send SIGINT to each callee's PID"

$SHELL -c "$cmd"; echo "Callee's exit status: $?"
$SHELL -c "$trp"; echo "Callee's exit status: $?"

trap ''  INT
echo "SIGINT ignored"

$SHELL -c "$cmd"; echo "Callee's exit status: $?"
$SHELL -c "$trp"; echo "Callee's exit status: $?"

trap 'echo "Caller received SIGINT"'  INT
echo "Type Ctrl-C in the terminal"

$SHELL -c "$cmd"; echo "Callee's exit status: $?"
$SHELL -c "$trp"; echo "Callee's exit status: $?"
------------------------------------------------------------

Try also "killall -INT sleep" in the 6 cases.

> Further I think Cracauer is very wrong here:
> 
>   Do nothing special when SIGINT appears while you wait for a child. You
>   don't even have to remember that one happened.
>   ...
>   Look at WIFSIGNALED(status) and WTERMSIG(status) to tell whether the
>   child says "I exited on SIGINT: in my opinion the user wants the
>   shellscript to be discontinued".
> 
> This is plain nonsense.
> 
> Not only does this potentially contradict a caller's explicit request
> to ignore SIGINT, but the script should not exit 130 every time any
> child exits 130.  It should exit only when SIGINT was received *by the
> script*.  "kill -INT ..." of the child should not cause the shell to
> behave as if it was interrupted.  Try it with bash.

It seems that bash behaves correctly in all those cases. If the caller
ignores SIGINT, then bash also ignores it. Moreover bash terminates
with exit status 130 only when it receives SIGINT and the child
terminates with exit status 130. (I've tried on a Linux machine with
bash 3.2 because I don't have access to my Mac OS X machine right
now.)

> Having said all that, I also looked at what it would take to implement
> WCE as an option.  There are two complications here:
> 
> (1) There's a race condition as to whether the shell receives SIGINT
> or SIGCHLD first.  With enough trials I can get it to happen either
> way, though the vast majority of the time the SIGINT wins.

How does bash handle that?

BTW, I wonder why typing Ctrl-g in emacs sends SIGINT to the parent
under Mac OS X, but not under Linux.

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-16 16:24         ` Vincent Lefevre
@ 2009-07-18  5:29           ` Bart Schaefer
  2009-07-18 10:16             ` Vincent Lefevre
  0 siblings, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2009-07-18  5:29 UTC (permalink / raw)
  To: zsh-workers

On Jul 16,  6:24pm, Vincent Lefevre wrote:
}
} Well, since bash implements WCE and is the default shell on Linux and
} Mac OS X machines, I'd say that such ill-behaved programs should not
} be common (and should be fixed). So, IMHO, there would be more benefit
} to have WCE in zsh.

So I investigated this a bit further and re-learned something I'd long
forgotten:

When running a shell script (not interactively), zsh does NO HANDLING
of SIGINT whatsoever.  It's implementing IUE, not WUE.  Or to be more
precise, it's implementing the default behavior on SIGINT, which is
usually to exit.

In reminding myself of this, I believe I've also remembered the reason
that it ended up this way, which leads to points of disagreement with
the analysis in http://www.cons.org/cracauer/sigint.html (source of
the IUE/WUE/WCE abbreviations).

The point I believe Cracauer is overlooking is that the CALLER of the
shell script may have specified that SIGINT is to be ignored.  SIG_IGN
is supposed to be inherited by child processes; but to implement WUE
or WCE, the shell must itself either ignore or handle SIGINT, which
may contradict what the caller has requested.

My recollection now, which may be wrong, is that there was a considerable
debate about this several years ago, leading to the decision to simply
stick with the default signal handling when the shell is not interactive,
for any signal that it isn't otherwise absolutely necessary to handle.

Further I think Cracauer is very wrong here:

  Do nothing special when SIGINT appears while you wait for a child. You
  don't even have to remember that one happened.
  ...
  Look at WIFSIGNALED(status) and WTERMSIG(status) to tell whether the
  child says "I exited on SIGINT: in my opinion the user wants the
  shellscript to be discontinued".

This is plain nonsense.

Not only does this potentially contradict a caller's explicit request
to ignore SIGINT, but the script should not exit 130 every time any
child exits 130.  It should exit only when SIGINT was received *by the
script*.  "kill -INT ..." of the child should not cause the shell to
behave as if it was interrupted.  Try it with bash.

Having said all that, I also looked at what it would take to implement
WCE as an option.  There are two complications here:

(1) There's a race condition as to whether the shell receives SIGINT
or SIGCHLD first.  With enough trials I can get it to happen either
way, though the vast majority of the time the SIGINT wins.

(2) Both the exiting and the waiting normally take place in zhandler()
when the signal in question arrives.  This means that to get the option
right, we have to record the state of both signals and then find a
common place guaranteed to be outside the race where we can examine
the combined state.

There might be enough state currently available in zhandler() to test
it on either signal and do the correct thing, but I'm not sure yet.


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-13 18:39       ` Peter Stephenson
@ 2009-07-16 16:24         ` Vincent Lefevre
  2009-07-18  5:29           ` Bart Schaefer
  0 siblings, 1 reply; 28+ messages in thread
From: Vincent Lefevre @ 2009-07-16 16:24 UTC (permalink / raw)
  To: zsh-workers

On 2009-07-13 19:39:24 +0100, Peter Stephenson wrote:
> Bart Schaefer wrote:
> > I'm not so sure.  You can emulate WCE with WUE and a trap,

I'll try to look at that.

> > but there is no way to make WCE do the right thing in the case of
> > an ill-behaved child that does not propagate the signal state
> > through exit status.

Well, since bash implements WCE and is the default shell on Linux and
Mac OS X machines, I'd say that such ill-behaved programs should not
be common (and should be fixed). So, IMHO, there would be more benefit
to have WCE in zsh.

> Could be an option (but I'm not writing it).

Yes, that would be nice, even though a trap emulating WCE could be as
simple (unless there are drawbacks).

In any case, I think that the behavior should be documented.

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-13  2:36     ` Bart Schaefer
@ 2009-07-13 18:39       ` Peter Stephenson
  2009-07-16 16:24         ` Vincent Lefevre
  0 siblings, 1 reply; 28+ messages in thread
From: Peter Stephenson @ 2009-07-13 18:39 UTC (permalink / raw)
  To: zsh-workers

Bart Schaefer wrote:
> } I've searched on Google, and found the explanations of the various
> } behaviors:
> } 
> }   http://www.cons.org/cracauer/sigint.html
> } 
> } IMHO, zsh should implement WCE, just like bash.
> 
> I'm not so sure.  You can emulate WCE with WUE and a trap, but there is
> no way to make WCE do the right thing in the case of an ill-behaved
> child that does not propagate the signal state through exit status.

Could be an option (but I'm not writing it).

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


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-13  0:43   ` Vincent Lefevre
@ 2009-07-13  2:36     ` Bart Schaefer
  2009-07-13 18:39       ` Peter Stephenson
  0 siblings, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2009-07-13  2:36 UTC (permalink / raw)
  To: zsh-workers

On Jul 13,  2:43am, Vincent Lefevre wrote:
} 
} Why does zsh 4.3.10 behave differently?

Hmm.  There was a change to trap handling, but that should only matter
if LOCAL_TRAPS is set.  I also wanted there to have been some change
related to configure detecting restartable syscalls, but I can't find
anything in the ChangeLog about that.

IMO 4.3.10 has got it right and the older zsh et al. do not.

} I've searched on Google, and found the explanations of the various
} behaviors:
} 
}   http://www.cons.org/cracauer/sigint.html
} 
} IMHO, zsh should implement WCE, just like bash.

I'm not so sure.  You can emulate WCE with WUE and a trap, but there is
no way to make WCE do the right thing in the case of an ill-behaved
child that does not propagate the signal state through exit status.


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-12 21:50 ` Bart Schaefer
@ 2009-07-13  0:43   ` Vincent Lefevre
  2009-07-13  2:36     ` Bart Schaefer
  0 siblings, 1 reply; 28+ messages in thread
From: Vincent Lefevre @ 2009-07-13  0:43 UTC (permalink / raw)
  To: zsh-workers

On 2009-07-12 14:50:01 -0700, Bart Schaefer wrote:
> This must be happening because either (1) emacs resets the TTY intr
> character to ^G or (2) emacs is sending a SIGINT to the terminal pgrp
> when it sees ^G.  Experimenting with "trap 'stty -a' INT" seems to
> point to the latter, but the SIGINT only makes it through to zsh once
> (or at least the trap fires only on the first ^G).

With zsh 4.3.10, all of them: with the script

trap 'echo INT' INT
/usr/bin/emacs -Q -nw
echo OK

if I hit C-g 4 times, then C-x C-c to quit emacs, I get:

INT
INT
INT
INT
OK

when I run the script with zsh 4.3.10, but just

INT
OK

when I run the script with bash, ksh or zsh 4.2.3.
Why does zsh 4.3.10 behave differently?

> Either way, I think this is a problem with emacs rather than zsh.  Try
> replacing emacs with a command that doesn't do its own input handling
> ("sleep 10", perhaps) and then type the normal intr character (^C).
> Do you expect the script to exit on *that* SIGINT?  [It does.]

With bash, the script exits, even though it doesn't exit in the
case of Ctrl-g in Emacs.

I've searched on Google, and found the explanations of the various
behaviors:

  http://www.cons.org/cracauer/sigint.html

IMHO, zsh should implement WCE, just like bash.

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


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

* Re: zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
  2009-07-12 20:59 Vincent Lefevre
@ 2009-07-12 21:50 ` Bart Schaefer
  2009-07-13  0:43   ` Vincent Lefevre
  0 siblings, 1 reply; 28+ messages in thread
From: Bart Schaefer @ 2009-07-12 21:50 UTC (permalink / raw)
  To: zsh-workers

On Jul 12, 10:59pm, Vincent Lefevre wrote:
}
} Consider a script with a line like
} 
}   /usr/bin/emacs -Q -nw
} 
} Run it with:
} 
}   zsh -f ./script
} 
} and type Ctrl-G in Emacs. Then zsh terminates with a SIGINT, killing
} Emacs at the same time.

This must be happening because either (1) emacs resets the TTY intr
character to ^G or (2) emacs is sending a SIGINT to the terminal pgrp
when it sees ^G.  Experimenting with "trap 'stty -a' INT" seems to
point to the latter, but the SIGINT only makes it through to zsh once
(or at least the trap fires only on the first ^G).

Either way, I think this is a problem with emacs rather than zsh.  Try
replacing emacs with a command that doesn't do its own input handling
("sleep 10", perhaps) and then type the normal intr character (^C).
Do you expect the script to exit on *that* SIGINT?  [It does.]


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

* zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X
@ 2009-07-12 20:59 Vincent Lefevre
  2009-07-12 21:50 ` Bart Schaefer
  0 siblings, 1 reply; 28+ messages in thread
From: Vincent Lefevre @ 2009-07-12 20:59 UTC (permalink / raw)
  To: zsh-workers

Hi,

I've found a problem with zsh 4.3.10 (and some previous versions, as
this bug has occurred for quite a long time, and I've identified it
only now). I could trigger it only under Mac OS X (version 10.4.11).

Consider a script with a line like

  /usr/bin/emacs -Q -nw

or

  /Applications/MacPorts/Emacs.app/Contents/MacOS/Emacs -Q -nw

(the problem doesn't depend on the version of emacs, e.g. 21 or 22).

Run it with:

  zsh -f ./script

and type Ctrl-G in Emacs. Then zsh terminates with a SIGINT, killing
Emacs at the same time.

This problem also occurs with ksh 1993-12-28 p, but not with bash.
With zsh 4.2.3, the SINGINT occurs only after Emacs terminates (e.g.
by quitting it with C-x C-c).

-- 
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


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

end of thread, other threads:[~2009-07-28 21:31 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-07-22 18:18 zsh 4.3.10 terminates with SIGINT when one types Ctrl-G in emacs under Mac OS X Martin Cracauer
2009-07-25 18:58 ` Bart Schaefer
2009-07-26  6:24   ` Philippe Troin
2009-07-26 21:14     ` Bart Schaefer
2009-07-27 23:10   ` Martin Cracauer
2009-07-28  4:29     ` Bart Schaefer
  -- strict thread matches above, loose matches on Subject: below --
2009-07-12 20:59 Vincent Lefevre
2009-07-12 21:50 ` Bart Schaefer
2009-07-13  0:43   ` Vincent Lefevre
2009-07-13  2:36     ` Bart Schaefer
2009-07-13 18:39       ` Peter Stephenson
2009-07-16 16:24         ` Vincent Lefevre
2009-07-18  5:29           ` Bart Schaefer
2009-07-18 10:16             ` Vincent Lefevre
2009-07-18 18:16               ` Bart Schaefer
2009-07-19 18:03                 ` Bart Schaefer
2009-07-19 19:15                   ` Bart Schaefer
2009-07-19 20:14                     ` Bart Schaefer
2009-07-19 20:41                       ` Peter Stephenson
2009-07-18 18:35               ` Bart Schaefer
2009-07-18 23:09                 ` Vincent Lefevre
2009-07-19  9:51                   ` Vincent Lefevre
2009-07-19 16:32                     ` Bart Schaefer
2009-07-19 22:24                       ` Vincent Lefevre
2009-07-19 18:31                   ` Bart Schaefer
2009-07-20  8:31                     ` Vincent Lefevre
2009-07-22  2:58                       ` Eric Blake
2009-07-22  8:16                         ` Vincent Lefevre

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