mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-09 08:28:02 +02:00
Merge branch 'dbus-run-session-add-delay' into 'master'
tools/dbus-run-session: fix race between manual and automatically started dbus-daemon on Windows Closes #297 See merge request dbus/dbus!195
This commit is contained in:
commit
d4203c3ee5
14 changed files with 314 additions and 33 deletions
13
bus/bus.c
13
bus/bus.c
|
|
@ -764,11 +764,13 @@ process_config_postinit (BusContext *context,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Takes ownership of print_addr_pipe fds, print_pid_pipe fds and ready_event_handle */
|
||||||
BusContext*
|
BusContext*
|
||||||
bus_context_new (const DBusString *config_file,
|
bus_context_new (const DBusString *config_file,
|
||||||
BusContextFlags flags,
|
BusContextFlags flags,
|
||||||
DBusPipe *print_addr_pipe,
|
DBusPipe *print_addr_pipe,
|
||||||
DBusPipe *print_pid_pipe,
|
DBusPipe *print_pid_pipe,
|
||||||
|
void *ready_event_handle,
|
||||||
const DBusString *address,
|
const DBusString *address,
|
||||||
DBusError *error)
|
DBusError *error)
|
||||||
{
|
{
|
||||||
|
|
@ -891,6 +893,17 @@ bus_context_new (const DBusString *config_file,
|
||||||
_dbus_string_free (&addr);
|
_dbus_string_free (&addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DBUS_WIN
|
||||||
|
if (ready_event_handle != NULL)
|
||||||
|
{
|
||||||
|
_dbus_verbose ("Notifying that we are ready to receive connections (event handle=%p)\n", ready_event_handle);
|
||||||
|
if (!_dbus_win_event_set (ready_event_handle, error))
|
||||||
|
goto failed;
|
||||||
|
if (!_dbus_win_event_free (ready_event_handle, error))
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
context->connections = bus_connections_new (context);
|
context->connections = bus_connections_new (context);
|
||||||
if (context->connections == NULL)
|
if (context->connections == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ BusContext* bus_context_new (const DBusStri
|
||||||
BusContextFlags flags,
|
BusContextFlags flags,
|
||||||
DBusPipe *print_addr_pipe,
|
DBusPipe *print_addr_pipe,
|
||||||
DBusPipe *print_pid_pipe,
|
DBusPipe *print_pid_pipe,
|
||||||
|
void *ready_event_handle,
|
||||||
const DBusString *address,
|
const DBusString *address,
|
||||||
DBusError *error);
|
DBusError *error);
|
||||||
dbus_bool_t bus_context_reload_config (BusContext *context,
|
dbus_bool_t bus_context_reload_config (BusContext *context,
|
||||||
|
|
|
||||||
26
bus/main.c
26
bus/main.c
|
|
@ -48,6 +48,10 @@
|
||||||
|
|
||||||
static BusContext *context;
|
static BusContext *context;
|
||||||
|
|
||||||
|
#ifdef DBUS_WIN
|
||||||
|
#include <dbus/dbus-sysdeps-win.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DBUS_UNIX
|
#ifdef DBUS_UNIX
|
||||||
|
|
||||||
/* Despite its name and its unidirectional nature, this is actually
|
/* Despite its name and its unidirectional nature, this is actually
|
||||||
|
|
@ -163,6 +167,9 @@ usage (void)
|
||||||
" [--syslog]"
|
" [--syslog]"
|
||||||
" [--syslog-only]"
|
" [--syslog-only]"
|
||||||
" [--nofork]"
|
" [--nofork]"
|
||||||
|
#ifdef DBUS_WIN
|
||||||
|
" [--ready-event-handle=value]"
|
||||||
|
#endif
|
||||||
#ifdef DBUS_UNIX
|
#ifdef DBUS_UNIX
|
||||||
" [--fork]"
|
" [--fork]"
|
||||||
" [--systemd-activation]"
|
" [--systemd-activation]"
|
||||||
|
|
@ -403,6 +410,8 @@ main (int argc, char **argv)
|
||||||
dbus_bool_t print_address;
|
dbus_bool_t print_address;
|
||||||
dbus_bool_t print_pid;
|
dbus_bool_t print_pid;
|
||||||
BusContextFlags flags;
|
BusContextFlags flags;
|
||||||
|
void *ready_event_handle;
|
||||||
|
|
||||||
#ifdef DBUS_UNIX
|
#ifdef DBUS_UNIX
|
||||||
const char *error_str;
|
const char *error_str;
|
||||||
|
|
||||||
|
|
@ -428,6 +437,7 @@ main (int argc, char **argv)
|
||||||
* to inherit fds we might have inherited from our caller. */
|
* to inherit fds we might have inherited from our caller. */
|
||||||
_dbus_fd_set_all_close_on_exec ();
|
_dbus_fd_set_all_close_on_exec ();
|
||||||
#endif
|
#endif
|
||||||
|
ready_event_handle = NULL;
|
||||||
|
|
||||||
if (!_dbus_string_init (&config_file))
|
if (!_dbus_string_init (&config_file))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -619,6 +629,20 @@ main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
print_pid = TRUE; /* and we'll get the next arg if appropriate */
|
print_pid = TRUE; /* and we'll get the next arg if appropriate */
|
||||||
}
|
}
|
||||||
|
#ifdef DBUS_WIN
|
||||||
|
else if (strstr (arg, "--ready-event-handle=") == arg)
|
||||||
|
{
|
||||||
|
const char *desc;
|
||||||
|
desc = strchr (arg, '=');
|
||||||
|
_dbus_assert (desc != NULL);
|
||||||
|
++desc;
|
||||||
|
if (sscanf (desc, "%p", &ready_event_handle) != 1)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s specified, but invalid handle provided\n", arg);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
usage ();
|
usage ();
|
||||||
|
|
@ -693,7 +717,7 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
dbus_error_init (&error);
|
dbus_error_init (&error);
|
||||||
context = bus_context_new (&config_file, flags,
|
context = bus_context_new (&config_file, flags,
|
||||||
&print_addr_pipe, &print_pid_pipe,
|
&print_addr_pipe, &print_pid_pipe, ready_event_handle,
|
||||||
_dbus_string_get_length(&address) > 0 ? &address : NULL,
|
_dbus_string_get_length(&address) > 0 ? &address : NULL,
|
||||||
&error);
|
&error);
|
||||||
_dbus_string_free (&config_file);
|
_dbus_string_free (&config_file);
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ bus_context_new_test (const DBusString *test_data_dir,
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus_error_init (&error);
|
dbus_error_init (&error);
|
||||||
context = bus_context_new (&config_file, BUS_CONTEXT_FLAG_NONE, NULL, NULL, NULL, &error);
|
context = bus_context_new (&config_file, BUS_CONTEXT_FLAG_NONE, NULL, NULL, NULL, NULL, &error);
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
{
|
{
|
||||||
_DBUS_ASSERT_ERROR_IS_SET (&error);
|
_DBUS_ASSERT_ERROR_IS_SET (&error);
|
||||||
|
|
|
||||||
|
|
@ -497,7 +497,8 @@ build_env_string (char** envp)
|
||||||
HANDLE
|
HANDLE
|
||||||
_dbus_spawn_program (const char *name,
|
_dbus_spawn_program (const char *name,
|
||||||
char **argv,
|
char **argv,
|
||||||
char **envp)
|
char **envp,
|
||||||
|
dbus_bool_t inherit_handles)
|
||||||
{
|
{
|
||||||
PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
|
PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
|
||||||
STARTUPINFOA si;
|
STARTUPINFOA si;
|
||||||
|
|
@ -531,7 +532,12 @@ _dbus_spawn_program (const char *name,
|
||||||
#ifdef DBUS_WINCE
|
#ifdef DBUS_WINCE
|
||||||
result = CreateProcessA (name, arg_string, NULL, NULL, FALSE, 0,
|
result = CreateProcessA (name, arg_string, NULL, NULL, FALSE, 0,
|
||||||
#else
|
#else
|
||||||
result = CreateProcessA (NULL, arg_string, NULL, NULL, FALSE, 0,
|
result = CreateProcessA (NULL, /* no application name */
|
||||||
|
arg_string,
|
||||||
|
NULL, /* no process attributes */
|
||||||
|
NULL, /* no thread attributes */
|
||||||
|
inherit_handles, /* inherit handles */
|
||||||
|
0, /* flags */
|
||||||
#endif
|
#endif
|
||||||
(LPVOID)env_string, NULL, &si, &pi);
|
(LPVOID)env_string, NULL, &si, &pi);
|
||||||
free (arg_string);
|
free (arg_string);
|
||||||
|
|
@ -666,7 +672,7 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
|
||||||
_dbus_verbose ("babysitter: spawn child '%s'\n", my_argv[0]);
|
_dbus_verbose ("babysitter: spawn child '%s'\n", my_argv[0]);
|
||||||
|
|
||||||
PING();
|
PING();
|
||||||
handle = _dbus_spawn_program (sitter->log_name, my_argv, (char **) envp);
|
handle = _dbus_spawn_program (sitter->log_name, my_argv, (char **) envp, FALSE);
|
||||||
|
|
||||||
if (my_argv != NULL)
|
if (my_argv != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1674,16 +1674,3 @@ void
|
||||||
_dbus_daemon_report_stopping (void)
|
_dbus_daemon_report_stopping (void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
_dbus_win_stderr_win_error (const char *app,
|
|
||||||
const char *message,
|
|
||||||
unsigned long code)
|
|
||||||
{
|
|
||||||
DBusError error;
|
|
||||||
|
|
||||||
dbus_error_init (&error);
|
|
||||||
_dbus_win_set_error_from_win_error (&error, code);
|
|
||||||
fprintf (stderr, "%s: %s: %s\n", app, message, error.message);
|
|
||||||
dbus_error_free (&error);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
* Copyright (C) 2005 Novell, Inc.
|
* Copyright (C) 2005 Novell, Inc.
|
||||||
* Copyright (C) 2006 Peter Kümmel <syntheticpp@gmx.net>
|
* Copyright (C) 2006 Peter Kümmel <syntheticpp@gmx.net>
|
||||||
* Copyright (C) 2006 Christian Ehrlicher <ch.ehrlicher@gmx.de>
|
* Copyright (C) 2006 Christian Ehrlicher <ch.ehrlicher@gmx.de>
|
||||||
* Copyright (C) 2006-2013 Ralf Habacker <ralf.habacker@freenet.de>
|
* Copyright (C) 2006-2021 Ralf Habacker <ralf.habacker@freenet.de>
|
||||||
*
|
*
|
||||||
* Licensed under the Academic Free License version 2.1
|
* Licensed under the Academic Free License version 2.1
|
||||||
*
|
*
|
||||||
|
|
@ -4009,5 +4009,174 @@ _dbus_get_low_level_socket_errno (void)
|
||||||
return WSAGetLastError ();
|
return WSAGetLastError ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_dbus_win_set_error_from_last_error (DBusError *error,
|
||||||
|
const char *format,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
char *message = NULL;
|
||||||
|
|
||||||
|
if (error == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* make sure to do this first, in case subsequent library calls overwrite GetLastError() */
|
||||||
|
name = _dbus_win_error_from_last_error ();
|
||||||
|
message = _dbus_win_error_string (GetLastError ());
|
||||||
|
|
||||||
|
if (format != NULL)
|
||||||
|
{
|
||||||
|
DBusString str;
|
||||||
|
va_list args;
|
||||||
|
dbus_bool_t retval;
|
||||||
|
|
||||||
|
if (!_dbus_string_init (&str))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
va_start (args, format);
|
||||||
|
retval = _dbus_string_append_printf_valist (&str, format, args);
|
||||||
|
va_end (args);
|
||||||
|
if (!retval)
|
||||||
|
{
|
||||||
|
_dbus_string_free (&str);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_set_error (error, name, "%s: %s", _dbus_string_get_const_data (&str), message);
|
||||||
|
_dbus_string_free (&str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbus_set_error (error, name, "%s", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (message != NULL)
|
||||||
|
_dbus_win_free_error_string (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Windows event object and returns the corresponding handle
|
||||||
|
*
|
||||||
|
* The returned object is unnamed, is a manual-reset event object,
|
||||||
|
* is initially in the non-signalled state, and is inheritable by child
|
||||||
|
* processes.
|
||||||
|
*
|
||||||
|
* @param error the error to set
|
||||||
|
* @return handle for the created event
|
||||||
|
* @return #NULL if an error has occurred, the reason is returned in \p error
|
||||||
|
*/
|
||||||
|
HANDLE
|
||||||
|
_dbus_win_event_create_inheritable (DBusError *error)
|
||||||
|
{
|
||||||
|
HANDLE handle;
|
||||||
|
|
||||||
|
handle = CreateEvent (NULL, TRUE, FALSE, NULL);
|
||||||
|
if (handle == NULL)
|
||||||
|
{
|
||||||
|
_dbus_win_set_error_from_last_error (error, "Could not create event");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (GetLastError () == ERROR_ALREADY_EXISTS)
|
||||||
|
{
|
||||||
|
_dbus_win_set_error_from_last_error (error, "Event already exists");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetHandleInformation (handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
|
||||||
|
{
|
||||||
|
_dbus_win_set_error_from_last_error (error, "Could not set inheritance for event %s", handle);
|
||||||
|
CloseHandle (handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a Windows event to the signalled state
|
||||||
|
*
|
||||||
|
* @param handle the handle for the event to be set
|
||||||
|
* @return TRUE the event was set successfully
|
||||||
|
* @return FALSE an error has occurred, the reason is returned in \p error
|
||||||
|
*/
|
||||||
|
dbus_bool_t
|
||||||
|
_dbus_win_event_set (HANDLE handle, DBusError *error)
|
||||||
|
{
|
||||||
|
_dbus_assert (handle != NULL);
|
||||||
|
|
||||||
|
if (!SetEvent (handle))
|
||||||
|
{
|
||||||
|
_dbus_win_set_error_from_last_error (error, "Could not trigger event (handle %p)", handle);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for a Windows event to enter the signalled state
|
||||||
|
*
|
||||||
|
* @param handle the handle for the event to wait for
|
||||||
|
* @param timeout the waiting time in milliseconds, or INFINITE to wait forever,
|
||||||
|
* or 0 to check immediately and not wait (polling)
|
||||||
|
* @param error the error to set
|
||||||
|
* @return TRUE the event was set successfully
|
||||||
|
* @return FALSE an error has occurred, the reason is returned in \p error
|
||||||
|
*/
|
||||||
|
dbus_bool_t
|
||||||
|
_dbus_win_event_wait (HANDLE handle, int timeout, DBusError *error)
|
||||||
|
{
|
||||||
|
DWORD status;
|
||||||
|
|
||||||
|
_dbus_assert (handle != NULL);
|
||||||
|
|
||||||
|
status = WaitForSingleObject (handle, timeout);
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case WAIT_FAILED:
|
||||||
|
{
|
||||||
|
_dbus_win_set_error_from_last_error (error, "Unable to wait for event (handle %p)", handle);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
/* GetLastError() is not set */
|
||||||
|
dbus_set_error (error, DBUS_ERROR_TIMEOUT, "Timed out waiting for event (handle %p)", handle);
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* GetLastError() is probably not set? */
|
||||||
|
dbus_set_error (error, DBUS_ERROR_FAILED, "Unknown result '%lu' while waiting for event (handle %p)", status, handle);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a Windows event
|
||||||
|
*
|
||||||
|
* @param handle handle for the event to delete
|
||||||
|
* @param error the error to set (optional)
|
||||||
|
* @return TRUE the event has been deleted successfully or the handle specifies a #NULL or invalid handle
|
||||||
|
* @return FALSE an error has occurred, the reason is returned in \p error if specified
|
||||||
|
*/
|
||||||
|
dbus_bool_t
|
||||||
|
_dbus_win_event_free (HANDLE handle, DBusError *error)
|
||||||
|
{
|
||||||
|
if (handle == NULL || handle == INVALID_HANDLE_VALUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (CloseHandle (handle))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* the handle may already be closed */
|
||||||
|
if (GetLastError () == ERROR_INVALID_HANDLE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
_dbus_win_set_error_from_last_error (error, "Could not close event (handle %p)", handle);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/** @} end of sysdeps-win */
|
/** @} end of sysdeps-win */
|
||||||
/* tests in dbus-sysdeps-util.c */
|
/* tests in dbus-sysdeps-util.c */
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,6 @@ const char* _dbus_win_error_from_last_error (void);
|
||||||
dbus_bool_t _dbus_win_startup_winsock (void);
|
dbus_bool_t _dbus_win_startup_winsock (void);
|
||||||
void _dbus_win_warn_win_error (const char *message,
|
void _dbus_win_warn_win_error (const char *message,
|
||||||
unsigned long code);
|
unsigned long code);
|
||||||
void _dbus_win_stderr_win_error (const char *app,
|
|
||||||
const char *message,
|
|
||||||
unsigned long code);
|
|
||||||
DBUS_PRIVATE_EXPORT
|
DBUS_PRIVATE_EXPORT
|
||||||
char * _dbus_win_error_string (int error_number);
|
char * _dbus_win_error_string (int error_number);
|
||||||
DBUS_PRIVATE_EXPORT
|
DBUS_PRIVATE_EXPORT
|
||||||
|
|
@ -93,7 +90,24 @@ void _dbus_threads_windows_ensure_ctor_linked (void);
|
||||||
DBUS_PRIVATE_EXPORT
|
DBUS_PRIVATE_EXPORT
|
||||||
dbus_bool_t _dbus_getsid(char **sid, dbus_pid_t process_id);
|
dbus_bool_t _dbus_getsid(char **sid, dbus_pid_t process_id);
|
||||||
|
|
||||||
HANDLE _dbus_spawn_program (const char *name, char **argv, char **envp);
|
HANDLE _dbus_spawn_program (const char *name,
|
||||||
|
char **argv,
|
||||||
|
char **envp,
|
||||||
|
dbus_bool_t inherit_handles);
|
||||||
|
|
||||||
|
DBUS_PRIVATE_EXPORT
|
||||||
|
void _dbus_win_set_error_from_last_error (DBusError *error,
|
||||||
|
const char *format,
|
||||||
|
...);
|
||||||
|
|
||||||
|
DBUS_PRIVATE_EXPORT
|
||||||
|
HANDLE _dbus_win_event_create_inheritable (DBusError *error);
|
||||||
|
DBUS_PRIVATE_EXPORT
|
||||||
|
dbus_bool_t _dbus_win_event_set (HANDLE handle, DBusError *error);
|
||||||
|
DBUS_PRIVATE_EXPORT
|
||||||
|
dbus_bool_t _dbus_win_event_wait (HANDLE handle, int timeout, DBusError *error);
|
||||||
|
DBUS_PRIVATE_EXPORT
|
||||||
|
dbus_bool_t _dbus_win_event_free (HANDLE handle, DBusError *error);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
<arg choice='opt'>--nosyslog </arg>
|
<arg choice='opt'>--nosyslog </arg>
|
||||||
<arg choice='opt'>--syslog </arg>
|
<arg choice='opt'>--syslog </arg>
|
||||||
<arg choice='opt'>--syslog-only </arg>
|
<arg choice='opt'>--syslog-only </arg>
|
||||||
|
<arg choice='opt'>--ready-event-handle=value</arg>
|
||||||
<sbr/>
|
<sbr/>
|
||||||
</cmdsynopsis>
|
</cmdsynopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
@ -199,6 +200,29 @@ files.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--ready-event-handle=value</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>With this option, the dbus daemon raises an event when it is ready to process
|
||||||
|
connections. The <replaceable>handle</replaceable> must be the Windows handle
|
||||||
|
for an event object, in the format printed by the <function>printf</function>
|
||||||
|
format string <literal>%p</literal>. The parent process must create this event
|
||||||
|
object (for example with the <function>CreateEvent</function> function) in a
|
||||||
|
nonsignaled state, then configure it to be inherited by the dbus-daemon process.
|
||||||
|
The dbus-daemon will signal the event as if via <function>SetEvent</function>
|
||||||
|
when it is ready to receive connections from clients. The parent process can
|
||||||
|
wait for this to occur by using functions such as
|
||||||
|
<function>WaitForSingleObject</function>.
|
||||||
|
This option is only supported under Windows. On Unix platforms,
|
||||||
|
a similar result can be achieved by waiting for the address and/or
|
||||||
|
process ID to be printed to the inherited file descriptors used
|
||||||
|
for <option>--print-address</option> and/or <option>--print-pid</option>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,8 @@ set(dbus_cleanup_sockets_SOURCES
|
||||||
|
|
||||||
set(dbus_run_session_SOURCES
|
set(dbus_run_session_SOURCES
|
||||||
dbus-run-session.c
|
dbus-run-session.c
|
||||||
|
tool-common.c
|
||||||
|
tool-common.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(dbus_uuidgen_SOURCES
|
set(dbus_uuidgen_SOURCES
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,10 @@ dbus_launch_LDADD = \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
dbus_run_session_SOURCES = \
|
dbus_run_session_SOURCES = \
|
||||||
dbus-run-session.c
|
dbus-run-session.c \
|
||||||
|
tool-common.c \
|
||||||
|
tool-common.h
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
dbus_run_session_LDADD = \
|
dbus_run_session_LDADD = \
|
||||||
$(CODE_COVERAGE_LIBS) \
|
$(CODE_COVERAGE_LIBS) \
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
* Copyright © 2003-2006 Red Hat, Inc.
|
* Copyright © 2003-2006 Red Hat, Inc.
|
||||||
* Copyright © 2006 Thiago Macieira <thiago@kde.org>
|
* Copyright © 2006 Thiago Macieira <thiago@kde.org>
|
||||||
* Copyright © 2011-2012 Nokia Corporation
|
* Copyright © 2011-2012 Nokia Corporation
|
||||||
* Copyright © 2018 Ralf Habacker
|
* Copyright © 2018, 2021 Ralf Habacker
|
||||||
*
|
*
|
||||||
* Licensed under the Academic Free License version 2.1
|
* Licensed under the Academic Free License version 2.1
|
||||||
*
|
*
|
||||||
|
|
@ -47,6 +47,8 @@
|
||||||
#include "dbus/dbus.h"
|
#include "dbus/dbus.h"
|
||||||
#include "dbus/dbus-internals.h"
|
#include "dbus/dbus-internals.h"
|
||||||
|
|
||||||
|
#include "tool-common.h"
|
||||||
|
|
||||||
#define MAX_ADDR_LEN 512
|
#define MAX_ADDR_LEN 512
|
||||||
#define PIPE_READ_END 0
|
#define PIPE_READ_END 0
|
||||||
#define PIPE_WRITE_END 1
|
#define PIPE_WRITE_END 1
|
||||||
|
|
@ -101,7 +103,7 @@ version (void)
|
||||||
"Copyright (C) 2003-2006 Red Hat, Inc.\n"
|
"Copyright (C) 2003-2006 Red Hat, Inc.\n"
|
||||||
"Copyright (C) 2006 Thiago Macieira\n"
|
"Copyright (C) 2006 Thiago Macieira\n"
|
||||||
"Copyright © 2011-2012 Nokia Corporation\n"
|
"Copyright © 2011-2012 Nokia Corporation\n"
|
||||||
"Copyright © 2018 Ralf Habacker\n"
|
"Copyright © 2018, 2021 Ralf Habacker\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This is free software; see the source for copying conditions.\n"
|
"This is free software; see the source for copying conditions.\n"
|
||||||
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
|
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
|
||||||
|
|
@ -381,10 +383,11 @@ run_session (const char *dbus_daemon,
|
||||||
char **argv,
|
char **argv,
|
||||||
int prog_arg)
|
int prog_arg)
|
||||||
{
|
{
|
||||||
char *dbus_daemon_argv[4];
|
char *dbus_daemon_argv[5];
|
||||||
int ret = 127;
|
int ret = 127;
|
||||||
HANDLE server_handle = NULL;
|
HANDLE server_handle = NULL;
|
||||||
HANDLE app_handle = NULL;
|
HANDLE app_handle = NULL;
|
||||||
|
HANDLE ready_event_handle = NULL;
|
||||||
DWORD exit_code;
|
DWORD exit_code;
|
||||||
DBusString argv_strings[4];
|
DBusString argv_strings[4];
|
||||||
DBusString address;
|
DBusString address;
|
||||||
|
|
@ -394,6 +397,7 @@ run_session (const char *dbus_daemon,
|
||||||
dbus_bool_t result = TRUE;
|
dbus_bool_t result = TRUE;
|
||||||
char *key = NULL;
|
char *key = NULL;
|
||||||
char *value = NULL;
|
char *value = NULL;
|
||||||
|
DBusError error;
|
||||||
|
|
||||||
if (!_dbus_string_init (&argv_strings[0]))
|
if (!_dbus_string_init (&argv_strings[0]))
|
||||||
result = FALSE;
|
result = FALSE;
|
||||||
|
|
@ -401,11 +405,20 @@ run_session (const char *dbus_daemon,
|
||||||
result = FALSE;
|
result = FALSE;
|
||||||
if (!_dbus_string_init (&argv_strings[2]))
|
if (!_dbus_string_init (&argv_strings[2]))
|
||||||
result = FALSE;
|
result = FALSE;
|
||||||
|
if (!_dbus_string_init (&argv_strings[3]))
|
||||||
|
result = FALSE;
|
||||||
if (!_dbus_string_init (&address))
|
if (!_dbus_string_init (&address))
|
||||||
result = FALSE;
|
result = FALSE;
|
||||||
if (!result)
|
if (!result)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* The handle of this event is used by the dbus daemon
|
||||||
|
* to signal that connections are ready. */
|
||||||
|
dbus_error_init (&error);
|
||||||
|
ready_event_handle = _dbus_win_event_create_inheritable (&error);
|
||||||
|
if (ready_event_handle == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* run dbus daemon */
|
/* run dbus daemon */
|
||||||
_dbus_get_real_time (&sec, &usec);
|
_dbus_get_real_time (&sec, &usec);
|
||||||
/* On Windows it's difficult to make use of --print-address to
|
/* On Windows it's difficult to make use of --print-address to
|
||||||
|
|
@ -421,18 +434,29 @@ run_session (const char *dbus_daemon,
|
||||||
else
|
else
|
||||||
_dbus_string_append_printf (&argv_strings[1], "--session");
|
_dbus_string_append_printf (&argv_strings[1], "--session");
|
||||||
_dbus_string_append_printf (&argv_strings[2], "--address=%s", _dbus_string_get_const_data (&address));
|
_dbus_string_append_printf (&argv_strings[2], "--address=%s", _dbus_string_get_const_data (&address));
|
||||||
|
_dbus_string_append_printf (&argv_strings[3], "--ready-event-handle=%p", ready_event_handle);
|
||||||
dbus_daemon_argv[0] = _dbus_string_get_data (&argv_strings[0]);
|
dbus_daemon_argv[0] = _dbus_string_get_data (&argv_strings[0]);
|
||||||
dbus_daemon_argv[1] = _dbus_string_get_data (&argv_strings[1]);
|
dbus_daemon_argv[1] = _dbus_string_get_data (&argv_strings[1]);
|
||||||
dbus_daemon_argv[2] = _dbus_string_get_data (&argv_strings[2]);
|
dbus_daemon_argv[2] = _dbus_string_get_data (&argv_strings[2]);
|
||||||
dbus_daemon_argv[3] = NULL;
|
dbus_daemon_argv[3] = _dbus_string_get_data (&argv_strings[3]);
|
||||||
|
dbus_daemon_argv[4] = NULL;
|
||||||
|
|
||||||
server_handle = _dbus_spawn_program (dbus_daemon, dbus_daemon_argv, NULL);
|
server_handle = _dbus_spawn_program (dbus_daemon, dbus_daemon_argv, NULL, TRUE);
|
||||||
if (!server_handle)
|
if (!server_handle)
|
||||||
{
|
{
|
||||||
_dbus_win_stderr_win_error (me, "Could not start dbus daemon", GetLastError ());
|
_dbus_win_set_error_from_last_error (&error, "Could not start dbus daemon");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wait until dbus-daemon is ready for connections */
|
||||||
|
if (ready_event_handle != NULL)
|
||||||
|
{
|
||||||
|
_dbus_verbose ("Wait until dbus-daemon is ready for connections (event handle %p)\n", ready_event_handle);
|
||||||
|
if (!_dbus_win_event_wait (ready_event_handle, 30000, &error))
|
||||||
|
goto out;
|
||||||
|
_dbus_verbose ("Got signal that dbus-daemon is ready for connections\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* run app */
|
/* run app */
|
||||||
env = _dbus_get_environment ();
|
env = _dbus_get_environment ();
|
||||||
env_table = _dbus_hash_table_new (DBUS_HASH_STRING,
|
env_table = _dbus_hash_table_new (DBUS_HASH_STRING,
|
||||||
|
|
@ -474,30 +498,36 @@ run_session (const char *dbus_daemon,
|
||||||
if (!env)
|
if (!env)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
app_handle = _dbus_spawn_program (argv[prog_arg], argv + prog_arg, env);
|
app_handle = _dbus_spawn_program (argv[prog_arg], argv + prog_arg, env, FALSE);
|
||||||
if (!app_handle)
|
if (!app_handle)
|
||||||
{
|
{
|
||||||
_dbus_win_stderr_win_error (me, "unable to start child process", GetLastError ());
|
_dbus_win_set_error_from_last_error (&error, "Unable to start child process");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitForSingleObject (app_handle, INFINITE);
|
WaitForSingleObject (app_handle, INFINITE);
|
||||||
if (!GetExitCodeProcess (app_handle, &exit_code))
|
if (!GetExitCodeProcess (app_handle, &exit_code))
|
||||||
{
|
{
|
||||||
_dbus_win_stderr_win_error (me, "could not fetch exit code", GetLastError ());
|
_dbus_win_set_error_from_last_error (&error, "Could not fetch exit code");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
ret = exit_code;
|
ret = exit_code;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (dbus_error_is_set (&error))
|
||||||
|
tool_stderr_error (me, &error);
|
||||||
|
dbus_error_free (&error);
|
||||||
TerminateProcess (server_handle, 0);
|
TerminateProcess (server_handle, 0);
|
||||||
if (server_handle != NULL)
|
if (server_handle != NULL)
|
||||||
CloseHandle (server_handle);
|
CloseHandle (server_handle);
|
||||||
if (app_handle != NULL)
|
if (app_handle != NULL)
|
||||||
CloseHandle (app_handle);
|
CloseHandle (app_handle);
|
||||||
|
if (ready_event_handle != NULL)
|
||||||
|
_dbus_win_event_free (ready_event_handle, NULL);
|
||||||
_dbus_string_free (&argv_strings[0]);
|
_dbus_string_free (&argv_strings[0]);
|
||||||
_dbus_string_free (&argv_strings[1]);
|
_dbus_string_free (&argv_strings[1]);
|
||||||
_dbus_string_free (&argv_strings[2]);
|
_dbus_string_free (&argv_strings[2]);
|
||||||
|
_dbus_string_free (&argv_strings[3]);
|
||||||
_dbus_string_free (&address);
|
_dbus_string_free (&address);
|
||||||
dbus_free_string_array (env);
|
dbus_free_string_array (env);
|
||||||
if (env_table != NULL)
|
if (env_table != NULL)
|
||||||
|
|
|
||||||
|
|
@ -80,3 +80,10 @@ tool_write_all (int fd,
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tool_stderr_error (const char *context,
|
||||||
|
DBusError *error)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: %s: %s\n", context, error->name, error->message);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,5 +34,6 @@
|
||||||
|
|
||||||
void tool_oom (const char *doing) _DBUS_GNUC_NORETURN;
|
void tool_oom (const char *doing) _DBUS_GNUC_NORETURN;
|
||||||
dbus_bool_t tool_write_all (int fd, const void *buf, size_t size);
|
dbus_bool_t tool_write_all (int fd, const void *buf, size_t size);
|
||||||
|
void tool_stderr_error (const char *context, DBusError *error);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue