medit/winbuild/glib.patch

296 lines
9.2 KiB
Diff

Index: glib/gspawn.h
===================================================================
--- glib/gspawn.h (revision 6301)
+++ glib/gspawn.h (working copy)
@@ -67,6 +67,9 @@ typedef enum
G_SPAWN_STDERR_TO_DEV_NULL = 1 << 4,
G_SPAWN_CHILD_INHERITS_STDIN = 1 << 5,
G_SPAWN_FILE_AND_ARGV_ZERO = 1 << 6
+#ifdef G_OS_WIN32
+ , G_SPAWN_WIN32_HIDDEN_CONSOLE = 1 << 7
+#endif
} GSpawnFlags;
GQuark g_spawn_error_quark (void);
Index: glib/gspawn-win32.c
===================================================================
--- glib/gspawn-win32.c (revision 6301)
+++ glib/gspawn-win32.c (working copy)
@@ -95,7 +95,8 @@ enum
};
enum {
- ARG_CHILD_ERR_REPORT = 1,
+ ARG_HANDLES_IN_ARGV = 1,
+ ARG_CHILD_ERR_REPORT,
ARG_STDIN,
ARG_STDOUT,
ARG_STDERR,
@@ -334,7 +335,11 @@ read_helper_report (int fd,
}
if (bytes < sizeof(gint)*2)
- return FALSE;
+ {
+ g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+ _("Failed to read from child pipe"));
+ return FALSE;
+ }
return TRUE;
}
@@ -500,6 +505,60 @@ do_spawn_directly (gint
return TRUE;
}
+static int
+spawn_with_hidden_console (wchar_t **wargv,
+ wchar_t **wenvp,
+ GError **error)
+{
+ GArray *cmd_line;
+ STARTUPINFOW sinfo;
+ PROCESS_INFORMATION pinfo;
+ wchar_t **p;
+ int rc = -1;
+
+ cmd_line = g_array_new (FALSE, FALSE, sizeof (wchar_t));
+ for (p = wargv; *p; p++)
+ {
+ if (p > wargv)
+ g_array_append_vals (cmd_line, L" ", 1);
+ g_array_append_vals (cmd_line, *p, wcslen (*p));
+ }
+ g_array_append_vals (cmd_line, L"", 1);
+
+ memset (&sinfo, 0, sizeof sinfo);
+ sinfo.cb = sizeof (STARTUPINFO);
+ sinfo.dwFlags = STARTF_USESHOWWINDOW;
+ sinfo.wShowWindow = SW_HIDE;
+
+ if (CreateProcessW (NULL, (wchar_t*) cmd_line->data, NULL, NULL, TRUE,
+ CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
+ wenvp, NULL, &sinfo, &pinfo))
+ {
+ rc = (int) pinfo.hProcess;
+ CloseHandle (pinfo.hThread);
+ }
+ else
+ {
+ g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+ _("Failed to execute helper program (%s)"),
+ g_win32_error_message (GetLastError ()));
+ }
+
+ g_array_free (cmd_line, TRUE);
+ return rc;
+}
+
+static void
+sprintf_file_descriptor (gchar *dest,
+ gint fd,
+ gboolean print_handle)
+{
+ if (print_handle)
+ _g_sprintf (dest, "%ld", _get_osfhandle (fd));
+ else
+ _g_sprintf (dest, "%d", fd);
+}
+
static gboolean
do_spawn_with_pipes (gint *exit_status,
gboolean do_return_handle,
@@ -534,7 +593,9 @@ do_spawn_with_pipes (gint
gchar *helper_process;
CONSOLE_CURSOR_INFO cursor_info;
wchar_t *whelper, **wargv, **wenvp;
-
+ gboolean error_set = FALSE;
+ gboolean handles_in_argv = FALSE;
+
SETUP_DEBUG();
if (child_setup && !warned_about_child_setup)
@@ -546,6 +607,7 @@ do_spawn_with_pipes (gint
argc = protect_argv (argv, &protected_argv);
if (!standard_input && !standard_output && !standard_error &&
+ !(flags & G_SPAWN_WIN32_HIDDEN_CONSOLE) &&
(flags & G_SPAWN_CHILD_INHERITS_STDIN) &&
!(flags & G_SPAWN_STDOUT_TO_DEV_NULL) &&
!(flags & G_SPAWN_STDERR_TO_DEV_NULL) &&
@@ -575,12 +637,21 @@ do_spawn_with_pipes (gint
goto cleanup_and_fail;
new_argv = g_new (char *, argc + 1 + ARG_COUNT);
- if (GetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cursor_info))
+ if ((flags & G_SPAWN_WIN32_HIDDEN_CONSOLE) ||
+ GetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cursor_info))
helper_process = HELPER_PROCESS "-console.exe";
else
helper_process = HELPER_PROCESS ".exe";
new_argv[0] = helper_process;
- _g_sprintf (args[ARG_CHILD_ERR_REPORT], "%d", child_err_report_pipe[1]);
+
+ if (flags & G_SPAWN_WIN32_HIDDEN_CONSOLE)
+ handles_in_argv = TRUE;
+
+ strcpy (args[ARG_HANDLES_IN_ARGV], handles_in_argv ? "y" : "n");
+ new_argv[ARG_HANDLES_IN_ARGV] = args[ARG_HANDLES_IN_ARGV];
+
+ sprintf_file_descriptor (args[ARG_CHILD_ERR_REPORT],
+ child_err_report_pipe[1], handles_in_argv);
new_argv[ARG_CHILD_ERR_REPORT] = args[ARG_CHILD_ERR_REPORT];
if (flags & G_SPAWN_FILE_AND_ARGV_ZERO)
@@ -593,7 +664,7 @@ do_spawn_with_pipes (gint
if (standard_input)
{
- _g_sprintf (args[ARG_STDIN], "%d", stdin_pipe[0]);
+ sprintf_file_descriptor (args[ARG_STDIN], stdin_pipe[0], handles_in_argv);
new_argv[ARG_STDIN] = args[ARG_STDIN];
}
else if (flags & G_SPAWN_CHILD_INHERITS_STDIN)
@@ -609,7 +680,7 @@ do_spawn_with_pipes (gint
if (standard_output)
{
- _g_sprintf (args[ARG_STDOUT], "%d", stdout_pipe[1]);
+ sprintf_file_descriptor (args[ARG_STDOUT], stdout_pipe[1], handles_in_argv);
new_argv[ARG_STDOUT] = args[ARG_STDOUT];
}
else if (flags & G_SPAWN_STDOUT_TO_DEV_NULL)
@@ -623,7 +694,7 @@ do_spawn_with_pipes (gint
if (standard_error)
{
- _g_sprintf (args[ARG_STDERR], "%d", stderr_pipe[1]);
+ sprintf_file_descriptor (args[ARG_STDERR], stderr_pipe[1], handles_in_argv);
new_argv[ARG_STDERR] = args[ARG_STDERR];
}
else if (flags & G_SPAWN_STDERR_TO_DEV_NULL)
@@ -704,7 +775,13 @@ do_spawn_with_pipes (gint
if (child_setup)
(* child_setup) (user_data);
- if (wenvp != NULL)
+ if (flags & G_SPAWN_WIN32_HIDDEN_CONSOLE)
+ {
+ rc = spawn_with_hidden_console (wargv, wenvp, error);
+ if (rc == -1)
+ error_set = TRUE;
+ }
+ else if (wenvp != NULL)
/* Let's hope envp hasn't mucked with PATH so that
* gspawn-win32-helper.exe isn't found.
*/
@@ -732,11 +809,12 @@ do_spawn_with_pipes (gint
g_free (new_argv);
/* Check if gspawn-win32-helper couldn't be run */
- if (rc == -1 && saved_errno != 0)
+ if (rc == -1 && (saved_errno != 0 || error_set))
{
- g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
- _("Failed to execute helper program (%s)"),
- g_strerror (saved_errno));
+ if (!error_set)
+ g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+ _("Failed to execute helper program (%s)"),
+ g_strerror (saved_errno));
goto cleanup_and_fail;
}
Index: glib/gspawn-win32-helper.c
===================================================================
--- glib/gspawn-win32-helper.c (revision 6301)
+++ glib/gspawn-win32-helper.c (working copy)
@@ -145,6 +145,16 @@ protect_wargv (wchar_t **wargv,
return argc;
}
+static int
+get_file_descriptor (const gchar *arg,
+ gboolean is_handle)
+{
+ if (is_handle)
+ return _open_osfhandle (atoi (arg), 0);
+ else
+ return atoi (arg);
+}
+
int _stdcall
WinMain (struct HINSTANCE__ *hInstance,
struct HINSTANCE__ *hPrevInstance,
@@ -163,6 +173,7 @@ WinMain (struct HINSTANCE__ *hInstance,
wchar_t **new_wargv;
int argc;
wchar_t **wargv, **wenvp;
+ gboolean handles_in_argv;
_startupinfo si = { 0 };
g_assert (__argc >= ARG_COUNT);
@@ -176,10 +187,17 @@ WinMain (struct HINSTANCE__ *hInstance,
*/
g_assert (argc == __argc);
- /* argv[ARG_CHILD_ERR_REPORT] is the file descriptor number onto
+ /* argv[ARG_HANDLES_IN_ARGV] is "y" or "n" telling whether
+ * file handle arguments contain HANDLE's or file descriptors.
+ */
+ handles_in_argv = __argv[ARG_HANDLES_IN_ARGV][0] == 'y';
+
+ /* argv[ARG_CHILD_ERR_REPORT] is the pipe handle onto
* which write error messages.
*/
- child_err_report_fd = atoi (__argv[ARG_CHILD_ERR_REPORT]);
+ child_err_report_fd = get_file_descriptor (__argv[ARG_CHILD_ERR_REPORT], handles_in_argv);
+ if (child_err_report_fd < 0)
+ g_error ("child_err_report_fd not set");
/* Hack to implement G_SPAWN_FILE_AND_ARGV_ZERO. If
* argv[ARG_CHILD_ERR_REPORT] is suffixed with a '#' it means we get
@@ -188,7 +206,7 @@ WinMain (struct HINSTANCE__ *hInstance,
if (__argv[ARG_CHILD_ERR_REPORT][strlen (__argv[ARG_CHILD_ERR_REPORT]) - 1] == '#')
argv_zero_offset++;
- /* argv[ARG_STDIN..ARG_STDERR] are the file descriptor numbers that
+ /* argv[ARG_STDIN..ARG_STDERR] are the pipe handles that
* should be dup2'd to 0, 1 and 2. '-' if the corresponding fd
* should be left alone, and 'z' if it should be connected to the
* bit bucket NUL:.
@@ -206,7 +224,9 @@ WinMain (struct HINSTANCE__ *hInstance,
}
else
{
- fd = atoi (__argv[ARG_STDIN]);
+ fd = get_file_descriptor (__argv[ARG_STDIN], handles_in_argv);
+ if (fd < 0)
+ g_error ("could not open stdin pipe");
if (fd != 0)
{
dup2 (fd, 0);
@@ -227,7 +247,9 @@ WinMain (struct HINSTANCE__ *hInstance,
}
else
{
- fd = atoi (__argv[ARG_STDOUT]);
+ fd = get_file_descriptor (__argv[ARG_STDOUT], handles_in_argv);
+ if (fd < 0)
+ g_error ("could not open stdout pipe");
if (fd != 1)
{
dup2 (fd, 1);
@@ -248,7 +270,9 @@ WinMain (struct HINSTANCE__ *hInstance,
}
else
{
- fd = atoi (__argv[ARG_STDERR]);
+ fd = get_file_descriptor (__argv[ARG_STDERR], handles_in_argv);
+ if (fd < 0)
+ g_error ("could not open stderr pipe");
if (fd != 2)
{
dup2 (fd, 2);