6
votes

How do I pipe the stdout and stderr of a process to the same Handle? On unix systems it's pretty easy, just use createPipe and pass the write end to runProcess as both stdout and stderr. On Windows it's harder:

  • Neither the unix-compat nor the Win32 package export a way to create pipes.

  • openTempFile (which could be use to simulate pipes) sets the wrong mode on the created Handle.

Edit: To give some more context: I want to run a process and have it write its stdout and stderr to the same Handle, in a cross-platform manner.

2
Interesting. In what way are the permissions wrong? According to the documentation, openTempFile's Handle is created with ReadWrite permission, which ought to be enough for another process (run by the same user) to write to it.Daniel Wagner

2 Answers

2
votes

You can use stuff from System.Process. In the CreateProcess definition there are

std_in       :: StdStream,               -- ^ How to determine stdin
std_out      :: StdStream,               -- ^ How to determine stdout
std_err      :: StdStream,               -- ^ How to determine stderr

and StdStream have this constructor:

data StdStream = UseHandle Handle

After that, pass the object you formed to the createProcess function to run your proc.

0
votes

I ended up implementing a cross-platform createPipe: https://github.com/haskell/cabal/blob/master/Cabal/tests/Distribution/Compat/CreatePipe.hsc

We should probably put it somewhere more accesible at some point.