Bill Allombert on Mon, 16 May 2005 11:07:54 +0200

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: GP handling of SIGINT (Linux)

On Mon, Apr 18, 2005 at 01:33:23PM +0200, Jeroen Demeyer wrote:
> Karim Belabas wrote:
> >* Jeroen Demeyer [2005-04-17 21:35]:
> >
> >>Hello list,
> >>
> >>while hacking with GP and shell scripts under Linux, I noted the 
> >>following:
> >>
> >>When using GP non-interactively (gp -f -q < >output),
> >>it only handles a SIGINT once.  The first SIGINT is caught and 
> >>interrupts the current command (as usual), but any further SIGINTs do 
> >>nothing.  I don't understand how come this behaviour is different from 
> >>an interactive GP, where multiple SIGINTs can be cought.
> >>
> >>Is this a feature or a bug?
> >
> >
> >It's a bug, which we've not been able to trace so far. See
> Looking at the code, I have an idea on what's going wrong.  The problem 
> seems to be with the use of longjmp().  This causes the function 
> gp_sighandler() never to return, so the rest of the program is treated 
> as being inside the signal handler.  By default a signal can never occur 
> during a signal handler.

After reading carefully the glibc documentation and the code, it looks
like the code was made for System V, and should also work on BSD but
not on Linux...

1) gp_sighandler start by doing 

This is a SYSV idiom: SYSV reset the signal handler to SIG_DFL when
calling the handler, so this line reinstate the gphandler.

BSD and POSIX instead does not change the handler, but block the signal
(see sigprocmask). However BSD longjmp will restore the set of blocked
signals, so will unblock it, but not Linux longjmp, you have to use
sigsetjmp/siglongjmp (which are slower). (POSIX itself allows both

One solution is to use sigsetjmp/siglongjmp and this seems to fix the 
problem, but I don't think this is the best solution because sigsetjmp
is slower than setjmp. I think it is cleaner to use sigaction to set up
the signal handling to behave the way we like.

> A very ugly hack around this is to change this default.  I have done 
> this in attached patch.  I can only say it fixes my problem, but it 
> could very well break things.  The behaviour is also likely to be 
> OS-dependent.

I am not sure it is a "very ugly hack". I think you are very close
to a correct fix to the problem. signal(2) is deprecated in favour
sigaction anyway.