
John Goerzen wrote:
The standard way of implemeting pipes between two external programs in Unix involves setting up pipes and forking, then duping things to stdin/stdout, and execing the final program. In this case, I am setting it up to let people pipe to Haskell functions as well, forking off a process that works with pipes to handle them.
I know how all these things work in Unix, in C, in Python, etc.
I have no idea how all of this will interact if I were to use forkOS. It is not clear to me what the semantics of forkProcess, executeFile, signal handling, etc. are under a Haskell thread instead of a forked process. This is, as far as I can tell, completely undocumented in System.Posix.* and the subject of differing advice on the WWW.
We can certainly add any missing documentation - can you suggest specifically waht you'd like to see mentioned? forkProcess does say what happens when there are multiple threads, and I've added some more notes about I/O with -threaded. executeFile isn't affected by threads. Signal handling unfortunately won't work in the child of forkProcess, with -threaded, right now for the same reason that I/O doesn't work.
But let me add a voice to keeping the non-threaded RTS around. I have learned the hard way that the threaded RTS is ported only to a very few platforms, a distinct minority of the platforms that Debian supports, for instance. (Just like ghci). Whereas the non-threaded RTS is supported much more broadly (such as Alpha support). My own program hpodder has failed to build in Debian on many platforms because I didn't realize this going in.
Not only that, but it is apparent that the threaded RTS is simply inappropriate when a person is trying to do anything remotely low-level on the system. I would hate to have to become a Haskell refugee, going back to Python, because Haskell I/O has become incompatible with fork().
I do not find a language to be useful, in general, unless it lets me fork and exec when I have to.
I share your concerns, and doing low-level system programming of this kind is certainly something we want to support. I'd also consider it a serious problem if we were to lose the ability to write a shell in Haskell. (I should point out that it's not usualy fork+exec that causes problems, rather fork on its own - fork+exec is pretty well supported, we use it in the timeout program in the GHC testsuite for example). Many people really need the facilities that the threaded RTS provides (non-blocking foreign calls, SMP parallelism, writing thread-safe DLLs, etc.). So we have to provide these facilities without losing support for system programming. I accept we may have tipped the balance a little recently in favour of the funky new stuff; apologies for that, and thanks for bringing it up. We won't be throwing away the non-threaded RTS any time soon, certainly not while there are certain programs and platforms that only work with it. Regarding platform support for the threaded RTS: that's certainly a problem, which is mainly due to lack of resources. I'm sure most bugs are probably fairly shallow, since we only use Posix thread support. 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. Cheers, Simon