[GHC] #2233: Overhaul System.Process
GHC
trac at galois.com
Fri May 23 10:26:12 EDT 2008
#2233: Overhaul System.Process
-------------------------------+--------------------------------------------
Reporter: simonmar | Owner:
Type: proposal | Status: new
Priority: normal | Milestone: Not GHC
Component: libraries/process | Version: 6.8.2
Severity: normal | Resolution:
Keywords: | Difficulty: Unknown
Testcase: | Architecture: Unknown
Os: Unknown |
-------------------------------+--------------------------------------------
Comment (by duncan):
Further to the changes already made we discussed some ideas on #ghc today:
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`.
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 `IOError`s 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 `ProcessHandle`s 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 behavior 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.
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/2233#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the Glasgow-haskell-bugs
mailing list