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); | 
