* win32/win32.c (new_console, output_console): attach new console on
  demand.


Index: win32/win32.c
===================================================================
RCS file: /cvs/ruby/src/ruby/win32/win32.c,v
retrieving revision 1.144
diff -U2 -p -r1.144 win32.c
--- win32/win32.c	10 Feb 2005 04:55:34 -0000	1.144
+++ win32/win32.c	10 Feb 2005 09:27:43 -0000
@@ -1653,7 +1653,81 @@ rb_w32_open_osfhandle(long osfhandle, in
 }
 
+static DWORD WINAPI
+new_console(PVOID argp)
+{
+    HANDLE pin = ((HANDLE *)argp)[0];
+    HANDLE pout = ((HANDLE *)argp)[1];
+    HANDLE console = NULL;
+    DWORD count;
+    char buf[2048];
+    int i, j, n, maxfd;
+
+    xfree(argp);
+    if (!ReadFile(pin, buf, sizeof(buf), &count, NULL)) return 0;
+    AllocConsole();
+    console = GetStdHandle(STD_OUTPUT_HANDLE);
+    SetStdHandle(STD_ERROR_HANDLE, console);
+    for (i = 0, maxfd = _getmaxstdio(); i < maxfd; i += IOINFO_ARRAY_ELTS) {
+	ioinfo *p = __pioinfo[i >> IOINFO_L2E];
+	if (!p) continue;
+	n = i + IOINFO_ARRAY_ELTS;
+	if (n > maxfd) n = maxfd;
+	for (j = i; j < n; ++j) {
+	    MTHREAD_ONLY(if (!p[j].lockinitflag) continue);
+	    MTHREAD_ONLY(EnterCriticalSection(&p[j].lock));
+	    if (p[j].osfhnd == (long)pout) {
+		p[j].osfhnd = (long)console;
+	    }
+	    MTHREAD_ONLY(LeaveCriticalSection(&p[j].lock));
+	}
+    }
+    CloseHandle(pout);
+    do {
+	WriteFile(console, buf, count, &count, NULL);
+    } while (ReadFile(pin, buf, sizeof(buf), &count, NULL) && count > 0);
+    CloseHandle(pin);
+    return 0;
+}
+
+static HANDLE
+output_console()
+{
+    SECURITY_ATTRIBUTES sa;
+    BOOL ret;
+    HANDLE *pfd, th, conout;
+    DWORD mode;
+
+    conout = CreateFile("CONOUT$", GENERIC_WRITE,
+			FILE_SHARE_READ|FILE_SHARE_WRITE,
+			NULL, OPEN_EXISTING, 0, NULL);
+    if (conout != INVALID_HANDLE_VALUE) {
+	CloseHandle(conout);
+	return INVALID_HANDLE_VALUE;
+    }
+    sa.nLength              = sizeof (SECURITY_ATTRIBUTES);
+    sa.lpSecurityDescriptor = NULL;
+    sa.bInheritHandle       = TRUE;
+    pfd = ALLOC_N(HANDLE, 2);
+    if (!CreatePipe(&pfd[0], &pfd[1], &sa, 2048L)) return 0;
+    if (!CreateThread(NULL, 0, new_console, (PVOID)pfd, 0, NULL)) {
+	CloseHandle(pfd[0]);
+	CloseHandle(pfd[1]);
+	return INVALID_HANDLE_VALUE;
+    }
+    return pfd[1];
+}
+
 static void
 init_stdhandle()
 {
+    HANDLE con = NULL;
+    if (_osfhnd(1) == INVALID_HANDLE_VALUE) {
+	if (!con) con = output_console();
+	if (con != INVALID_HANDLE_VALUE) _set_osfhnd(2, (long)con);
+    }
+    if (_osfhnd(2) == INVALID_HANDLE_VALUE) {
+	if (!con) con = output_console();
+	if (con != INVALID_HANDLE_VALUE) _set_osfhnd(1, (long)con);
+    }
     if (fileno(stdin) < 0) {
 	stdin->_file = 0;
