Fix typo: Should be SOCKET_ERROR, not SO_ERROR. Noticed by Daniel

2003-02-04  Tor Lillqvist  <tml@iki.fi>

	* glib/giowin32.c (g_io_channel_unix_new): Fix typo: Should be
	SOCKET_ERROR, not SO_ERROR. Noticed by Daniel Kaufmann.

	Merge from stable branch:

	Fix for bug #104014, reported by Alex Shaduri:

	* glib/gspawn-win32.c (protect_argv): New function. Add
	double-quotes around argv elements that need it, and escape
	embedded double-quotes with backslash.
	(do_spawn_with_pipes) Call protect_argv().

	* glib/gspawn-win32-helper.c (WinMain): Call protect_argv().

	* glib/gspawn.c (g_spawn_async_with_pipes): Document argument
	vector vs. command line details on Win32.
	(g_spawn_command_line_sync): Improve documentation about
	backslashes in the command line on Windows.
This commit is contained in:
Tor Lillqvist 2003-02-04 23:37:04 +00:00 committed by Tor Lillqvist
parent 305742130f
commit 5d48d565e3
10 changed files with 250 additions and 13 deletions

View File

@ -1,3 +1,24 @@
2003-02-04 Tor Lillqvist <tml@iki.fi>
* glib/giowin32.c (g_io_channel_unix_new): Fix typo: Should be
SOCKET_ERROR, not SO_ERROR. Noticed by Daniel Kaufmann.
Merge from stable branch:
Fix for bug #104014, reported by Alex Shaduri:
* glib/gspawn-win32.c (protect_argv): New function. Add
double-quotes around argv elements that need it, and escape
embedded double-quotes with backslash.
(do_spawn_with_pipes) Call protect_argv().
* glib/gspawn-win32-helper.c (WinMain): Call protect_argv().
* glib/gspawn.c (g_spawn_async_with_pipes): Document argument
vector vs. command line details on Win32.
(g_spawn_command_line_sync): Improve documentation about
backslashes in the command line on Windows.
Thu Jan 30 16:45:13 2003 Owen Taylor <otaylor@redhat.com>
* Makefile.am: Remove references to glib.spec.

View File

@ -1,3 +1,24 @@
2003-02-04 Tor Lillqvist <tml@iki.fi>
* glib/giowin32.c (g_io_channel_unix_new): Fix typo: Should be
SOCKET_ERROR, not SO_ERROR. Noticed by Daniel Kaufmann.
Merge from stable branch:
Fix for bug #104014, reported by Alex Shaduri:
* glib/gspawn-win32.c (protect_argv): New function. Add
double-quotes around argv elements that need it, and escape
embedded double-quotes with backslash.
(do_spawn_with_pipes) Call protect_argv().
* glib/gspawn-win32-helper.c (WinMain): Call protect_argv().
* glib/gspawn.c (g_spawn_async_with_pipes): Document argument
vector vs. command line details on Win32.
(g_spawn_command_line_sync): Improve documentation about
backslashes in the command line on Windows.
Thu Jan 30 16:45:13 2003 Owen Taylor <otaylor@redhat.com>
* Makefile.am: Remove references to glib.spec.

View File

@ -1,3 +1,24 @@
2003-02-04 Tor Lillqvist <tml@iki.fi>
* glib/giowin32.c (g_io_channel_unix_new): Fix typo: Should be
SOCKET_ERROR, not SO_ERROR. Noticed by Daniel Kaufmann.
Merge from stable branch:
Fix for bug #104014, reported by Alex Shaduri:
* glib/gspawn-win32.c (protect_argv): New function. Add
double-quotes around argv elements that need it, and escape
embedded double-quotes with backslash.
(do_spawn_with_pipes) Call protect_argv().
* glib/gspawn-win32-helper.c (WinMain): Call protect_argv().
* glib/gspawn.c (g_spawn_async_with_pipes): Document argument
vector vs. command line details on Win32.
(g_spawn_command_line_sync): Improve documentation about
backslashes in the command line on Windows.
Thu Jan 30 16:45:13 2003 Owen Taylor <otaylor@redhat.com>
* Makefile.am: Remove references to glib.spec.

View File

@ -1,3 +1,24 @@
2003-02-04 Tor Lillqvist <tml@iki.fi>
* glib/giowin32.c (g_io_channel_unix_new): Fix typo: Should be
SOCKET_ERROR, not SO_ERROR. Noticed by Daniel Kaufmann.
Merge from stable branch:
Fix for bug #104014, reported by Alex Shaduri:
* glib/gspawn-win32.c (protect_argv): New function. Add
double-quotes around argv elements that need it, and escape
embedded double-quotes with backslash.
(do_spawn_with_pipes) Call protect_argv().
* glib/gspawn-win32-helper.c (WinMain): Call protect_argv().
* glib/gspawn.c (g_spawn_async_with_pipes): Document argument
vector vs. command line details on Win32.
(g_spawn_command_line_sync): Improve documentation about
backslashes in the command line on Windows.
Thu Jan 30 16:45:13 2003 Owen Taylor <otaylor@redhat.com>
* Makefile.am: Remove references to glib.spec.

View File

@ -1,3 +1,24 @@
2003-02-04 Tor Lillqvist <tml@iki.fi>
* glib/giowin32.c (g_io_channel_unix_new): Fix typo: Should be
SOCKET_ERROR, not SO_ERROR. Noticed by Daniel Kaufmann.
Merge from stable branch:
Fix for bug #104014, reported by Alex Shaduri:
* glib/gspawn-win32.c (protect_argv): New function. Add
double-quotes around argv elements that need it, and escape
embedded double-quotes with backslash.
(do_spawn_with_pipes) Call protect_argv().
* glib/gspawn-win32-helper.c (WinMain): Call protect_argv().
* glib/gspawn.c (g_spawn_async_with_pipes): Document argument
vector vs. command line details on Win32.
(g_spawn_command_line_sync): Improve documentation about
backslashes in the command line on Windows.
Thu Jan 30 16:45:13 2003 Owen Taylor <otaylor@redhat.com>
* Makefile.am: Remove references to glib.spec.

View File

@ -1,3 +1,24 @@
2003-02-04 Tor Lillqvist <tml@iki.fi>
* glib/giowin32.c (g_io_channel_unix_new): Fix typo: Should be
SOCKET_ERROR, not SO_ERROR. Noticed by Daniel Kaufmann.
Merge from stable branch:
Fix for bug #104014, reported by Alex Shaduri:
* glib/gspawn-win32.c (protect_argv): New function. Add
double-quotes around argv elements that need it, and escape
embedded double-quotes with backslash.
(do_spawn_with_pipes) Call protect_argv().
* glib/gspawn-win32-helper.c (WinMain): Call protect_argv().
* glib/gspawn.c (g_spawn_async_with_pipes): Document argument
vector vs. command line details on Win32.
(g_spawn_command_line_sync): Improve documentation about
backslashes in the command line on Windows.
Thu Jan 30 16:45:13 2003 Owen Taylor <otaylor@redhat.com>
* Makefile.am: Remove references to glib.spec.

View File

@ -1494,7 +1494,7 @@ g_io_channel_unix_new (gint fd)
if (fstat (fd, &st) == 0)
return g_io_channel_win32_new_fd_internal (fd, &st);
if (getsockopt (fd, SOL_SOCKET, SO_TYPE, NULL, NULL) != SO_ERROR)
if (getsockopt (fd, SOL_SOCKET, SO_TYPE, NULL, NULL) != SOCKET_ERROR)
return g_io_channel_win32_new_socket(fd);
g_warning (G_STRLOC ": %d is neither a file descriptor or a socket", fd);

View File

@ -76,6 +76,7 @@ WinMain (struct HINSTANCE__ *hInstance,
int handle;
int no_error = CHILD_NO_ERROR;
int zero = 0;
gchar **new_argv;
SETUP_DEBUG();
@ -204,6 +205,11 @@ WinMain (struct HINSTANCE__ *hInstance,
* __argv[ARG_PROGRAM+1]... is its __argv.
*/
protect_argv (__argv, &new_argv);
/* For the program name passed to spawnv(), don't use the quoted
* version. */
if (debug)
{
debugstring = g_string_new ("");
@ -215,19 +221,19 @@ WinMain (struct HINSTANCE__ *hInstance,
(mode == P_WAIT ?
"P_WAIT" : "P_NOWAIT")));
i = ARG_PROGRAM+1;
while (__argv[i])
while (new_argv[i])
{
g_string_append (debugstring, __argv[i++]);
if (__argv[i])
g_string_append (debugstring, new_argv[i++]);
if (new_argv[i])
g_string_append (debugstring, " ");
}
MessageBox (NULL, debugstring->str, "gspawn-win32-helper", 0);
}
if (__argv[ARG_USE_PATH][0] == 'y')
handle = spawnvp (mode, __argv[ARG_PROGRAM], __argv+ARG_PROGRAM);
if (new_argv[ARG_USE_PATH][0] == 'y')
handle = spawnvp (mode, __argv[ARG_PROGRAM], new_argv+ARG_PROGRAM);
else
handle = spawnv (mode, __argv[ARG_PROGRAM], __argv+ARG_PROGRAM);
handle = spawnv (mode, __argv[ARG_PROGRAM], new_argv+ARG_PROGRAM);
if (debug)
{

View File

@ -97,6 +97,84 @@ enum {
ARG_COUNT = ARG_PROGRAM
};
static gint
protect_argv (gchar **argv,
gchar ***new_argv)
{
gint i;
gint argc = 0;
while (argv[argc])
++argc;
*new_argv = g_new (gchar *, argc+1);
/* Quote each argv element if necessary, so that it will get
* reconstructed correctly in the C runtime startup code. Note that
* the unquoting algorithm in the C runtime is really weird, and
* rather different than what Unix shells do. See stdargv.c in the C
* runtime sources (in the Platform SDK, in src/crt).
*
* Note that an new_argv[0] constructed by this function should
* *not* be passed as the filename argument to a spawn* or exec*
* family function. That argument should be the real file name
* without any quoting.
*/
for (i = 0; i < argc; i++)
{
gchar *p = argv[i];
gchar *q;
gint len = 0;
gboolean need_dblquotes = FALSE;
while (*p)
{
if (*p == ' ' || *p == '\t')
need_dblquotes = TRUE;
else if (*p == '"')
len++;
else if (*p == '\\')
{
gchar *pp = p;
while (*pp && *pp == '\\')
pp++;
if (*pp == '"')
len++;
}
len++;
p++;
}
q = (*new_argv)[i] = g_malloc (len + need_dblquotes*2 + 1);
p = argv[i];
if (need_dblquotes)
*q++ = '"';
while (*p)
{
if (*p == '"')
*q++ = '\\';
else if (*p == '\\')
{
gchar *pp = p;
while (*pp && *pp == '\\')
pp++;
if (*pp == '"')
*q++ = '\\';
}
*q++ = *p;
p++;
}
if (need_dblquotes)
*q++ = '"';
*q++ = '\0';
/* printf ("argv[%d]:%s, need_dblquotes:%s len:%d => %s\n", i, argv[i], need_dblquotes?"TRUE":"FALSE", len, (*new_argv)[i]); */
}
(*new_argv)[argc] = NULL;
return argc;
}
#ifndef GSPAWN_HELPER
static gboolean make_pipe (gint p[2],
@ -746,6 +824,9 @@ do_spawn_with_pipes (gboolean dont_wait,
gint helper = -1;
gint buf[2];
gint n_ints = 0;
gint i;
gint argc;
gchar **new_argv;
if (!make_pipe (child_err_report_pipe, error))
return FALSE;
@ -759,13 +840,15 @@ do_spawn_with_pipes (gboolean dont_wait,
if (standard_error && !make_pipe (stderr_pipe, error))
goto cleanup_and_fail;
argc = protect_argv (argv, &new_argv);
helper = do_spawn (dont_wait,
child_err_report_pipe[1],
stdin_pipe[0],
stdout_pipe[1],
stderr_pipe[1],
working_directory,
argv,
new_argv,
envp,
close_descriptors,
search_path,
@ -775,6 +858,10 @@ do_spawn_with_pipes (gboolean dont_wait,
child_setup,
user_data);
for (i = 0; i < argc; i++)
g_free (new_argv[i]);
g_free (new_argv);
/* do_spawn() returns -1 if gspawn-win32-helper couldn't be run */
if (helper == -1)
{

View File

@ -432,6 +432,24 @@ g_spawn_sync (const gchar *working_directory,
* the program must be a full path; the <envar>PATH</envar> shell variable
* will only be searched if you pass the %G_SPAWN_SEARCH_PATH flag.
*
* On Windows, the low-level child process creation API
* (<function>CreateProcess()</function>)doesn't use argument vectors,
* but a command line. The C runtime library's
* <function>spawn*()</function> family of functions (which
* g_spawn_async_with_pipes() eventually calls) paste the argument
* vector elements into a command line, and the C runtime startup code
* does a corresponding recostruction of an argument vector from the
* command line, to be passed to
* <function>main()</function>. Complications arise when you have
* argument vector elements that contain spaces of double quotes. The
* <function>spawn()</function> functions don't do any quoting or
* escaping, but on the other hand the startup code does do unquoting
* and unescaping in order to enable receiving arguments with embedded
* spaces or double quotes. To work around this asymmetry,
* g_spawn_async_with_pipes() will do quoting and escaping on argument
* vector elements that need it before calling the C runtime
* <function>spawn()</function> function.
*
* @envp is a %NULL-terminated array of strings, where each string
* has the form <literal>KEY=VALUE</literal>. This will become
* the child's environment. If @envp is %NULL, the child inherits its
@ -584,11 +602,11 @@ g_spawn_async_with_pipes (const gchar *working_directory,
*
* On Windows, please note the implications of g_shell_parse_argv()
* parsing @command_line. Space is a separator, and backslashes are
* special. Thus you cannot simply pass a @command_line consisting of
* a canonical Windows path, like "c:\\program files\\app\\app.exe",
* as the backslashes will be eaten, and the space will act as a
* separator. You need to enclose the path with single quotes, like
* "'c:\\program files\\app\\app.exe'".
* special. Thus you cannot simply pass a @command_line containing
* canonical Windows paths, like "c:\\program files\\app\\app.exe", as
* the backslashes will be eaten, and the space will act as a
* separator. You need to enclose such paths with single quotes, like
* "'c:\\program files\\app\\app.exe' 'e:\\folder\\argument.txt'".
*
* Return value: %TRUE on success, %FALSE if an error was set
**/