diff options
author | Anders Carlsson <andersca@codefactory.se> | 2003-02-17 09:59:23 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@codefactory.se> | 2003-02-17 09:59:23 +0000 |
commit | 3c8db267892bbce5c82d5060cef993dd54dc6ed4 (patch) | |
tree | 9560edcebc5bf79b4550611a67505b7677543418 | |
parent | 8faf99b118daf0040a58981cdf24a344ff2578ca (diff) |
2003-02-17 Anders Carlsson <andersca@codefactory.se>
* bus/activation.c: (bus_activation_init), (child_setup),
(bus_activation_activate_service):
* bus/activation.h:
* bus/main.c: (main):
Set DBUS_ADDRESS environment variable.
* dbus/dbus-errors.c: (dbus_set_error):
Don't use va_copy since that's a C99 feature.
* dbus/dbus-sysdeps.c: (_dbus_setenv), (do_exec),
(_dbus_spawn_async):
* dbus/dbus-sysdeps.h:
Add child_setup_func to _dbus_spawn_async.
* doc/dbus-specification.sgml:
Update specification.
* test/spawn-test.c: (setup_func), (main):
Fix test.
-rw-r--r-- | ChangeLog | 22 | ||||
-rw-r--r-- | bus/activation.c | 18 | ||||
-rw-r--r-- | bus/activation.h | 3 | ||||
-rw-r--r-- | bus/main.c | 19 | ||||
-rw-r--r-- | dbus/dbus-errors.c | 5 | ||||
-rw-r--r-- | dbus/dbus-sysdeps.c | 34 | ||||
-rw-r--r-- | dbus/dbus-sysdeps.h | 13 | ||||
-rw-r--r-- | doc/dbus-specification.sgml | 496 | ||||
-rw-r--r-- | test/spawn-test.c | 8 |
9 files changed, 589 insertions, 29 deletions
@@ -1,3 +1,25 @@ +2003-02-17 Anders Carlsson <andersca@codefactory.se> + + * bus/activation.c: (bus_activation_init), (child_setup), + (bus_activation_activate_service): + * bus/activation.h: + * bus/main.c: (main): + Set DBUS_ADDRESS environment variable. + + * dbus/dbus-errors.c: (dbus_set_error): + Don't use va_copy since that's a C99 feature. + + * dbus/dbus-sysdeps.c: (_dbus_setenv), (do_exec), + (_dbus_spawn_async): + * dbus/dbus-sysdeps.h: + Add child_setup_func to _dbus_spawn_async. + + * doc/dbus-specification.sgml: + Update specification. + + * test/spawn-test.c: (setup_func), (main): + Fix test. + 2003-02-17 Alexander Larsson <alexl@redhat.com> * dbus/dbus-connection.c (_dbus_connection_handler_destroyed_locked): diff --git a/bus/activation.c b/bus/activation.c index b4acd0f3..b5cec44a 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -34,6 +34,7 @@ #define DBUS_SERVICE_EXEC "Exec" static DBusHashTable *activation_entries = NULL; +static char *server_address = NULL; typedef struct { @@ -174,10 +175,14 @@ load_directory (const char *directory) void -bus_activation_init (const char **directories) +bus_activation_init (const char *address, + const char **directories) { int i; + /* FIXME: We should split up the server addresses. */ + BUS_HANDLE_OOM (server_address = _dbus_strdup (address)); + BUS_HANDLE_OOM (activation_entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, (DBusFreeFunction)bus_activation_entry_free)); @@ -191,6 +196,13 @@ bus_activation_init (const char **directories) } } +static void +child_setup (void *data) +{ + /* FIXME: Check return value in case of OOM */ + _dbus_setenv ("DBUS_ADDRESS", server_address); +} + dbus_bool_t bus_activation_activate_service (const char *service_name, DBusError *error) @@ -212,7 +224,9 @@ bus_activation_activate_service (const char *service_name, argv[0] = entry->exec; argv[1] = NULL; - if (!_dbus_spawn_async (argv, error)) + if (!_dbus_spawn_async (argv, + child_setup, NULL, + error)) return FALSE; return TRUE; diff --git a/bus/activation.h b/bus/activation.h index 15260f01..5f29871e 100644 --- a/bus/activation.h +++ b/bus/activation.h @@ -26,7 +26,8 @@ #include <dbus/dbus.h> -void bus_activation_init (const char **paths); +void bus_activation_init (const char *address, + const char **paths); dbus_bool_t bus_activation_activate_service (const char *service_name, DBusError *error); @@ -82,6 +82,15 @@ main (int argc, char **argv) return 1; } + + server = dbus_server_listen (argv[1], &result); + if (server == NULL) + { + _dbus_warn ("Failed to start server on %s: %s\n", + argv[1], dbus_result_to_string (result)); + return 1; + } + if (argc < 3) { _dbus_warn ("No service location given, not activating activation\n"); @@ -90,15 +99,7 @@ main (int argc, char **argv) { char *paths[] = { argv[2], NULL }; - bus_activation_init (paths); - } - - server = dbus_server_listen (argv[1], &result); - if (server == NULL) - { - _dbus_warn ("Failed to start server on %s: %s\n", - argv[1], dbus_result_to_string (result)); - return 1; + bus_activation_init (argv[1], paths); } setup_server (server); diff --git a/dbus/dbus-errors.c b/dbus/dbus-errors.c index dfc52fb3..92cca03c 100644 --- a/dbus/dbus-errors.c +++ b/dbus/dbus-errors.c @@ -238,13 +238,14 @@ dbus_set_error (DBusError *error, va_start (args, format); - va_copy (args2, args); - /* Measure the message length */ message_length = vsnprintf (&c, 1,format, args) + 1; message = dbus_malloc (message_length); + va_end (args); + + va_start (args, format); vsprintf (message, format, args2); if (!message) diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 83b1f044..1308a6ba 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -67,6 +67,19 @@ _dbus_abort (void) } /** + * Wrapper for setenv(). + * + * @param varname name of environment variable + * @param value value of environment variable + * @returns #TRUE on success. + */ +dbus_bool_t +_dbus_setenv (const char *varname, const char *value) +{ + return (setenv (varname, value, TRUE) == 0); +} + +/** * Wrapper for getenv(). * * @param varname name of environment variable @@ -1564,12 +1577,18 @@ read_ints (int fd, } static void -do_exec (int child_err_report_fd, - char **argv) +do_exec (int child_err_report_fd, + char **argv, + DBusSpawnChildSetupFunc child_setup, + void *user_data) { #ifdef DBUS_BUILD_TESTS int i, max_open; - +#endif + + if (child_setup) + (* child_setup) (user_data); +#ifdef DBUS_BUILD_TESTS max_open = sysconf (_SC_OPEN_MAX); @@ -1593,8 +1612,10 @@ do_exec (int child_err_report_fd, } dbus_bool_t -_dbus_spawn_async (char **argv, - DBusError *error) +_dbus_spawn_async (char **argv, + DBusSpawnChildSetupFunc child_setup, + void *user_data, + DBusError *error) { int pid = -1, grandchild_pid; int child_err_report_pipe[2] = { -1, -1 }; @@ -1643,7 +1664,8 @@ _dbus_spawn_async (char **argv, else if (grandchild_pid == 0) { do_exec (child_err_report_pipe[1], - argv); + argv, + child_setup, user_data); } else { diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 42697a00..50da679c 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -49,7 +49,8 @@ DBUS_BEGIN_DECLS; void _dbus_abort (void); const char* _dbus_getenv (const char *varname); - +dbus_bool_t _dbus_setenv (const char *varname, + const char *value); int _dbus_read (int fd, DBusString *buffer, @@ -148,8 +149,14 @@ dbus_bool_t _dbus_generate_random_bytes (DBusString *str, int n_bytes); const char *_dbus_errno_to_string (int errnum); -dbus_bool_t _dbus_spawn_async (char **argv, - DBusError *error); + +typedef void (* DBusSpawnChildSetupFunc) (void *user_data); + +dbus_bool_t _dbus_spawn_async (char **argv, + DBusSpawnChildSetupFunc child_setup, + void *user_data, + DBusError *error); + void _dbus_disable_sigpipe (void); diff --git a/doc/dbus-specification.sgml b/doc/dbus-specification.sgml index b54be17e..6412bf5b 100644 --- a/doc/dbus-specification.sgml +++ b/doc/dbus-specification.sgml @@ -698,15 +698,500 @@ responds to a number of messages, allowing applications to interact with the message bus. </para> + </sect2> + <sect2 id="bus-messages-hello"> + <title><literal>org.freedesktop.DBus.Hello</literal></title> <para> - - [document the messages here] + As a method: + <programlisting> + STRING Hello () + </programlisting> + Reply arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING</entry> + <entry>Name of the service assigned to the client</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + Before a client is able to send messages to other clients it + must send the <literal>org.freedesktop.DBus.Hello</literal> + message to the message bus service. If a client tries to send + a message to another client, or a message to the message bus + service that isn't the + <literal>org.freedesktop.DBus.Hello</literal> message, it will + be disconnected from the bus. + </para> + <para> + The reply message contains the name of the base service. Any + messages sent to the base service will be rereouted by the + message bus, delivering it to the client. + </para> + </sect2> + <sect2 id="bus-messages-list-services"> + <title><literal>org.freedesktop.DBus.ListServices</literal></title> + <para> + As a method: + <programlisting> + STRING_ARRAY ListServices () + </programlisting> + Reply arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING_ARRAY</entry> + <entry>Array of strings where each string is the name of a service</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + Returns a list of all existing services registered with the message bus. + </para> + </sect2> + <sect2 id="bus-messages-service-exists"> + <title><literal>org.freedesktop.DBus.ServiceExists</literal></title> + <para> + As a method: + <programlisting> + UINT32 ServiceExists (in STRING service_name) + </programlisting> + Message arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING</entry> + <entry>Name of the service</entry> + </row> + </tbody> + </tgroup> + </informaltable> + Reply arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>UINT32</entry> + <entry>Return value, 1 if the service exists and 0 otherwise</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + Checks if a service with a specified name exists. + </para> + </sect2> + + <sect2 id="bus-messages-acquire-service"> + <title><literal>org.freedesktop.DBus.AcquireService</literal></title> + <para> + As a method: + <programlisting> + UINT32 AcquireService (in STRING service_name) + </programlisting> + Message arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING</entry> + <entry>Name of the service</entry> + </row> + <row> + <entry>1</entry> + <entry>UINT32</entry> + <entry>Flags</entry> + </row> + </tbody> + </tgroup> + </informaltable> + Reply arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>UINT32</entry> + <entry>Return value</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + Tries to become owner of a specific service. The flags + specified can be the following values logically ORed together: + + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Identifier</entry> + <entry>Value</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>DBUS_SERVICE_FLAGS_PROHIBIT_REPLACEMENT</entry> + <entry>0x1</entry> + <entry> + If the client succeeds in being the owner of the specified service, + then ownership of the service can't be transferred until the service + disconnects. If this flag is not set, then any client trying to become + the owner of the service will succeed and the previous owner will be + sent a <literal>org.freedesktop.DBus.ServiceLost</literal> message. +</entry> + </row> + <row> + <entry>DBUS_SERVICE_FLAGS_REPLACE_EXISTING</entry> + <entry>0x2</entry> + <entry>Only become the owner of the service if there is no current owner.</entry> + </row> + </tbody> + </tgroup> + </informaltable> + + The return value can be one of the following values: + + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Identifier</entry> + <entry>Value</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>DBUS_SERVICE_REPLY_PRIMARY_OWNER</entry> + <entry>0x1</entry> + <entry>The client is now the primary owner of the service.</entry> + </row> + <row> + <entry>DBUS_SERVICE_REPLY_IN_QUEUE</entry> + <entry>0x2</entry> + <entry>The service already has an owner which do not want to give up ownership and therefore the client has been put in a queue.</entry> + </row> + <row> + <entry>DBUS_SERVICE_REPLY_SERVICE_EXISTS</entry> + <entry>0x4</entry> + <entry>The service does already have a primary owner, and DBUS_SERVICE_FLAG_REPLACE_EXISTING was not specified when trying to acquire the service.</entry> + </row> + <row> + <entry>DBUS_SERVICE_REPLY_ALREADY_OWNER</entry> + <entry>0x8</entry> + <entry>The client trying to request ownership of the service is already the owner of it.</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + </sect2> + <sect2 id="bus-messages-service-acquired"> + <title><literal>org.freedesktop.DBus.ServiceAcquired</literal></title> + <para> + As a method: + <programlisting> + ServiceAcquired (in STRING service_name) + </programlisting> + Message arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING</entry> + <entry>Name of the service</entry> + </row> + <row> + <entry>1</entry> + <entry>UINT32</entry> + <entry>Flags</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + This message is sent to a specific client when it becomes the primary owner of a service. + </para> + </sect2> + <sect2 id="bus-messages-service-lost"> + <title><literal>org.freedesktop.DBus.ServiceLost</literal></title> + <para> + As a method: + <programlisting> + ServiceLost (in STRING service_name) + </programlisting> + Message arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING</entry> + <entry>Name of the service</entry> + </row> + <row> + <entry>1</entry> + <entry>UINT32</entry> + <entry>Flags</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + This message is sent to a specific client when it loses primary ownership of a service. + </para> + </sect2> + + <sect2 id="bus-messages-service-created"> + <title><literal>org.freedesktop.DBus.ServiceCreated</literal></title> + <para> + As a method: + <programlisting> + ServiceCreated (in STRING service_name) + </programlisting> + Message arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING</entry> + <entry>Name of the service</entry> + </row> + <row> + <entry>1</entry> + <entry>UINT32</entry> + <entry>Flags</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + This message is broadcast to all clients when a service has been successfully registered on the message bus. + </para> + </sect2> + + <sect2 id="bus-messages-service-deleted"> + <title><literal>org.freedesktop.DBus.ServiceDeleted</literal></title> + <para> + As a method: + <programlisting> + ServiceDeleted (in STRING service_name) + </programlisting> + Message arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING</entry> + <entry>Name of the service</entry> + </row> + <row> + <entry>1</entry> + <entry>UINT32</entry> + <entry>Flags</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + This message is broadcast to all clients when a service has been deleted from the message bus. + </para> + </sect2> + + <sect2 id="bus-messages-activate-service"> + <title><literal>org.freedesktop.DBus.ActivateService</literal></title> + <para> + As a method: + <programlisting> + void ActivateService (in STRING service_name, in UINT32 flags) + </programlisting> + Message arguments: + <informaltable> + <tgroup cols=3> + <thead> + <row> + <entry>Argument</entry> + <entry>Type</entry> + <entry>Description</entry> + </row> + </thead> + <tbody> + <row> + <entry>0</entry> + <entry>STRING</entry> + <entry>Name of the service to activate</entry> + </row> + <row> + <entry>1</entry> + <entry>UINT32</entry> + <entry>Flags (currently not used)</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </para> + <para> + Tries to launch the executable associated with a service. For more information, see the part on <xref linkend="message-bus-activation"> + </para> + </sect2> + + <sect2 id="services"> + <title>Message Bus Services</title> + <para> + A service is a name that identifies a certain client. Each + client connected to the message bus has at least one service + name acquired through the + <literal>org.freedesktop.DBus.Hello</literal> message. In + addition, a client can request additional service names to be + associated with it using the + <literal>org.freedesktop.DBus.AcquireService</literal> + message. + </para> + <para> + Service ownership handling can be specified in the flags part + of the <literal>org.freedesktop.DBus.AcquireService</literal> + message. If a client specifies the + DBUS_SERVICE_FLAGS_PROHIBIT_REPLACEMENT flag, then all clients + trying to acquire the service will be put in a queue. When the + primary owner disconnects from the bus or removes ownership + from the service, the next client in the queue will be the + primary owner. If the DBUS_SERVICE_FLAGS_PROHIBIT_REPLACEMENT + flag is not specified, then the primary owner will lose + ownership whenever another client requests ownership of the + service. </para> </sect2> <sect2 id="message-bus-activation"> <title>Message Bus Service Activation</title> <para> - [document file format, filesystem locations, etc. for activation] + Activation is a way to launch executables that handle certain + services. The bus daemon looks in certain directories + (possibly different depending on if it's a system bus or a + message bus) for service description files. + </para> + <para> + Service description files have the ".service" file + extension. The message bus will only load service description + files ending with .service; all other files will be ignored. + The file format is similar to that of <ulink + url="http://www.freedesktop.org/standards/desktop-entry-spec/desktop-entry-spec.html">desktop + entries</ulink>. All service description files must be in + UTF-8 encoding. + + <figure> + <title>Example service description file</title> + <programlisting> + # Sample service description file + [D-BUS Service] + Name=org.gnome.ConfigurationDatabase + Exec=gconfd-2 + </programlisting> + </figure> + </para> + <para> + When a client requests a service to be activated, the bus + daemon tries to find it in the list of activation entries. It + then tries to spawn the executable associated with it. If this + fails, it will report an error. + </para> + <para> + The executable launched will have the environment variable + <literal>DBUS_ADDRESS</literal> set to the address of the + server so it can connect and register the appropriate services. </para> </sect2> <sect2 id="message-bus-location"> @@ -730,16 +1215,17 @@ </para> </sect2> </sect1> - +<!-- <appendix id="implementation-notes"> <title>Implementation notes</title> <sect1 id="implementation-notes-subsection"> <title></title> <para> - </para> </sect1> </appendix> +--> + <glossary><title>Glossary</title> <para> This glossary defines some of the terms used in this specification. diff --git a/test/spawn-test.c b/test/spawn-test.c index fda0309b..18462eba 100644 --- a/test/spawn-test.c +++ b/test/spawn-test.c @@ -5,6 +5,12 @@ #undef DBUS_COMPILATION #include <stdio.h> +static void +setup_func (void *data) +{ + printf ("entering setup func.\n"); +} + int main (int argc, char **argv) { @@ -24,7 +30,7 @@ main (int argc, char **argv) argv_copy [i] = argv[i + 1]; argv_copy[argc - 1] = NULL; - if (!_dbus_spawn_async (argv_copy, &error)) + if (!_dbus_spawn_async (argv_copy, setup_func, NULL, &error)) { fprintf (stderr, "Could not launch application: \"%s\"\n", error.message); |