
John Goerzen wrote:
On 2007-03-02, Simon Marlow
wrote: Regarding your shell: I would suggest trying forkIO for the Haskell "processes" (not forkOS unless for some reason you really need another OS thread). However, I can imagine that it might be hard to implement job control and signal handling in that system. You could also consider using System.Process.runInteractiveProcess, for portability.
Thinking about forkIO seems that it could be fairly complex to just drop in. The problem lies around file descriptors. When you fork off a new process, and then close file descriptors in the parent, they stay open in the child, and vice versa. Proper management of file descriptors is a critical part of a shell, and it's vital to close the proper set of FDs at the proper time in the parent and the child, or else bad things like pipes never closing could easily lead to deadlock.
Of course, it is possible to work around this, but I fear that it could make the program very complex.
Admittedly I haven't completely thought this through, but my intuition was that you would be able to use forkIO at a higher level. That is, instead of just trying to replace forkProcess with forkIO, you replace forkProcess + pipes + FD handling with forkIO + lazy streams, for Haskell processes. So the way in which data is fed between processes depends on the process: Haskell processes talk to each other using lazy streams, external processes talk to each other over pipes, and at a boundary between the two you need a pipe with another Haskell thread to feed the pipe from a lazy stream, or vice-versa. Cheers, Simon