Process library and signals
Simon Marlow
simonmar at microsoft.com
Wed Oct 27 06:16:26 EDT 2004
My apologies if I misinterpreted your comments. There appear to be some
use cases and conventions here that I'm not altogether familiar with.
So basically you're saying that if runProcess is to be used in a
system()-like way, that is the parent is going to wait synchronously for
the child, then the parent should be ignoring SIGQUIT/SIGINT. On the
other hand, if runProcess is going to be used in a popen()-like way,
then the parent should not be ignoring SIGQUIT/SIGINT. The current
interface doesn't allow for controlling the behaviour in this way.
So the current signal handling in runProcess is wrong, and should
probably be removed. What should we have instead? We could implement
the system()-like signal handling for System.Cmd.system only, perhaps.
Cheers,
Simon
On 26 October 2004 23:38, Glynn Clements wrote:
> Having looked at the latest version of the Process library, it appears
> that my earlier comments about signal handling may have been
> misinterpreted.
>
> First, my comments regarding the handling of SIGINT/SIGQUIT were
> specific to system(). The C system() function ignores these signals in
> the parent while the child is executing. However, this doesn't
> necessarily apply to other functions; e.g. popen() doesn't ignore
> these signals, and runProcess probably shouldn't either.
>
> With system(), the parent blocks until the child is finished, so if
> the user presses Ctrl-C to kill the "currently executing" process,
> they probably want to kill the child. If the parent wants to die on
> Ctrl-C, it can use WIFSIGNALED/WTERMSIG to determine that the child
> was killed and terminate itself.
>
> OTOH, with popen(), the parent continues to run alongside the child,
> with the child behaving as a "slave", so the parent will normally want
> to control the signal handling.
>
> Ideally, system() equivalents (e.g. system, rawSystem) would ignore
> the signals in the parent, popen() equivalents (e.g.
> runInteractiveProcess) wouldn't, and lower-level functions (e.g.
> runProcess) would give you a choice.
>
> Unfortunately, there is an inherent conflict between portability and
> generality, as the Unix and Windows interfaces are substantially
> different. Unix has separate fork/exec primitives, with the option to
> execute arbitrary code between the two, whilst Windows has a single
> primitive with a fixed set of options.
>
> Essentially, I'm not sure that a Windows-compatible runProcess would
> be sufficiently general to accurately implement both system() and
> popen() equivalents on Unix. Either system/rawSystem should be
> implemented using lower-level functions (i.e. not runProcess) or
> runProcess needs an additional option to control the handling of
> signals in the child.
>
> Also, my comment regarding the signals being "reset" in the child was
> inaccurate. system() doesn't reset them in the sense of SIG_DFL. It
> sets them to SIG_IGN before the fork(), recording their previous
> handlers. After the fork, it resets them in the child to the values
> they had upon entry to the system() function (i.e. to the values they
> had before they were ignored). The effect is as if they had been set
> to SIG_IGN in the parent after the fork(), but without the potential
> race condition.
>
> Thus, if they were originally ignored in the parent before system()
> was entered, they will be ignored in the child. If they were at their
> defaults (SIG_DFL) before system() was entered, they will be so in the
> child. If they had been set to specific handlers, system() will
> restore those handlers in the child, but then execve() will reset them
> to SIG_DFL, as the handler functions won't exist after the execve().
More information about the Glasgow-haskell-users
mailing list