

Redirecting Stdio Is Hard - Arkanosis
http://blog.httrack.com/blog/2014/12/20/redirecting-stdio-is-hard/

======
kyberias
This reminds me of a bug I was hunting years ago in an obscure web server
software written in C that was ported from Unix (Solaris perhaps) to Windows.
It implemented connections to backend-systems and databases using sockets.
Sometimes we got random file errors out of nowhere on Windows but not on Unix.

Turns out BSD sockets are closed with close() just like file descriptors but
winsock requires applications to use closesocket(). The guy that ported this
to Windows didn't know this and used close() on sockets leaving them dangling
and sometimes closing random files on specific circumstances.

------
cesarb
Dealing with stdin/stdout/stderr is much harder on Windows than on Unix.

On Unix, you have the stdio layer (FILE *) and the file descriptor layer. On
Windows, you have multiple stdio layers (one for each C runtime you have
loaded in your process), multiple file descriptor layers (again, one for each
C runtime), and the native "standard handles" layer
(GetStdHandle/SetStdHandle).

On Unix, to redirect stdout is just a dup2() call, perhaps preceded by a
fflush. But on Windows, there's no handle equivalent of dup2()
(DuplicateHandle can duplicate a handle, but it will give you a new handle;
you cannot use it to replace an existing handle).

So you have to either use SetStdHandle, which won't work well on multithreaded
programs (see the comments for the blog post at
[http://blogs.msdn.com/b/oldnewthing/archive/2013/03/07/10399...](http://blogs.msdn.com/b/oldnewthing/archive/2013/03/07/10399690.aspx)),
or call a dup2() equivalent on each C runtime the process is using, which
won't work if (as in the second bug report in this article) another component
is directly using the underlying handle.

~~~
SCHiM
On windows you use DuplicateHandle() on pipes made by CreatePipe(). You can
then pass these handles to, for example, CreateProcess() (which does what the
name implies). Now when the child process writes to a handle (stdout), the
parent process can then read from this handle as if it were stdin.

------
dnr
These problems would basically all go away if you used a process monitor to
handle setting up the environment for the server process, including fds 1 and
2, and then just let it log to stdout or stderr. Any halfway-decent process
monitor can do this, and most of them can handle log rotation as well.

------
mapcars
So, what about modern OSes, like plan9?

------
notacoward
tl;dr Windows and Java both have crappy file-descriptor handling.

~~~
comex
And Unix, when it comes to O_CLOEXEC stuff. Everybody loses!

------
rollypollybear
Interesting article...I wonder if the Java problem could have been solved more
succinctly?

