This is the mail archive of the
cygwin
mailing list for the Cygwin project.
[RFA] patch for run.exe -- ATTN: ago
- From: Charles Wilson <cygwin at cwilson dot fastmail dot fm>
- To: cygwin at cygwin dot com
- Date: Thu, 18 May 2006 02:45:23 -0400
- Subject: [RFA] patch for run.exe -- ATTN: ago
As detailed here:
http://cygwin.com/ml/cygwin/2006-05/msg00471.html
run.exe currently launches clients without any stdio handles and without
any console at all. That's over-ambitious: what run REALLY should do is
launch the client with a *hidden* console and *working* stdio handles.
Run is a console-hider, not a daemonizer -- and some apps (like, err,
rxvt-unicode), even tho they are GUIs, don't behave well when launched
without working stdio (even if those handles point to an invisible
console, and really shouldn't be used by the app anyway!)
The attached patch adapts code from cygwin's fhandler_init, using
NT/2K/XP-only APIs to enable AllocConsole() to initialize the stdio
handles *without* that console ever becoming visible, not even for a
brief flash. Because these APIs are only available on some of the
supported OSes, I use LoadLibrary/GetProcAddress and function pointers,
so that on the older OSes the behavior should be unchanged from 1.1.9-1.
With this patch, rxvt-unicode-X is happy and no longer sucks 100% CPU
when launched by run.exe with loginShell=true, as is the case with
run-1.1.9-1. (At least, on NT/2K/XP. On 95/98/Me, I expect
rxvt-unicode-X will be just as unhappy with this patch as without. Half
loaves and baby steps...)
--
Chuck
diff -urN -x .build -x .inst -x .sinst -x .buildlogs run-1.1.9-orig/src/run.c run-1.1.9/src/run.c
--- run-1.1.9-orig/src/run.c 2006-04-06 14:10:55.000000000 -0400
+++ run-1.1.9/src/run.c 2006-05-18 01:50:43.859375000 -0400
@@ -32,6 +32,7 @@
#define WIN32
#include <windows.h>
+#include <winuser.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
@@ -193,6 +194,67 @@
free(var);
}
}
+BOOL setup_invisible_console()
+{
+ HWINSTA h, horig;
+ USEROBJECTFLAGS oi;
+ DWORD len;
+ BOOL b = FALSE;
+ HMODULE lib = NULL;
+ HWINSTA WINAPI (*GetProcessWindowStationFP)(void) = NULL;
+ BOOL WINAPI (*GetUserObjectInformationFP)(HANDLE, int, PVOID, DWORD, PDWORD) = NULL;
+ HWINSTA WINAPI (*CreateWindowStationFP)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES) = NULL;
+ BOOL WINAPI (*SetProcessWindowStationFP)(HWINSTA) = NULL;
+ BOOL WINAPI (*CloseWindowStationFP)(HWINSTA) = NULL;
+
+ /* First, set up function pointers */
+ if (lib = LoadLibrary ("user32.dll"))
+ {
+ GetProcessWindowStationFP = (HWINSTA WINAPI (*)(void))
+ GetProcAddress (lib, "GetProcessWindowStation");
+ GetUserObjectInformationFP = (BOOL WINAPI (*)(HANDLE, int, PVOID, DWORD, PDWORD))
+ GetProcAddress (lib, "GetUserObjectInformationW"); /* ugly! */
+ CreateWindowStationFP = (HWINSTA WINAPI (*)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES))
+ GetProcAddress (lib, "CreateWindowStationW"); /* ugly */
+ SetProcessWindowStationFP = (BOOL WINAPI (*)(HWINSTA))
+ GetProcAddress (lib, "SetProcessWindowStation");
+ CloseWindowStationFP = (BOOL WINAPI (*)(HWINSTA))
+ GetProcAddress (lib, "CloseWindowStation");
+
+ if (GetProcessWindowStationFP &&
+ GetUserObjectInformationFP &&
+ CreateWindowStationFP &&
+ SetProcessWindowStationFP &&
+ CloseWindowStationFP)
+ {
+ /* Then, do the work */
+ FreeConsole();
+ h = horig = (*GetProcessWindowStationFP)();
+ if (!horig
+ || !(*GetUserObjectInformationFP) (horig, UOI_FLAGS, &oi, sizeof (oi), &len )
+ || !(oi.dwFlags & WSF_VISIBLE))
+ {
+ b = AllocConsole();
+ }
+ else
+ {
+ h = (*CreateWindowStationFP) (NULL, 0, STANDARD_RIGHTS_READ, NULL);
+ if (h)
+ {
+ b = (*SetProcessWindowStationFP) (h);
+ }
+ b = AllocConsole();
+ if (horig && h && h != horig && (*SetProcessWindowStationFP) (horig))
+ {
+ (*CloseWindowStationFP) (h);
+ }
+ }
+ return b;
+ }
+ }
+ /* otherwise, fail */
+ return FALSE;
+}
int start_child(char* cmdline, int wait_for_child)
{
@@ -204,6 +266,8 @@
setup_win_environ();
+ setup_invisible_console();
+
memset (&start, 0, sizeof (start));
start.cb = sizeof (start);
start.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/