mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2025-12-26 16:50:09 +01:00
2003-02-16 Anders Carlsson <andersca@codefactory.se>
* bus/activation.c: (load_directory), (bus_activation_init), (bus_activation_activate_service): * bus/activation.h: * bus/driver.c: (bus_driver_handle_activate_service), (bus_driver_handle_message): More work on the activation handling. * dbus/dbus-errors.h: Add some error messages * dbus/dbus-message.c: (dbus_message_new_error_reply): * dbus/dbus-message.h: New function that creates an error message. * dbus/dbus-protocol.h: Add ACTIVATE_SERVER message. * dbus/dbus-server-unix.c: (unix_handle_watch), (_dbus_server_new_for_domain_socket): Call _dbus_fd_set_close_on_exec. * dbus/dbus-sysdeps.c: (make_pipe), (do_exec), (_dbus_spawn_async), (_dbus_disable_sigpipe), (_dbus_fd_set_close_on_exec): * dbus/dbus-sysdeps.h: Add _dbus_fd_set_close_on exec function. Also add function that checks that all open fds are set to close-on-exec and warns otherwise. * dbus/dbus-transport-unix.c: (_dbus_transport_new_for_domain_socket): Call _dbus_fd_set_close_on_exec.
This commit is contained in:
parent
ac5183eafc
commit
f116b1282f
11 changed files with 209 additions and 59 deletions
34
ChangeLog
34
ChangeLog
|
|
@ -1,3 +1,37 @@
|
|||
2003-02-16 Anders Carlsson <andersca@codefactory.se>
|
||||
|
||||
* bus/activation.c: (load_directory), (bus_activation_init),
|
||||
(bus_activation_activate_service):
|
||||
* bus/activation.h:
|
||||
* bus/driver.c:
|
||||
(bus_driver_handle_activate_service), (bus_driver_handle_message):
|
||||
More work on the activation handling.
|
||||
|
||||
* dbus/dbus-errors.h:
|
||||
Add some error messages
|
||||
|
||||
* dbus/dbus-message.c: (dbus_message_new_error_reply):
|
||||
* dbus/dbus-message.h:
|
||||
New function that creates an error message.
|
||||
|
||||
* dbus/dbus-protocol.h:
|
||||
Add ACTIVATE_SERVER message.
|
||||
|
||||
* dbus/dbus-server-unix.c: (unix_handle_watch),
|
||||
(_dbus_server_new_for_domain_socket):
|
||||
Call _dbus_fd_set_close_on_exec.
|
||||
|
||||
* dbus/dbus-sysdeps.c: (make_pipe), (do_exec),
|
||||
(_dbus_spawn_async), (_dbus_disable_sigpipe),
|
||||
(_dbus_fd_set_close_on_exec):
|
||||
* dbus/dbus-sysdeps.h:
|
||||
Add _dbus_fd_set_close_on exec function. Also add function that checks
|
||||
that all open fds are set to close-on-exec and warns otherwise.
|
||||
|
||||
* dbus/dbus-transport-unix.c:
|
||||
(_dbus_transport_new_for_domain_socket):
|
||||
Call _dbus_fd_set_close_on_exec.
|
||||
|
||||
2003-02-16 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* dbus/dbus-connection.c (dbus_connection_set_change_sigpipe):
|
||||
|
|
|
|||
|
|
@ -41,6 +41,12 @@ typedef struct
|
|||
char *exec;
|
||||
} BusActivationEntry;
|
||||
|
||||
static DBusHashTable *pending_activations = NULL;
|
||||
typedef struct
|
||||
{
|
||||
char *service;
|
||||
} BusPendingActivation;
|
||||
|
||||
static void
|
||||
bus_activation_entry_free (BusActivationEntry *entry)
|
||||
{
|
||||
|
|
@ -164,36 +170,6 @@ load_directory (const char *directory)
|
|||
bus_desktop_file_free (desktop_file);
|
||||
_dbus_string_free (&full_path);
|
||||
}
|
||||
|
||||
#if 0
|
||||
while ((directory_entry = readdir (directory_handle)))
|
||||
{
|
||||
DBusString path, filename;
|
||||
BusDesktopFile *desktop_file;
|
||||
DBusError error;
|
||||
const char *filename_c;
|
||||
|
||||
|
||||
_dbus_string_init_const (&filename, directory_entry->d_name);
|
||||
|
||||
|
||||
_dbus_string_get_const_data (&path, &filename_c);
|
||||
|
||||
if (!desktop_file)
|
||||
{
|
||||
_dbus_verbose ("Could not load %s: %s\n", filename_c,
|
||||
error.message);
|
||||
dbus_error_free (&error);
|
||||
_dbus_string_free (&path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!add_desktop_file_entry (desktop_file))
|
||||
{
|
||||
_dbus_verbose ("Could not add %s to activation entry list.\n", filename_c);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -214,3 +190,30 @@ bus_activation_init (const char **directories)
|
|||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_activation_activate_service (const char *service_name,
|
||||
DBusError *error)
|
||||
{
|
||||
BusActivationEntry *entry;
|
||||
char *argv[2];
|
||||
|
||||
entry = _dbus_hash_table_lookup_string (activation_entries, service_name);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND,
|
||||
"The service %s was not found in the activation entry list",
|
||||
service_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now try to spawn the process */
|
||||
argv[0] = entry->exec;
|
||||
argv[1] = NULL;
|
||||
|
||||
if (!_dbus_spawn_async (argv, error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@
|
|||
#ifndef BUS_ACTIVATION_H
|
||||
#define BUS_ACTIVATION_H
|
||||
|
||||
void bus_activation_init (const char **paths);
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
void bus_activation_init (const char **paths);
|
||||
dbus_bool_t bus_activation_activate_service (const char *service_name,
|
||||
DBusError *error);
|
||||
|
||||
|
||||
#endif /* BUS_ACTIVATION_H */
|
||||
|
|
|
|||
41
bus/driver.c
41
bus/driver.c
|
|
@ -21,6 +21,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "activation.h"
|
||||
#include "connection.h"
|
||||
#include "driver.h"
|
||||
#include "dispatch.h"
|
||||
|
|
@ -169,7 +170,7 @@ bus_driver_handle_hello (DBusConnection *connection,
|
|||
{
|
||||
DBusString unique_name;
|
||||
BusService *service;
|
||||
|
||||
|
||||
BUS_HANDLE_OOM (_dbus_string_init (&unique_name, _DBUS_INT_MAX));
|
||||
BUS_HANDLE_OOM (create_unique_client_name (&unique_name));
|
||||
|
||||
|
|
@ -208,7 +209,7 @@ bus_driver_send_welcome_message (DBusConnection *connection,
|
|||
NULL));
|
||||
|
||||
BUS_HANDLE_OOM (dbus_connection_send_message (connection, welcome, NULL, NULL));
|
||||
|
||||
|
||||
dbus_message_unref (welcome);
|
||||
}
|
||||
|
||||
|
|
@ -363,6 +364,39 @@ bus_driver_handle_service_exists (DBusConnection *connection,
|
|||
dbus_free (name);
|
||||
}
|
||||
|
||||
static void
|
||||
bus_driver_handle_activate_service (DBusConnection *connection,
|
||||
DBusMessage *message)
|
||||
{
|
||||
DBusResultCode result;
|
||||
dbus_uint32_t flags;
|
||||
char *name;
|
||||
DBusError error;
|
||||
|
||||
BUS_HANDLE_OOM ((result = dbus_message_get_args (message,
|
||||
DBUS_TYPE_STRING, &name,
|
||||
DBUS_TYPE_UINT32, &flags,
|
||||
0)) != DBUS_RESULT_NO_MEMORY);
|
||||
if (result != DBUS_RESULT_SUCCESS)
|
||||
{
|
||||
dbus_free (name);
|
||||
dbus_connection_disconnect (connection);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bus_activation_activate_service (name, &error))
|
||||
{
|
||||
DBusMessage *error_reply;
|
||||
|
||||
BUS_HANDLE_OOM (error_reply = dbus_message_new_error_reply (message,
|
||||
error.name, error.message));
|
||||
dbus_error_free (&error);
|
||||
|
||||
BUS_HANDLE_OOM (dbus_connection_send_message (connection, error_reply, NULL, NULL));
|
||||
dbus_message_unref (error_reply);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bus_driver_handle_message (DBusConnection *connection,
|
||||
DBusMessage *message)
|
||||
|
|
@ -391,7 +425,8 @@ bus_driver_handle_message (DBusConnection *connection,
|
|||
bus_driver_handle_acquire_service (connection, message);
|
||||
else if (strcmp (name, DBUS_MESSAGE_SERVICE_EXISTS) == 0)
|
||||
bus_driver_handle_service_exists (connection, message);
|
||||
|
||||
else if (strcmp (name, DBUS_MESSAGE_ACTIVATE_SERVICE) == 0)
|
||||
bus_driver_handle_activate_service (connection, message);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -49,9 +49,10 @@ struct DBusError
|
|||
void *padding1; /**< placeholder */
|
||||
};
|
||||
|
||||
#define DBUS_ERROR_SPAWN_FORK_FAILED "org.freedesktop.DBus.Error.Spawn.ForkFailed"
|
||||
#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed"
|
||||
#define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory"
|
||||
#define DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND "org.freedesktop.DBus.Activate.ServiceNotFound"
|
||||
#define DBUS_ERROR_SPAWN_FORK_FAILED "org.freedesktop.DBus.Error.Spawn.ForkFailed"
|
||||
#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed"
|
||||
#define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
|
|||
|
|
@ -816,6 +816,50 @@ dbus_message_new_reply (DBusMessage *original_message)
|
|||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new message that is an error reply to a certain message.
|
||||
*
|
||||
* @param original_message the original message
|
||||
* @param error_name the error name
|
||||
* @param error_message the error message string
|
||||
* @returns a new error message
|
||||
*/
|
||||
DBusMessage*
|
||||
dbus_message_new_error_reply (DBusMessage *original_message,
|
||||
const char *error_name,
|
||||
const char *error_message)
|
||||
{
|
||||
DBusMessage *message;
|
||||
const char *sender;
|
||||
|
||||
sender = get_string_field (original_message,
|
||||
FIELD_SENDER, NULL);
|
||||
|
||||
_dbus_assert (sender != NULL);
|
||||
|
||||
message = dbus_message_new (sender, error_name);
|
||||
|
||||
if (message == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!_dbus_message_set_reply_serial (message,
|
||||
_dbus_message_get_client_serial (original_message)))
|
||||
{
|
||||
dbus_message_unref (message);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dbus_message_append_string (message, error_message))
|
||||
{
|
||||
dbus_message_unref (message);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dbus_message_set_is_error (message, TRUE);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new message that is an exact replica of the message
|
||||
* specified, except that its refcount is set to 1.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ typedef struct DBusMessageIter DBusMessageIter;
|
|||
DBusMessage* dbus_message_new (const char *service,
|
||||
const char *name);
|
||||
DBusMessage* dbus_message_new_reply (DBusMessage *original_message);
|
||||
DBusMessage* dbus_message_new_error_reply (DBusMessage *original_message,
|
||||
const char *error_name,
|
||||
const char *error_message);
|
||||
DBusMessage *dbus_message_new_from_message (const DBusMessage *message);
|
||||
|
||||
void dbus_message_ref (DBusMessage *message);
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ extern "C" {
|
|||
#define DBUS_SERVICE_REPLY_ALREADY_OWNER 0x8
|
||||
|
||||
/* Messages */
|
||||
#define DBUS_MESSAGE_ACTIVATE_SERVICE "org.freedesktop.DBus.ActivateService"
|
||||
#define DBUS_MESSAGE_SERVICE_EXISTS "org.freedesktop.DBus.ServiceExists"
|
||||
#define DBUS_MESSAGE_HELLO "org.freedesktop.DBus.Hello"
|
||||
#define DBUS_MESSAGE_LIST_SERVICES "org.freedesktop.DBus.ListServices"
|
||||
|
|
@ -84,7 +85,7 @@ extern "C" {
|
|||
#define DBUS_MESSAGE_SERVICE_CREATED "org.freedesktop.DBus.ServiceCreated"
|
||||
#define DBUS_MESSAGE_SERVICE_DELETED "org.freedesktop.DBus.ServiceDeleted"
|
||||
#define DBUS_MESSAGE_SERVICE_LOST "org.freedesktop.DBus.ServiceLost"
|
||||
|
||||
|
||||
#define DBUS_MESSAGE_LOCAL_DISCONNECT "org.freedesktop.Local.Disconnect"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ unix_handle_watch (DBusServer *server,
|
|||
}
|
||||
else
|
||||
{
|
||||
_dbus_fd_set_close_on_exec (client_fd);
|
||||
handle_new_client_fd (server, client_fd);
|
||||
}
|
||||
}
|
||||
|
|
@ -247,6 +248,8 @@ _dbus_server_new_for_domain_socket (const char *path,
|
|||
int listen_fd;
|
||||
|
||||
listen_fd = _dbus_listen_unix_socket (path, result);
|
||||
_dbus_fd_set_close_on_exec (listen_fd);
|
||||
|
||||
if (listen_fd < 0)
|
||||
return NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ _dbus_connect_unix_socket (const char *path,
|
|||
struct sockaddr_un addr;
|
||||
|
||||
fd = socket (AF_LOCAL, SOCK_STREAM, 0);
|
||||
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
dbus_set_result (result,
|
||||
|
|
@ -340,7 +340,7 @@ _dbus_listen_unix_socket (const char *path,
|
|||
struct sockaddr_un addr;
|
||||
|
||||
listen_fd = socket (AF_LOCAL, SOCK_STREAM, 0);
|
||||
|
||||
|
||||
if (listen_fd < 0)
|
||||
{
|
||||
dbus_set_result (result, _dbus_result_from_errno (errno));
|
||||
|
|
@ -1490,7 +1490,11 @@ make_pipe (int p[2],
|
|||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
{
|
||||
_dbus_fd_set_close_on_exec (p[0]);
|
||||
_dbus_fd_set_close_on_exec (p[1]);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
enum
|
||||
|
|
@ -1563,6 +1567,23 @@ static void
|
|||
do_exec (int child_err_report_fd,
|
||||
char **argv)
|
||||
{
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
int i, max_open;
|
||||
|
||||
max_open = sysconf (_SC_OPEN_MAX);
|
||||
|
||||
|
||||
for (i = 3; i < max_open; i++)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = fcntl (i, F_GETFD);
|
||||
|
||||
if (retval != -1 && !(retval & FD_CLOEXEC))
|
||||
_dbus_warn ("Fd %d did not have the close-on-exec flag set!\n", i);
|
||||
}
|
||||
#endif
|
||||
|
||||
execvp (argv[0], argv);
|
||||
|
||||
/* Exec failed */
|
||||
|
|
@ -1577,19 +1598,13 @@ _dbus_spawn_async (char **argv,
|
|||
{
|
||||
int pid = -1, grandchild_pid;
|
||||
int child_err_report_pipe[2] = { -1, -1 };
|
||||
int child_pid_report_pipe[2] = { -1, -1 };
|
||||
int status;
|
||||
|
||||
printf ("spawning application: %s\n", argv[0]);
|
||||
|
||||
if (!make_pipe (child_err_report_pipe, error))
|
||||
return FALSE;
|
||||
|
||||
if (!make_pipe (child_pid_report_pipe, error))
|
||||
goto cleanup_and_fail;
|
||||
|
||||
pid = fork ();
|
||||
|
||||
|
||||
if (pid < 0)
|
||||
{
|
||||
dbus_set_error (error,
|
||||
|
|
@ -1612,7 +1627,6 @@ _dbus_spawn_async (char **argv,
|
|||
* though
|
||||
*/
|
||||
close_and_invalidate (&child_err_report_pipe[0]);
|
||||
close_and_invalidate (&child_pid_report_pipe[0]);
|
||||
|
||||
/* We need to fork an intermediate child that launches the
|
||||
* final child. The purpose of the intermediate child
|
||||
|
|
@ -1623,10 +1637,6 @@ _dbus_spawn_async (char **argv,
|
|||
|
||||
if (grandchild_pid < 0)
|
||||
{
|
||||
/* report -1 as child PID */
|
||||
write (child_pid_report_pipe[1], &grandchild_pid,
|
||||
sizeof(grandchild_pid));
|
||||
|
||||
write_err_and_exit (child_err_report_pipe[1],
|
||||
CHILD_FORK_FAILED);
|
||||
}
|
||||
|
|
@ -1637,9 +1647,6 @@ _dbus_spawn_async (char **argv,
|
|||
}
|
||||
else
|
||||
{
|
||||
write (child_pid_report_pipe[1], &grandchild_pid, sizeof(grandchild_pid));
|
||||
close_and_invalidate (&child_pid_report_pipe[1]);
|
||||
|
||||
_exit (0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1652,7 +1659,6 @@ _dbus_spawn_async (char **argv,
|
|||
|
||||
/* Close the uncared-about ends of the pipes */
|
||||
close_and_invalidate (&child_err_report_pipe[1]);
|
||||
close_and_invalidate (&child_pid_report_pipe[1]);
|
||||
|
||||
wait_again:
|
||||
if (waitpid (pid, &status, 0) < 0)
|
||||
|
|
@ -1716,8 +1722,6 @@ _dbus_spawn_async (char **argv,
|
|||
|
||||
close_and_invalidate (&child_err_report_pipe[0]);
|
||||
close_and_invalidate (&child_err_report_pipe[1]);
|
||||
close_and_invalidate (&child_pid_report_pipe[0]);
|
||||
close_and_invalidate (&child_pid_report_pipe[1]);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -1731,4 +1735,19 @@ _dbus_disable_sigpipe (void)
|
|||
signal (SIGPIPE, SIG_IGN);
|
||||
}
|
||||
|
||||
void
|
||||
_dbus_fd_set_close_on_exec (int fd)
|
||||
{
|
||||
int val;
|
||||
|
||||
val = fcntl (fd, F_GETFD, 0);
|
||||
|
||||
if (val < 0)
|
||||
return;
|
||||
|
||||
val |= FD_CLOEXEC;
|
||||
|
||||
fcntl (fd, F_SETFD, val);
|
||||
}
|
||||
|
||||
/** @} end of sysdeps */
|
||||
|
|
|
|||
|
|
@ -1102,6 +1102,8 @@ _dbus_transport_new_for_domain_socket (const char *path,
|
|||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
_dbus_fd_set_close_on_exec (fd);
|
||||
|
||||
_dbus_verbose ("Successfully connected to unix socket %s\n",
|
||||
path);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue