dbus-spawn-win.c revision 70bfc74e54ac8a9a93885710cd8350d1a58b3406
170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "config.h" 270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#if !defined(DBUS_ENABLE_VERBOSE_MODE) || defined(_MSC_VER) 470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#define PING() 570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#else 670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#define PING() fprintf (stderr, "%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); fflush (stderr) 770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include <stdio.h> 1070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_WINCE 1170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include <process.h> 1270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 1370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 1470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/* -*- mode: C; c-file-style: "gnu" -*- */ 1570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/* dbus-spawn-win32.c Wrapper around g_spawn 1670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 1770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Copyright (C) 2002, 2003, 2004 Red Hat, Inc. 1870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Copyright (C) 2003 CodeFactory AB 1970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Copyright (C) 2005 Novell, Inc. 2070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 2170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Licensed under the Academic Free License version 2.1 2270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 2370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * This program is free software; you can redistribute it and/or modify 2470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * it under the terms of the GNU General Public License as published by 2570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * the Free Software Foundation; either version 2 of the License, or 2670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * (at your option) any later version. 2770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 2870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * This program is distributed in the hope that it will be useful, 2970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * but WITHOUT ANY WARRANTY; without even the implied warranty of 3070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 3170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * GNU General Public License for more details. 3270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 3370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * You should have received a copy of the GNU General Public License 3470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * along with this program; if not, write to the Free Software 3570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 3670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 3770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 3870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-spawn.h" 3970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-sysdeps.h" 4070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-sysdeps-win.h" 4170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-internals.h" 4270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-test.h" 4370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include "dbus-protocol.h" 4470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 4570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#define WIN32_LEAN_AND_MEAN 4670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker//#define STRICT 4770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker//#include <windows.h> 4870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker//#undef STRICT 4970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include <winsock2.h> 5070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#undef interface 5170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 5270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include <stdlib.h> 5370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 5470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#include <process.h> 5570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 5670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/** 5770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Babysitter implementation details 5870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 5970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstruct DBusBabysitter 6070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 6170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int refcount; 6270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 6370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker HANDLE start_sync_event; 6470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_BUILD_TESTS 6570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 6670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker HANDLE end_sync_event; 6770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 6870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 6970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *executable; 7070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusSpawnChildSetupFunc child_setup; 7170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker void *user_data; 7270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 7370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int argc; 7470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char **argv; 7570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char **envp; 7670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 7770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker HANDLE child_handle; 7870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int socket_to_babysitter; /* Connection to the babysitter thread */ 7970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int socket_to_main; 8070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 8170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusWatchList *watches; 8270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusWatch *sitter_watch; 8370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 8470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_bool_t have_spawn_errno; 8570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int spawn_errno; 8670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_bool_t have_child_status; 8770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int child_status; 8870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker }; 8970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 9070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic DBusBabysitter* 9170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_new (void) 9270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 9370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter; 9470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 9570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter = dbus_new0 (DBusBabysitter, 1); 9670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter == NULL) 9770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return NULL; 9870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 9970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->refcount = 1; 10070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 10170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->start_sync_event = CreateEvent (NULL, FALSE, FALSE, NULL); 10270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->start_sync_event == NULL) 10370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 10470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 10570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return NULL; 10670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 10770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 10870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_BUILD_TESTS 10970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->end_sync_event = CreateEvent (NULL, FALSE, FALSE, NULL); 11070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->end_sync_event == NULL) 11170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 11270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 11370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return NULL; 11470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 11570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 11670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 11770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_handle = NULL; 11870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 11970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->socket_to_babysitter = sitter->socket_to_main = -1; 12070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 12170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->argc = 0; 12270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->argv = NULL; 12370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->envp = NULL; 12470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 12570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->watches = _dbus_watch_list_new (); 12670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->watches == NULL) 12770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 12870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 12970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return NULL; 13070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 13170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 13270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->have_spawn_errno = FALSE; 13370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->have_child_status = FALSE; 13470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 13570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return sitter; 13670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 13770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 13870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/** 13970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Increment the reference count on the babysitter object. 14070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 14170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @param sitter the babysitter 14270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @returns the babysitter 14370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 14470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf HabackerDBusBabysitter * 14570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_ref (DBusBabysitter *sitter) 14670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 14770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 14870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_assert (sitter != NULL); 14970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_assert (sitter->refcount > 0); 15070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 15170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->refcount += 1; 15270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 15370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return sitter; 15470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 15570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 15670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/** 15770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Decrement the reference count on the babysitter object. 15870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 15970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @param sitter the babysitter 16070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 16170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackervoid 16270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_unref (DBusBabysitter *sitter) 16370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 16470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int i; 16570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 16670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 16770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_assert (sitter != NULL); 16870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_assert (sitter->refcount > 0); 16970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 17070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->refcount -= 1; 17170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 17270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->refcount == 0) 17370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 17470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->socket_to_babysitter != -1) 17570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 17670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_close_socket (sitter->socket_to_babysitter, NULL); 17770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->socket_to_babysitter = -1; 17870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 17970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 18070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->socket_to_main != -1) 18170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 18270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_close_socket (sitter->socket_to_main, NULL); 18370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->socket_to_main = -1; 18470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 18570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 18670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 18770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->argv != NULL) 18870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 18970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker for (i = 0; i < sitter->argc; i++) 19070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->argv[i] != NULL) 19170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 19270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (sitter->argv[i]); 19370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->argv[i] = NULL; 19470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 19570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (sitter->argv); 19670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->argv = NULL; 19770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 19870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 19970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->envp != NULL) 20070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 20170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char **e = sitter->envp; 20270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 20370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (*e) 20470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (*e++); 20570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (sitter->envp); 20670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->envp = NULL; 20770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 20870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 20970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_handle != NULL) 21070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 21170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker CloseHandle (sitter->child_handle); 21270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_handle = NULL; 21370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 21470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 21570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->sitter_watch) 21670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 21770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_watch_invalidate (sitter->sitter_watch); 21870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_watch_unref (sitter->sitter_watch); 21970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->sitter_watch = NULL; 22070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 22170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 22270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->watches) 22370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_watch_list_free (sitter->watches); 22470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 22570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->start_sync_event != NULL) 22670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 22770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 22870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker CloseHandle (sitter->start_sync_event); 22970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->end_sync_event = NULL; 23070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 23170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 23270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_BUILD_TESTS 23370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->end_sync_event != NULL) 23470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 23570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker CloseHandle (sitter->end_sync_event); 23670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->end_sync_event = NULL; 23770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 23870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 23970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 24070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (sitter->executable); 24170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 24270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_free (sitter); 24370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 24470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 24570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 24670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackervoid 24770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_kill_child (DBusBabysitter *sitter) 24870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 24970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 25070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_handle == NULL) 25170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return; /* child is already dead, or we're so hosed we'll never recover */ 25270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 25370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 25470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker TerminateProcess (sitter->child_handle, 12345); 25570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 25670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 25770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/** 25870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Checks whether the child has exited, without blocking. 25970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 26070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @param sitter the babysitter 26170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 26270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerdbus_bool_t 26370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_get_child_exited (DBusBabysitter *sitter) 26470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 26570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 26670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return (sitter->child_handle == NULL); 26770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 26870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 26970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/** 27070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Sets the #DBusError with an explanation of why the spawned 27170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * child process exited (on a signal, or whatever). If 27270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * the child process has not exited, does nothing (error 27370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * will remain unset). 27470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 27570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @param sitter the babysitter 27670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * @param error an error to fill in 27770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 27870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackervoid 27970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter, 28070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusError *error) 28170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 28270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 28370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_babysitter_get_child_exited (sitter)) 28470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return; 28570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 28670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 28770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->have_spawn_errno) 28870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 28970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 29070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker "Failed to execute program %s: %s", 29170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->executable, _dbus_strerror (sitter->spawn_errno)); 29270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 29370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else if (sitter->have_child_status) 29470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 29570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 29670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED, 29770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker "Process %s exited with status %d", 29870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->executable, sitter->child_status); 29970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 30070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else 30170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 30270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 30370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_set_error (error, DBUS_ERROR_FAILED, 30470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker "Process %s exited, status unknown", 30570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->executable); 30670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 30770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 30870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 30970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 31070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerdbus_bool_t 31170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_set_watch_functions (DBusBabysitter *sitter, 31270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusAddWatchFunction add_function, 31370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusRemoveWatchFunction remove_function, 31470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusWatchToggledFunction toggled_function, 31570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker void *data, 31670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusFreeFunction free_data_function) 31770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 31870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 31970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return _dbus_watch_list_set_functions (sitter->watches, 32070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker add_function, 32170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker remove_function, 32270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker toggled_function, 32370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker data, 32470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker free_data_function); 32570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 32670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 32770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic dbus_bool_t 32870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerhandle_watch (DBusWatch *watch, 32970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker unsigned int condition, 33070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker void *data) 33170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 33270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter = data; 33370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 33470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /* On Unix dbus-spawn uses a babysitter *process*, thus it has to 33570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * actually send the exit statuses, error codes and whatnot through 33670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * sockets and/or pipes. On Win32, the babysitter is jus a thread, 33770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * so it can set the status fields directly in the babysitter struct 33870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * just fine. The socket pipe is used just so we can watch it with 33970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * select(), as soon as anything is written to it we know that the 34070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * babysitter thread has recorded the status in the babysitter 34170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * struct. 34270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 34370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 34470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 34570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_close_socket (sitter->socket_to_babysitter, NULL); 34670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 34770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->socket_to_babysitter = -1; 34870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 34970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 35070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 35170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 35270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker/* protect_argv lifted from GLib, relicensed by author, Tor Lillqvist */ 35370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic int 35470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerprotect_argv (char **argv, 35570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char ***new_argv) 35670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 35770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int i; 35870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int argc = 0; 35970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 36070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (argv[argc]) 36170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker ++argc; 36270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *new_argv = dbus_malloc ((argc + 1) * sizeof (char *)); 36370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (*new_argv == NULL) 36470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return -1; 36570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 36670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker for (i = 0; i < argc; i++) 36770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker (*new_argv)[i] = NULL; 36870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 36970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /* Quote each argv element if necessary, so that it will get 37070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * reconstructed correctly in the C runtime startup code. Note that 37170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * the unquoting algorithm in the C runtime is really weird, and 37270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * rather different than what Unix shells do. See stdargv.c in the C 37370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * runtime sources (in the Platform SDK, in src/crt). 37470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * 37570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * Note that an new_argv[0] constructed by this function should 37670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * *not* be passed as the filename argument to a spawn* or exec* 37770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * family function. That argument should be the real file name 37870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * without any quoting. 37970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 38070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker for (i = 0; i < argc; i++) 38170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 38270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *p = argv[i]; 38370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *q; 38470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int len = 0; 38570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int need_dblquotes = FALSE; 38670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (*p) 38770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 38870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (*p == ' ' || *p == '\t') 38970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker need_dblquotes = TRUE; 39070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else if (*p == '"') 39170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker len++; 39270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else if (*p == '\\') 39370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 39470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *pp = p; 39570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (*pp && *pp == '\\') 39670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker pp++; 39770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (*pp == '"') 39870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker len++; 39970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 40070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker len++; 40170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker p++; 40270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 40370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 40470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker q = (*new_argv)[i] = dbus_malloc (len + need_dblquotes*2 + 1); 40570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 40670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (q == NULL) 40770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return -1; 40870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 40970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 41070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker p = argv[i]; 41170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 41270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (need_dblquotes) 41370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = '"'; 41470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 41570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (*p) 41670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 41770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (*p == '"') 41870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = '\\'; 41970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else if (*p == '\\') 42070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 42170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *pp = p; 42270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker while (*pp && *pp == '\\') 42370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker pp++; 42470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (*pp == '"') 42570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = '\\'; 42670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 42770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = *p; 42870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker p++; 42970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 43070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 43170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (need_dblquotes) 43270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = '"'; 43370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *q++ = '\0'; 43470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /* printf ("argv[%d]:%s, need_dblquotes:%s len:%d => %s\n", i, argv[i], need_dblquotes?"TRUE":"FALSE", len, (*new_argv)[i]); */ 43570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 43670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker (*new_argv)[argc] = NULL; 43770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 43870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return argc; 43970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 44070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 44170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic unsigned __stdcall 44270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerbabysitter (void *parameter) 44370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 44470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter = (DBusBabysitter *) parameter; 44570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusSocket *sock; 44670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 44770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_ref (sitter); 44870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 44970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_setup) 45070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 45170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 45270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker (*sitter->child_setup) (sitter->user_data); 45370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 45470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 45570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_verbose ("babysitter: spawning %s\n", sitter->executable); 45670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker fprintf (stderr, "babysitter: spawning %s\n", sitter->executable); 45770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 45870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 45970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->envp != NULL) 46070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_handle = (HANDLE) spawnve (P_NOWAIT, sitter->executable, 46170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker (const char * const *) sitter->argv, 46270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker (const char * const *) sitter->envp); 46370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else 46470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_handle = (HANDLE) spawnv (P_NOWAIT, sitter->executable, 46570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker (const char * const *) sitter->argv); 46670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 46770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 46870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_handle == (HANDLE) -1) 46970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 47070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_handle = NULL; 47170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->have_spawn_errno = TRUE; 47270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->spawn_errno = errno; 47370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 47470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 47570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 47670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker SetEvent (sitter->start_sync_event); 47770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 47870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_handle != NULL) 47970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 48070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int ret; 48170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DWORD status; 48270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 48370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 48470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker WaitForSingleObject (sitter->child_handle, INFINITE); 48570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 48670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 48770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker ret = GetExitCodeProcess (sitter->child_handle, &status); 48870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 48970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_status = status; 49070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->have_child_status = TRUE; 49170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 49270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker CloseHandle (sitter->child_handle); 49370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_handle = NULL; 49470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 49570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 49670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_BUILD_TESTS 49770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker SetEvent (sitter->end_sync_event); 49870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 49970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 50070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 50170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_handle_to_socket (sitter->socket_to_main, &sock); 50270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker send (sock->fd, " ", 1, 0); 50370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 50470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 50570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 50670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return 0; 50770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 50870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 50970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerdbus_bool_t 51070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, 51170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char **argv, 51270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char **envp, 51370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusSpawnChildSetupFunc child_setup, 51470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker void *user_data, 51570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusError *error) 51670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 51770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter; 51870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker HANDLE sitter_thread; 51970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker int sitter_thread_id; 52070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 52170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_ASSERT_ERROR_IS_CLEAR (error); 52270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 52370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *sitter_p = NULL; 52470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 52570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 52670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter = _dbus_babysitter_new (); 52770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter == NULL) 52870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 52970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_SET_OOM (error); 53070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 53170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 53270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 53370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->child_setup = child_setup; 53470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->user_data = user_data; 53570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 53670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->executable = _dbus_strdup (argv[0]); 53770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->executable == NULL) 53870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 53970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_SET_OOM (error); 54070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 54170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 54270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 54370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 54470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_full_duplex_pipe (&sitter->socket_to_babysitter, 54570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker &sitter->socket_to_main, 54670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker FALSE, error)) 54770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 54870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 54970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->sitter_watch = _dbus_watch_new (sitter->socket_to_babysitter, 55070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBUS_WATCH_READABLE, 55170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker TRUE, handle_watch, sitter, NULL); 55270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 55370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->sitter_watch == NULL) 55470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 55570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_SET_OOM (error); 55670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 55770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 55870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 55970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 56070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_watch_list_add_watch (sitter->watches, sitter->sitter_watch)) 56170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 56270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_SET_OOM (error); 56370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 56470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 56570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 56670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->argc = protect_argv (argv, &sitter->argv); 56770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->argc == -1) 56870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 56970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_SET_OOM (error); 57070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 57170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 57270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter->envp = envp; 57370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 57470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 57570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter_thread = (HANDLE) _beginthreadex (NULL, 0, babysitter, 57670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter, 0, &sitter_thread_id); 57770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 57870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter_thread == 0) 57970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 58070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 58170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_set_error_const (error, DBUS_ERROR_SPAWN_FORK_FAILED, 58270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker "Failed to create new thread"); 58370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker goto out0; 58470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 58570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker CloseHandle (sitter_thread); 58670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 58770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 58870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker WaitForSingleObject (sitter->start_sync_event, INFINITE); 58970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 59070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 59170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter_p != NULL) 59270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker *sitter_p = sitter; 59370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker else 59470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 59570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 59670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _DBUS_ASSERT_ERROR_IS_CLEAR (error); 59770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 59870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker PING(); 59970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 60070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 60170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerout0: 60270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 60370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 60470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 60570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 60670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 60770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#ifdef DBUS_BUILD_TESTS 60870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 60970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#define LIVE_CHILDREN(sitter) ((sitter)->child_handle != NULL) 61070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 61170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic void 61270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter) 61370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 61470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter->child_handle == NULL) 61570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return; 61670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 61770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker WaitForSingleObject (sitter->end_sync_event, INFINITE); 61870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 61970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 62070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic dbus_bool_t 62170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackercheck_spawn_nonexistent (void *data) 62270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 62370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *argv[4] = { NULL, NULL, NULL, NULL }; 62470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter; 62570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusError error; 62670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 62770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter = NULL; 62870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 62970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_init (&error); 63070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 63170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /*** Test launching nonexistent binary */ 63270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 63370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker argv[0] = "/this/does/not/exist/32542sdgafgafdg"; 63470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, 63570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL, NULL, 63670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker &error)) 63770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 63870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_block_for_child_exit (sitter); 63970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_set_child_exit_error (sitter, &error); 64070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 64170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 64270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter) 64370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 64470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 64570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!dbus_error_is_set (&error)) 64670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 64770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Did not get an error launching nonexistent executable\n"); 64870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 64970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 65070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 65170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 65270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED))) 65370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 65470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s\n", 65570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker error.name, error.message); 65670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 65770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 65870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 65970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 66070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 66170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 66270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 66370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 66470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 66570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic dbus_bool_t 66670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackercheck_spawn_segfault (void *data) 66770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 66870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *argv[4] = { NULL, NULL, NULL, NULL }; 66970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter; 67070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusError error; 67170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 67270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter = NULL; 67370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 67470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_init (&error); 67570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 67670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /*** Test launching segfault binary */ 67770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 67870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker argv[0] = TEST_SEGFAULT_BINARY; 67970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, 68070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL, NULL, 68170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker &error)) 68270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 68370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_block_for_child_exit (sitter); 68470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_set_child_exit_error (sitter, &error); 68570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 68670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 68770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter) 68870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 68970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 69070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!dbus_error_is_set (&error)) 69170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 69270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Did not get an error launching segfaulting binary\n"); 69370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 69470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 69570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 69670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 69770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED))) 69870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 69970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s\n", 70070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker error.name, error.message); 70170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 70270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 70370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 70470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 70570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 70670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 70770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 70870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 70970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 71070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic dbus_bool_t 71170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackercheck_spawn_exit (void *data) 71270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 71370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *argv[4] = { NULL, NULL, NULL, NULL }; 71470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter; 71570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusError error; 71670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 71770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter = NULL; 71870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 71970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_init (&error); 72070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 72170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /*** Test launching exit failure binary */ 72270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 72370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker argv[0] = TEST_EXIT_BINARY; 72470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, 72570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL, NULL, 72670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker &error)) 72770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 72870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_block_for_child_exit (sitter); 72970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_set_child_exit_error (sitter, &error); 73070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 73170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 73270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter) 73370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 73470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 73570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!dbus_error_is_set (&error)) 73670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 73770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Did not get an error launching binary that exited with failure code\n"); 73870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 73970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 74070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 74170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 74270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED))) 74370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 74470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Not expecting error when launching exiting executable: %s: %s\n", 74570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker error.name, error.message); 74670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 74770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 74870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 74970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 75070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 75170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 75270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 75370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 75470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 75570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerstatic dbus_bool_t 75670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackercheck_spawn_and_kill (void *data) 75770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 75870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker char *argv[4] = { NULL, NULL, NULL, NULL }; 75970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusBabysitter *sitter; 76070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker DBusError error; 76170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 76270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker sitter = NULL; 76370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 76470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_init (&error); 76570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 76670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /*** Test launching sleeping binary then killing it */ 76770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 76870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker argv[0] = TEST_SLEEP_FOREVER_BINARY; 76970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, 77070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL, NULL, 77170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker &error)) 77270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 77370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_kill_child (sitter); 77470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 77570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_block_for_child_exit (sitter); 77670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 77770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_set_child_exit_error (sitter, &error); 77870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 77970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 78070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (sitter) 78170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_babysitter_unref (sitter); 78270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 78370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!dbus_error_is_set (&error)) 78470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 78570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Did not get an error after killing spawned binary\n"); 78670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 78770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 78870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 78970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) || 79070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED))) 79170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker { 79270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker _dbus_warn ("Not expecting error when killing executable: %s: %s\n", 79370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker error.name, error.message); 79470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 79570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 79670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker } 79770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 79870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker dbus_error_free (&error); 79970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 80070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 80170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 80270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 80370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habackerdbus_bool_t 80470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker_dbus_spawn_test (const char *test_data_dir) 80570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker{ 80670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_test_oom_handling ("spawn_nonexistent", 80770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker check_spawn_nonexistent, 80870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL)) 80970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 81070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 81170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker /* Don't run the obnoxious segfault test by default, 81270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker * it's a pain to have to click all those error boxes. 81370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker */ 81470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (getenv ("DO_SEGFAULT_TEST")) 81570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_test_oom_handling ("spawn_segfault", 81670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker check_spawn_segfault, 81770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL)) 81870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 81970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 82070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_test_oom_handling ("spawn_exit", 82170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker check_spawn_exit, 82270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL)) 82370bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 82470bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 82570bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker if (!_dbus_test_oom_handling ("spawn_and_kill", 82670bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker check_spawn_and_kill, 82770bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker NULL)) 82870bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return FALSE; 82970bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker 83070bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker return TRUE; 83170bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker} 83270bfc74e54ac8a9a93885710cd8350d1a58b3406Ralf Habacker#endif 833