
On Thu, Jun 19, 2008 at 04:20:52PM -0700, Frederik Eaton wrote:
David Roundy-2 wrote:
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...
The problem presumably is that there isn't sufficient similarity between systems to create smaller components which are themselves cross-platform that can be combined to write a function like createProcess. I don't know enough windows programming to confirm or deny whether it would be possible to create a cross-platform pipe-creation function, but I doubt it would be possible to create something with semantics sufficiently similar to posix pipes so as to be useful. There's certainly no guarantee that there exist "small" cross-platform pieces that can be used to construct a powerful process-spawning function. Perhaps Simon can enlighten us? I just did a bit of a search and came across a bit of API from microsoft: http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx It looks vaguely similar to the posix approach: you create pipes, create backup copies of whichever of stdin/out/err you wish to change, set your stdin/out/err to the values you wish to pass to your child process, spawn the process, then you set stdin/out/err back to your saved values, and maybe close one end of the newly-created pipes (I'm not sure of this). Under posix, the order is different, which probably means that you can't break this into smaller pieces. Under posix, you fork first, and only then do you modify stdin/out/err and close one end of any pipes you might have created, and then call exec. Since the order of operations is different, we can't write a portable version of Simon's createProcess out of pretty smaller pieces. Obviously, we could write it out of functions like forkIfWeAreRunningPosix, etc, but that would be stupid. That's my half-baked analysis, based on reading a couple of web pages... David