summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog34
-rw-r--r--bus/activation.c63
-rw-r--r--bus/activation.h7
-rw-r--r--bus/driver.c41
-rw-r--r--dbus/dbus-errors.h7
-rw-r--r--dbus/dbus-message.c44
-rw-r--r--dbus/dbus-message.h3
-rw-r--r--dbus/dbus-protocol.h3
-rw-r--r--dbus/dbus-server-unix.c3
-rw-r--r--dbus/dbus-sysdeps.c61
-rw-r--r--dbus/dbus-transport-unix.c2
11 files changed, 209 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index 94768963..afb58cf4 100644
--- a/ChangeLog
+++ b/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):
diff --git a/bus/activation.c b/bus/activation.c
index 7f7dd438..b4acd0f3 100644
--- a/bus/activation.c
+++ b/bus/activation.c
@@ -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;
+}
diff --git a/bus/activation.h b/bus/activation.h
index 901c4eee..15260f01 100644
--- a/bus/activation.h
+++ b/bus/activation.h
@@ -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 */
diff --git a/bus/driver.c b/bus/driver.c
index 9983f573..80478e45 100644
--- a/bus/driver.c
+++ b/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
diff --git a/dbus/dbus-errors.h b/dbus/dbus-errors.h
index 5cc77491..1b7b474a 100644
--- a/dbus/dbus-errors.h
+++ b/dbus/dbus-errors.h
@@ -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
{
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index aca8c2cb..fced9c72 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -817,6 +817,50 @@ dbus_message_new_reply (DBusMessage *original_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.
*
diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h
index 82faf658..2038978b 100644
--- a/dbus/dbus-message.h
+++ b/dbus/dbus-message.h
@@ -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);
diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h
index f043346a..dd9b3122 100644
--- a/dbus/dbus-protocol.h
+++ b/dbus/dbus-protocol.h
@@ -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
diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c
index 23bbdab3..6da70537 100644
--- a/dbus/dbus-server-unix.c
+++ b/dbus/dbus-server-unix.c
@@ -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;
diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
index 67677707..83b1f044 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -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 */
diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c
index ef50863d..84703345 100644
--- a/dbus/dbus-transport-unix.c
+++ b/dbus/dbus-transport-unix.c
@@ -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);