[Top][All Lists]

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

Re: [Bug-gnulib] addition: wait-process.h, wait-process.c

From: Paul Eggert
Subject: Re: [Bug-gnulib] addition: wait-process.h, wait-process.c
Date: 26 Sep 2003 23:05:08 -0700
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3

Bruno Haible <address@hidden> writes:

> Paul Eggert wrote back on April 23:
> > Also, some programs need to run code if waitpid fails with errno ==
> > EINTR.
> whereupon I replied:
> > If waitpid fails with errno == EINTR, a signal handler was run.

Not necessarily, unfortunately.  It is a fairly common bug that system
calls like waitpid can return with errno == EINTR even though no
signal handler was run.  SIGCONT is a common culprit.  I've seen
the bug both with AIX and with Linux.  E.g., see


> > The program can run its code from within the signal handler, can't it?

Not necessarily, because the set of things that one can do portably
within signal handlers is fairly limited.  (This is assuming that we
don't care about the sort of bugs mentioned above, or can work around
them somehow.)

> > Specifically, diffutils' checksigs() could call exit (EXIT_TROUBLE)
> > after longjmping back to main, no?

I suppose it might be able to, if we can assume POSIX semantics.  But
isn't it safer to stick with the C89 semantics that it currently uses,
where it merely stores into a volatile int variable?  That way, I
don't have to worry so much about handling signals at arbitrary

Here are some more details about the tricky situation in sdiff.c, if
you're interested.  Sdiff can be interrupted while a child is running.
If the signal handler were to exit right away, then sdiff would exit
even though its child was still running.  Sdiff wants to kill off its
child in that situation, but it shouldn't just send a signal to the
child's pid, since the child may already have been reaped and a new,
unrelated process may have taken its place.  The current code
sidesteps all this mess (which reminds me a bit of Emacs's
signal-blocking mess :-) by checking a global variable at well-defined
points that are never too far apart.  The signal handler merely sets
the global variable.

> > Or do you mean, the wait_subprocess function really needs to take an
> > additional argument
> >           void (*eintr_hook) (void)  ?

Sorry, I hadn't thought it through that carefully.  Perhaps there's no
simple solution.

> So what's the general opinion on this? Do we have to add an argument
>             void (*eintr_hook) (void)
> to all functions which retry a system call when they see EINTR

I hope not.  sdiff doesn't need that.

I see that I didn't mention this earlier in this old thread, but
bison's lib/subpipe.c has a function reap_subpipe that doesn't have
all the functionality of wait_subprocess (as Bison doesn't need it),
but has some extra stuff (e.g., support for status 126) that
wait_subprocess lacks.  You might want to look at it for ideas.  It'd
be nice if we didn't have to have two sets of code to do this; on the
other hand subpipe.c is a fairly specialized application (it's
efficient, but it allows only subsidiary commands like "sort", which
are known to read everything before writing anything) so perhaps you
shouldn't worry too much about supporting with the modules you're

I briefly looked at
and noted a potential portability problem: "*(int *) &status = 0;"
looks a bit suspicious.  Surely hosts that don't allow using 'int' for
a wait status are long dead; are they still worth worrying about?

reply via email to

[Prev in Thread] Current Thread [Next in Thread]