2000-11-28 20:04:08 +00:00
|
|
|
/* gspawn-win32.c - Process launching on Win32
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
*
|
|
|
|
* Copyright 2000 Red Hat, Inc.
|
2003-07-31 01:25:19 +00:00
|
|
|
* Copyright 2003 Tor Lillqvist
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
*
|
|
|
|
* GLib is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* GLib is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with GLib; see the file COPYING.LIB. If not, write
|
|
|
|
* to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Implementation details on Win32.
|
|
|
|
*
|
|
|
|
* - There is no way to set the no-inherit flag for
|
|
|
|
* a "file descriptor" in the MS C runtime. The flag is there,
|
|
|
|
* and the dospawn() function uses it, but unfortunately
|
|
|
|
* this flag can only be set when opening the file.
|
|
|
|
* - As there is no fork(), we cannot reliably change directory
|
|
|
|
* before starting the child process. (There might be several threads
|
|
|
|
* running, and the current directory is common for all threads.)
|
|
|
|
*
|
|
|
|
* Thus, we must in most cases use a helper program to handle closing
|
2003-07-31 01:25:19 +00:00
|
|
|
* of (inherited) file descriptors and changing of directory. The
|
|
|
|
* helper process is also needed if the standard input, standard
|
|
|
|
* output, or standard error of the process to be run are supposed to
|
|
|
|
* be redirected somewhere.
|
|
|
|
*
|
|
|
|
* The structure of the source code in this file is a mess, I know.
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* Define this to get some logging all the time */
|
2001-09-17 00:41:39 +00:00
|
|
|
/* #define G_SPAWN_WIN32_DEBUG */
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2002-02-19 09:08:24 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
#include "glib.h"
|
2002-11-21 00:35:15 +00:00
|
|
|
#include "gprintfint.h"
|
2005-03-14 04:26:57 +00:00
|
|
|
#include "galias.h"
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
2000-10-19 17:52:12 +00:00
|
|
|
#include <stdio.h>
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <io.h>
|
|
|
|
#include <process.h>
|
2000-10-19 17:52:12 +00:00
|
|
|
#include <direct.h>
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2005-08-25 23:28:24 +00:00
|
|
|
#ifdef __MINGW32__
|
|
|
|
/* Mingw doesn't have prototypes for these */
|
|
|
|
int _wspawnvpe (int, const wchar_t *, const wchar_t **, const wchar_t **);
|
|
|
|
int _wspawnvp (int, const wchar_t *, const wchar_t **);
|
|
|
|
int _wspawnve (int, const wchar_t *, const wchar_t **, const wchar_t **);
|
|
|
|
int _wspawnv (int, const wchar_t *, const wchar_t **);
|
|
|
|
#endif
|
|
|
|
|
2001-01-16 02:24:24 +00:00
|
|
|
#include "glibintl.h"
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
|
|
|
#ifdef G_SPAWN_WIN32_DEBUG
|
|
|
|
static int debug = 1;
|
|
|
|
#define SETUP_DEBUG() /* empty */
|
|
|
|
#else
|
|
|
|
static int debug = -1;
|
|
|
|
#define SETUP_DEBUG() \
|
|
|
|
G_STMT_START \
|
|
|
|
{ \
|
|
|
|
if (debug == -1) \
|
2001-03-18 19:54:01 +00:00
|
|
|
{ \
|
|
|
|
if (getenv ("G_SPAWN_WIN32_DEBUG") != NULL) \
|
|
|
|
debug = 1; \
|
|
|
|
else \
|
|
|
|
debug = 0; \
|
|
|
|
} \
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
} \
|
|
|
|
G_STMT_END
|
|
|
|
#endif
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
CHILD_NO_ERROR,
|
|
|
|
CHILD_CHDIR_FAILED,
|
|
|
|
CHILD_SPAWN_FAILED,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
ARG_CHILD_ERR_REPORT = 1,
|
|
|
|
ARG_STDIN,
|
|
|
|
ARG_STDOUT,
|
|
|
|
ARG_STDERR,
|
|
|
|
ARG_WORKING_DIRECTORY,
|
|
|
|
ARG_CLOSE_DESCRIPTORS,
|
|
|
|
ARG_USE_PATH,
|
|
|
|
ARG_WAIT,
|
|
|
|
ARG_PROGRAM,
|
|
|
|
ARG_COUNT = ARG_PROGRAM
|
|
|
|
};
|
|
|
|
|
2005-08-26 01:43:11 +00:00
|
|
|
static gchar *
|
|
|
|
protect_argv_string (const gchar *string)
|
|
|
|
{
|
|
|
|
const gchar *p = string;
|
|
|
|
gchar *retval, *q;
|
|
|
|
gint len = 0;
|
|
|
|
gboolean need_dblquotes = FALSE;
|
|
|
|
while (*p)
|
|
|
|
{
|
|
|
|
if (*p == ' ' || *p == '\t')
|
|
|
|
need_dblquotes = TRUE;
|
|
|
|
else if (*p == '"')
|
|
|
|
len++;
|
|
|
|
else if (*p == '\\')
|
|
|
|
{
|
|
|
|
const gchar *pp = p;
|
|
|
|
while (*pp && *pp == '\\')
|
|
|
|
pp++;
|
|
|
|
if (*pp == '"')
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
len++;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
q = retval = g_malloc (len + need_dblquotes*2 + 1);
|
|
|
|
p = string;
|
|
|
|
|
|
|
|
if (need_dblquotes)
|
|
|
|
*q++ = '"';
|
|
|
|
|
|
|
|
while (*p)
|
|
|
|
{
|
|
|
|
if (*p == '"')
|
|
|
|
*q++ = '\\';
|
|
|
|
else if (*p == '\\')
|
|
|
|
{
|
|
|
|
const gchar *pp = p;
|
|
|
|
while (*pp && *pp == '\\')
|
|
|
|
pp++;
|
|
|
|
if (*pp == '"')
|
|
|
|
*q++ = '\\';
|
|
|
|
}
|
|
|
|
*q++ = *p;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (need_dblquotes)
|
|
|
|
*q++ = '"';
|
|
|
|
*q++ = '\0';
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2003-02-04 23:37:04 +00:00
|
|
|
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++)
|
2005-08-26 01:43:11 +00:00
|
|
|
(*new_argv)[i] = protect_argv_string (argv[i]);
|
2003-02-04 23:37:04 +00:00
|
|
|
|
|
|
|
(*new_argv)[argc] = NULL;
|
|
|
|
|
|
|
|
return argc;
|
|
|
|
}
|
|
|
|
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
#ifndef GSPAWN_HELPER
|
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
#define HELPER_PROCESS "gspawn-win32-helper"
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
|
|
|
GQuark
|
|
|
|
g_spawn_error_quark (void)
|
|
|
|
{
|
|
|
|
static GQuark quark = 0;
|
|
|
|
if (quark == 0)
|
|
|
|
quark = g_quark_from_static_string ("g-exec-error-quark");
|
|
|
|
return quark;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2005-08-25 23:28:24 +00:00
|
|
|
g_spawn_async_utf8 (const gchar *working_directory,
|
|
|
|
gchar **argv,
|
|
|
|
gchar **envp,
|
|
|
|
GSpawnFlags flags,
|
|
|
|
GSpawnChildSetupFunc child_setup,
|
|
|
|
gpointer user_data,
|
|
|
|
GPid *child_handle,
|
|
|
|
GError **error)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (argv != NULL, FALSE);
|
|
|
|
|
2005-08-25 23:28:24 +00:00
|
|
|
return g_spawn_async_with_pipes_utf8 (working_directory,
|
|
|
|
argv, envp,
|
|
|
|
flags,
|
|
|
|
child_setup,
|
|
|
|
user_data,
|
|
|
|
child_handle,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
error);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Avoids a danger in threaded situations (calling close()
|
|
|
|
* on a file descriptor twice, and another thread has
|
|
|
|
* re-opened it since the first close)
|
|
|
|
*/
|
2004-12-11 03:47:32 +00:00
|
|
|
static void
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
close_and_invalidate (gint *fd)
|
|
|
|
{
|
Ignore the G_SPAWN_DO_NOT_REAP_CHILD flag, can't be meaninfully
2002-11-17 Tor Lillqvist <tml@iki.fi>
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
G_SPAWN_DO_NOT_REAP_CHILD flag, can't be meaninfully implemented
on Windows, at least not now. Always pass dont_wait as TRUE to
do_spawn_with_pipes(). The semantics of the dont_wait parameter is
very different from the semantics of the intermediate_child
parameter to fork_exec_with_pipes() in the Unix version. This
fixes a serious bug, g_spawn_async() in fact behaved
synchronously.
(do_spawn_with_pipes, do_spawn): Rename from
fork_exec_with_pipes() and do_exec(), those names were from the
Unix bersion, and misleading.
(close_and_invalidate): Don't try to close invalid fds.
* glib/gspawn.c (g_spawn_async_with_pipes): Add warning about
Windows behaviour. There is no fork(), so the child_setup()
function is in fact called in the parent.
* glib/gspawn-win32-helper.c (WinMain): Insert spaces in argv
debugging output.
* tests/spawn-test-win32-gui.c: New file. Test program to be
linked as a GUI application. Behaves differently depending on how
invoked (by spawn-test).
* tests/spawn-test.c (run_tests): On Win32, run the
spawn-test-win32-gui program, too, in several ways, synchronously
and asynchronously.
* tests/Makefile.am: Corresponding change.
2002-11-17 03:52:55 +00:00
|
|
|
if (*fd < 0)
|
2004-12-11 03:47:32 +00:00
|
|
|
return;
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
close (*fd);
|
|
|
|
*fd = -1;
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
READ_FAILED = 0, /* FALSE */
|
|
|
|
READ_OK,
|
|
|
|
READ_EOF
|
|
|
|
} ReadResult;
|
|
|
|
|
|
|
|
static ReadResult
|
|
|
|
read_data (GString *str,
|
|
|
|
GIOChannel *iochannel,
|
|
|
|
GError **error)
|
|
|
|
{
|
2002-02-19 09:08:24 +00:00
|
|
|
GIOStatus giostatus;
|
Ignore the G_SPAWN_DO_NOT_REAP_CHILD flag, can't be meaninfully
2002-11-17 Tor Lillqvist <tml@iki.fi>
* glib/gspawn-win32.c (g_spawn_async_with_pipes): Ignore the
G_SPAWN_DO_NOT_REAP_CHILD flag, can't be meaninfully implemented
on Windows, at least not now. Always pass dont_wait as TRUE to
do_spawn_with_pipes(). The semantics of the dont_wait parameter is
very different from the semantics of the intermediate_child
parameter to fork_exec_with_pipes() in the Unix version. This
fixes a serious bug, g_spawn_async() in fact behaved
synchronously.
(do_spawn_with_pipes, do_spawn): Rename from
fork_exec_with_pipes() and do_exec(), those names were from the
Unix bersion, and misleading.
(close_and_invalidate): Don't try to close invalid fds.
* glib/gspawn.c (g_spawn_async_with_pipes): Add warning about
Windows behaviour. There is no fork(), so the child_setup()
function is in fact called in the parent.
* glib/gspawn-win32-helper.c (WinMain): Insert spaces in argv
debugging output.
* tests/spawn-test-win32-gui.c: New file. Test program to be
linked as a GUI application. Behaves differently depending on how
invoked (by spawn-test).
* tests/spawn-test.c (run_tests): On Win32, run the
spawn-test-win32-gui program, too, in several ways, synchronously
and asynchronously.
* tests/Makefile.am: Corresponding change.
2002-11-17 03:52:55 +00:00
|
|
|
gssize bytes;
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
gchar buf[4096];
|
|
|
|
|
|
|
|
again:
|
|
|
|
|
2002-02-19 09:08:24 +00:00
|
|
|
giostatus = g_io_channel_read_chars (iochannel, buf, sizeof (buf), &bytes, NULL);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
|
|
|
if (bytes == 0)
|
|
|
|
return READ_EOF;
|
|
|
|
else if (bytes > 0)
|
|
|
|
{
|
|
|
|
g_string_append_len (str, buf, bytes);
|
|
|
|
return READ_OK;
|
|
|
|
}
|
2002-02-19 09:08:24 +00:00
|
|
|
else if (giostatus == G_IO_STATUS_AGAIN)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
goto again;
|
2002-02-19 09:08:24 +00:00
|
|
|
else if (giostatus == G_IO_STATUS_ERROR)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2005-08-26 01:43:11 +00:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_READ,
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
_("Failed to read data from child process"));
|
|
|
|
|
|
|
|
return READ_FAILED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return READ_OK;
|
|
|
|
}
|
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
static gboolean
|
|
|
|
make_pipe (gint p[2],
|
|
|
|
GError **error)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
if (pipe (p) < 0)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2005-08-26 01:43:11 +00:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
2004-12-11 03:47:32 +00:00
|
|
|
_("Failed to create pipe for communicating with child process (%s)"),
|
|
|
|
g_strerror (errno));
|
|
|
|
return FALSE;
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
else
|
|
|
|
return TRUE;
|
|
|
|
}
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
/* The helper process writes a status report back to us, through a
|
|
|
|
* pipe, consisting of two ints.
|
|
|
|
*/
|
|
|
|
static gboolean
|
|
|
|
read_helper_report (int fd,
|
|
|
|
gint report[2],
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gint bytes = 0;
|
|
|
|
|
|
|
|
while (bytes < sizeof(gint)*2)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
gint chunk;
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
|
|
|
if (debug)
|
2004-12-11 03:47:32 +00:00
|
|
|
g_print ("%s:read_helper_report: read %d...\n",
|
|
|
|
__FILE__,
|
|
|
|
sizeof(gint)*2 - bytes);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
chunk = read (fd, ((gchar*)report) + bytes,
|
|
|
|
sizeof(gint)*2 - bytes);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
if (debug)
|
|
|
|
g_print ("...got %d bytes\n", chunk);
|
|
|
|
|
|
|
|
if (chunk < 0)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
/* Some weird shit happened, bail out */
|
|
|
|
|
2005-08-26 01:43:11 +00:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
2004-12-11 03:47:32 +00:00
|
|
|
_("Failed to read from child pipe (%s)"),
|
|
|
|
g_strerror (errno));
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
return FALSE;
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
else if (chunk == 0)
|
|
|
|
break; /* EOF */
|
|
|
|
else
|
|
|
|
bytes += chunk;
|
|
|
|
}
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
if (bytes < sizeof(gint)*2)
|
|
|
|
return FALSE;
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
set_child_error (gint report[2],
|
|
|
|
const gchar *working_directory,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
switch (report[0])
|
|
|
|
{
|
|
|
|
case CHILD_CHDIR_FAILED:
|
2005-08-26 01:43:11 +00:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR,
|
2004-12-11 03:47:32 +00:00
|
|
|
_("Failed to change to directory '%s' (%s)"),
|
|
|
|
working_directory,
|
|
|
|
g_strerror (report[1]));
|
|
|
|
break;
|
|
|
|
case CHILD_SPAWN_FAILED:
|
2005-08-26 01:43:11 +00:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
2004-12-11 03:47:32 +00:00
|
|
|
_("Failed to execute child process (%s)"),
|
|
|
|
g_strerror (report[1]));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
}
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2005-08-26 01:43:11 +00:00
|
|
|
static gboolean
|
|
|
|
utf8_charv_to_wcharv (char **utf8_charv,
|
|
|
|
wchar_t ***wcharv,
|
|
|
|
int *error_index,
|
|
|
|
GError **error)
|
2005-08-25 23:28:24 +00:00
|
|
|
{
|
|
|
|
wchar_t **retval = NULL;
|
|
|
|
|
2005-08-26 01:43:11 +00:00
|
|
|
*wcharv = NULL;
|
2005-08-25 23:28:24 +00:00
|
|
|
if (utf8_charv != NULL)
|
|
|
|
{
|
|
|
|
int n = 0, i;
|
|
|
|
|
|
|
|
while (utf8_charv[n])
|
|
|
|
n++;
|
|
|
|
retval = g_new (wchar_t *, n + 1);
|
|
|
|
|
|
|
|
for (i = 0; i < n; i++)
|
2005-08-26 01:43:11 +00:00
|
|
|
{
|
|
|
|
retval[i] = g_utf8_to_utf16 (utf8_charv[i], -1, NULL, NULL, error);
|
|
|
|
if (retval[i] == NULL)
|
|
|
|
{
|
|
|
|
if (error_index)
|
|
|
|
*error_index = i;
|
|
|
|
while (i)
|
|
|
|
g_free (retval[--i]);
|
|
|
|
g_free (retval);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-08-25 23:28:24 +00:00
|
|
|
retval[n] = NULL;
|
|
|
|
}
|
2005-08-26 01:43:11 +00:00
|
|
|
*wcharv = retval;
|
|
|
|
return TRUE;
|
2005-08-25 23:28:24 +00:00
|
|
|
}
|
|
|
|
|
2005-08-26 01:43:11 +00:00
|
|
|
static gboolean
|
|
|
|
utf8_charv_to_cp_charv (char **utf8_charv,
|
|
|
|
gchar ***cp_charv,
|
|
|
|
int *error_index,
|
|
|
|
GError **error)
|
2005-08-25 23:28:24 +00:00
|
|
|
{
|
|
|
|
char **retval = NULL;
|
|
|
|
|
2005-08-26 01:43:11 +00:00
|
|
|
*cp_charv = NULL;
|
2005-08-25 23:28:24 +00:00
|
|
|
if (utf8_charv != NULL)
|
|
|
|
{
|
|
|
|
int n = 0, i;
|
|
|
|
|
|
|
|
while (utf8_charv[n])
|
|
|
|
n++;
|
|
|
|
retval = g_new (char *, n + 1);
|
|
|
|
|
|
|
|
for (i = 0; i < n; i++)
|
2005-08-26 01:43:11 +00:00
|
|
|
{
|
|
|
|
retval[i] = g_locale_from_utf8 (utf8_charv[i], -1, NULL, NULL, error);
|
|
|
|
if (retval[i] == NULL)
|
|
|
|
{
|
|
|
|
if (error_index)
|
|
|
|
*error_index = i;
|
|
|
|
while (i)
|
|
|
|
g_free (retval[--i]);
|
|
|
|
g_free (retval);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2005-08-25 23:28:24 +00:00
|
|
|
retval[n] = NULL;
|
|
|
|
}
|
2005-08-26 01:43:11 +00:00
|
|
|
|
|
|
|
*cp_charv = retval;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2005-09-07 10:10:49 +00:00
|
|
|
do_spawn_directly (gint *exit_status,
|
|
|
|
gboolean do_return_handle,
|
2005-08-26 01:43:11 +00:00
|
|
|
GSpawnFlags flags,
|
|
|
|
gchar **argv,
|
|
|
|
char **envp,
|
|
|
|
char **protected_argv,
|
|
|
|
GSpawnChildSetupFunc child_setup,
|
|
|
|
gpointer user_data,
|
|
|
|
GPid *child_handle,
|
|
|
|
GError **error)
|
|
|
|
{
|
2005-09-07 10:10:49 +00:00
|
|
|
const int mode = (exit_status == NULL) ? P_NOWAIT : P_WAIT;
|
2005-08-26 01:43:11 +00:00
|
|
|
char **new_argv;
|
|
|
|
int rc = -1;
|
|
|
|
int saved_errno;
|
|
|
|
GError *conv_error = NULL;
|
|
|
|
gint conv_error_index;
|
|
|
|
|
|
|
|
new_argv = (flags & G_SPAWN_FILE_AND_ARGV_ZERO) ? protected_argv + 1 : protected_argv;
|
|
|
|
if (G_WIN32_HAVE_WIDECHAR_API ())
|
|
|
|
{
|
|
|
|
wchar_t *wargv0, **wargv, **wenvp;
|
|
|
|
|
|
|
|
wargv0 = g_utf8_to_utf16 (argv[0], -1, NULL, NULL, &conv_error);
|
|
|
|
if (wargv0 == NULL)
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Invalid program name: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!utf8_charv_to_wcharv (new_argv, &wargv, &conv_error_index, &conv_error))
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Invalid string in argument vector at %d: %s"),
|
|
|
|
conv_error_index, conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
g_free (wargv0);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!utf8_charv_to_wcharv (envp, &wenvp, NULL, &conv_error))
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Invalid string in environment: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
g_free (wargv0);
|
|
|
|
g_strfreev ((gchar **) wargv);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child_setup)
|
|
|
|
(* child_setup) (user_data);
|
|
|
|
|
|
|
|
if (flags & G_SPAWN_SEARCH_PATH)
|
|
|
|
if (wenvp != NULL)
|
|
|
|
rc = _wspawnvpe (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp);
|
|
|
|
else
|
|
|
|
rc = _wspawnvp (mode, wargv0, (const wchar_t **) wargv);
|
|
|
|
else
|
|
|
|
if (wenvp != NULL)
|
|
|
|
rc = _wspawnve (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp);
|
|
|
|
else
|
|
|
|
rc = _wspawnv (mode, wargv0, (const wchar_t **) wargv);
|
|
|
|
|
|
|
|
g_free (wargv0);
|
|
|
|
g_strfreev ((gchar **) wargv);
|
|
|
|
g_strfreev ((gchar **) wenvp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char *cpargv0, **cpargv, **cpenvp;
|
|
|
|
|
|
|
|
cpargv0 = g_locale_from_utf8 (argv[0], -1, NULL, NULL, &conv_error);
|
|
|
|
if (cpargv0 == NULL)
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Invalid program name: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!utf8_charv_to_cp_charv (new_argv, &cpargv, &conv_error_index, &conv_error))
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Invalid string in argument vector at %d: %s"),
|
|
|
|
conv_error_index, conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
g_free (cpargv0);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!utf8_charv_to_cp_charv (envp, &cpenvp, NULL, &conv_error))
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Invalid string in environment: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
g_free (cpargv0);
|
|
|
|
g_strfreev (cpargv);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child_setup)
|
|
|
|
(* child_setup) (user_data);
|
|
|
|
|
|
|
|
if (flags & G_SPAWN_SEARCH_PATH)
|
|
|
|
if (cpenvp != NULL)
|
|
|
|
rc = spawnvpe (mode, cpargv0, (const char **) cpargv, (const char **) cpenvp);
|
|
|
|
else
|
|
|
|
rc = spawnvp (mode, cpargv0, (const char **) cpargv);
|
|
|
|
else
|
|
|
|
if (envp != NULL)
|
|
|
|
rc = spawnve (mode, cpargv0, (const char **) cpargv, (const char **) cpenvp);
|
|
|
|
else
|
|
|
|
rc = spawnv (mode, cpargv0, (const char **) cpargv);
|
|
|
|
|
|
|
|
g_free (cpargv0);
|
|
|
|
g_strfreev (cpargv);
|
|
|
|
g_strfreev (cpenvp);
|
|
|
|
}
|
|
|
|
|
|
|
|
saved_errno = errno;
|
|
|
|
|
|
|
|
if (rc == -1 && saved_errno != 0)
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Failed to execute child process (%s)"),
|
|
|
|
g_strerror (saved_errno));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-09-07 10:10:49 +00:00
|
|
|
if (exit_status == NULL)
|
2005-08-26 01:43:11 +00:00
|
|
|
{
|
2005-09-07 10:10:49 +00:00
|
|
|
if (child_handle && do_return_handle)
|
2005-08-26 01:43:11 +00:00
|
|
|
*child_handle = (GPid) rc;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CloseHandle ((HANDLE) rc);
|
|
|
|
if (child_handle)
|
|
|
|
*child_handle = 0;
|
|
|
|
}
|
|
|
|
}
|
2005-09-07 10:10:49 +00:00
|
|
|
else
|
2005-08-26 01:43:11 +00:00
|
|
|
*exit_status = rc;
|
|
|
|
|
|
|
|
return TRUE;
|
2005-08-25 23:28:24 +00:00
|
|
|
}
|
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
static gboolean
|
2005-09-07 10:10:49 +00:00
|
|
|
do_spawn_with_pipes (gint *exit_status,
|
|
|
|
gboolean do_return_handle,
|
2004-12-11 03:47:32 +00:00
|
|
|
const gchar *working_directory,
|
|
|
|
gchar **argv,
|
|
|
|
char **envp,
|
|
|
|
GSpawnFlags flags,
|
|
|
|
GSpawnChildSetupFunc child_setup,
|
|
|
|
gpointer user_data,
|
|
|
|
GPid *child_handle,
|
|
|
|
gint *standard_input,
|
|
|
|
gint *standard_output,
|
|
|
|
gint *standard_error,
|
|
|
|
gint *err_report,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
char **protected_argv;
|
|
|
|
char args[ARG_COUNT][10];
|
|
|
|
char **new_argv;
|
|
|
|
int i;
|
|
|
|
int rc = -1;
|
|
|
|
int saved_errno;
|
|
|
|
int argc;
|
|
|
|
int stdin_pipe[2] = { -1, -1 };
|
|
|
|
int stdout_pipe[2] = { -1, -1 };
|
|
|
|
int stderr_pipe[2] = { -1, -1 };
|
|
|
|
int child_err_report_pipe[2] = { -1, -1 };
|
|
|
|
int helper_report[2];
|
2005-08-26 01:43:11 +00:00
|
|
|
static gboolean warned_about_child_setup = FALSE;
|
|
|
|
GError *conv_error = NULL;
|
|
|
|
gint conv_error_index;
|
2005-09-07 10:10:49 +00:00
|
|
|
gchar *helper_process;
|
|
|
|
CONSOLE_CURSOR_INFO cursor_info;
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
SETUP_DEBUG();
|
2004-03-01 20:47:49 +00:00
|
|
|
|
2005-08-26 01:43:11 +00:00
|
|
|
if (child_setup && !warned_about_child_setup)
|
|
|
|
{
|
|
|
|
warned_about_child_setup = TRUE;
|
|
|
|
g_warning ("passing a child setup function to the g_spawn functions is pointless and dangerous on Win32");
|
|
|
|
}
|
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
argc = protect_argv (argv, &protected_argv);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
if (!standard_input && !standard_output && !standard_error &&
|
|
|
|
(flags & G_SPAWN_CHILD_INHERITS_STDIN) &&
|
|
|
|
!(flags & G_SPAWN_STDOUT_TO_DEV_NULL) &&
|
|
|
|
!(flags & G_SPAWN_STDERR_TO_DEV_NULL) &&
|
|
|
|
(working_directory == NULL || !*working_directory) &&
|
|
|
|
(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN))
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
/* We can do without the helper process */
|
2005-08-26 01:43:11 +00:00
|
|
|
gboolean retval =
|
2005-09-07 10:10:49 +00:00
|
|
|
do_spawn_directly (exit_status, do_return_handle, flags,
|
2005-08-26 01:43:11 +00:00
|
|
|
argv, envp, protected_argv,
|
|
|
|
child_setup, user_data, child_handle,
|
2005-09-07 10:10:49 +00:00
|
|
|
error);
|
2005-08-25 23:28:24 +00:00
|
|
|
g_strfreev (protected_argv);
|
2005-08-26 01:43:11 +00:00
|
|
|
return retval;
|
2003-07-31 01:25:19 +00:00
|
|
|
}
|
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
if (standard_input && !make_pipe (stdin_pipe, error))
|
|
|
|
goto cleanup_and_fail;
|
|
|
|
|
|
|
|
if (standard_output && !make_pipe (stdout_pipe, error))
|
|
|
|
goto cleanup_and_fail;
|
|
|
|
|
|
|
|
if (standard_error && !make_pipe (stderr_pipe, error))
|
|
|
|
goto cleanup_and_fail;
|
|
|
|
|
|
|
|
if (!make_pipe (child_err_report_pipe, error))
|
|
|
|
goto cleanup_and_fail;
|
|
|
|
|
2005-08-26 01:43:11 +00:00
|
|
|
new_argv = g_new (char *, argc + 1 + ARG_COUNT);
|
2005-09-07 10:10:49 +00:00
|
|
|
if (GetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cursor_info))
|
|
|
|
helper_process = HELPER_PROCESS "-console.exe";
|
|
|
|
else
|
|
|
|
helper_process = HELPER_PROCESS ".exe";
|
|
|
|
new_argv[0] = helper_process;
|
2004-12-11 03:47:32 +00:00
|
|
|
_g_sprintf (args[ARG_CHILD_ERR_REPORT], "%d", child_err_report_pipe[1]);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
new_argv[ARG_CHILD_ERR_REPORT] = args[ARG_CHILD_ERR_REPORT];
|
2004-12-11 03:47:32 +00:00
|
|
|
|
|
|
|
if (flags & G_SPAWN_FILE_AND_ARGV_ZERO)
|
2004-03-10 22:59:14 +00:00
|
|
|
{
|
|
|
|
/* Overload ARG_CHILD_ERR_REPORT to also encode the
|
|
|
|
* G_SPAWN_FILE_AND_ARGV_ZERO functionality.
|
|
|
|
*/
|
|
|
|
strcat (args[ARG_CHILD_ERR_REPORT], "#");
|
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
|
|
|
|
if (standard_input)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
_g_sprintf (args[ARG_STDIN], "%d", stdin_pipe[0]);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
new_argv[ARG_STDIN] = args[ARG_STDIN];
|
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
else if (flags & G_SPAWN_CHILD_INHERITS_STDIN)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
|
|
|
/* Let stdin be alone */
|
|
|
|
new_argv[ARG_STDIN] = "-";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Keep process from blocking on a read of stdin */
|
|
|
|
new_argv[ARG_STDIN] = "z";
|
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
|
|
|
|
if (standard_output)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
_g_sprintf (args[ARG_STDOUT], "%d", stdout_pipe[1]);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
new_argv[ARG_STDOUT] = args[ARG_STDOUT];
|
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
else if (flags & G_SPAWN_STDOUT_TO_DEV_NULL)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
|
|
|
new_argv[ARG_STDOUT] = "z";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
new_argv[ARG_STDOUT] = "-";
|
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
|
|
|
|
if (standard_error)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
_g_sprintf (args[ARG_STDERR], "%d", stderr_pipe[1]);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
new_argv[ARG_STDERR] = args[ARG_STDERR];
|
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
else if (flags & G_SPAWN_STDERR_TO_DEV_NULL)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
|
|
|
new_argv[ARG_STDERR] = "z";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
new_argv[ARG_STDERR] = "-";
|
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
if (working_directory && *working_directory)
|
2005-08-26 01:43:11 +00:00
|
|
|
new_argv[ARG_WORKING_DIRECTORY] = protect_argv_string (working_directory);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
else
|
2002-12-16 05:22:08 +00:00
|
|
|
new_argv[ARG_WORKING_DIRECTORY] = g_strdup ("-");
|
2004-12-11 03:47:32 +00:00
|
|
|
|
|
|
|
if (!(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN))
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
new_argv[ARG_CLOSE_DESCRIPTORS] = "y";
|
|
|
|
else
|
|
|
|
new_argv[ARG_CLOSE_DESCRIPTORS] = "-";
|
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
if (flags & G_SPAWN_SEARCH_PATH)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
new_argv[ARG_USE_PATH] = "y";
|
|
|
|
else
|
|
|
|
new_argv[ARG_USE_PATH] = "-";
|
|
|
|
|
2005-09-07 10:10:49 +00:00
|
|
|
if (exit_status == NULL)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
new_argv[ARG_WAIT] = "-";
|
|
|
|
else
|
|
|
|
new_argv[ARG_WAIT] = "w";
|
|
|
|
|
|
|
|
for (i = 0; i <= argc; i++)
|
2003-09-30 20:04:51 +00:00
|
|
|
new_argv[ARG_PROGRAM + i] = protected_argv[i];
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
|
|
|
if (debug)
|
|
|
|
{
|
2005-09-07 10:10:49 +00:00
|
|
|
g_print ("calling %s with argv:\n", helper_process);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
for (i = 0; i < argc + 1 + ARG_COUNT; i++)
|
|
|
|
g_print ("argv[%d]: %s\n", i, (new_argv[i] ? new_argv[i] : "NULL"));
|
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
|
2005-08-25 23:28:24 +00:00
|
|
|
if (G_WIN32_HAVE_WIDECHAR_API ())
|
|
|
|
{
|
2005-09-07 10:10:49 +00:00
|
|
|
wchar_t *whelper = g_utf8_to_utf16 (helper_process, -1, NULL, NULL, NULL);
|
2005-08-26 01:43:11 +00:00
|
|
|
wchar_t **wargv, **wenvp;
|
|
|
|
|
|
|
|
if (!utf8_charv_to_wcharv (new_argv, &wargv, &conv_error_index, &conv_error))
|
|
|
|
{
|
|
|
|
if (conv_error_index == ARG_WORKING_DIRECTORY)
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR,
|
|
|
|
_("Invalid working directory: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
else
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Invalid string in argument vector at %d: %s"),
|
|
|
|
conv_error_index - ARG_PROGRAM, conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
g_strfreev (protected_argv);
|
|
|
|
g_free (new_argv[ARG_WORKING_DIRECTORY]);
|
|
|
|
g_free (new_argv);
|
|
|
|
g_free (whelper);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!utf8_charv_to_wcharv (envp, &wenvp, NULL, &conv_error))
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Invalid string in environment: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
g_strfreev (protected_argv);
|
|
|
|
g_free (new_argv[ARG_WORKING_DIRECTORY]);
|
|
|
|
g_free (new_argv);
|
|
|
|
g_free (whelper);
|
|
|
|
g_strfreev ((gchar **) wargv);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child_setup)
|
|
|
|
(* child_setup) (user_data);
|
2005-08-25 23:28:24 +00:00
|
|
|
|
|
|
|
if (wenvp != NULL)
|
|
|
|
/* Let's hope envp hasn't mucked with PATH so that
|
|
|
|
* gspawn-win32-helper.exe isn't found.
|
|
|
|
*/
|
|
|
|
rc = _wspawnvpe (P_NOWAIT, whelper, (const wchar_t **) wargv, (const wchar_t **) wenvp);
|
|
|
|
else
|
|
|
|
rc = _wspawnvp (P_NOWAIT, whelper, (const wchar_t **) wargv);
|
|
|
|
|
|
|
|
saved_errno = errno;
|
|
|
|
|
|
|
|
g_free (whelper);
|
|
|
|
g_strfreev ((gchar **) wargv);
|
|
|
|
g_strfreev ((gchar **) wenvp);
|
|
|
|
}
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
else
|
2005-08-25 23:28:24 +00:00
|
|
|
{
|
2005-08-26 01:43:11 +00:00
|
|
|
char **cpargv, **cpenvp;
|
|
|
|
|
|
|
|
if (!utf8_charv_to_cp_charv (new_argv, &cpargv, &conv_error_index, &conv_error))
|
|
|
|
{
|
|
|
|
if (conv_error_index == ARG_WORKING_DIRECTORY)
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR,
|
|
|
|
_("Invalid working directory: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
else
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Invalid string in argument vector at %d: %s"),
|
|
|
|
conv_error_index - ARG_PROGRAM, conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
g_strfreev (protected_argv);
|
|
|
|
g_free (new_argv[ARG_WORKING_DIRECTORY]);
|
|
|
|
g_free (new_argv);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!utf8_charv_to_cp_charv (envp, &cpenvp, NULL, &conv_error))
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Invalid string in environment: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
g_strfreev (protected_argv);
|
|
|
|
g_free (new_argv[ARG_WORKING_DIRECTORY]);
|
|
|
|
g_free (new_argv);
|
|
|
|
g_strfreev (cpargv);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child_setup)
|
|
|
|
(* child_setup) (user_data);
|
2005-08-25 23:28:24 +00:00
|
|
|
|
|
|
|
if (cpenvp != NULL)
|
2005-09-07 10:10:49 +00:00
|
|
|
rc = spawnvpe (P_NOWAIT, helper_process, (const char **) cpargv, (const char **) cpenvp);
|
2005-08-25 23:28:24 +00:00
|
|
|
else
|
2005-09-07 10:10:49 +00:00
|
|
|
rc = spawnvp (P_NOWAIT, helper_process, (const char **) cpargv);
|
2004-12-11 03:47:32 +00:00
|
|
|
|
2005-08-25 23:28:24 +00:00
|
|
|
saved_errno = errno;
|
|
|
|
|
|
|
|
g_strfreev (cpargv);
|
|
|
|
g_strfreev (cpenvp);
|
|
|
|
}
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2005-08-25 23:28:24 +00:00
|
|
|
/* Close the other process's ends of the pipes in this process,
|
|
|
|
* otherwise the reader will never get EOF.
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
*/
|
2004-12-11 03:47:32 +00:00
|
|
|
close_and_invalidate (&child_err_report_pipe[1]);
|
|
|
|
close_and_invalidate (&stdin_pipe[0]);
|
|
|
|
close_and_invalidate (&stdout_pipe[1]);
|
|
|
|
close_and_invalidate (&stderr_pipe[1]);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2005-08-25 23:28:24 +00:00
|
|
|
g_strfreev (protected_argv);
|
2003-09-30 20:04:51 +00:00
|
|
|
|
2002-11-17 23:30:32 +00:00
|
|
|
g_free (new_argv[ARG_WORKING_DIRECTORY]);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
g_free (new_argv);
|
|
|
|
|
2003-07-31 01:25:19 +00:00
|
|
|
/* Check if gspawn-win32-helper couldn't be run */
|
2004-12-11 03:47:32 +00:00
|
|
|
if (rc == -1 && saved_errno != 0)
|
2002-11-17 23:30:32 +00:00
|
|
|
{
|
2005-08-26 01:43:11 +00:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Failed to execute helper program (%s)"),
|
|
|
|
g_strerror (saved_errno));
|
2002-11-17 23:30:32 +00:00
|
|
|
goto cleanup_and_fail;
|
|
|
|
}
|
|
|
|
|
2005-09-07 10:10:49 +00:00
|
|
|
if (exit_status != NULL)
|
2003-07-31 01:25:19 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
/* Synchronous case. Pass helper's report pipe back to caller,
|
|
|
|
* which takes care of reading it after the grandchild has
|
|
|
|
* finished.
|
|
|
|
*/
|
|
|
|
g_assert (err_report != NULL);
|
|
|
|
*err_report = child_err_report_pipe[0];
|
2003-07-31 01:25:19 +00:00
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
else
|
2003-07-31 01:25:19 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
/* Asynchronous case. We read the helper's report right away. */
|
|
|
|
if (!read_helper_report (child_err_report_pipe[0], helper_report, error))
|
|
|
|
goto cleanup_and_fail;
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
close (child_err_report_pipe[0]);
|
|
|
|
|
|
|
|
switch (helper_report[0])
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
case CHILD_NO_ERROR:
|
2005-09-07 10:10:49 +00:00
|
|
|
if (child_handle && do_return_handle)
|
2004-12-11 03:47:32 +00:00
|
|
|
{
|
|
|
|
/* rc is our HANDLE for gspawn-win32-helper. It has
|
|
|
|
* told us the HANDLE of its child. Duplicate that into
|
|
|
|
* a HANDLE valid in this process.
|
|
|
|
*/
|
|
|
|
if (!DuplicateHandle ((HANDLE) rc, (HANDLE) helper_report[1],
|
|
|
|
GetCurrentProcess (), (LPHANDLE) child_handle,
|
|
|
|
0, TRUE, DUPLICATE_SAME_ACCESS))
|
|
|
|
*child_handle = 0;
|
|
|
|
}
|
|
|
|
else if (child_handle)
|
2003-07-31 01:25:19 +00:00
|
|
|
*child_handle = 0;
|
2004-12-11 03:47:32 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
set_child_error (helper_report, working_directory, error);
|
|
|
|
goto cleanup_and_fail;
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Success against all odds! return the information */
|
|
|
|
|
|
|
|
if (standard_input)
|
|
|
|
*standard_input = stdin_pipe[1];
|
|
|
|
if (standard_output)
|
|
|
|
*standard_output = stdout_pipe[0];
|
|
|
|
if (standard_error)
|
|
|
|
*standard_error = stderr_pipe[0];
|
2004-12-11 03:47:32 +00:00
|
|
|
if (rc != -1)
|
|
|
|
CloseHandle ((HANDLE) rc);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
cleanup_and_fail:
|
2004-12-11 03:47:32 +00:00
|
|
|
if (rc != -1)
|
|
|
|
CloseHandle ((HANDLE) rc);
|
|
|
|
if (child_err_report_pipe[0] != -1)
|
|
|
|
close (child_err_report_pipe[0]);
|
|
|
|
if (child_err_report_pipe[1] != -1)
|
|
|
|
close (child_err_report_pipe[1]);
|
|
|
|
if (stdin_pipe[0] != -1)
|
|
|
|
close (stdin_pipe[0]);
|
|
|
|
if (stdin_pipe[1] != -1)
|
|
|
|
close (stdin_pipe[1]);
|
|
|
|
if (stdout_pipe[0] != -1)
|
|
|
|
close (stdout_pipe[0]);
|
|
|
|
if (stdout_pipe[1] != -1)
|
|
|
|
close (stdout_pipe[1]);
|
|
|
|
if (stderr_pipe[0] != -1)
|
|
|
|
close (stderr_pipe[0]);
|
|
|
|
if (stderr_pipe[1] != -1)
|
|
|
|
close (stderr_pipe[1]);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
gboolean
|
2005-08-25 23:28:24 +00:00
|
|
|
g_spawn_sync_utf8 (const gchar *working_directory,
|
|
|
|
gchar **argv,
|
|
|
|
gchar **envp,
|
|
|
|
GSpawnFlags flags,
|
|
|
|
GSpawnChildSetupFunc child_setup,
|
|
|
|
gpointer user_data,
|
|
|
|
gchar **standard_output,
|
|
|
|
gchar **standard_error,
|
|
|
|
gint *exit_status,
|
|
|
|
GError **error)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
gint outpipe = -1;
|
|
|
|
gint errpipe = -1;
|
|
|
|
gint reportpipe = -1;
|
|
|
|
GIOChannel *outchannel = NULL;
|
|
|
|
GIOChannel *errchannel = NULL;
|
|
|
|
GPollFD outfd, errfd;
|
|
|
|
GPollFD fds[2];
|
|
|
|
gint nfds;
|
|
|
|
gint outindex = -1;
|
|
|
|
gint errindex = -1;
|
|
|
|
gint ret;
|
|
|
|
GString *outstr = NULL;
|
|
|
|
GString *errstr = NULL;
|
|
|
|
gboolean failed;
|
|
|
|
gint status;
|
|
|
|
|
|
|
|
g_return_val_if_fail (argv != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (!(flags & G_SPAWN_DO_NOT_REAP_CHILD), FALSE);
|
|
|
|
g_return_val_if_fail (standard_output == NULL ||
|
|
|
|
!(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
|
|
|
|
g_return_val_if_fail (standard_error == NULL ||
|
|
|
|
!(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
|
|
|
|
|
|
|
|
/* Just to ensure segfaults if callers try to use
|
|
|
|
* these when an error is reported.
|
|
|
|
*/
|
|
|
|
if (standard_output)
|
|
|
|
*standard_output = NULL;
|
|
|
|
|
|
|
|
if (standard_error)
|
|
|
|
*standard_error = NULL;
|
|
|
|
|
2005-09-07 10:10:49 +00:00
|
|
|
if (!do_spawn_with_pipes (&status,
|
|
|
|
FALSE,
|
2004-12-11 03:47:32 +00:00
|
|
|
working_directory,
|
|
|
|
argv,
|
|
|
|
envp,
|
|
|
|
flags,
|
|
|
|
child_setup,
|
|
|
|
user_data,
|
2005-03-20 11:46:27 +00:00
|
|
|
NULL,
|
2004-12-11 03:47:32 +00:00
|
|
|
NULL,
|
|
|
|
standard_output ? &outpipe : NULL,
|
|
|
|
standard_error ? &errpipe : NULL,
|
|
|
|
&reportpipe,
|
|
|
|
error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Read data from child. */
|
|
|
|
|
|
|
|
failed = FALSE;
|
|
|
|
|
|
|
|
if (outpipe >= 0)
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
{
|
2004-12-11 03:47:32 +00:00
|
|
|
outstr = g_string_new (NULL);
|
|
|
|
outchannel = g_io_channel_win32_new_fd (outpipe);
|
|
|
|
g_io_channel_set_encoding (outchannel, NULL, NULL);
|
2006-01-01 11:15:56 +00:00
|
|
|
g_io_channel_set_buffered (outchannel, FALSE);
|
2004-12-11 03:47:32 +00:00
|
|
|
g_io_channel_win32_make_pollfd (outchannel,
|
|
|
|
G_IO_IN | G_IO_ERR | G_IO_HUP,
|
|
|
|
&outfd);
|
2006-01-01 11:15:56 +00:00
|
|
|
if (debug)
|
|
|
|
g_print ("outfd=%x\n", outfd.fd);
|
2004-12-11 03:47:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (errpipe >= 0)
|
|
|
|
{
|
|
|
|
errstr = g_string_new (NULL);
|
|
|
|
errchannel = g_io_channel_win32_new_fd (errpipe);
|
|
|
|
g_io_channel_set_encoding (errchannel, NULL, NULL);
|
2006-01-01 11:15:56 +00:00
|
|
|
g_io_channel_set_buffered (errchannel, FALSE);
|
2004-12-11 03:47:32 +00:00
|
|
|
g_io_channel_win32_make_pollfd (errchannel,
|
|
|
|
G_IO_IN | G_IO_ERR | G_IO_HUP,
|
|
|
|
&errfd);
|
2006-01-01 11:15:56 +00:00
|
|
|
if (debug)
|
|
|
|
g_print ("errfd=%x\n", errfd.fd);
|
2004-12-11 03:47:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Read data until we get EOF on all pipes. */
|
|
|
|
while (!failed && (outpipe >= 0 || errpipe >= 0))
|
|
|
|
{
|
|
|
|
nfds = 0;
|
|
|
|
if (outpipe >= 0)
|
|
|
|
{
|
|
|
|
fds[nfds] = outfd;
|
|
|
|
outindex = nfds;
|
|
|
|
nfds++;
|
|
|
|
}
|
|
|
|
if (errpipe >= 0)
|
|
|
|
{
|
|
|
|
fds[nfds] = errfd;
|
|
|
|
errindex = nfds;
|
|
|
|
nfds++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
g_print ("g_spawn_sync: calling g_io_channel_win32_poll, nfds=%d\n",
|
|
|
|
nfds);
|
|
|
|
|
|
|
|
ret = g_io_channel_win32_poll (fds, nfds, -1);
|
|
|
|
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
failed = TRUE;
|
|
|
|
|
2005-08-26 01:43:11 +00:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_READ,
|
2004-12-11 03:47:32 +00:00
|
|
|
_("Unexpected error in g_io_channel_win32_poll() reading data from a child process"));
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (outpipe >= 0 && (fds[outindex].revents & G_IO_IN))
|
|
|
|
{
|
|
|
|
switch (read_data (outstr, outchannel, error))
|
|
|
|
{
|
|
|
|
case READ_FAILED:
|
|
|
|
if (debug)
|
|
|
|
g_print ("g_spawn_sync: outchannel: READ_FAILED\n");
|
|
|
|
failed = TRUE;
|
|
|
|
break;
|
|
|
|
case READ_EOF:
|
|
|
|
if (debug)
|
|
|
|
g_print ("g_spawn_sync: outchannel: READ_EOF\n");
|
|
|
|
g_io_channel_unref (outchannel);
|
|
|
|
outchannel = NULL;
|
|
|
|
close_and_invalidate (&outpipe);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (debug)
|
|
|
|
g_print ("g_spawn_sync: outchannel: OK\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (failed)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (errpipe >= 0 && (fds[errindex].revents & G_IO_IN))
|
|
|
|
{
|
|
|
|
switch (read_data (errstr, errchannel, error))
|
|
|
|
{
|
|
|
|
case READ_FAILED:
|
|
|
|
if (debug)
|
|
|
|
g_print ("g_spawn_sync: errchannel: READ_FAILED\n");
|
|
|
|
failed = TRUE;
|
|
|
|
break;
|
|
|
|
case READ_EOF:
|
|
|
|
if (debug)
|
|
|
|
g_print ("g_spawn_sync: errchannel: READ_EOF\n");
|
|
|
|
g_io_channel_unref (errchannel);
|
|
|
|
errchannel = NULL;
|
|
|
|
close_and_invalidate (&errpipe);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (debug)
|
|
|
|
g_print ("g_spawn_sync: errchannel: OK\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (failed)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (reportpipe == -1)
|
|
|
|
{
|
|
|
|
/* No helper process, exit status of actual spawned process
|
|
|
|
* already available.
|
|
|
|
*/
|
|
|
|
if (exit_status)
|
|
|
|
*exit_status = status;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Helper process was involved. Read its report now after the
|
|
|
|
* grandchild has finished.
|
|
|
|
*/
|
|
|
|
gint helper_report[2];
|
|
|
|
|
|
|
|
if (!read_helper_report (reportpipe, helper_report, error))
|
|
|
|
failed = TRUE;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (helper_report[0])
|
|
|
|
{
|
|
|
|
case CHILD_NO_ERROR:
|
|
|
|
if (exit_status)
|
|
|
|
*exit_status = helper_report[1];
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
set_child_error (helper_report, working_directory, error);
|
|
|
|
failed = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close_and_invalidate (&reportpipe);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* These should only be open still if we had an error. */
|
|
|
|
|
|
|
|
if (outchannel != NULL)
|
|
|
|
g_io_channel_unref (outchannel);
|
|
|
|
if (errchannel != NULL)
|
|
|
|
g_io_channel_unref (errchannel);
|
|
|
|
if (outpipe >= 0)
|
|
|
|
close_and_invalidate (&outpipe);
|
|
|
|
if (errpipe >= 0)
|
|
|
|
close_and_invalidate (&errpipe);
|
|
|
|
|
|
|
|
if (failed)
|
|
|
|
{
|
|
|
|
if (outstr)
|
|
|
|
g_string_free (outstr, TRUE);
|
|
|
|
if (errstr)
|
|
|
|
g_string_free (errstr, TRUE);
|
|
|
|
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
2004-12-11 03:47:32 +00:00
|
|
|
{
|
|
|
|
if (standard_output)
|
|
|
|
*standard_output = g_string_free (outstr, FALSE);
|
|
|
|
|
|
|
|
if (standard_error)
|
|
|
|
*standard_error = g_string_free (errstr, FALSE);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2005-08-25 23:28:24 +00:00
|
|
|
g_spawn_async_with_pipes_utf8 (const gchar *working_directory,
|
|
|
|
gchar **argv,
|
|
|
|
gchar **envp,
|
|
|
|
GSpawnFlags flags,
|
|
|
|
GSpawnChildSetupFunc child_setup,
|
|
|
|
gpointer user_data,
|
|
|
|
GPid *child_handle,
|
|
|
|
gint *standard_input,
|
|
|
|
gint *standard_output,
|
|
|
|
gint *standard_error,
|
|
|
|
GError **error)
|
2004-12-11 03:47:32 +00:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (argv != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (standard_output == NULL ||
|
|
|
|
!(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
|
|
|
|
g_return_val_if_fail (standard_error == NULL ||
|
|
|
|
!(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
|
|
|
|
/* can't inherit stdin if we have an input pipe. */
|
|
|
|
g_return_val_if_fail (standard_input == NULL ||
|
|
|
|
!(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE);
|
|
|
|
|
2005-09-07 10:10:49 +00:00
|
|
|
return do_spawn_with_pipes (NULL,
|
|
|
|
(flags & G_SPAWN_DO_NOT_REAP_CHILD),
|
2004-12-11 03:47:32 +00:00
|
|
|
working_directory,
|
|
|
|
argv,
|
|
|
|
envp,
|
|
|
|
flags,
|
|
|
|
child_setup,
|
|
|
|
user_data,
|
|
|
|
child_handle,
|
|
|
|
standard_input,
|
|
|
|
standard_output,
|
|
|
|
standard_error,
|
|
|
|
NULL,
|
|
|
|
error);
|
Some more debugging output. (g_io_channel_win32_poll): Remove unused vars.
2000-10-16 Tor Lillqvist <tml@iki.fi>
* giowin32.c (reader_thread): Some more debugging output.
(g_io_channel_win32_poll): Remove unused vars.
* gfileutils.c: Changes for Win32, with no unistd.h and no
S_ISLNK().
* gspawn-win32.c: Implementation of the g_spwan_* functions for
Win32. Due to the general non-Unixness of Win32, much of the
functionality that is relatively clean to implement on Unix, is
hard to do on Win32. We must use a separate helper program to
change directory, close extra file descriptors, redirect the std
ones, as needed, and only then start the child process. No child
process pid can be returned, unfortunately. Or if we used
CreateProcess directly, it probably could. (Now we use the spawnv*
functions from msvcrt.)
* glib.def: Add new entry points.
* glib.def
* giowin32.c: Remove g_io_channel_win32_wait_for_condition(),
g_io_channel_win32_poll() subsumes it.
* gbacktrace.h: G_BREAKPOINT for MSVC (on the ix86).
* gwin32.c (g_win32_getlocale): Use "sp" for
LANG_CROATIAN+SUBLANG_SERBIAN_LATIN.
* makefile.{mingw,msc}.in (glib_OBJECTS): Add new files.
Add gspawn-win32-helper.exe rule.
* tests/makefile.{mingw,msc}.in (TESTS): Add shell-test and
spawn-test.
* tests/spawn-test.c: (run_tests): On Win32, don't try to run
/bin/sh, but ipconfig (no special significance in choosing that,
just a program that outputs something to stdout).
2000-10-16 18:54:29 +00:00
|
|
|
}
|
2004-12-11 03:47:32 +00:00
|
|
|
|
2005-08-25 23:28:24 +00:00
|
|
|
gboolean
|
|
|
|
g_spawn_command_line_sync_utf8 (const gchar *command_line,
|
|
|
|
gchar **standard_output,
|
|
|
|
gchar **standard_error,
|
|
|
|
gint *exit_status,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gboolean retval;
|
|
|
|
gchar **argv = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail (command_line != NULL, FALSE);
|
|
|
|
|
|
|
|
if (!g_shell_parse_argv (command_line,
|
|
|
|
NULL, &argv,
|
|
|
|
error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
retval = g_spawn_sync_utf8 (NULL,
|
|
|
|
argv,
|
|
|
|
NULL,
|
|
|
|
G_SPAWN_SEARCH_PATH,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
standard_output,
|
|
|
|
standard_error,
|
|
|
|
exit_status,
|
|
|
|
error);
|
|
|
|
g_strfreev (argv);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
g_spawn_command_line_async_utf8 (const gchar *command_line,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gboolean retval;
|
|
|
|
gchar **argv = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail (command_line != NULL, FALSE);
|
|
|
|
|
|
|
|
if (!g_shell_parse_argv (command_line,
|
|
|
|
NULL, &argv,
|
|
|
|
error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
retval = g_spawn_async_utf8 (NULL,
|
|
|
|
argv,
|
|
|
|
NULL,
|
|
|
|
G_SPAWN_SEARCH_PATH,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
error);
|
|
|
|
g_strfreev (argv);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
g_spawn_close_pid (GPid pid)
|
|
|
|
{
|
|
|
|
CloseHandle (pid);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Binary compatibility versions that take system codepage pathnames,
|
|
|
|
* argument vectors and environments. These get used only by code
|
|
|
|
* built against 2.8.1 or earlier. Code built against 2.8.2 or later
|
|
|
|
* will use the _utf8 versions above (see the #defines in gspawn.h).
|
|
|
|
*/
|
|
|
|
|
|
|
|
#undef g_spawn_async
|
|
|
|
#undef g_spawn_async_with_pipes
|
|
|
|
#undef g_spawn_sync
|
|
|
|
#undef g_spawn_command_line_sync
|
|
|
|
#undef g_spawn_command_line_async
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
setup_utf8_copies (const gchar *working_directory,
|
|
|
|
gchar **utf8_working_directory,
|
|
|
|
gchar **argv,
|
|
|
|
gchar ***utf8_argv,
|
|
|
|
gchar **envp,
|
|
|
|
gchar ***utf8_envp,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gint i, argc, envc;
|
|
|
|
|
|
|
|
if (working_directory == NULL)
|
|
|
|
*utf8_working_directory = NULL;
|
|
|
|
else
|
|
|
|
{
|
2005-08-26 01:43:11 +00:00
|
|
|
GError *conv_error = NULL;
|
|
|
|
|
|
|
|
*utf8_working_directory = g_locale_to_utf8 (working_directory, -1, NULL, NULL, &conv_error);
|
2005-08-25 23:28:24 +00:00
|
|
|
if (*utf8_working_directory == NULL)
|
2005-08-26 01:43:11 +00:00
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR,
|
|
|
|
_("Invalid working directory: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-08-25 23:28:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
argc = 0;
|
|
|
|
while (argv[argc])
|
|
|
|
++argc;
|
|
|
|
*utf8_argv = g_new (gchar *, argc + 1);
|
|
|
|
for (i = 0; i < argc; i++)
|
|
|
|
{
|
2005-08-26 01:43:11 +00:00
|
|
|
GError *conv_error = NULL;
|
|
|
|
|
|
|
|
(*utf8_argv)[i] = g_locale_to_utf8 (argv[i], -1, NULL, NULL, &conv_error);
|
2005-08-25 23:28:24 +00:00
|
|
|
if ((*utf8_argv)[i] == NULL)
|
2005-08-26 01:43:11 +00:00
|
|
|
{
|
2005-08-25 23:28:24 +00:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
2005-08-26 01:43:11 +00:00
|
|
|
_("Invalid string in argument vector at %d: %s"),
|
|
|
|
i, conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
2005-08-25 23:28:24 +00:00
|
|
|
|
|
|
|
g_strfreev (*utf8_argv);
|
|
|
|
*utf8_argv = NULL;
|
|
|
|
|
|
|
|
g_free (*utf8_working_directory);
|
|
|
|
*utf8_working_directory = NULL;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(*utf8_argv)[argc] = NULL;
|
|
|
|
|
|
|
|
if (envp == NULL)
|
|
|
|
{
|
|
|
|
*utf8_envp = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
envc = 0;
|
|
|
|
while (envp[envc])
|
|
|
|
++envc;
|
|
|
|
*utf8_envp = g_new (gchar *, envc + 1);
|
|
|
|
for (i = 0; i < envc; i++)
|
|
|
|
{
|
2005-08-26 01:43:11 +00:00
|
|
|
GError *conv_error = NULL;
|
|
|
|
|
|
|
|
(*utf8_envp)[i] = g_locale_to_utf8 (envp[i], -1, NULL, NULL, &conv_error);
|
2005-08-25 23:28:24 +00:00
|
|
|
if ((*utf8_envp)[i] == NULL)
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
2005-08-26 01:43:11 +00:00
|
|
|
_("Invalid string in environment: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
2005-08-25 23:28:24 +00:00
|
|
|
|
|
|
|
g_strfreev (*utf8_envp);
|
|
|
|
*utf8_envp = NULL;
|
|
|
|
|
|
|
|
g_strfreev (*utf8_argv);
|
|
|
|
*utf8_argv = NULL;
|
|
|
|
|
|
|
|
g_free (*utf8_working_directory);
|
|
|
|
*utf8_working_directory = NULL;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(*utf8_envp)[envc] = NULL;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_utf8_copies (gchar *utf8_working_directory,
|
|
|
|
gchar **utf8_argv,
|
|
|
|
gchar **utf8_envp)
|
|
|
|
{
|
|
|
|
g_free (utf8_working_directory);
|
|
|
|
g_strfreev (utf8_argv);
|
|
|
|
g_strfreev (utf8_envp);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
g_spawn_async_with_pipes (const gchar *working_directory,
|
|
|
|
gchar **argv,
|
|
|
|
gchar **envp,
|
|
|
|
GSpawnFlags flags,
|
|
|
|
GSpawnChildSetupFunc child_setup,
|
|
|
|
gpointer user_data,
|
|
|
|
GPid *child_handle,
|
|
|
|
gint *standard_input,
|
|
|
|
gint *standard_output,
|
|
|
|
gint *standard_error,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gchar *utf8_working_directory;
|
|
|
|
gchar **utf8_argv;
|
|
|
|
gchar **utf8_envp;
|
|
|
|
gboolean retval;
|
|
|
|
|
|
|
|
if (!setup_utf8_copies (working_directory, &utf8_working_directory,
|
|
|
|
argv, &utf8_argv,
|
|
|
|
envp, &utf8_envp,
|
|
|
|
error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
retval = g_spawn_async_with_pipes_utf8 (utf8_working_directory,
|
|
|
|
utf8_argv, utf8_envp,
|
|
|
|
flags, child_setup, user_data,
|
|
|
|
child_handle,
|
|
|
|
standard_input, standard_output, standard_error,
|
|
|
|
error);
|
|
|
|
|
|
|
|
free_utf8_copies (utf8_working_directory, utf8_argv, utf8_envp);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
g_spawn_async (const gchar *working_directory,
|
|
|
|
gchar **argv,
|
|
|
|
gchar **envp,
|
|
|
|
GSpawnFlags flags,
|
|
|
|
GSpawnChildSetupFunc child_setup,
|
|
|
|
gpointer user_data,
|
|
|
|
GPid *child_handle,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
return g_spawn_async_with_pipes (working_directory,
|
|
|
|
argv, envp,
|
|
|
|
flags,
|
|
|
|
child_setup,
|
|
|
|
user_data,
|
|
|
|
child_handle,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
error);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
g_spawn_sync (const gchar *working_directory,
|
|
|
|
gchar **argv,
|
|
|
|
gchar **envp,
|
|
|
|
GSpawnFlags flags,
|
|
|
|
GSpawnChildSetupFunc child_setup,
|
|
|
|
gpointer user_data,
|
|
|
|
gchar **standard_output,
|
|
|
|
gchar **standard_error,
|
|
|
|
gint *exit_status,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gchar *utf8_working_directory;
|
|
|
|
gchar **utf8_argv;
|
|
|
|
gchar **utf8_envp;
|
|
|
|
gboolean retval;
|
|
|
|
|
|
|
|
if (!setup_utf8_copies (working_directory, &utf8_working_directory,
|
|
|
|
argv, &utf8_argv,
|
|
|
|
envp, &utf8_envp,
|
|
|
|
error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
retval = g_spawn_sync_utf8 (utf8_working_directory,
|
|
|
|
utf8_argv, utf8_envp,
|
|
|
|
flags, child_setup, user_data,
|
|
|
|
standard_output, standard_error, exit_status,
|
|
|
|
error);
|
|
|
|
|
|
|
|
free_utf8_copies (utf8_working_directory, utf8_argv, utf8_envp);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2004-12-11 03:47:32 +00:00
|
|
|
gboolean
|
|
|
|
g_spawn_command_line_sync (const gchar *command_line,
|
2005-08-25 23:28:24 +00:00
|
|
|
gchar **standard_output,
|
|
|
|
gchar **standard_error,
|
|
|
|
gint *exit_status,
|
|
|
|
GError **error)
|
2004-12-11 03:47:32 +00:00
|
|
|
{
|
|
|
|
gboolean retval;
|
|
|
|
gchar **argv = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail (command_line != NULL, FALSE);
|
|
|
|
|
|
|
|
if (!g_shell_parse_argv (command_line,
|
|
|
|
NULL, &argv,
|
|
|
|
error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
retval = g_spawn_sync (NULL,
|
|
|
|
argv,
|
|
|
|
NULL,
|
|
|
|
G_SPAWN_SEARCH_PATH,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
standard_output,
|
|
|
|
standard_error,
|
|
|
|
exit_status,
|
|
|
|
error);
|
|
|
|
g_strfreev (argv);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
g_spawn_command_line_async (const gchar *command_line,
|
2005-08-25 23:28:24 +00:00
|
|
|
GError **error)
|
2004-12-11 03:47:32 +00:00
|
|
|
{
|
|
|
|
gboolean retval;
|
|
|
|
gchar **argv = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail (command_line != NULL, FALSE);
|
|
|
|
|
|
|
|
if (!g_shell_parse_argv (command_line,
|
|
|
|
NULL, &argv,
|
|
|
|
error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
retval = g_spawn_async (NULL,
|
|
|
|
argv,
|
|
|
|
NULL,
|
|
|
|
G_SPAWN_SEARCH_PATH,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
error);
|
|
|
|
g_strfreev (argv);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2000-11-28 20:04:08 +00:00
|
|
|
#endif /* !GSPAWN_HELPER */
|
2004-03-01 20:47:49 +00:00
|
|
|
|
2005-03-14 04:26:57 +00:00
|
|
|
#define __G_SPAWN_C__
|
|
|
|
#include "galiasdef.c"
|