Process library and signals

Glynn Clements glynn at gclements.plus.com
Wed Oct 27 10:07:35 EDT 2004


Simon Marlow wrote:

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

Exactly.

> The current
> interface doesn't allow for controlling the behaviour in this way.

Yep.

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

Well, probably for system and rawSystem.

The problem, as I see it, is that the Process library is meant to be
both flexible and portable. If you don't need the portability, you
already have the primitives in System.Posix, and separate fork/exec
will inevitably provide more flexibility than an all-in one version.

If you provide system/rawSystem and runInteractive{Command,Process},
that's covered the most common cases (i.e. system() and popen()). So
what is runProcess for? If it doesn't do the signal handling, it's
only really suitable for popen-style usage.

Which is unfortunate; I can imagine a use for an intermediate
"semi-raw" system, which supports e.g. file redirection or even
command pipelines, but without using the shell (i.e. accepts the
argv[] individually). In particular, using the shell is risky if you
want to use untrusted data in the argument list (e.g. CGI programs).

If runProcess doesn't do the signal handling between the fork and the
exec, you can't change the child's signal handling after the exec. You
could change the signal handling of the parent (i.e. the current
process) before calling runProcess, let the child inherit it, then
change it back again after runProcess returns, but that gives rise to
a potential race condition.

One possibility would be to allow an extra argument of type IO () (or
Maybe (IO ()), where Nothing is shorthand for Just $ return ()) which
would be executed between the fork and the exec on Unix and ignored on
Windows. AFAICT, that would expose the full functionality available on
Unix without interfering with Windows usage or adding complexity.

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the Glasgow-haskell-users mailing list