summaryrefslogtreecommitdiff
path: root/src/3rd_party/dbus-1.7.8/dbus/dbus-spawn-win.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rd_party/dbus-1.7.8/dbus/dbus-spawn-win.c')
-rw-r--r--src/3rd_party/dbus-1.7.8/dbus/dbus-spawn-win.c1046
1 files changed, 0 insertions, 1046 deletions
diff --git a/src/3rd_party/dbus-1.7.8/dbus/dbus-spawn-win.c b/src/3rd_party/dbus-1.7.8/dbus/dbus-spawn-win.c
deleted file mode 100644
index 7da7a431bf..0000000000
--- a/src/3rd_party/dbus-1.7.8/dbus/dbus-spawn-win.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-#include <config.h>
-
-//#define SPAWN_DEBUG
-
-#if !defined(SPAWN_DEBUG) || defined(_MSC_VER)
-#define PING()
-#else
-#define PING() fprintf (stderr, "%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); fflush (stderr)
-#endif
-
-#include <stdio.h>
-
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-/* dbus-spawn-win32.c Wrapper around g_spawn
- *
- * Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
- * Copyright (C) 2003 CodeFactory AB
- * Copyright (C) 2005 Novell, Inc.
- *
- * Licensed under the Academic Free License version 2.1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-#include "dbus-spawn.h"
-#include "dbus-sysdeps.h"
-#include "dbus-sysdeps-win.h"
-#include "dbus-internals.h"
-#include "dbus-test.h"
-#include "dbus-protocol.h"
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-//#define STRICT
-//#include <windows.h>
-//#undef STRICT
-#include <winsock2.h>
-#undef interface
-
-#include <stdlib.h>
-
-#ifndef DBUS_WINCE
-#include <process.h>
-#endif
-
-/**
- * Babysitter implementation details
- */
-struct DBusBabysitter
- {
- int refcount;
-
- HANDLE start_sync_event;
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
-
- HANDLE end_sync_event;
-#endif
-
- char *log_name;
- DBusSpawnChildSetupFunc child_setup;
- void *user_data;
-
- int argc;
- char **argv;
- char **envp;
-
- HANDLE child_handle;
- int socket_to_babysitter; /* Connection to the babysitter thread */
- int socket_to_main;
-
- DBusWatchList *watches;
- DBusWatch *sitter_watch;
- DBusBabysitterFinishedFunc finished_cb;
- void *finished_data;
-
- dbus_bool_t have_spawn_errno;
- int spawn_errno;
- dbus_bool_t have_child_status;
- int child_status;
- };
-
-static DBusBabysitter*
-_dbus_babysitter_new (void)
-{
- DBusBabysitter *sitter;
-
- sitter = dbus_new0 (DBusBabysitter, 1);
- if (sitter == NULL)
- return NULL;
-
- sitter->refcount = 1;
-
- sitter->start_sync_event = CreateEvent (NULL, FALSE, FALSE, NULL);
- if (sitter->start_sync_event == NULL)
- {
- _dbus_babysitter_unref (sitter);
- return NULL;
- }
-
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
- sitter->end_sync_event = CreateEvent (NULL, FALSE, FALSE, NULL);
- if (sitter->end_sync_event == NULL)
- {
- _dbus_babysitter_unref (sitter);
- return NULL;
- }
-#endif
-
- sitter->child_handle = NULL;
-
- sitter->socket_to_babysitter = sitter->socket_to_main = -1;
-
- sitter->argc = 0;
- sitter->argv = NULL;
- sitter->envp = NULL;
-
- sitter->watches = _dbus_watch_list_new ();
- if (sitter->watches == NULL)
- {
- _dbus_babysitter_unref (sitter);
- return NULL;
- }
-
- sitter->have_spawn_errno = FALSE;
- sitter->have_child_status = FALSE;
-
- return sitter;
-}
-
-/**
- * Increment the reference count on the babysitter object.
- *
- * @param sitter the babysitter
- * @returns the babysitter
- */
-DBusBabysitter *
-_dbus_babysitter_ref (DBusBabysitter *sitter)
-{
- PING();
- _dbus_assert (sitter != NULL);
- _dbus_assert (sitter->refcount > 0);
-
- sitter->refcount += 1;
-
- return sitter;
-}
-
-static void
-close_socket_to_babysitter (DBusBabysitter *sitter)
-{
- _dbus_verbose ("Closing babysitter\n");
-
- if (sitter->sitter_watch != NULL)
- {
- _dbus_assert (sitter->watches != NULL);
- _dbus_watch_list_remove_watch (sitter->watches, sitter->sitter_watch);
- _dbus_watch_invalidate (sitter->sitter_watch);
- _dbus_watch_unref (sitter->sitter_watch);
- sitter->sitter_watch = NULL;
- }
-
- if (sitter->socket_to_babysitter != -1)
- {
- _dbus_close_socket (sitter->socket_to_babysitter, NULL);
- sitter->socket_to_babysitter = -1;
- }
-}
-
-/**
- * Decrement the reference count on the babysitter object.
- *
- * @param sitter the babysitter
- */
-void
-_dbus_babysitter_unref (DBusBabysitter *sitter)
-{
- int i;
-
- PING();
- _dbus_assert (sitter != NULL);
- _dbus_assert (sitter->refcount > 0);
-
- sitter->refcount -= 1;
-
- if (sitter->refcount == 0)
- {
- close_socket_to_babysitter (sitter);
-
- if (sitter->socket_to_main != -1)
- {
- _dbus_close_socket (sitter->socket_to_main, NULL);
- sitter->socket_to_main = -1;
- }
-
- PING();
- if (sitter->argv != NULL)
- {
- for (i = 0; i < sitter->argc; i++)
- if (sitter->argv[i] != NULL)
- {
- dbus_free (sitter->argv[i]);
- sitter->argv[i] = NULL;
- }
- dbus_free (sitter->argv);
- sitter->argv = NULL;
- }
-
- if (sitter->envp != NULL)
- {
- char **e = sitter->envp;
-
- while (*e)
- dbus_free (*e++);
- dbus_free (sitter->envp);
- sitter->envp = NULL;
- }
-
- if (sitter->child_handle != NULL)
- {
- CloseHandle (sitter->child_handle);
- sitter->child_handle = NULL;
- }
-
- if (sitter->sitter_watch)
- {
- _dbus_watch_invalidate (sitter->sitter_watch);
- _dbus_watch_unref (sitter->sitter_watch);
- sitter->sitter_watch = NULL;
- }
-
- if (sitter->watches)
- _dbus_watch_list_free (sitter->watches);
-
- if (sitter->start_sync_event != NULL)
- {
- PING();
- CloseHandle (sitter->start_sync_event);
- sitter->start_sync_event = NULL;
- }
-
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
- if (sitter->end_sync_event != NULL)
- {
- CloseHandle (sitter->end_sync_event);
- sitter->end_sync_event = NULL;
- }
-#endif
-
- dbus_free (sitter->log_name);
-
- dbus_free (sitter);
- }
-}
-
-void
-_dbus_babysitter_kill_child (DBusBabysitter *sitter)
-{
- PING();
- if (sitter->child_handle == NULL)
- return; /* child is already dead, or we're so hosed we'll never recover */
-
- PING();
- TerminateProcess (sitter->child_handle, 12345);
-}
-
-/**
- * Checks whether the child has exited, without blocking.
- *
- * @param sitter the babysitter
- */
-dbus_bool_t
-_dbus_babysitter_get_child_exited (DBusBabysitter *sitter)
-{
- PING();
- return (sitter->child_handle == NULL);
-}
-
-/**
- * Gets the exit status of the child. We do this so implementation specific
- * detail is not cluttering up dbus, for example the system launcher code.
- * This can only be called if the child has exited, i.e. call
- * _dbus_babysitter_get_child_exited(). It returns FALSE if the child
- * did not return a status code, e.g. because the child was signaled
- * or we failed to ever launch the child in the first place.
- *
- * @param sitter the babysitter
- * @param status the returned status code
- * @returns #FALSE on failure
- */
-dbus_bool_t
-_dbus_babysitter_get_child_exit_status (DBusBabysitter *sitter,
- int *status)
-{
- if (!_dbus_babysitter_get_child_exited (sitter))
- _dbus_assert_not_reached ("Child has not exited");
-
- if (!sitter->have_child_status ||
- sitter->child_status == STILL_ACTIVE)
- return FALSE;
-
- *status = sitter->child_status;
- return TRUE;
-}
-
-/**
- * Sets the #DBusError with an explanation of why the spawned
- * child process exited (on a signal, or whatever). If
- * the child process has not exited, does nothing (error
- * will remain unset).
- *
- * @param sitter the babysitter
- * @param error an error to fill in
- */
-void
-_dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter,
- DBusError *error)
-{
- PING();
- if (!_dbus_babysitter_get_child_exited (sitter))
- return;
-
- PING();
- if (sitter->have_spawn_errno)
- {
- char *emsg = _dbus_win_error_string (sitter->spawn_errno);
- dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
- "Failed to execute program %s: %s",
- sitter->log_name, emsg);
- _dbus_win_free_error_string (emsg);
- }
- else if (sitter->have_child_status)
- {
- PING();
- dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED,
- "Process %s exited with status %d",
- sitter->log_name, sitter->child_status);
- }
- else
- {
- PING();
- dbus_set_error (error, DBUS_ERROR_FAILED,
- "Process %s exited, status unknown",
- sitter->log_name);
- }
- PING();
-}
-
-dbus_bool_t
-_dbus_babysitter_set_watch_functions (DBusBabysitter *sitter,
- DBusAddWatchFunction add_function,
- DBusRemoveWatchFunction remove_function,
- DBusWatchToggledFunction toggled_function,
- void *data,
- DBusFreeFunction free_data_function)
-{
- PING();
- return _dbus_watch_list_set_functions (sitter->watches,
- add_function,
- remove_function,
- toggled_function,
- data,
- free_data_function);
-}
-
-static dbus_bool_t
-handle_watch (DBusWatch *watch,
- unsigned int condition,
- void *data)
-{
- DBusBabysitter *sitter = data;
-
- /* On Unix dbus-spawn uses a babysitter *process*, thus it has to
- * actually send the exit statuses, error codes and whatnot through
- * sockets and/or pipes. On Win32, the babysitter is jus a thread,
- * so it can set the status fields directly in the babysitter struct
- * just fine. The socket pipe is used just so we can watch it with
- * select(), as soon as anything is written to it we know that the
- * babysitter thread has recorded the status in the babysitter
- * struct.
- */
-
- PING();
- close_socket_to_babysitter (sitter);
- PING();
-
- if (_dbus_babysitter_get_child_exited (sitter) &&
- sitter->finished_cb != NULL)
- {
- sitter->finished_cb (sitter, sitter->finished_data);
- sitter->finished_cb = NULL;
- }
-
- return TRUE;
-}
-
-/* protect_argv lifted from GLib, relicensed by author, Tor Lillqvist */
-static int
-protect_argv (char **argv,
- char ***new_argv)
-{
- int i;
- int argc = 0;
-
- while (argv[argc])
- ++argc;
- *new_argv = dbus_malloc ((argc + 1) * sizeof (char *));
- if (*new_argv == NULL)
- return -1;
-
- for (i = 0; i < argc; i++)
- (*new_argv)[i] = NULL;
-
- /* 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++)
- {
- char *p = argv[i];
- char *q;
- int len = 0;
- int need_dblquotes = FALSE;
- while (*p)
- {
- if (*p == ' ' || *p == '\t')
- need_dblquotes = TRUE;
- else if (*p == '"')
- len++;
- else if (*p == '\\')
- {
- char *pp = p;
- while (*pp && *pp == '\\')
- pp++;
- if (*pp == '"')
- len++;
- }
- len++;
- p++;
- }
-
- q = (*new_argv)[i] = dbus_malloc (len + need_dblquotes*2 + 1);
-
- if (q == NULL)
- return -1;
-
-
- p = argv[i];
-
- if (need_dblquotes)
- *q++ = '"';
-
- while (*p)
- {
- if (*p == '"')
- *q++ = '\\';
- else if (*p == '\\')
- {
- char *pp = p;
- while (*pp && *pp == '\\')
- pp++;
- if (*pp == '"')
- *q++ = '\\';
- }
- *q++ = *p;
- p++;
- }
-
- if (need_dblquotes)
- *q++ = '"';
- *q++ = '\0';
- /* printf ("argv[%d]:%s, need_dblquotes:%s len:%d => %s\n", i, argv[i], need_dblquotes?"TRUE":"FALSE", len, (*new_argv)[i]); */
- }
- (*new_argv)[argc] = NULL;
-
- return argc;
-}
-
-
-/* From GPGME, relicensed by g10 Code GmbH. */
-static char *
-compose_string (char **strings, char separator)
-{
- int i;
- int n = 0;
- char *buf;
- char *p;
-
- if (!strings || !strings[0])
- return 0;
- for (i = 0; strings[i]; i++)
- n += strlen (strings[i]) + 1;
- n++;
-
- buf = p = malloc (n);
- if (!buf)
- return NULL;
- for (i = 0; strings[i]; i++)
- {
- strcpy (p, strings[i]);
- p += strlen (strings[i]);
- *(p++) = separator;
- }
- p--;
- *(p++) = '\0';
- *p = '\0';
-
- return buf;
-}
-
-static char *
-build_commandline (char **argv)
-{
- return compose_string (argv, ' ');
-}
-
-static char *
-build_env_string (char** envp)
-{
- return compose_string (envp, '\0');
-}
-
-static HANDLE
-spawn_program (char* name, char** argv, char** envp)
-{
- PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
- STARTUPINFOA si;
- char *arg_string, *env_string;
- BOOL result;
-
-#ifdef DBUS_WINCE
- if (argv && argv[0])
- arg_string = build_commandline (argv + 1);
- else
- arg_string = NULL;
-#else
- arg_string = build_commandline (argv);
-#endif
- if (!arg_string)
- return INVALID_HANDLE_VALUE;
-
- env_string = build_env_string(envp);
-
- memset (&si, 0, sizeof (si));
- si.cb = sizeof (si);
-#ifdef DBUS_WINCE
- result = CreateProcessA (name, arg_string, NULL, NULL, FALSE, 0,
-#else
- result = CreateProcessA (NULL, arg_string, NULL, NULL, FALSE, 0,
-#endif
- (LPVOID)env_string, NULL, &si, &pi);
- free (arg_string);
- if (env_string)
- free (env_string);
-
- if (!result)
- return INVALID_HANDLE_VALUE;
-
- CloseHandle (pi.hThread);
- return pi.hProcess;
-}
-
-
-static DWORD __stdcall
-babysitter (void *parameter)
-{
- DBusBabysitter *sitter = (DBusBabysitter *) parameter;
-
- PING();
- _dbus_babysitter_ref (sitter);
-
- if (sitter->child_setup)
- {
- PING();
- (*sitter->child_setup) (sitter->user_data);
- }
-
- _dbus_verbose ("babysitter: spawning %s\n", sitter->log_name);
-
- PING();
- sitter->child_handle = spawn_program (sitter->log_name,
- sitter->argv, sitter->envp);
-
- PING();
- if (sitter->child_handle == (HANDLE) -1)
- {
- sitter->child_handle = NULL;
- sitter->have_spawn_errno = TRUE;
- sitter->spawn_errno = GetLastError();
- }
-
- PING();
- SetEvent (sitter->start_sync_event);
-
- if (sitter->child_handle != NULL)
- {
- int ret;
- DWORD status;
-
- PING();
- WaitForSingleObject (sitter->child_handle, INFINITE);
-
- PING();
- ret = GetExitCodeProcess (sitter->child_handle, &status);
-
- sitter->child_status = status;
- sitter->have_child_status = TRUE;
-
- CloseHandle (sitter->child_handle);
- sitter->child_handle = NULL;
- }
-
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
- SetEvent (sitter->end_sync_event);
-#endif
-
- PING();
- send (sitter->socket_to_main, " ", 1, 0);
-
- _dbus_babysitter_unref (sitter);
-
- return 0;
-}
-
-dbus_bool_t
-_dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
- const char *log_name,
- char **argv,
- char **envp,
- DBusSpawnChildSetupFunc child_setup,
- void *user_data,
- DBusError *error)
-{
- DBusBabysitter *sitter;
- HANDLE sitter_thread;
- DWORD sitter_thread_id;
-
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
- _dbus_assert (argv[0] != NULL);
-
- *sitter_p = NULL;
-
- PING();
- sitter = _dbus_babysitter_new ();
- if (sitter == NULL)
- {
- _DBUS_SET_OOM (error);
- return FALSE;
- }
-
- sitter->child_setup = child_setup;
- sitter->user_data = user_data;
-
- sitter->log_name = _dbus_strdup (log_name);
- if (sitter->log_name == NULL && log_name != NULL)
- {
- _DBUS_SET_OOM (error);
- goto out0;
- }
-
- if (sitter->log_name == NULL)
- sitter->log_name = _dbus_strdup (argv[0]);
-
- if (sitter->log_name == NULL)
- {
- _DBUS_SET_OOM (error);
- goto out0;
- }
-
- PING();
- if (!_dbus_full_duplex_pipe (&sitter->socket_to_babysitter,
- &sitter->socket_to_main,
- FALSE, error))
- goto out0;
-
- sitter->sitter_watch = _dbus_watch_new (sitter->socket_to_babysitter,
- DBUS_WATCH_READABLE,
- TRUE, handle_watch, sitter, NULL);
- PING();
- if (sitter->sitter_watch == NULL)
- {
- _DBUS_SET_OOM (error);
- goto out0;
- }
-
- PING();
- if (!_dbus_watch_list_add_watch (sitter->watches, sitter->sitter_watch))
- {
- /* we need to free it early so the destructor won't try to remove it
- * without it having been added, which DBusLoop doesn't allow */
- _dbus_watch_invalidate (sitter->sitter_watch);
- _dbus_watch_unref (sitter->sitter_watch);
- sitter->sitter_watch = NULL;
-
- _DBUS_SET_OOM (error);
- goto out0;
- }
-
- sitter->argc = protect_argv (argv, &sitter->argv);
- if (sitter->argc == -1)
- {
- _DBUS_SET_OOM (error);
- goto out0;
- }
- sitter->envp = envp;
-
- PING();
- sitter_thread = (HANDLE) CreateThread (NULL, 0, babysitter,
- sitter, 0, &sitter_thread_id);
-
- if (sitter_thread == 0)
- {
- PING();
- dbus_set_error_const (error, DBUS_ERROR_SPAWN_FORK_FAILED,
- "Failed to create new thread");
- goto out0;
- }
- CloseHandle (sitter_thread);
-
- PING();
- WaitForSingleObject (sitter->start_sync_event, INFINITE);
-
- PING();
- if (sitter_p != NULL)
- *sitter_p = sitter;
- else
- _dbus_babysitter_unref (sitter);
-
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
- PING();
- return TRUE;
-
-out0:
- _dbus_babysitter_unref (sitter);
-
- return FALSE;
-}
-
-void
-_dbus_babysitter_set_result_function (DBusBabysitter *sitter,
- DBusBabysitterFinishedFunc finished,
- void *user_data)
-{
- sitter->finished_cb = finished;
- sitter->finished_data = user_data;
-}
-
-#ifdef DBUS_ENABLE_EMBEDDED_TESTS
-
-static char *
-get_test_exec (const char *exe,
- DBusString *scratch_space)
-{
- const char *dbus_test_exec;
-
- dbus_test_exec = _dbus_getenv ("DBUS_TEST_EXEC");
-
- if (dbus_test_exec == NULL)
- dbus_test_exec = DBUS_TEST_EXEC;
-
- if (!_dbus_string_init (scratch_space))
- return NULL;
-
- if (!_dbus_string_append_printf (scratch_space, "%s/%s%s",
- dbus_test_exec, exe, DBUS_EXEEXT))
- {
- _dbus_string_free (scratch_space);
- return NULL;
- }
-
- return _dbus_string_get_data (scratch_space);
-}
-
-#define LIVE_CHILDREN(sitter) ((sitter)->child_handle != NULL)
-
-static void
-_dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter)
-{
- if (sitter->child_handle == NULL)
- return;
-
- WaitForSingleObject (sitter->end_sync_event, INFINITE);
-}
-
-static dbus_bool_t
-check_spawn_nonexistent (void *data)
-{
- char *argv[4] = { NULL, NULL, NULL, NULL };
- DBusBabysitter *sitter;
- DBusError error;
-
- sitter = NULL;
-
- dbus_error_init (&error);
-
- /*** Test launching nonexistent binary */
-
- argv[0] = "/this/does/not/exist/32542sdgafgafdg";
- if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_nonexistent", argv, NULL,
- NULL, NULL,
- &error))
- {
- _dbus_babysitter_block_for_child_exit (sitter);
- _dbus_babysitter_set_child_exit_error (sitter, &error);
- }
-
- if (sitter)
- _dbus_babysitter_unref (sitter);
-
- if (!dbus_error_is_set (&error))
- {
- _dbus_warn ("Did not get an error launching nonexistent executable\n");
- return FALSE;
- }
-
- if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
- dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED)))
- {
- _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n",
- error.name, error.message);
- dbus_error_free (&error);
- return FALSE;
- }
-
- dbus_error_free (&error);
-
- return TRUE;
-}
-
-static dbus_bool_t
-check_spawn_segfault (void *data)
-{
- char *argv[4] = { NULL, NULL, NULL, NULL };
- DBusBabysitter *sitter;
- DBusError error;
- DBusString argv0;
-
- sitter = NULL;
-
- dbus_error_init (&error);
-
- /*** Test launching segfault binary */
-
- argv[0] = get_test_exec ("test-segfault", &argv0);
-
- if (argv[0] == NULL)
- {
- /* OOM was simulated, never mind */
- return TRUE;
- }
-
- if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_segfault", argv, NULL,
- NULL, NULL,
- &error))
- {
- _dbus_babysitter_block_for_child_exit (sitter);
- _dbus_babysitter_set_child_exit_error (sitter, &error);
- }
-
- _dbus_string_free (&argv0);
-
- if (sitter)
- _dbus_babysitter_unref (sitter);
-
- if (!dbus_error_is_set (&error))
- {
- _dbus_warn ("Did not get an error launching segfaulting binary\n");
- return FALSE;
- }
-
- if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
- dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
- {
- _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n",
- error.name, error.message);
- dbus_error_free (&error);
- return FALSE;
- }
-
- dbus_error_free (&error);
-
- return TRUE;
-}
-
-static dbus_bool_t
-check_spawn_exit (void *data)
-{
- char *argv[4] = { NULL, NULL, NULL, NULL };
- DBusBabysitter *sitter;
- DBusError error;
- DBusString argv0;
-
- sitter = NULL;
-
- dbus_error_init (&error);
-
- /*** Test launching exit failure binary */
-
- argv[0] = get_test_exec ("test-exit", &argv0);
-
- if (argv[0] == NULL)
- {
- /* OOM was simulated, never mind */
- return TRUE;
- }
-
- if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_exit", argv, NULL,
- NULL, NULL,
- &error))
- {
- _dbus_babysitter_block_for_child_exit (sitter);
- _dbus_babysitter_set_child_exit_error (sitter, &error);
- }
-
- _dbus_string_free (&argv0);
-
- if (sitter)
- _dbus_babysitter_unref (sitter);
-
- if (!dbus_error_is_set (&error))
- {
- _dbus_warn ("Did not get an error launching binary that exited with failure code\n");
- return FALSE;
- }
-
- if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
- dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
- {
- _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n",
- error.name, error.message);
- dbus_error_free (&error);
- return FALSE;
- }
-
- dbus_error_free (&error);
-
- return TRUE;
-}
-
-static dbus_bool_t
-check_spawn_and_kill (void *data)
-{
- char *argv[4] = { NULL, NULL, NULL, NULL };
- DBusBabysitter *sitter;
- DBusError error;
- DBusString argv0;
-
- sitter = NULL;
-
- dbus_error_init (&error);
-
- /*** Test launching sleeping binary then killing it */
-
- argv[0] = get_test_exec ("test-sleep-forever", &argv0);
-
- if (argv[0] == NULL)
- {
- /* OOM was simulated, never mind */
- return TRUE;
- }
-
- if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_and_kill", argv, NULL,
- NULL, NULL,
- &error))
- {
- _dbus_babysitter_kill_child (sitter);
-
- _dbus_babysitter_block_for_child_exit (sitter);
-
- _dbus_babysitter_set_child_exit_error (sitter, &error);
- }
-
- _dbus_string_free (&argv0);
-
- if (sitter)
- _dbus_babysitter_unref (sitter);
-
- if (!dbus_error_is_set (&error))
- {
- _dbus_warn ("Did not get an error after killing spawned binary\n");
- return FALSE;
- }
-
- if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
- dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
- {
- _dbus_warn ("Not expecting error when killing executable: %s: %s\n",
- error.name, error.message);
- dbus_error_free (&error);
- return FALSE;
- }
-
- dbus_error_free (&error);
-
- return TRUE;
-}
-
-dbus_bool_t
-_dbus_spawn_test (const char *test_data_dir)
-{
- if (!_dbus_test_oom_handling ("spawn_nonexistent",
- check_spawn_nonexistent,
- NULL))
- return FALSE;
-
- /* Don't run the obnoxious segfault test by default,
- * it's a pain to have to click all those error boxes.
- */
- if (getenv ("DO_SEGFAULT_TEST"))
- if (!_dbus_test_oom_handling ("spawn_segfault",
- check_spawn_segfault,
- NULL))
- return FALSE;
-
- if (!_dbus_test_oom_handling ("spawn_exit",
- check_spawn_exit,
- NULL))
- return FALSE;
-
- if (!_dbus_test_oom_handling ("spawn_and_kill",
- check_spawn_and_kill,
- NULL))
- return FALSE;
-
- return TRUE;
-}
-#endif