}
-dbus_bool_t
+BusResult
bus_activation_activate_service (BusActivation *activation,
DBusConnection *connection,
BusTransaction *transaction,
dbus_bool_t auto_activation,
DBusMessage *activation_message,
const char *service_name,
- DBusError *error)
+ DBusError *error,
+ BusDeferredMessage **deferred_message)
{
DBusError tmp_error;
BusActivationEntry *entry;
char **argv;
char **envp = NULL;
int argc;
- dbus_bool_t retval = FALSE;
+ BusResult retval = BUS_RESULT_FALSE;
dbus_bool_t was_pending_activation;
DBusString command;
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
"The maximum number of pending activations has been reached, activation of %s failed",
service_name);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
entry = activation_find_entry (activation, service_name, error);
if (!entry)
- return FALSE;
+ return BUS_RESULT_FALSE;
/* Bypass the registry lookup if we're auto-activating, bus_dispatch would not
* call us if the service is already active.
if (bus_registry_lookup (bus_context_get_registry (activation->context), &service_str) != NULL)
{
dbus_uint32_t result;
+ dbus_bool_t send_retval;
_dbus_verbose ("Service \"%s\" is already active\n", service_name);
{
_dbus_verbose ("No memory to create reply to activate message\n");
BUS_SET_OOM (error);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
result = DBUS_START_REPLY_ALREADY_RUNNING;
_dbus_verbose ("No memory to set args of reply to activate message\n");
BUS_SET_OOM (error);
dbus_message_unref (message);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
- retval = bus_transaction_send_from_driver (transaction, connection, message);
+ send_retval = bus_transaction_send_from_driver (transaction, connection, message);
dbus_message_unref (message);
- if (!retval)
+ if (!send_retval)
{
_dbus_verbose ("Failed to send reply\n");
BUS_SET_OOM (error);
+ return BUS_RESULT_FALSE;
}
- return retval;
+ return BUS_RESULT_TRUE;
}
}
{
_dbus_verbose ("Failed to create pending activation entry\n");
BUS_SET_OOM (error);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
pending_activation_entry->auto_activation = auto_activation;
BUS_SET_OOM (error);
bus_pending_activation_entry_free (pending_activation_entry);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
pending_activation->n_entries += 1;
BUS_SET_OOM (error);
bus_pending_activation_entry_free (pending_activation_entry);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
pending_activation->activation = activation;
BUS_SET_OOM (error);
bus_pending_activation_unref (pending_activation);
bus_pending_activation_entry_free (pending_activation_entry);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
pending_activation->exec = _dbus_strdup (entry->exec);
BUS_SET_OOM (error);
bus_pending_activation_unref (pending_activation);
bus_pending_activation_entry_free (pending_activation_entry);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
}
BUS_SET_OOM (error);
bus_pending_activation_unref (pending_activation);
bus_pending_activation_entry_free (pending_activation_entry);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
if (!_dbus_loop_add_timeout (bus_context_get_loop (activation->context),
BUS_SET_OOM (error);
bus_pending_activation_unref (pending_activation);
bus_pending_activation_entry_free (pending_activation_entry);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
pending_activation->timeout_added = TRUE;
BUS_SET_OOM (error);
bus_pending_activation_unref (pending_activation);
bus_pending_activation_entry_free (pending_activation_entry);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
pending_activation->n_entries += 1;
BUS_SET_OOM (error);
bus_pending_activation_unref (pending_activation);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
}
}
if (was_pending_activation)
- return TRUE;
+ return BUS_RESULT_TRUE;
if (bus_context_get_systemd_activation (activation->context))
{
/* systemd itself is missing apparently. That can happen
only during early startup. Let's just wait until systemd
connects to us and do nothing. */
- return TRUE;
+ return BUS_RESULT_TRUE;
if (entry->systemd_service)
{
service_name,
entry->systemd_service);
/* Wonderful, systemd is connected, let's just send the msg */
- switch (bus_dispatch_matches (activation_transaction, NULL,
+ retval = bus_dispatch_matches (activation_transaction, NULL,
bus_service_get_primary_owners_connection (service),
- message, NULL, error))
- {
- case BUS_RESULT_TRUE:
- retval = TRUE;
- break;
- case BUS_RESULT_FALSE:
- retval = FALSE;
- break;
- case BUS_RESULT_LATER:
- _dbus_verbose("Unexpectedly need time to check message from bus driver to systemd - dropping the message.\n");
- retval = FALSE;
- break;
- }
+ message, NULL, error);
+ if (BUS_RESULT_LATER == retval)
+ _dbus_verbose("Unexpectedly need time to check message from bus driver to systemd - dropping the message.\n");
}
else
{
entry->systemd_service);
/* systemd is not around, let's "activate" it. */
retval = bus_activation_activate_service (activation, NULL, activation_transaction, TRUE,
- message, "org.freedesktop.systemd1", error);
+ message, "org.freedesktop.systemd1", error, deferred_message);
}
dbus_message_unref (message);
- if (!retval)
+ if (retval != BUS_RESULT_TRUE)
{
bus_context_log (activation->context,
DBUS_SYSTEM_LOG_INFO, "Failed to activate via systemd: service name='%s' unit='%s'",
}
bus_transaction_execute_and_free (activation_transaction);
- return TRUE;
+ return BUS_RESULT_TRUE;
}
/* OK, we have no configured systemd service, hence let's
goto cancel_pending_activation;
}
- return TRUE;
+ return BUS_RESULT_TRUE;
cancel_pending_activation:
_DBUS_ASSERT_ERROR_IS_SET (error);
_dbus_hash_table_remove_string (activation->pending_activations,
pending_activation->service_name);
- return FALSE;
+ return BUS_RESULT_FALSE;
}
dbus_bool_t
if (service == NULL && dbus_message_get_auto_start (message))
{
BusActivation *activation;
+ BusDeferredMessage *deferred_message;
+
/* We can't do the security policy check here, since the addressed
* recipient service doesn't exist yet. We do it before sending the
* message after the service has been created.
*/
activation = bus_connection_get_activation (connection);
- if (!bus_activation_activate_service (activation, connection, transaction, TRUE,
- message, service_name, &error))
+ switch (bus_activation_activate_service (activation, connection, transaction, TRUE,
+ message, service_name, &error,
+ &deferred_message))
{
+ case BUS_RESULT_FALSE:
_DBUS_ASSERT_ERROR_IS_SET (&error);
_dbus_verbose ("bus_activation_activate_service() failed: %s\n", error.name);
- goto out;
+ break;
+ case BUS_RESULT_LATER:
+ bus_deferred_message_disable_sender(deferred_message);
+ bus_transaction_cancel_and_free (transaction);
+ transaction = NULL;
+ result = DBUS_HANDLER_RESULT_LATER;
+ break;
+ case BUS_RESULT_TRUE:
+ break;
}
goto out;