PATCH: Windows I/O Redirection Code

I banged my head for a long time trying to figure out a better way to deal
with this. What I wanted was to load the Ruby API (embedded) as a DLL in a
Windows application. However, because the application had no standard
console, stdin/stdout/stderr activity by Ruby or any scripts was causing my
application to hang, and I couldn’t find any way to get it redirected to my
application.

So I made a cheap little patch for myself.

Basically, the code I stuck in the Ruby DLL was just a quick little way to
get all standard I/O to be redirected through a Windows I/O handle, so I was
able to just create an anonymous pipe between my application and the Ruby
DLL, catching all the output from Ruby code or any scripts I ran.

In case Matz or anyone else is interested in using this code:

// ======== for WIN32.H:

int rb_w32_redirect_stdin(HANDLE);
int rb_w32_redirect_stdout(HANDLE);
int rb_w32_redirect_stderr(HANDLE);

// ======== for WIN32.C:

int rb_w32_redirect_stdin(HANDLE pipe)
{
return dup2(_open_osfhandle((long)pipe, _O_TEXT), 0);
}

int rb_w32_redirect_stdout(HANDLE pipe)
{
return dup2(_open_osfhandle((long)pipe, _O_TEXT), 1);
}

int rb_w32_redirect_stderr(HANDLE pipe)
{
return dup2(_open_osfhandle((long)pipe, _O_TEXT), 2);
}

Also, I had previously posted about this whole thing (my application is a
Borland C++ Builder application) and I had somewhat solved the problem by
delay-loading the DLL. It turns out, doing that is somewhat impractical
because there are exported data which can’t be exported when loading is
delayed. So, I went back to normal pre-loading and just stuck the above
patch into win32.h and win32.c, respectively.

I hope this helps some Windows coder(s) out there,

Sean O'Dell