From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14193 invoked from network); 17 May 2005 08:17:43 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 17 May 2005 08:17:43 -0000 Received: (qmail 34723 invoked from network); 17 May 2005 08:17:37 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 17 May 2005 08:17:37 -0000 Received: (qmail 18316 invoked by alias); 17 May 2005 08:17:34 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 21263 Received: (qmail 18295 invoked from network); 17 May 2005 08:17:33 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 17 May 2005 08:17:33 -0000 Received: (qmail 34398 invoked from network); 17 May 2005 08:17:33 -0000 Received: from lakermmtao08.cox.net (68.230.240.31) by a.mx.sunsite.dk with SMTP; 17 May 2005 08:17:27 -0000 Received: from quark.hightek.org ([68.12.75.33]) by lakermmtao08.cox.net (InterMail vM.6.01.04.00 201-2131-118-20041027) with ESMTP id <20050517081724.JJNP18139.lakermmtao08.cox.net@quark.hightek.org> for ; Tue, 17 May 2005 04:17:24 -0400 Received: by quark.hightek.org (Postfix, from userid 501) id 4DE6F45929; Tue, 17 May 2005 03:15:14 -0500 (CDT) Date: Tue, 17 May 2005 03:15:13 -0500 From: Vincent Stemen To: zsh-workers@sunsite.dk Subject: Re: Z shell signal handling Message-ID: <20050517081513.GA93407@quark.hightek.org> References: <20050426030308.GA21501@quark.hightek.org> <200504261834.j3QIYHSa018951@news01.csr.com> <1050427053638.ZM28743@candle.brasslantern.com> <200504270954.j3R9sujP029445@news01.csr.com> <20050507171938.GA51740@quark.hightek.org> <5415.1115631148@csr.com> <20050510184600.GA67763@quark.hightek.org> <200505131127.j4DBR0Yt014380@news01.csr.com> <20050514043338.GA82132@quark.hightek.org> <200505161046.j4GAknfO018203@news01.csr.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200505161046.j4GAknfO018203@news01.csr.com> User-Agent: Mutt/1.4.1i X-Spam-Checker-Version: SpamAssassin 3.0.2 on a.mx.sunsite.dk X-Spam-Level: X-Spam-Status: No, score=-2.6 required=6.0 tests=AWL,BAYES_00 autolearn=ham version=3.0.2 X-Spam-Hits: -2.6 On Mon, May 16, 2005 at 11:46:49AM +0100, Peter Stephenson wrote: > Vincent Stemen wrote: > > # --------- ----------- > > sigterm1() > > { > > trap 'echo "-- sigterm2 --"' TERM > > echo "sigterm1(): sending SIGTERM" > > kill -TERM $$ > > trap sigterm1 TERM > > sleep 1 > > } > > > > trap sigterm1 TERM > > > > echo > > echo "main: sending SIGTERM" > > kill -TERM $$ > > echo "main: sending SIGTERM" > > kill -TERM $$ > > # --------- ----------- > > > > Here is the output of zsh and bash. > > > > > > main: sending SIGTERM > > sigterm1(): sending SIGTERM > > sigterm1(): sending SIGTERM > > sigterm1(): sending SIGTERM > > sigterm1(): sending SIGTERM > > ... continues forever > > > > Yes, I can see this, but this isn't the same example I was looking at > when I saw different behaviour from you. Yes, I think that is because we were discussing localtraps earlier as well, but I thought it was better to simplify the test case as much as possible and set any localtrap issues aside for now and focus on the fundamental signal behavior that can be directly compared to other shells. > What I think is happening here is that signals *are* being queued. Then > the SIGTERM is delivered after sigterm1 has returned, at which point > sigterm1 has been reinstalled as the signal handler, so gets called > again ad infinitum. Yes. That is the problem basically as I see it. > In this case bash and zsh are actually trying a bit harder to do the > right thing, at least as far as safety of the execution environment is > concerned. Not queueing signals can cause significant reentrancy > problems. However, it may be possible to unqueue signals temporarily at > some point. That's still not trivial; the code's currently not written > to allow that, since as I said before the queue/unqueues are all nested > and you need to have some clue about the environment to decide whether > temporarily unqueuing is safe. Possibly some queue/unqueue pair can be > moved deeper into the code, leaving some points at which signals will be > handled, but that's not trivial either. I have a proposal as to the way I think the signals should be handled, although, as you say, it may not be trivial. First, let me provide one more example to elaborate on the current bahavior comparing zsh to sh. There is a problem with the way sh does it also, which I will describe below. # --- --- signal() { echo "-- signal() --" echo "sleeping" sleep 1 echo "sleeping again" sleep 1 } trap signal INT echo "main: sending SIGINT" kill -INT $$ # --- --- To test, I hit ^C several times while it is in signal(). main: sending SIGINT -- signal() -- sleeping ^C^C^C^Csleeping again ^C-- signal() -- sleeping sleeping again main: sending SIGINT -- signal() -- sleeping ^C-- signal() -- sleeping ^C-- signal() -- sleeping ^C-- signal() -- sleeping sleeping again sleeping again sleeping again sleeping again zsh seems to queue one signal and re-calls the handler once. All additional signals are ignored. I am not sure I see the benefit of this. sh would appear to queue many signals, but actually it is not having to queue them because it calls the handler immediately on each one. So, I don't know if it even has any kind of queuing mechanism. There are a couple potential problems I can see with the sh approach, that I am guessing zsh and bash were trying to fix. 1. It enters the handler with the signal still enabled, so the programmer needs to know to immediately use trap to disable the signal, once in the handler, if he does not want get hit with another signal before exiting the handler. 2. Even if you disable the signal in the handler, there might be the remote possibility of a race case where it could catch another signal before getting it disabled. If you are talking about dealing with interrupts at the kernel level, I would certainly consider this an issue. But with signals in shell script, I would generally consider the chance of this very low or near zero. I don't know of many things that would generate multiple signals that close together. The user certainly is not going to be able to hit ^C or type the kill command that fast. Maybe if you had multiple other processes sending signals to the same process and two of them happen to hit at near the same time. This leaves problem 1 as the primary issue. Here is my proposal of the way I think it should be handled, which is very simple conceptually. Although I understand, Peter, that implementing it might not be so simple. I will, of course, leave that up to you or whoever might have the time, ability, and hopefully willingness to work on it to determine. Proposal: When a signal is caught, enter the handler with the signal automatically disabled the way bash does. Then allow the programmer to re-enable the signal with a trap statement inside the handler if needed. If another signal is caught after that, process it immediately like sh does, rather than waiting for the handler to return. This way, there would be no potential race cases, programmers won't get themselves into trouble by not thinking of disabling the signal in the handler, and our hands won't be tied when we need to do more sophisticated signal handling. It seems to me that would solve all the problems and possibly eliminate the need to have complex signal queuing code. I not sure you would need to do any queuing at all since all signals would be processed immediately. -- Vincent Stemen Avoid the VeriSign/Network Solutions domain registration trap! Read how Network Solutions (NSI) was involved in stealing our domain name. http://inetaddresses.net/about_NSI.html