2000-11-28 21:04:08 +01: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 20:54:29 +02:00
|
|
|
*
|
|
|
|
* Copyright 2000 Red Hat, Inc.
|
2003-07-31 03:25:19 +02: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 20:54:29 +02: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.)
|
|
|
|
*
|
2008-02-24 22:15:47 +01:00
|
|
|
* Thus, we must in many cases use a helper program to handle closing
|
2003-07-31 03:25:19 +02: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 20:54:29 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* Define this to get some logging all the time */
|
2001-09-17 02:41:39 +02: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 20:54:29 +02:00
|
|
|
|
2006-05-10 01:07:27 +02:00
|
|
|
#include "config.h"
|
2002-02-19 10:08:24 +01: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 20:54:29 +02:00
|
|
|
#include "glib.h"
|
2012-11-10 16:51:18 +01:00
|
|
|
#include "glib-private.h"
|
2002-11-21 01:35:15 +01:00
|
|
|
#include "gprintfint.h"
|
2006-09-30 16:06:45 +02:00
|
|
|
#include "glibintl.h"
|
2012-08-28 11:52:24 +02:00
|
|
|
#include "gthread.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 20:54:29 +02:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
2000-10-19 19:52:12 +02: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 20:54:29 +02:00
|
|
|
|
|
|
|
#include <windows.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <io.h>
|
|
|
|
#include <process.h>
|
2000-10-19 19:52:12 +02:00
|
|
|
#include <direct.h>
|
2008-02-24 22:15:47 +01:00
|
|
|
#include <wchar.h>
|
2005-08-26 01:28:24 +02:00
|
|
|
|
2012-11-10 16:58:19 +01:00
|
|
|
#ifndef GSPAWN_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 20:54:29 +02: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 20:54:01 +01: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 20:54:29 +02:00
|
|
|
} \
|
|
|
|
G_STMT_END
|
|
|
|
#endif
|
2012-11-10 16:58:19 +01:00
|
|
|
#endif
|
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 20:54:29 +02:00
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
CHILD_NO_ERROR,
|
|
|
|
CHILD_CHDIR_FAILED,
|
|
|
|
CHILD_SPAWN_FAILED,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
ARG_CHILD_ERR_REPORT = 1,
|
2008-02-24 22:15:47 +01:00
|
|
|
ARG_HELPER_SYNC,
|
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 20:54:29 +02:00
|
|
|
ARG_STDIN,
|
|
|
|
ARG_STDOUT,
|
|
|
|
ARG_STDERR,
|
|
|
|
ARG_WORKING_DIRECTORY,
|
|
|
|
ARG_CLOSE_DESCRIPTORS,
|
|
|
|
ARG_USE_PATH,
|
|
|
|
ARG_WAIT,
|
|
|
|
ARG_PROGRAM,
|
|
|
|
ARG_COUNT = ARG_PROGRAM
|
|
|
|
};
|
|
|
|
|
2008-02-24 22:15:47 +01:00
|
|
|
static int
|
|
|
|
dup_noninherited (int fd,
|
|
|
|
int mode)
|
|
|
|
{
|
|
|
|
HANDLE filehandle;
|
|
|
|
|
|
|
|
DuplicateHandle (GetCurrentProcess (), (LPHANDLE) _get_osfhandle (fd),
|
|
|
|
GetCurrentProcess (), &filehandle,
|
|
|
|
0, FALSE, DUPLICATE_SAME_ACCESS);
|
|
|
|
close (fd);
|
2008-08-04 20:46:59 +02:00
|
|
|
return _open_osfhandle ((gintptr) filehandle, mode | _O_NOINHERIT);
|
2008-02-24 22:15:47 +01:00
|
|
|
}
|
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
#ifndef GSPAWN_HELPER
|
|
|
|
|
Fix problems on 64-bit Windows. Avoid warnings, some of which indicated
2008-07-28 Tor Lillqvist <tml@novell.com>
Fix problems on 64-bit Windows. Avoid warnings, some of which
indicated actual problems, some which were just annoyances.
Where casts to an integer type are needed for pointers, use
gssize. Technically intptr_t would be the more proper type, but we
still want to be compilable with MSVS6 and 7 which don't have
intptr_t. MSVS8 and 9 do have intptr_t, but in <crtdefs.h>, not
<stdint.h>.
Use %p to print out handles. Use gssize casts when assigning
GPollFD::fd fields.
Use G_GSIZE_FORMAT when printing size_t values.
* configure.in: Define automake conditional G_OS_WIN32_X64 which
is true on Win64.
* glib/giochannel.h: Use slightly different prototype for
g_io_channel_win32_new_messages() on Win64 with gsize instead of
guint.
* glib/giowin32.c
* glib/gmain.c
* glib/gspawn-win32.c
* tests/testglib.c: Generic changes as described above.
* glib/gmain.h: Don't bother mentioning GIMP in comment.
* glib/grel.c (tuple_hash_2): Use all bits of pointer.
* glib/gspawn-win32.c
* glib/gspawn-win32-helper.c: Use gssize types in the
communication between parent and helper process, so that we can
pass process handles, which are pointers, also on Win64.
* glib/gtimer.c (g_time_val_to_iso8601): time_t is 64 bits on
Win64 so we can't pass the address of a GTimeVal::tv_sec which is
a long directly to gmtime(). On the other hand, changing
GTimeVal::tv_sec to be a gint64 on Win64 is not really feasible
either, as that would then require changes in much code that uses
GTimeVals.
* glib/gspawn-win32.c
* glib/Makefile.am: Call the helper programs
gspawn-win64-helper.exe and gspawn-win64-helper-console.exe on
Win64, to avoid potential risk of running a 32-bit version of the
helper.
svn path=/trunk/; revision=7260
2008-07-28 02:24:14 +02:00
|
|
|
#ifdef _WIN64
|
|
|
|
#define HELPER_PROCESS "gspawn-win64-helper"
|
|
|
|
#else
|
2006-08-30 00:45:00 +02:00
|
|
|
#define HELPER_PROCESS "gspawn-win32-helper"
|
Fix problems on 64-bit Windows. Avoid warnings, some of which indicated
2008-07-28 Tor Lillqvist <tml@novell.com>
Fix problems on 64-bit Windows. Avoid warnings, some of which
indicated actual problems, some which were just annoyances.
Where casts to an integer type are needed for pointers, use
gssize. Technically intptr_t would be the more proper type, but we
still want to be compilable with MSVS6 and 7 which don't have
intptr_t. MSVS8 and 9 do have intptr_t, but in <crtdefs.h>, not
<stdint.h>.
Use %p to print out handles. Use gssize casts when assigning
GPollFD::fd fields.
Use G_GSIZE_FORMAT when printing size_t values.
* configure.in: Define automake conditional G_OS_WIN32_X64 which
is true on Win64.
* glib/giochannel.h: Use slightly different prototype for
g_io_channel_win32_new_messages() on Win64 with gsize instead of
guint.
* glib/giowin32.c
* glib/gmain.c
* glib/gspawn-win32.c
* tests/testglib.c: Generic changes as described above.
* glib/gmain.h: Don't bother mentioning GIMP in comment.
* glib/grel.c (tuple_hash_2): Use all bits of pointer.
* glib/gspawn-win32.c
* glib/gspawn-win32-helper.c: Use gssize types in the
communication between parent and helper process, so that we can
pass process handles, which are pointers, also on Win64.
* glib/gtimer.c (g_time_val_to_iso8601): time_t is 64 bits on
Win64 so we can't pass the address of a GTimeVal::tv_sec which is
a long directly to gmtime(). On the other hand, changing
GTimeVal::tv_sec to be a gint64 on Win64 is not really feasible
either, as that would then require changes in much code that uses
GTimeVals.
* glib/gspawn-win32.c
* glib/Makefile.am: Call the helper programs
gspawn-win64-helper.exe and gspawn-win64-helper-console.exe on
Win64, to avoid potential risk of running a 32-bit version of the
helper.
svn path=/trunk/; revision=7260
2008-07-28 02:24:14 +02:00
|
|
|
#endif
|
2006-08-30 00:45:00 +02:00
|
|
|
|
2005-08-26 03:43:11 +02: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-05 00:37:04 +01: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 03:43:11 +02:00
|
|
|
(*new_argv)[i] = protect_argv_string (argv[i]);
|
2003-02-05 00:37:04 +01:00
|
|
|
|
|
|
|
(*new_argv)[argc] = NULL;
|
|
|
|
|
|
|
|
return argc;
|
|
|
|
}
|
|
|
|
|
2012-08-28 19:15:56 +02:00
|
|
|
G_DEFINE_QUARK (g-exec-error-quark, g_spawn_error)
|
|
|
|
G_DEFINE_QUARK (g-spawn-exit-error-quark, g_spawn_exit_error)
|
2012-07-11 19:41:58 +02: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 20:54:29 +02:00
|
|
|
gboolean
|
2005-08-26 01:28:24 +02: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 20:54:29 +02:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (argv != NULL, FALSE);
|
|
|
|
|
2005-08-26 01:28:24 +02: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 20:54:29 +02: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 04:47:32 +01: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 20:54:29 +02: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 04:52:55 +01:00
|
|
|
if (*fd < 0)
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
|
2004-12-11 04:47:32 +01: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 20:54:29 +02: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 10:08:24 +01:00
|
|
|
GIOStatus giostatus;
|
Fix problems on 64-bit Windows. Avoid warnings, some of which indicated
2008-07-28 Tor Lillqvist <tml@novell.com>
Fix problems on 64-bit Windows. Avoid warnings, some of which
indicated actual problems, some which were just annoyances.
Where casts to an integer type are needed for pointers, use
gssize. Technically intptr_t would be the more proper type, but we
still want to be compilable with MSVS6 and 7 which don't have
intptr_t. MSVS8 and 9 do have intptr_t, but in <crtdefs.h>, not
<stdint.h>.
Use %p to print out handles. Use gssize casts when assigning
GPollFD::fd fields.
Use G_GSIZE_FORMAT when printing size_t values.
* configure.in: Define automake conditional G_OS_WIN32_X64 which
is true on Win64.
* glib/giochannel.h: Use slightly different prototype for
g_io_channel_win32_new_messages() on Win64 with gsize instead of
guint.
* glib/giowin32.c
* glib/gmain.c
* glib/gspawn-win32.c
* tests/testglib.c: Generic changes as described above.
* glib/gmain.h: Don't bother mentioning GIMP in comment.
* glib/grel.c (tuple_hash_2): Use all bits of pointer.
* glib/gspawn-win32.c
* glib/gspawn-win32-helper.c: Use gssize types in the
communication between parent and helper process, so that we can
pass process handles, which are pointers, also on Win64.
* glib/gtimer.c (g_time_val_to_iso8601): time_t is 64 bits on
Win64 so we can't pass the address of a GTimeVal::tv_sec which is
a long directly to gmtime(). On the other hand, changing
GTimeVal::tv_sec to be a gint64 on Win64 is not really feasible
either, as that would then require changes in much code that uses
GTimeVals.
* glib/gspawn-win32.c
* glib/Makefile.am: Call the helper programs
gspawn-win64-helper.exe and gspawn-win64-helper-console.exe on
Win64, to avoid potential risk of running a 32-bit version of the
helper.
svn path=/trunk/; revision=7260
2008-07-28 02:24:14 +02:00
|
|
|
gsize 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 20:54:29 +02:00
|
|
|
gchar buf[4096];
|
|
|
|
|
|
|
|
again:
|
|
|
|
|
2002-02-19 10:08:24 +01: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 20:54:29 +02:00
|
|
|
|
|
|
|
if (bytes == 0)
|
|
|
|
return READ_EOF;
|
|
|
|
else if (bytes > 0)
|
|
|
|
{
|
|
|
|
g_string_append_len (str, buf, bytes);
|
|
|
|
return READ_OK;
|
|
|
|
}
|
2002-02-19 10:08:24 +01: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 20:54:29 +02:00
|
|
|
goto again;
|
2002-02-19 10:08:24 +01: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 20:54:29 +02:00
|
|
|
{
|
2008-06-16 18:53:58 +02:00
|
|
|
g_set_error_literal (error, G_SPAWN_ERROR, G_SPAWN_ERROR_READ,
|
|
|
|
_("Failed to read data from child 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 20:54:29 +02:00
|
|
|
|
|
|
|
return READ_FAILED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return READ_OK;
|
|
|
|
}
|
|
|
|
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
{
|
2007-05-13 22:46:59 +02:00
|
|
|
if (_pipe (p, 4096, _O_BINARY) < 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 20:54:29 +02:00
|
|
|
{
|
2009-08-20 15:13:43 +02:00
|
|
|
int errsv = errno;
|
|
|
|
|
2005-08-26 03:43:11 +02:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
2004-12-11 04:47:32 +01:00
|
|
|
_("Failed to create pipe for communicating with child process (%s)"),
|
2009-08-20 15:13:43 +02:00
|
|
|
g_strerror (errsv));
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
}
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
|
2004-12-11 04:47:32 +01: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,
|
2008-08-04 20:46:59 +02:00
|
|
|
gintptr report[2],
|
2004-12-11 04:47:32 +01:00
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gint bytes = 0;
|
|
|
|
|
2008-08-04 20:46:59 +02:00
|
|
|
while (bytes < sizeof(gintptr)*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 20:54:29 +02:00
|
|
|
{
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
|
|
|
|
if (debug)
|
Fix problems on 64-bit Windows. Avoid warnings, some of which indicated
2008-07-28 Tor Lillqvist <tml@novell.com>
Fix problems on 64-bit Windows. Avoid warnings, some of which
indicated actual problems, some which were just annoyances.
Where casts to an integer type are needed for pointers, use
gssize. Technically intptr_t would be the more proper type, but we
still want to be compilable with MSVS6 and 7 which don't have
intptr_t. MSVS8 and 9 do have intptr_t, but in <crtdefs.h>, not
<stdint.h>.
Use %p to print out handles. Use gssize casts when assigning
GPollFD::fd fields.
Use G_GSIZE_FORMAT when printing size_t values.
* configure.in: Define automake conditional G_OS_WIN32_X64 which
is true on Win64.
* glib/giochannel.h: Use slightly different prototype for
g_io_channel_win32_new_messages() on Win64 with gsize instead of
guint.
* glib/giowin32.c
* glib/gmain.c
* glib/gspawn-win32.c
* tests/testglib.c: Generic changes as described above.
* glib/gmain.h: Don't bother mentioning GIMP in comment.
* glib/grel.c (tuple_hash_2): Use all bits of pointer.
* glib/gspawn-win32.c
* glib/gspawn-win32-helper.c: Use gssize types in the
communication between parent and helper process, so that we can
pass process handles, which are pointers, also on Win64.
* glib/gtimer.c (g_time_val_to_iso8601): time_t is 64 bits on
Win64 so we can't pass the address of a GTimeVal::tv_sec which is
a long directly to gmtime(). On the other hand, changing
GTimeVal::tv_sec to be a gint64 on Win64 is not really feasible
either, as that would then require changes in much code that uses
GTimeVals.
* glib/gspawn-win32.c
* glib/Makefile.am: Call the helper programs
gspawn-win64-helper.exe and gspawn-win64-helper-console.exe on
Win64, to avoid potential risk of running a 32-bit version of the
helper.
svn path=/trunk/; revision=7260
2008-07-28 02:24:14 +02:00
|
|
|
g_print ("%s:read_helper_report: read %" G_GSIZE_FORMAT "...\n",
|
2004-12-11 04:47:32 +01:00
|
|
|
__FILE__,
|
2008-08-04 20:46:59 +02:00
|
|
|
sizeof(gintptr)*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 20:54:29 +02:00
|
|
|
|
2004-12-11 04:47:32 +01:00
|
|
|
chunk = read (fd, ((gchar*)report) + bytes,
|
2008-08-04 20:46:59 +02:00
|
|
|
sizeof(gintptr)*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 20:54:29 +02:00
|
|
|
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
{
|
2009-08-20 15:13:43 +02:00
|
|
|
int errsv = errno;
|
|
|
|
|
2004-12-11 04:47:32 +01:00
|
|
|
/* Some weird shit happened, bail out */
|
2005-08-26 03:43:11 +02:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
2004-12-11 04:47:32 +01:00
|
|
|
_("Failed to read from child pipe (%s)"),
|
2009-08-20 15:13:43 +02:00
|
|
|
g_strerror (errsv));
|
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 20:54:29 +02:00
|
|
|
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
}
|
2004-12-11 04:47:32 +01:00
|
|
|
else if (chunk == 0)
|
2008-03-03 05:23:16 +01:00
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Failed to read from child pipe (%s)"),
|
|
|
|
"EOF");
|
|
|
|
break; /* EOF */
|
|
|
|
}
|
2004-12-11 04:47:32 +01:00
|
|
|
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 20:54:29 +02:00
|
|
|
|
2008-08-04 20:46:59 +02:00
|
|
|
if (bytes < sizeof(gintptr)*2)
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
|
2004-12-11 04:47:32 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-08-04 20:46:59 +02:00
|
|
|
set_child_error (gintptr report[2],
|
2004-12-11 04:47:32 +01:00
|
|
|
const gchar *working_directory,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
switch (report[0])
|
|
|
|
{
|
|
|
|
case CHILD_CHDIR_FAILED:
|
2005-08-26 03:43:11 +02:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR,
|
2004-12-11 04:47:32 +01:00
|
|
|
_("Failed to change to directory '%s' (%s)"),
|
|
|
|
working_directory,
|
|
|
|
g_strerror (report[1]));
|
|
|
|
break;
|
|
|
|
case CHILD_SPAWN_FAILED:
|
2005-08-26 03:43:11 +02:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
}
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
|
2005-08-26 03:43:11 +02:00
|
|
|
static gboolean
|
|
|
|
utf8_charv_to_wcharv (char **utf8_charv,
|
|
|
|
wchar_t ***wcharv,
|
|
|
|
int *error_index,
|
|
|
|
GError **error)
|
2005-08-26 01:28:24 +02:00
|
|
|
{
|
|
|
|
wchar_t **retval = NULL;
|
|
|
|
|
2005-08-26 03:43:11 +02:00
|
|
|
*wcharv = NULL;
|
2005-08-26 01:28:24 +02: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 03:43:11 +02: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-26 01:28:24 +02:00
|
|
|
retval[n] = NULL;
|
|
|
|
}
|
2005-08-26 03:43:11 +02:00
|
|
|
*wcharv = retval;
|
|
|
|
return TRUE;
|
2005-08-26 01:28:24 +02:00
|
|
|
}
|
|
|
|
|
2005-08-26 03:43:11 +02:00
|
|
|
static gboolean
|
2005-09-07 12:10:49 +02:00
|
|
|
do_spawn_directly (gint *exit_status,
|
|
|
|
gboolean do_return_handle,
|
2005-08-26 03:43:11 +02:00
|
|
|
GSpawnFlags flags,
|
|
|
|
gchar **argv,
|
|
|
|
char **envp,
|
|
|
|
char **protected_argv,
|
|
|
|
GPid *child_handle,
|
|
|
|
GError **error)
|
|
|
|
{
|
2005-09-07 12:10:49 +02:00
|
|
|
const int mode = (exit_status == NULL) ? P_NOWAIT : P_WAIT;
|
2005-08-26 03:43:11 +02:00
|
|
|
char **new_argv;
|
2008-08-04 20:46:59 +02:00
|
|
|
gintptr rc = -1;
|
2005-08-26 03:43:11 +02:00
|
|
|
int saved_errno;
|
|
|
|
GError *conv_error = NULL;
|
|
|
|
gint conv_error_index;
|
2006-08-30 00:45:00 +02:00
|
|
|
wchar_t *wargv0, **wargv, **wenvp;
|
2005-08-26 03:43:11 +02:00
|
|
|
|
|
|
|
new_argv = (flags & G_SPAWN_FILE_AND_ARGV_ZERO) ? protected_argv + 1 : protected_argv;
|
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
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);
|
2005-08-26 03:43:11 +02:00
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
return FALSE;
|
2005-08-26 03:43:11 +02:00
|
|
|
}
|
2006-08-30 00:45:00 +02:00
|
|
|
|
|
|
|
if (!utf8_charv_to_wcharv (new_argv, &wargv, &conv_error_index, &conv_error))
|
2005-08-26 03:43:11 +02:00
|
|
|
{
|
2006-08-30 00:45:00 +02:00
|
|
|
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);
|
2005-08-26 03:43:11 +02:00
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
2005-08-26 03:43:11 +02:00
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
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);
|
2005-08-26 03:43:11 +02:00
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
2005-08-26 03:43:11 +02:00
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
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);
|
2005-08-26 03:43:11 +02:00
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
g_free (wargv0);
|
|
|
|
g_strfreev ((gchar **) wargv);
|
|
|
|
g_strfreev ((gchar **) wenvp);
|
2005-08-26 03:43:11 +02:00
|
|
|
|
|
|
|
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 12:10:49 +02:00
|
|
|
if (exit_status == NULL)
|
2005-08-26 03:43:11 +02:00
|
|
|
{
|
2005-09-07 12:10:49 +02:00
|
|
|
if (child_handle && do_return_handle)
|
2005-08-26 03:43:11 +02:00
|
|
|
*child_handle = (GPid) rc;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CloseHandle ((HANDLE) rc);
|
|
|
|
if (child_handle)
|
|
|
|
*child_handle = 0;
|
|
|
|
}
|
|
|
|
}
|
2005-09-07 12:10:49 +02:00
|
|
|
else
|
2005-08-26 03:43:11 +02:00
|
|
|
*exit_status = rc;
|
|
|
|
|
|
|
|
return TRUE;
|
2005-08-26 01:28:24 +02:00
|
|
|
}
|
|
|
|
|
2004-12-11 04:47:32 +01:00
|
|
|
static gboolean
|
2005-09-07 12:10:49 +02:00
|
|
|
do_spawn_with_pipes (gint *exit_status,
|
|
|
|
gboolean do_return_handle,
|
2004-12-11 04:47:32 +01:00
|
|
|
const gchar *working_directory,
|
|
|
|
gchar **argv,
|
|
|
|
char **envp,
|
|
|
|
GSpawnFlags flags,
|
|
|
|
GSpawnChildSetupFunc child_setup,
|
|
|
|
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;
|
2008-08-04 20:46:59 +02:00
|
|
|
gintptr rc = -1;
|
2004-12-11 04:47:32 +01:00
|
|
|
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 };
|
2008-02-24 22:15:47 +01:00
|
|
|
int helper_sync_pipe[2] = { -1, -1 };
|
2008-08-04 20:46:59 +02:00
|
|
|
gintptr helper_report[2];
|
2005-08-26 03:43:11 +02:00
|
|
|
static gboolean warned_about_child_setup = FALSE;
|
|
|
|
GError *conv_error = NULL;
|
|
|
|
gint conv_error_index;
|
2005-09-07 12:10:49 +02:00
|
|
|
gchar *helper_process;
|
|
|
|
CONSOLE_CURSOR_INFO cursor_info;
|
2006-08-30 00:45:00 +02:00
|
|
|
wchar_t *whelper, **wargv, **wenvp;
|
2008-09-19 12:20:41 +02:00
|
|
|
gchar *glib_dll_directory;
|
2004-03-01 21:47:49 +01:00
|
|
|
|
2005-08-26 03:43:11 +02:00
|
|
|
if (child_setup && !warned_about_child_setup)
|
|
|
|
{
|
|
|
|
warned_about_child_setup = TRUE;
|
2008-09-25 10:05:41 +02:00
|
|
|
g_warning ("passing a child setup function to the g_spawn functions is pointless on Windows and it is ignored");
|
2005-08-26 03:43:11 +02:00
|
|
|
}
|
|
|
|
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
{
|
2004-12-11 04:47:32 +01:00
|
|
|
/* We can do without the helper process */
|
2005-08-26 03:43:11 +02:00
|
|
|
gboolean retval =
|
2005-09-07 12:10:49 +02:00
|
|
|
do_spawn_directly (exit_status, do_return_handle, flags,
|
2005-08-26 03:43:11 +02:00
|
|
|
argv, envp, protected_argv,
|
2008-09-25 10:05:41 +02:00
|
|
|
child_handle, error);
|
2005-08-26 01:28:24 +02:00
|
|
|
g_strfreev (protected_argv);
|
2005-08-26 03:43:11 +02:00
|
|
|
return retval;
|
2003-07-31 03:25:19 +02:00
|
|
|
}
|
|
|
|
|
2004-12-11 04:47:32 +01: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;
|
|
|
|
|
2008-02-24 22:15:47 +01:00
|
|
|
if (!make_pipe (helper_sync_pipe, error))
|
|
|
|
goto cleanup_and_fail;
|
|
|
|
|
2005-08-26 03:43:11 +02:00
|
|
|
new_argv = g_new (char *, argc + 1 + ARG_COUNT);
|
2014-07-30 09:15:39 +02:00
|
|
|
if (GetConsoleWindow () != NULL)
|
2005-09-07 12:10:49 +02:00
|
|
|
helper_process = HELPER_PROCESS "-console.exe";
|
|
|
|
else
|
|
|
|
helper_process = HELPER_PROCESS ".exe";
|
2008-02-24 22:15:47 +01:00
|
|
|
|
2008-09-19 12:20:41 +02:00
|
|
|
glib_dll_directory = _glib_get_dll_directory ();
|
|
|
|
if (glib_dll_directory != NULL)
|
2008-02-24 22:31:44 +01:00
|
|
|
{
|
2008-09-19 12:20:41 +02:00
|
|
|
helper_process = g_build_filename (glib_dll_directory, helper_process, NULL);
|
|
|
|
g_free (glib_dll_directory);
|
2008-02-24 22:31:44 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
helper_process = g_strdup (helper_process);
|
2008-02-24 22:15:47 +01:00
|
|
|
|
2008-03-03 05:23:16 +01:00
|
|
|
new_argv[0] = protect_argv_string (helper_process);
|
2008-02-24 22:15:47 +01:00
|
|
|
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
new_argv[ARG_CHILD_ERR_REPORT] = args[ARG_CHILD_ERR_REPORT];
|
2004-12-11 04:47:32 +01:00
|
|
|
|
2008-02-24 22:15:47 +01:00
|
|
|
/* Make the read end of the child error report pipe
|
|
|
|
* noninherited. Otherwise it will needlessly be inherited by the
|
|
|
|
* helper process, and the started actual user process. As such that
|
|
|
|
* shouldn't harm, but it is unnecessary.
|
|
|
|
*/
|
|
|
|
child_err_report_pipe[0] = dup_noninherited (child_err_report_pipe[0], _O_RDONLY);
|
|
|
|
|
2004-12-11 04:47:32 +01:00
|
|
|
if (flags & G_SPAWN_FILE_AND_ARGV_ZERO)
|
2004-03-10 23:59:14 +01: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 04:47:32 +01:00
|
|
|
|
2008-02-24 22:15:47 +01:00
|
|
|
_g_sprintf (args[ARG_HELPER_SYNC], "%d", helper_sync_pipe[0]);
|
|
|
|
new_argv[ARG_HELPER_SYNC] = args[ARG_HELPER_SYNC];
|
|
|
|
|
|
|
|
/* Make the write end of the sync pipe noninherited. Otherwise the
|
|
|
|
* helper process will inherit it, and thus if this process happens
|
|
|
|
* to crash before writing the sync byte to the pipe, the helper
|
|
|
|
* process won't read but won't get any EOF either, as it has the
|
|
|
|
* write end open itself.
|
|
|
|
*/
|
|
|
|
helper_sync_pipe[1] = dup_noninherited (helper_sync_pipe[1], _O_WRONLY);
|
|
|
|
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
{
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
new_argv[ARG_STDIN] = args[ARG_STDIN];
|
|
|
|
}
|
2004-12-11 04:47:32 +01: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 20:54:29 +02: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 04:47:32 +01: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 20:54:29 +02:00
|
|
|
{
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
new_argv[ARG_STDOUT] = args[ARG_STDOUT];
|
|
|
|
}
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
{
|
|
|
|
new_argv[ARG_STDOUT] = "z";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
new_argv[ARG_STDOUT] = "-";
|
|
|
|
}
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
{
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
new_argv[ARG_STDERR] = args[ARG_STDERR];
|
|
|
|
}
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
{
|
|
|
|
new_argv[ARG_STDERR] = "z";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
new_argv[ARG_STDERR] = "-";
|
|
|
|
}
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
if (working_directory && *working_directory)
|
2005-08-26 03:43:11 +02: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 20:54:29 +02:00
|
|
|
else
|
2002-12-16 06:22:08 +01:00
|
|
|
new_argv[ARG_WORKING_DIRECTORY] = g_strdup ("-");
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
new_argv[ARG_CLOSE_DESCRIPTORS] = "y";
|
|
|
|
else
|
|
|
|
new_argv[ARG_CLOSE_DESCRIPTORS] = "-";
|
|
|
|
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
new_argv[ARG_USE_PATH] = "y";
|
|
|
|
else
|
|
|
|
new_argv[ARG_USE_PATH] = "-";
|
|
|
|
|
2005-09-07 12:10:49 +02: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 20:54:29 +02:00
|
|
|
new_argv[ARG_WAIT] = "-";
|
|
|
|
else
|
|
|
|
new_argv[ARG_WAIT] = "w";
|
|
|
|
|
|
|
|
for (i = 0; i <= argc; i++)
|
2003-09-30 22:04:51 +02: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 20:54:29 +02:00
|
|
|
|
2008-02-24 22:15:47 +01:00
|
|
|
SETUP_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 20:54:29 +02:00
|
|
|
if (debug)
|
|
|
|
{
|
2005-09-07 12:10:49 +02: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 20:54:29 +02: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 04:47:32 +01:00
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
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);
|
2005-08-26 01:28:24 +02:00
|
|
|
else
|
2006-08-30 00:45:00 +02:00
|
|
|
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);
|
2008-03-03 05:23:16 +01:00
|
|
|
g_free (new_argv[0]);
|
2006-08-30 00:45:00 +02:00
|
|
|
g_free (new_argv[ARG_WORKING_DIRECTORY]);
|
|
|
|
g_free (new_argv);
|
2008-02-24 22:15:47 +01:00
|
|
|
g_free (helper_process);
|
2005-08-26 01:28:24 +02:00
|
|
|
|
2008-02-24 22:15:47 +01:00
|
|
|
goto cleanup_and_fail;
|
2006-08-30 00:45:00 +02:00
|
|
|
}
|
2005-08-26 01:28:24 +02:00
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
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);
|
2008-03-03 05:23:16 +01:00
|
|
|
g_free (new_argv[0]);
|
2006-08-30 00:45:00 +02:00
|
|
|
g_free (new_argv[ARG_WORKING_DIRECTORY]);
|
|
|
|
g_free (new_argv);
|
2008-02-24 22:15:47 +01:00
|
|
|
g_free (helper_process);
|
2005-08-26 01:28:24 +02:00
|
|
|
g_strfreev ((gchar **) wargv);
|
2006-08-30 00:45:00 +02:00
|
|
|
|
2008-02-24 22:15:47 +01:00
|
|
|
goto cleanup_and_fail;
|
2005-08-26 01:28:24 +02:00
|
|
|
}
|
2005-08-26 03:43:11 +02:00
|
|
|
|
2008-02-24 22:15:47 +01:00
|
|
|
whelper = g_utf8_to_utf16 (helper_process, -1, NULL, NULL, NULL);
|
|
|
|
g_free (helper_process);
|
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
if (wenvp != NULL)
|
|
|
|
rc = _wspawnvpe (P_NOWAIT, whelper, (const wchar_t **) wargv, (const wchar_t **) wenvp);
|
|
|
|
else
|
|
|
|
rc = _wspawnvp (P_NOWAIT, whelper, (const wchar_t **) wargv);
|
2004-12-11 04:47:32 +01:00
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
saved_errno = errno;
|
2005-08-26 01:28:24 +02:00
|
|
|
|
2006-08-30 00:45:00 +02:00
|
|
|
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 20:54:29 +02:00
|
|
|
|
2005-08-26 01:28:24 +02: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 20:54:29 +02:00
|
|
|
*/
|
2004-12-11 04:47:32 +01:00
|
|
|
close_and_invalidate (&child_err_report_pipe[1]);
|
2008-02-24 22:15:47 +01:00
|
|
|
close_and_invalidate (&helper_sync_pipe[0]);
|
2004-12-11 04:47:32 +01:00
|
|
|
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 20:54:29 +02:00
|
|
|
|
2005-08-26 01:28:24 +02:00
|
|
|
g_strfreev (protected_argv);
|
2003-09-30 22:04:51 +02:00
|
|
|
|
2008-03-03 05:23:16 +01:00
|
|
|
g_free (new_argv[0]);
|
2002-11-18 00:30:32 +01: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 20:54:29 +02:00
|
|
|
g_free (new_argv);
|
|
|
|
|
2003-07-31 03:25:19 +02:00
|
|
|
/* Check if gspawn-win32-helper couldn't be run */
|
2004-12-11 04:47:32 +01:00
|
|
|
if (rc == -1 && saved_errno != 0)
|
2002-11-18 00:30:32 +01:00
|
|
|
{
|
2005-08-26 03:43:11 +02:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
|
|
|
_("Failed to execute helper program (%s)"),
|
|
|
|
g_strerror (saved_errno));
|
2002-11-18 00:30:32 +01:00
|
|
|
goto cleanup_and_fail;
|
|
|
|
}
|
|
|
|
|
2005-09-07 12:10:49 +02:00
|
|
|
if (exit_status != NULL)
|
2003-07-31 03:25:19 +02:00
|
|
|
{
|
2004-12-11 04:47:32 +01: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];
|
2008-02-24 22:15:47 +01:00
|
|
|
write (helper_sync_pipe[1], " ", 1);
|
|
|
|
close_and_invalidate (&helper_sync_pipe[1]);
|
2003-07-31 03:25:19 +02:00
|
|
|
}
|
2004-12-11 04:47:32 +01:00
|
|
|
else
|
2003-07-31 03:25:19 +02:00
|
|
|
{
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
|
2008-02-24 22:15:47 +01:00
|
|
|
close_and_invalidate (&child_err_report_pipe[0]);
|
2004-12-11 04:47:32 +01:00
|
|
|
|
|
|
|
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 20:54:29 +02:00
|
|
|
{
|
2004-12-11 04:47:32 +01:00
|
|
|
case CHILD_NO_ERROR:
|
2005-09-07 12:10:49 +02:00
|
|
|
if (child_handle && do_return_handle)
|
2004-12-11 04:47:32 +01: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))
|
2008-02-24 22:15:47 +01:00
|
|
|
{
|
|
|
|
char *emsg = g_win32_error_message (GetLastError ());
|
|
|
|
g_print("%s\n", emsg);
|
|
|
|
*child_handle = 0;
|
|
|
|
}
|
2004-12-11 04:47:32 +01:00
|
|
|
}
|
|
|
|
else if (child_handle)
|
2003-07-31 03:25:19 +02:00
|
|
|
*child_handle = 0;
|
2008-02-24 22:15:47 +01:00
|
|
|
write (helper_sync_pipe[1], " ", 1);
|
|
|
|
close_and_invalidate (&helper_sync_pipe[1]);
|
2004-12-11 04:47:32 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2008-02-24 22:15:47 +01:00
|
|
|
write (helper_sync_pipe[1], " ", 1);
|
|
|
|
close_and_invalidate (&helper_sync_pipe[1]);
|
2004-12-11 04:47:32 +01:00
|
|
|
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 20:54:29 +02: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 04:47:32 +01: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 20:54:29 +02:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
cleanup_and_fail:
|
2008-03-03 05:23:16 +01:00
|
|
|
|
2004-12-11 04:47:32 +01: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]);
|
2008-02-24 22:15:47 +01:00
|
|
|
if (helper_sync_pipe[0] != -1)
|
|
|
|
close (helper_sync_pipe[0]);
|
|
|
|
if (helper_sync_pipe[1] != -1)
|
|
|
|
close (helper_sync_pipe[1]);
|
2004-12-11 04:47:32 +01:00
|
|
|
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 20:54:29 +02:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-12-11 04:47:32 +01:00
|
|
|
gboolean
|
2005-08-26 01:28:24 +02: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 20:54:29 +02:00
|
|
|
{
|
2004-12-11 04:47:32 +01: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 12:10:49 +02:00
|
|
|
if (!do_spawn_with_pipes (&status,
|
|
|
|
FALSE,
|
2004-12-11 04:47:32 +01:00
|
|
|
working_directory,
|
|
|
|
argv,
|
|
|
|
envp,
|
|
|
|
flags,
|
|
|
|
child_setup,
|
2005-03-20 12:46:27 +01:00
|
|
|
NULL,
|
2004-12-11 04:47:32 +01: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 20:54:29 +02:00
|
|
|
{
|
2004-12-11 04:47:32 +01: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 12:15:56 +01:00
|
|
|
g_io_channel_set_buffered (outchannel, FALSE);
|
2004-12-11 04:47:32 +01:00
|
|
|
g_io_channel_win32_make_pollfd (outchannel,
|
|
|
|
G_IO_IN | G_IO_ERR | G_IO_HUP,
|
|
|
|
&outfd);
|
2006-01-01 12:15:56 +01:00
|
|
|
if (debug)
|
Fix problems on 64-bit Windows. Avoid warnings, some of which indicated
2008-07-28 Tor Lillqvist <tml@novell.com>
Fix problems on 64-bit Windows. Avoid warnings, some of which
indicated actual problems, some which were just annoyances.
Where casts to an integer type are needed for pointers, use
gssize. Technically intptr_t would be the more proper type, but we
still want to be compilable with MSVS6 and 7 which don't have
intptr_t. MSVS8 and 9 do have intptr_t, but in <crtdefs.h>, not
<stdint.h>.
Use %p to print out handles. Use gssize casts when assigning
GPollFD::fd fields.
Use G_GSIZE_FORMAT when printing size_t values.
* configure.in: Define automake conditional G_OS_WIN32_X64 which
is true on Win64.
* glib/giochannel.h: Use slightly different prototype for
g_io_channel_win32_new_messages() on Win64 with gsize instead of
guint.
* glib/giowin32.c
* glib/gmain.c
* glib/gspawn-win32.c
* tests/testglib.c: Generic changes as described above.
* glib/gmain.h: Don't bother mentioning GIMP in comment.
* glib/grel.c (tuple_hash_2): Use all bits of pointer.
* glib/gspawn-win32.c
* glib/gspawn-win32-helper.c: Use gssize types in the
communication between parent and helper process, so that we can
pass process handles, which are pointers, also on Win64.
* glib/gtimer.c (g_time_val_to_iso8601): time_t is 64 bits on
Win64 so we can't pass the address of a GTimeVal::tv_sec which is
a long directly to gmtime(). On the other hand, changing
GTimeVal::tv_sec to be a gint64 on Win64 is not really feasible
either, as that would then require changes in much code that uses
GTimeVals.
* glib/gspawn-win32.c
* glib/Makefile.am: Call the helper programs
gspawn-win64-helper.exe and gspawn-win64-helper-console.exe on
Win64, to avoid potential risk of running a 32-bit version of the
helper.
svn path=/trunk/; revision=7260
2008-07-28 02:24:14 +02:00
|
|
|
g_print ("outfd=%p\n", (HANDLE) outfd.fd);
|
2004-12-11 04:47:32 +01: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 12:15:56 +01:00
|
|
|
g_io_channel_set_buffered (errchannel, FALSE);
|
2004-12-11 04:47:32 +01:00
|
|
|
g_io_channel_win32_make_pollfd (errchannel,
|
|
|
|
G_IO_IN | G_IO_ERR | G_IO_HUP,
|
|
|
|
&errfd);
|
2006-01-01 12:15:56 +01:00
|
|
|
if (debug)
|
Fix problems on 64-bit Windows. Avoid warnings, some of which indicated
2008-07-28 Tor Lillqvist <tml@novell.com>
Fix problems on 64-bit Windows. Avoid warnings, some of which
indicated actual problems, some which were just annoyances.
Where casts to an integer type are needed for pointers, use
gssize. Technically intptr_t would be the more proper type, but we
still want to be compilable with MSVS6 and 7 which don't have
intptr_t. MSVS8 and 9 do have intptr_t, but in <crtdefs.h>, not
<stdint.h>.
Use %p to print out handles. Use gssize casts when assigning
GPollFD::fd fields.
Use G_GSIZE_FORMAT when printing size_t values.
* configure.in: Define automake conditional G_OS_WIN32_X64 which
is true on Win64.
* glib/giochannel.h: Use slightly different prototype for
g_io_channel_win32_new_messages() on Win64 with gsize instead of
guint.
* glib/giowin32.c
* glib/gmain.c
* glib/gspawn-win32.c
* tests/testglib.c: Generic changes as described above.
* glib/gmain.h: Don't bother mentioning GIMP in comment.
* glib/grel.c (tuple_hash_2): Use all bits of pointer.
* glib/gspawn-win32.c
* glib/gspawn-win32-helper.c: Use gssize types in the
communication between parent and helper process, so that we can
pass process handles, which are pointers, also on Win64.
* glib/gtimer.c (g_time_val_to_iso8601): time_t is 64 bits on
Win64 so we can't pass the address of a GTimeVal::tv_sec which is
a long directly to gmtime(). On the other hand, changing
GTimeVal::tv_sec to be a gint64 on Win64 is not really feasible
either, as that would then require changes in much code that uses
GTimeVals.
* glib/gspawn-win32.c
* glib/Makefile.am: Call the helper programs
gspawn-win64-helper.exe and gspawn-win64-helper-console.exe on
Win64, to avoid potential risk of running a 32-bit version of the
helper.
svn path=/trunk/; revision=7260
2008-07-28 02:24:14 +02:00
|
|
|
g_print ("errfd=%p\n", (HANDLE) errfd.fd);
|
2004-12-11 04:47:32 +01: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;
|
|
|
|
|
2008-06-16 18:53:58 +02:00
|
|
|
g_set_error_literal (error, G_SPAWN_ERROR, G_SPAWN_ERROR_READ,
|
|
|
|
_("Unexpected error in g_io_channel_win32_poll() reading data from a child process"));
|
2004-12-11 04:47:32 +01:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
2008-08-04 20:46:59 +02:00
|
|
|
gintptr helper_report[2];
|
2004-12-11 04:47:32 +01:00
|
|
|
|
|
|
|
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 20:54:29 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
2004-12-11 04:47:32 +01: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-26 01:28:24 +02: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 04:47:32 +01: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 12:10:49 +02:00
|
|
|
return do_spawn_with_pipes (NULL,
|
|
|
|
(flags & G_SPAWN_DO_NOT_REAP_CHILD),
|
2004-12-11 04:47:32 +01:00
|
|
|
working_directory,
|
|
|
|
argv,
|
|
|
|
envp,
|
|
|
|
flags,
|
|
|
|
child_setup,
|
|
|
|
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 20:54:29 +02:00
|
|
|
}
|
2004-12-11 04:47:32 +01:00
|
|
|
|
2005-08-26 01:28:24 +02: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);
|
|
|
|
}
|
|
|
|
|
2012-07-11 19:41:58 +02:00
|
|
|
gboolean
|
|
|
|
g_spawn_check_exit_status (gint exit_status,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
gboolean ret = FALSE;
|
|
|
|
|
|
|
|
if (exit_status != 0)
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_EXIT_ERROR, exit_status,
|
|
|
|
_("Child process exited with code %ld"),
|
|
|
|
(long) exit_status);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = TRUE;
|
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-07-27 19:15:16 +02:00
|
|
|
#if !defined (_WIN64)
|
|
|
|
|
2005-08-26 01:28:24 +02:00
|
|
|
/* 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 03:43:11 +02:00
|
|
|
GError *conv_error = NULL;
|
|
|
|
|
|
|
|
*utf8_working_directory = g_locale_to_utf8 (working_directory, -1, NULL, NULL, &conv_error);
|
2005-08-26 01:28:24 +02:00
|
|
|
if (*utf8_working_directory == NULL)
|
2005-08-26 03:43:11 +02: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-26 01:28:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
argc = 0;
|
|
|
|
while (argv[argc])
|
|
|
|
++argc;
|
|
|
|
*utf8_argv = g_new (gchar *, argc + 1);
|
|
|
|
for (i = 0; i < argc; i++)
|
|
|
|
{
|
2005-08-26 03:43:11 +02:00
|
|
|
GError *conv_error = NULL;
|
|
|
|
|
|
|
|
(*utf8_argv)[i] = g_locale_to_utf8 (argv[i], -1, NULL, NULL, &conv_error);
|
2005-08-26 01:28:24 +02:00
|
|
|
if ((*utf8_argv)[i] == NULL)
|
2005-08-26 03:43:11 +02:00
|
|
|
{
|
2005-08-26 01:28:24 +02:00
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
2005-08-26 03:43:11 +02:00
|
|
|
_("Invalid string in argument vector at %d: %s"),
|
|
|
|
i, conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
2005-08-26 01:28:24 +02: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 03:43:11 +02:00
|
|
|
GError *conv_error = NULL;
|
|
|
|
|
|
|
|
(*utf8_envp)[i] = g_locale_to_utf8 (envp[i], -1, NULL, NULL, &conv_error);
|
2005-08-26 01:28:24 +02:00
|
|
|
if ((*utf8_envp)[i] == NULL)
|
|
|
|
{
|
|
|
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
2005-08-26 03:43:11 +02:00
|
|
|
_("Invalid string in environment: %s"),
|
|
|
|
conv_error->message);
|
|
|
|
g_error_free (conv_error);
|
2005-08-26 01:28:24 +02: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 04:47:32 +01:00
|
|
|
gboolean
|
|
|
|
g_spawn_command_line_sync (const gchar *command_line,
|
2005-08-26 01:28:24 +02:00
|
|
|
gchar **standard_output,
|
|
|
|
gchar **standard_error,
|
|
|
|
gint *exit_status,
|
|
|
|
GError **error)
|
2004-12-11 04:47:32 +01: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-26 01:28:24 +02:00
|
|
|
GError **error)
|
2004-12-11 04:47:32 +01: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;
|
|
|
|
}
|
|
|
|
|
2008-07-27 19:15:16 +02:00
|
|
|
#endif /* !_WIN64 */
|
|
|
|
|
2000-11-28 21:04:08 +01:00
|
|
|
#endif /* !GSPAWN_HELPER */
|