
On Thu, 2008-05-15 at 10:45 +0100, Simon Marlow wrote:
The latest version of the Process overhaul is here:
http://darcs.haskell.org/~simonmar/process/System-Process.html
We discussed some ideas on #ghc today and I'm posting them here so people can comment. Deprecate: * runCommand * runProcess * runInteractiveCommand * runInteractiveCommand The rationale is that these are all more limited than the new createProcess and yet none of them are really convenient. It's better to have fewer variations if they can all be expressed easily using createProcess. It makes the API much simpler. Also we'd not add `system` or `rawSystem` to `System.Process` and instead add new equivalents with more consistent names. That would leave just: * createProcess * readProcess * readProcessWithExitCode Then add the following: * callProcess :: FilePath -> [String] -> IO () * callCommand :: String -> IO () These would be synchronous like the current system and rawSystem. The difference is they would throw IOErrors on failure rather than returning the ExitCode which is so easily ignored. These are of course only convenience functions. If someone wants the exit code it should be easy to do it via createProcess and waitForProcess. We need to make sure that is indeed the case. We'd also add async versions of the above: * spawnProcess :: FilePath -> [String] -> IO ProcessHandle * spawnCommand :: String -> IO ProcessHandle that do not wait for the process to finish and return the ProcessHandle. Again these should be easy instances of createProcess. The docs should probably say as much so it's clear how to make minor variations. We also discussed how it should be safe to GC the ProcessHandle and not end up with zombie processes on unix systems. On Windows it's actually easy because you can close the process handle which means you don't get the exit status of the process. On unix we have to collect the exit status of every child process (actually you can ignore all of them, but you cannot ignore them selectively). The point is that with a convenient spawnProcess it's tempting to ignore the ProcessHandle result and never bother calling waitForProcess on it. We do want to support that. At the moment doing that would leave zombie processes. We discussed a mechanism to allow GC'ing ProcessHandles that does not leave zombies. It'd probably involve keeping a Map PID (MVar ExitCode) and embedding a MVar ExitCode in the ProcessHandle. Then when we get notified that a child process terminated we would store the exit status in the MVar. Then waitForProcess would just wait on that MVar ExitCode. The one thing we have left that we cannot express with createProcess is the behaviour with respect to ^C handling. For some processes we want to delegate ^C handling to that child process (eg imagine calling ghci). For others we want to handle ^C 'normally'. For details see #2301: http://hackage.haskell.org/trac/ghc/ticket/2301 Duncan