
David Roundy-2 wrote:
On Wed, Jun 18, 2008 at 04:22:24PM -0700, Frederik Eaton wrote:
David Roundy-2 wrote:
No, createProcess is more low-level than the previous interface, which is why it can't be implemented using the previous interfaces, but rather they can be implemented using createProcess. Which is why they can be deprecated, although I'd hope they won't be removed for at least a couple more ghc releases after createProcess is introduced.
In what way is 'createProcess' more low-level than the previous interfaces?
The easiest sense in which it's more low-level is that the previous two commands runProcess and runInteractiveProcess can both be implemented using createProcess, but not the other way around.
New API: (a subset thereof, actually)
createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
data CreateProcess = CreateProcess { cmdspec :: CmdSpec cwd :: (Maybe FilePath) env :: (Maybe [(String, String)]) std_in :: StdStream std_out :: StdStream std_err :: StdStream close_fds :: Bool }
Old API:
runProcess :: FilePath -> [String] -> Maybe FilePath -> Maybe [(String, String)] -> Maybe Handle -> Maybe Handle -> Maybe Handle -> IO ProcessHandle
runInteractiveProcess :: FilePath -> [String] -> Maybe FilePath -> Maybe [(String, String)] -> IO (Handle, Handle, Handle, ProcessHandle)
In the old API, you are required to either use preexisting handles for each of stdin/stdout/stderr (possibly allowing the child process to inherit some or all of them), *or* create new pipes for all three.
You might consider trying to implement runInteractiveProcess using runProcess (you certainly can't do the opposite) by setting up pipes and passing them to runProcess, but there's no portable function that can be used to do this, so you'd be out of luck. You'd be stuck doing what darcs has long done: write to temporary files on disk, which is totally braindead.
createProcess is (so far as I can tell) the lowest-level *portable* Haskell API for spawning processes that has yet been proposed, in the sense that there are no other proposed functions that could be used to implement createProcess, and no other proposed functions that cannot be implemented using createProcess.
It sounds like we are confusing "low-level" with "powerful". I don't know enough about portability and the constraints imposed by portability to comment on what else could be done, but the fact that we keep changing interfaces for process execution suggests to me that the existing interfaces have not been low-level enough. For instance, why can't we create a pipe independently of a process? What about creating pipes to file descriptors other than standard input/output/error? If we had good Haskell interfaces to OS-level primitives, as John Meacham suggested, then we could build something that tries to be a "greatest common denominator" on top of these. I am skeptical that the result would look very much like 'createProcess', for instance doesn't Windows have a concept of file descriptors other than standard input/output/error? I suppose that I can always use System.Posix.Process, though, and hope that it doesn't change too much... Frederik -- View this message in context: http://www.nabble.com/Proposal%3A-overhaul-System.Process-tp16844161p1802014... Sent from the Haskell - Libraries mailing list archive at Nabble.com.