Do not attempt to call child_setup on Windows

child_setup() is defined to be called after fork() and before exec(),
but Windows' process model does not have fork(): the equivalent of
those two operations is a single CreateProcess() call. This means
that there is no point at which we could call child_setup() and
have it affect only the child's process-global state. At the point
where it is currently executed, it affects the parent's process-global
state instead, which would be actively harmful if we used any
child_setup() function that was not a no-op on Windows.

The equivalent function in GLib, g_spawn_async_with_pipes(), documents
child_setup() as unused on Windows. Do the same here.

In practice, our only use of child_setup() outside tests
is #ifdef DBUS_UNIX anyway, so this change has no practical effect
right now.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=85857
Reviewed-by: Ralf Habacker <ralf.habacker@freenet.de>
This commit is contained in:
Simon McVittie 2015-11-26 10:37:48 +00:00 committed by Simon McVittie
parent 7c7f4a5110
commit 420f3474ed
2 changed files with 10 additions and 16 deletions

View file

@ -69,8 +69,6 @@ struct DBusBabysitter
#endif #endif
char *log_name; char *log_name;
DBusSpawnChildSetupFunc child_setup;
void *user_data;
int argc; int argc;
char **argv; char **argv;
@ -588,12 +586,6 @@ babysitter (void *parameter)
PING(); PING();
_dbus_babysitter_ref (sitter); _dbus_babysitter_ref (sitter);
if (sitter->child_setup)
{
PING();
(*sitter->child_setup) (sitter->user_data);
}
_dbus_verbose ("babysitter: spawning %s\n", sitter->log_name); _dbus_verbose ("babysitter: spawning %s\n", sitter->log_name);
PING(); PING();
@ -648,8 +640,8 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
const char *log_name, const char *log_name,
char **argv, char **argv,
char **envp, char **envp,
DBusSpawnChildSetupFunc child_setup, DBusSpawnChildSetupFunc child_setup _DBUS_GNUC_UNUSED,
void *user_data, void *user_data _DBUS_GNUC_UNUSED,
DBusError *error) DBusError *error)
{ {
DBusBabysitter *sitter; DBusBabysitter *sitter;
@ -669,9 +661,6 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
return FALSE; return FALSE;
} }
sitter->child_setup = child_setup;
sitter->user_data = user_data;
sitter->log_name = _dbus_strdup (log_name); sitter->log_name = _dbus_strdup (log_name);
if (sitter->log_name == NULL && log_name != NULL) if (sitter->log_name == NULL && log_name != NULL)
{ {

View file

@ -1188,9 +1188,14 @@ babysit (pid_t grandchild_pid,
} }
/** /**
* Spawns a new process. The child_setup * Spawns a new process.
* function is passed the given user_data and is run in the child *
* just before calling exec(). * On Unix platforms, the child_setup function is passed the given
* user_data and is run in the child after fork() but before calling exec().
* This can be used to change uid, resource limits and so on.
* On Windows, this functionality does not fit the multi-processing model
* (Windows does the equivalent of fork() and exec() in a single API call),
* and the child_setup function and its user_data are ignored.
* *
* Also creates a "babysitter" which tracks the status of the * Also creates a "babysitter" which tracks the status of the
* child process, advising the parent if the child exits. * child process, advising the parent if the child exits.