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@gclements.plus.com>