1dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann#include <config.h> 270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 30c0df1910d8ab15b214f5129a72e10f54941524fRalf Habacker//#define SPAWN_DEBUG 40c0df1910d8ab15b214f5129a72e10f54941524fRalf Habacker 51f9f66bba806475dc38f225f9a394742ad3f8d69Ralf Habacker#if !defined(SPAWN_DEBUG) || defined(_MSC_VER) 670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#define PING() 770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#else 870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#define PING() fprintf (stderr, "%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); fflush (stderr) 970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 1070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 1170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include <stdio.h> 1270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 13d012387afef0ba02185ebe27bc6bb15551912e92Havoc Pennington/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 1470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/* dbus-spawn-win32.c Wrapper around g_spawn 1570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 1670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. 1770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Copyright (C) 2003 CodeFactory AB 1870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Copyright (C) 2005 Novell, Inc. 1970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 2070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Licensed under the Academic Free License version 2.1 2170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 2270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * This program is free software; you can redistribute it and/or modify 2370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * it under the terms of the GNU General Public License as published by 2470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * the Free Software Foundation; either version 2 of the License, or 2570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * (at your option) any later version. 2670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 2770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * This program is distributed in the hope that it will be useful, 2870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * but WITHOUT ANY WARRANTY; without even the implied warranty of 2970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * GNU General Public License for more details. 3170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 3270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * You should have received a copy of the GNU General Public License 3370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * along with this program; if not, write to the Free Software 345baf2f856a9c6625993234855b07680da1c8916fTobias Mueller * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 3570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 3670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 3770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-spawn.h" 3870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-sysdeps.h" 3970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-sysdeps-win.h" 4070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-internals.h" 4170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-test.h" 4270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-protocol.h" 4370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 4470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#define WIN32_LEAN_AND_MEAN 4570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker//#define STRICT 4670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker//#include <windows.h> 4770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker//#undef STRICT 4870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include <winsock2.h> 4970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#undef interface 5070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 5170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include <stdlib.h> 5270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 533404bb7238f2bb6dd5d678bc8f782810f3079241Marcus Brinkmann#ifndef DBUS_WINCE 5470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include <process.h> 553404bb7238f2bb6dd5d678bc8f782810f3079241Marcus Brinkmann#endif 5670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 5770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/** 5870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Babysitter implementation details 5970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 6070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstruct DBusBabysitter 6170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 6270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int refcount; 6370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 6470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker HANDLE start_sync_event; 6570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_BUILD_TESTS 6670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 6770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker HANDLE end_sync_event; 6870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 6970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 7070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *executable; 7170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusSpawnChildSetupFunc child_setup; 7270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker void *user_data; 7370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 7470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int argc; 7570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char **argv; 7670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char **envp; 7770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 7870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker HANDLE child_handle; 7970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int socket_to_babysitter; /* Connection to the babysitter thread */ 8070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int socket_to_main; 8170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 8270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusWatchList *watches; 8370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusWatch *sitter_watch; 8470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 8570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_bool_t have_spawn_errno; 8670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int spawn_errno; 8770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_bool_t have_child_status; 8870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int child_status; 8970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker }; 9070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 9170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic DBusBabysitter* 9270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_new (void) 9370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 9470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter; 9570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 9670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter = dbus_new0 (DBusBabysitter, 1); 9770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter == NULL) 9870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return NULL; 9970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 10070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->refcount = 1; 10170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 10270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->start_sync_event = CreateEvent (NULL, FALSE, FALSE, NULL); 10370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->start_sync_event == NULL) 10470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 10570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 10670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return NULL; 10770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 10870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 10970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_BUILD_TESTS 11070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->end_sync_event = CreateEvent (NULL, FALSE, FALSE, NULL); 11170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->end_sync_event == NULL) 11270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 11370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 11470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return NULL; 11570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 11670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 11770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 11870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_handle = NULL; 11970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 12070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->socket_to_babysitter = sitter->socket_to_main = -1; 12170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 12270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->argc = 0; 12370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->argv = NULL; 12470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->envp = NULL; 12570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 12670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->watches = _dbus_watch_list_new (); 12770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->watches == NULL) 12870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 12970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 13070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return NULL; 13170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 13270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 13370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->have_spawn_errno = FALSE; 13470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->have_child_status = FALSE; 13570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 13670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return sitter; 13770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 13870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 13970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/** 14070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Increment the reference count on the babysitter object. 14170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 14270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @param sitter the babysitter 14370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @returns the babysitter 14470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 14570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf HabackerDBusBabysitter * 14670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_ref (DBusBabysitter *sitter) 14770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 14870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 14970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_assert (sitter != NULL); 15070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_assert (sitter->refcount > 0); 15170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 15270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->refcount += 1; 15370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 15470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return sitter; 15570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 15670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 15770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/** 15870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Decrement the reference count on the babysitter object. 15970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 16070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @param sitter the babysitter 16170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 16270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackervoid 16370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_unref (DBusBabysitter *sitter) 16470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 16570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int i; 16670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 16770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 16870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_assert (sitter != NULL); 16970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_assert (sitter->refcount > 0); 17070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 17170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->refcount -= 1; 17270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 17370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->refcount == 0) 17470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 17570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->socket_to_babysitter != -1) 17670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 17770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_close_socket (sitter->socket_to_babysitter, NULL); 17870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->socket_to_babysitter = -1; 17970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 18070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 18170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->socket_to_main != -1) 18270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 18370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_close_socket (sitter->socket_to_main, NULL); 18470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->socket_to_main = -1; 18570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 18670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 18770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 18870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->argv != NULL) 18970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 19070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker for (i = 0; i < sitter->argc; i++) 19170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->argv[i] != NULL) 19270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 19370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (sitter->argv[i]); 19470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->argv[i] = NULL; 19570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 19670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (sitter->argv); 19770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->argv = NULL; 19870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 19970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 20070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->envp != NULL) 20170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 20270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char **e = sitter->envp; 20370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 20470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (*e) 20570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (*e++); 20670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (sitter->envp); 20770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->envp = NULL; 20870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 20970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 21070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_handle != NULL) 21170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 21270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker CloseHandle (sitter->child_handle); 21370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_handle = NULL; 21470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 21570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 21670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->sitter_watch) 21770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 21870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_watch_invalidate (sitter->sitter_watch); 21970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_watch_unref (sitter->sitter_watch); 22070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->sitter_watch = NULL; 22170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 22270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 22370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->watches) 22470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_watch_list_free (sitter->watches); 22570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 22670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->start_sync_event != NULL) 22770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 22870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 22970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker CloseHandle (sitter->start_sync_event); 230e73985bb144b5de819baa3f9f47a892f8ce21618Christian Ehrlicher sitter->start_sync_event = NULL; 23170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 23270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 23370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_BUILD_TESTS 23470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->end_sync_event != NULL) 23570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 23670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker CloseHandle (sitter->end_sync_event); 23770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->end_sync_event = NULL; 23870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 23970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 24070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 24170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (sitter->executable); 24270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 24370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (sitter); 24470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 24570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 24670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 24770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackervoid 24870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_kill_child (DBusBabysitter *sitter) 24970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 25070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 25170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_handle == NULL) 25270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return; /* child is already dead, or we're so hosed we'll never recover */ 25370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 25470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 25570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker TerminateProcess (sitter->child_handle, 12345); 25670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 25770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 25870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/** 25970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Checks whether the child has exited, without blocking. 26070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 26170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @param sitter the babysitter 26270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 26370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerdbus_bool_t 26470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_get_child_exited (DBusBabysitter *sitter) 26570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 26670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 26770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return (sitter->child_handle == NULL); 26870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 26970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 27070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/** 271722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher * Gets the exit status of the child. We do this so implementation specific 272722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher * detail is not cluttering up dbus, for example the system launcher code. 273722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher * This can only be called if the child has exited, i.e. call 274722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher * _dbus_babysitter_get_child_exited(). It returns FALSE if the child 275722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher * did not return a status code, e.g. because the child was signaled 276722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher * or we failed to ever launch the child in the first place. 277722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher * 278722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher * @param sitter the babysitter 279722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher * @param status the returned status code 280722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher * @returns #FALSE on failure 281722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher */ 282722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicherdbus_bool_t 283722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher_dbus_babysitter_get_child_exit_status (DBusBabysitter *sitter, 284722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher int *status) 285722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher{ 286722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher if (!_dbus_babysitter_get_child_exited (sitter)) 287722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher _dbus_assert_not_reached ("Child has not exited"); 288722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 289722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher if (!sitter->have_child_status || 290722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher sitter->child_status == STILL_ACTIVE) 291722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher return FALSE; 292722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 293722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher *status = sitter->child_status; 294722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher return TRUE; 295722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher} 296722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 297722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher/** 29870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Sets the #DBusError with an explanation of why the spawned 29970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * child process exited (on a signal, or whatever). If 30070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * the child process has not exited, does nothing (error 30170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * will remain unset). 30270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 30370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @param sitter the babysitter 30470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @param error an error to fill in 30570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 30670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackervoid 30770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter, 30870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusError *error) 30970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 31070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 31170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_babysitter_get_child_exited (sitter)) 31270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return; 31370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 31470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 31570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->have_spawn_errno) 31670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 3176e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann char *emsg = _dbus_win_error_string (sitter->spawn_errno); 31870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 31970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker "Failed to execute program %s: %s", 3206e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann sitter->executable, emsg); 3216e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann _dbus_win_free_error_string (emsg); 32270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 32370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else if (sitter->have_child_status) 32470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 32570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 32670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED, 32770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker "Process %s exited with status %d", 32870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->executable, sitter->child_status); 32970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 33070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else 33170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 33270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 33370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_set_error (error, DBUS_ERROR_FAILED, 33470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker "Process %s exited, status unknown", 33570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->executable); 33670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 33770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 33870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 33970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 34070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerdbus_bool_t 34170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_set_watch_functions (DBusBabysitter *sitter, 34270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusAddWatchFunction add_function, 34370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusRemoveWatchFunction remove_function, 34470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusWatchToggledFunction toggled_function, 34570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker void *data, 34670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusFreeFunction free_data_function) 34770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 34870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 34970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return _dbus_watch_list_set_functions (sitter->watches, 35070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker add_function, 35170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker remove_function, 35270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker toggled_function, 35370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker data, 35470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker free_data_function); 35570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 35670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 35770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic dbus_bool_t 35870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerhandle_watch (DBusWatch *watch, 35970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker unsigned int condition, 36070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker void *data) 36170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 36270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter = data; 36370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 36470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /* On Unix dbus-spawn uses a babysitter *process*, thus it has to 36570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * actually send the exit statuses, error codes and whatnot through 36670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * sockets and/or pipes. On Win32, the babysitter is jus a thread, 36770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * so it can set the status fields directly in the babysitter struct 36870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * just fine. The socket pipe is used just so we can watch it with 36970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * select(), as soon as anything is written to it we know that the 37070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * babysitter thread has recorded the status in the babysitter 37170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * struct. 37270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 37370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 37470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 37570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_close_socket (sitter->socket_to_babysitter, NULL); 37670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 37770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->socket_to_babysitter = -1; 37870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 37970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 38070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 38170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 38270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/* protect_argv lifted from GLib, relicensed by author, Tor Lillqvist */ 38370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic int 38470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerprotect_argv (char **argv, 38570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char ***new_argv) 38670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 38770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int i; 38870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int argc = 0; 38970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 39070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (argv[argc]) 39170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker ++argc; 39270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *new_argv = dbus_malloc ((argc + 1) * sizeof (char *)); 39370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (*new_argv == NULL) 39470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return -1; 39570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 39670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker for (i = 0; i < argc; i++) 39770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker (*new_argv)[i] = NULL; 39870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 39970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /* Quote each argv element if necessary, so that it will get 40070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * reconstructed correctly in the C runtime startup code. Note that 40170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * the unquoting algorithm in the C runtime is really weird, and 40270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * rather different than what Unix shells do. See stdargv.c in the C 40370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * runtime sources (in the Platform SDK, in src/crt). 40470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 40570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Note that an new_argv[0] constructed by this function should 40670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * *not* be passed as the filename argument to a spawn* or exec* 40770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * family function. That argument should be the real file name 40870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * without any quoting. 40970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 41070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker for (i = 0; i < argc; i++) 41170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 41270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *p = argv[i]; 41370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *q; 41470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int len = 0; 41570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int need_dblquotes = FALSE; 41670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (*p) 41770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 41870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (*p == ' ' || *p == '\t') 41970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker need_dblquotes = TRUE; 42070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else if (*p == '"') 42170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker len++; 42270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else if (*p == '\\') 42370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 42470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *pp = p; 42570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (*pp && *pp == '\\') 42670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker pp++; 42770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (*pp == '"') 42870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker len++; 42970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 43070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker len++; 43170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker p++; 43270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 43370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 43470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker q = (*new_argv)[i] = dbus_malloc (len + need_dblquotes*2 + 1); 43570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 43670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (q == NULL) 43770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return -1; 43870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 43970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 44070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker p = argv[i]; 44170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 44270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (need_dblquotes) 44370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = '"'; 44470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 44570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (*p) 44670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 44770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (*p == '"') 44870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = '\\'; 44970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else if (*p == '\\') 45070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 45170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *pp = p; 45270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (*pp && *pp == '\\') 45370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker pp++; 45470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (*pp == '"') 45570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = '\\'; 45670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 45770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = *p; 45870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker p++; 45970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 46070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 46170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (need_dblquotes) 46270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = '"'; 46370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = '\0'; 46470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /* printf ("argv[%d]:%s, need_dblquotes:%s len:%d => %s\n", i, argv[i], need_dblquotes?"TRUE":"FALSE", len, (*new_argv)[i]); */ 46570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 46670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker (*new_argv)[argc] = NULL; 46770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 46870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return argc; 46970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 47070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 4716e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 4726e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann/* From GPGME, relicensed by g10 Code GmbH. */ 4736e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmannstatic char * 474ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trbacompose_string (char **strings, char separator) 4756e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann{ 4766e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann int i; 4776e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann int n = 0; 4786e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann char *buf; 4796e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann char *p; 4806e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann const char *ptr; 4816e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 482ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba if (!strings || !strings[0]) 483ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba return 0; 484ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba for (i = 0; strings[i]; i++) 485ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba n += strlen (strings[i]) + 1; 4866e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann n++; 4876e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 4886e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann buf = p = malloc (n); 4896e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann if (!buf) 4906e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann return NULL; 491ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba for (i = 0; strings[i]; i++) 4926e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann { 493ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba strcpy (p, strings[i]); 494ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba p += strlen (strings[i]); 495ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba *(p++) = separator; 4966e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann } 497ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba p--; 498ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba *(p++) = '\0'; 4996e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann *p = '\0'; 5006e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 5016e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann return buf; 5026e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann} 5036e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 504ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trbastatic char * 505ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trbabuild_commandline (char **argv) 506ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba{ 507ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba return compose_string (argv, ' '); 508ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba} 509ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba 510ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trbastatic char * 511ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trbabuild_env_string (char** envp) 512ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba{ 513ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba return compose_string (envp, '\0'); 514ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba} 5156e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 5166e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmannstatic HANDLE 517ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trbaspawn_program (char* name, char** argv, char** envp) 5186e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann{ 5196e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann PROCESS_INFORMATION pi = { NULL, 0, 0, 0 }; 5206e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann STARTUPINFOA si; 521ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba char *arg_string, *env_string; 5226e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann BOOL result; 5236e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 52448801c87df51f3864c9bcae28e34233222497e20Marcus Brinkmann#ifdef DBUS_WINCE 5259165229a0a4eb95c5709dd048e0e12470971a899Marcus Brinkmann if (argv && argv[0]) 5269165229a0a4eb95c5709dd048e0e12470971a899Marcus Brinkmann arg_string = build_commandline (argv + 1); 5279165229a0a4eb95c5709dd048e0e12470971a899Marcus Brinkmann else 5289165229a0a4eb95c5709dd048e0e12470971a899Marcus Brinkmann arg_string = NULL; 52948801c87df51f3864c9bcae28e34233222497e20Marcus Brinkmann#else 5306e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann arg_string = build_commandline (argv); 53148801c87df51f3864c9bcae28e34233222497e20Marcus Brinkmann#endif 5326e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann if (!arg_string) 5336e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann return INVALID_HANDLE_VALUE; 5346e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 535ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba env_string = build_env_string(envp); 536ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba 5376e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann memset (&si, 0, sizeof (si)); 5386e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann si.cb = sizeof (si); 539f578ad20ef9b6db635c5178651def600fb5ccbe9Fridrich Å trba#ifdef DBUS_WINCE 5406e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann result = CreateProcessA (name, arg_string, NULL, NULL, FALSE, 0, 541f578ad20ef9b6db635c5178651def600fb5ccbe9Fridrich Å trba#else 542f578ad20ef9b6db635c5178651def600fb5ccbe9Fridrich Å trba result = CreateProcessA (NULL, arg_string, NULL, NULL, FALSE, 0, 543f578ad20ef9b6db635c5178651def600fb5ccbe9Fridrich Å trba#endif 544ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba (LPVOID)env_string, NULL, &si, &pi); 5456e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann free (arg_string); 546ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba if (env_string) 547ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba free (env_string); 548ecb7a5606cdb077c86ed81a7db81df5038824de6Fridrich Å trba 5496e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann if (!result) 5506e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann return INVALID_HANDLE_VALUE; 5516e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 5526e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann CloseHandle (pi.hThread); 5536e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann return pi.hProcess; 5546e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann} 5556e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 5566e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 5576e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmannstatic DWORD __stdcall 55870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerbabysitter (void *parameter) 55970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 56070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter = (DBusBabysitter *) parameter; 561a1a285b10d92708515977d8e9e5f07cb920e92c6Ralf Habacker int fd; 56270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 56370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_ref (sitter); 56470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 56570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_setup) 56670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 56770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 56870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker (*sitter->child_setup) (sitter->user_data); 56970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 57070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 57170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_verbose ("babysitter: spawning %s\n", sitter->executable); 57270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 57370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 5746e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann sitter->child_handle = spawn_program (sitter->executable, 5756e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann sitter->argv, sitter->envp); 57670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 57770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 57870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_handle == (HANDLE) -1) 57970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 58070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_handle = NULL; 58170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->have_spawn_errno = TRUE; 5826e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann sitter->spawn_errno = GetLastError(); 58370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 5846e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 58570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 58670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker SetEvent (sitter->start_sync_event); 58770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 58870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_handle != NULL) 58970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 59070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int ret; 59170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DWORD status; 59270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 59370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 59470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker WaitForSingleObject (sitter->child_handle, INFINITE); 59570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 59670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 59770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker ret = GetExitCodeProcess (sitter->child_handle, &status); 59870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 59970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_status = status; 60070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->have_child_status = TRUE; 60170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 60270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker CloseHandle (sitter->child_handle); 60370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_handle = NULL; 60470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 60570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 60670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_BUILD_TESTS 60770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker SetEvent (sitter->end_sync_event); 60870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 60970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 61070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 611a1a285b10d92708515977d8e9e5f07cb920e92c6Ralf Habacker send (sitter->socket_to_main, " ", 1, 0); 61270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 61370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 61470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 61570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return 0; 61670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 61770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 61870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerdbus_bool_t 61970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, 62070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char **argv, 62170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char **envp, 62270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusSpawnChildSetupFunc child_setup, 62370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker void *user_data, 62470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusError *error) 62570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 62670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter; 62770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker HANDLE sitter_thread; 6286e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann DWORD sitter_thread_id; 6296e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann 63070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_ASSERT_ERROR_IS_CLEAR (error); 63170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 63270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *sitter_p = NULL; 63370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 63470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 63570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter = _dbus_babysitter_new (); 63670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter == NULL) 63770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 63870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_SET_OOM (error); 63970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 64070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 64170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 64270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_setup = child_setup; 64370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->user_data = user_data; 64470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 64570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->executable = _dbus_strdup (argv[0]); 64670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->executable == NULL) 64770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 64870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_SET_OOM (error); 64970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 65070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 65170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 65270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 65370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_full_duplex_pipe (&sitter->socket_to_babysitter, 65470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker &sitter->socket_to_main, 65570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker FALSE, error)) 65670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 65770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 65870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->sitter_watch = _dbus_watch_new (sitter->socket_to_babysitter, 65970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBUS_WATCH_READABLE, 66070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker TRUE, handle_watch, sitter, NULL); 66170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 66270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->sitter_watch == NULL) 66370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 66470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_SET_OOM (error); 66570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 66670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 66770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 66870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 66970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_watch_list_add_watch (sitter->watches, sitter->sitter_watch)) 67070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 67170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_SET_OOM (error); 67270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 67370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 67470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 67570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->argc = protect_argv (argv, &sitter->argv); 67670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->argc == -1) 67770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 67870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_SET_OOM (error); 67970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 68070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 68170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->envp = envp; 68270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 68370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 6846e214b5b3c283798b5743b4ebf7c9ec466fe3667Marcus Brinkmann sitter_thread = (HANDLE) CreateThread (NULL, 0, babysitter, 68570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter, 0, &sitter_thread_id); 68670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 68770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter_thread == 0) 68870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 68970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 69070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_set_error_const (error, DBUS_ERROR_SPAWN_FORK_FAILED, 69170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker "Failed to create new thread"); 69270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 69370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 69470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker CloseHandle (sitter_thread); 69570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 69670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 69770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker WaitForSingleObject (sitter->start_sync_event, INFINITE); 69870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 69970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 70070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter_p != NULL) 70170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *sitter_p = sitter; 70270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else 70370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 70470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 70570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_ASSERT_ERROR_IS_CLEAR (error); 70670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 70770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 70870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 70970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 71070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerout0: 71170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 71270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 71370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 71470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 71570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 71670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_BUILD_TESTS 71770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 71870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#define LIVE_CHILDREN(sitter) ((sitter)->child_handle != NULL) 71970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 72070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic void 72170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter) 72270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 72370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_handle == NULL) 72470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return; 72570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 72670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker WaitForSingleObject (sitter->end_sync_event, INFINITE); 72770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 72870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 72970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic dbus_bool_t 73070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackercheck_spawn_nonexistent (void *data) 73170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 73270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *argv[4] = { NULL, NULL, NULL, NULL }; 733722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher DBusBabysitter *sitter; 734722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher DBusError error; 735722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 736722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher sitter = NULL; 737722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 738722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher dbus_error_init (&error); 73970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 74070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /*** Test launching nonexistent binary */ 74170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 74270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker argv[0] = "/this/does/not/exist/32542sdgafgafdg"; 74370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, 74470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL, NULL, 74570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker &error)) 74670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 74770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_block_for_child_exit (sitter); 74870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_set_child_exit_error (sitter, &error); 74970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 75070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 75170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter) 75270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 75370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 75470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!dbus_error_is_set (&error)) 75570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 75670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Did not get an error launching nonexistent executable\n"); 75770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 75870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 75970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 76070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 76170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED))) 76270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 76370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n", 76470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker error.name, error.message); 76570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 76670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 76770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 76870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 76970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 77070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 77170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 77270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 77370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 77470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic dbus_bool_t 77570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackercheck_spawn_segfault (void *data) 77670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 77770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *argv[4] = { NULL, NULL, NULL, NULL }; 778722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher DBusBabysitter *sitter; 779722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher DBusError error; 780722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 781722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher sitter = NULL; 782722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 783722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher dbus_error_init (&error); 78470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 78570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /*** Test launching segfault binary */ 78670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 78770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker argv[0] = TEST_SEGFAULT_BINARY; 78870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, 78970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL, NULL, 79070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker &error)) 79170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 79270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_block_for_child_exit (sitter); 79370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_set_child_exit_error (sitter, &error); 79470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 79570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 79670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter) 79770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 79870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 79970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!dbus_error_is_set (&error)) 80070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 80170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Did not get an error launching segfaulting binary\n"); 80270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 80370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 80470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 80570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 80670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED))) 80770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 80870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n", 80970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker error.name, error.message); 81070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 81170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 81270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 81370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 81470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 81570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 81670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 81770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 81870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 81970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic dbus_bool_t 82070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackercheck_spawn_exit (void *data) 82170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 82270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *argv[4] = { NULL, NULL, NULL, NULL }; 823722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher DBusBabysitter *sitter; 824722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher DBusError error; 825722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 826722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher sitter = NULL; 827722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 828722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher dbus_error_init (&error); 82970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 83070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /*** Test launching exit failure binary */ 83170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 83270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker argv[0] = TEST_EXIT_BINARY; 83370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, 83470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL, NULL, 83570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker &error)) 83670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 83770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_block_for_child_exit (sitter); 83870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_set_child_exit_error (sitter, &error); 83970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 84070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 84170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter) 84270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 84370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 84470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!dbus_error_is_set (&error)) 84570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 84670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Did not get an error launching binary that exited with failure code\n"); 84770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 84870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 84970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 85070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 85170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED))) 85270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 85370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n", 85470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker error.name, error.message); 85570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 85670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 85770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 85870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 85970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 86070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 86170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 86270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 86370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 86470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic dbus_bool_t 86570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackercheck_spawn_and_kill (void *data) 86670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 86770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *argv[4] = { NULL, NULL, NULL, NULL }; 868722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher DBusBabysitter *sitter; 869722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher DBusError error; 870722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 871722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher sitter = NULL; 872722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher 873722a90c9cbc7368ffde9ad768ef4f2e45c3a620dChristian Ehrlicher dbus_error_init (&error); 87470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 87570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /*** Test launching sleeping binary then killing it */ 87670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 87770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker argv[0] = TEST_SLEEP_FOREVER_BINARY; 87870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, 87970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL, NULL, 88070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker &error)) 88170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 88270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_kill_child (sitter); 88370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 88470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_block_for_child_exit (sitter); 88570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 88670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_set_child_exit_error (sitter, &error); 88770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 88870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 88970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter) 89070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 89170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 89270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!dbus_error_is_set (&error)) 89370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 89470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Did not get an error after killing spawned binary\n"); 89570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 89670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 89770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 89870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 89970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED))) 90070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 90170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Not expecting error when killing executable: %s: %s\n", 90270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker error.name, error.message); 90370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 90470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 90570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 90670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 90770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 90870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 90970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 91070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 91170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 91270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerdbus_bool_t 91370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_spawn_test (const char *test_data_dir) 91470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 91570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_test_oom_handling ("spawn_nonexistent", 91670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker check_spawn_nonexistent, 91770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL)) 91870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 91970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 92070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /* Don't run the obnoxious segfault test by default, 92170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * it's a pain to have to click all those error boxes. 92270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 92370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (getenv ("DO_SEGFAULT_TEST")) 92470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_test_oom_handling ("spawn_segfault", 92570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker check_spawn_segfault, 92670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL)) 92770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 92870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 92970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_test_oom_handling ("spawn_exit", 93070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker check_spawn_exit, 93170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL)) 93270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 93370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 93470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_test_oom_handling ("spawn_and_kill", 93570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker check_spawn_and_kill, 93670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL)) 93770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 93870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 93970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 94070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 94170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 942