diff options
| author | Havoc Pennington <hp@redhat.com> | 2002-12-13 03:55:38 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2002-12-13 03:55:38 +0000 | 
| commit | 271fa7fc335f332bb2be3beeef735334546c4957 (patch) | |
| tree | 6c20f827eaa2575b6d94f0eaee5ce975c7061da8 | |
| parent | d4b870e7f91b7018524f7b85dc00b90cc64453bf (diff) | |
2002-12-12  Havoc Pennington  <hp@pobox.com>
	* dbus/dbus-transport-unix.c, dbus/dbus-server-unix.c: use the
	below new interfaces and include fewer system headers.
	* dbus/dbus-sysdeps.c (_dbus_read): new function
	(_dbus_write): new function
	(_dbus_write_two): new function
	(_dbus_connect_unix_socket): new function
	(_dbus_listen_unix_socket): new function
	* dbus/dbus-message-internal.h: change interfaces to use
	DBusString
| -rw-r--r-- | ChangeLog | 14 | ||||
| -rw-r--r-- | dbus/dbus-message-internal.h | 13 | ||||
| -rw-r--r-- | dbus/dbus-message.c | 140 | ||||
| -rw-r--r-- | dbus/dbus-server-unix.c | 53 | ||||
| -rw-r--r-- | dbus/dbus-string.c | 1 | ||||
| -rw-r--r-- | dbus/dbus-string.h | 3 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps.c | 328 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps.h | 26 | ||||
| -rw-r--r-- | dbus/dbus-transport-unix.c | 135 | ||||
| -rw-r--r-- | test/watch.c | 3 | 
10 files changed, 485 insertions, 231 deletions
| @@ -1,3 +1,17 @@ +2002-12-12  Havoc Pennington  <hp@pobox.com> + +	* dbus/dbus-transport-unix.c, dbus/dbus-server-unix.c: use the +	below new interfaces and include fewer system headers. + +	* dbus/dbus-sysdeps.c (_dbus_read): new function +	(_dbus_write): new function +	(_dbus_write_two): new function +	(_dbus_connect_unix_socket): new function +	(_dbus_listen_unix_socket): new function + +	* dbus/dbus-message-internal.h: change interfaces to use +	DBusString +  2002-12-11  Havoc Pennington  <hp@pobox.com>  	* dbus/dbus-types.h: add dbus_unichar diff --git a/dbus/dbus-message-internal.h b/dbus/dbus-message-internal.h index 5b1aea66..dc36a244 100644 --- a/dbus/dbus-message-internal.h +++ b/dbus/dbus-message-internal.h @@ -30,10 +30,8 @@ DBUS_BEGIN_DECLS;  typedef struct DBusMessageLoader DBusMessageLoader;  void _dbus_message_get_network_data (DBusMessage          *message, -                                     const unsigned char **header, -                                     int                  *header_len, -                                     const unsigned char **body, -                                     int                  *body_len); +                                     const DBusString    **header, +                                     const DBusString    **body);  void _dbus_message_lock             (DBusMessage          *message); @@ -41,11 +39,10 @@ void _dbus_message_lock             (DBusMessage          *message);  DBusMessageLoader* _dbus_message_loader_new                   (void);  void               _dbus_message_loader_ref                   (DBusMessageLoader  *loader);  void               _dbus_message_loader_unref                 (DBusMessageLoader  *loader); -dbus_bool_t        _dbus_message_loader_get_buffer            (DBusMessageLoader  *loader, -                                                               unsigned char     **buffer, -                                                               int                *buffer_len); +void               _dbus_message_loader_get_buffer            (DBusMessageLoader  *loader, +                                                               DBusString        **buffer);  void               _dbus_message_loader_return_buffer         (DBusMessageLoader  *loader, -                                                               unsigned char      *buffer, +                                                               DBusString         *buffer,                                                                 int                 bytes_read);  DBusMessage*       _dbus_message_loader_pop_message           (DBusMessageLoader  *loader); diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 1e95bec7..d86f8318 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -39,6 +39,13 @@   */  /** + * The largest-length message we allow + * + * @todo match this up with whatever the protocol spec says. + */ +#define _DBUS_MAX_MESSAGE_LENGTH (_DBUS_INT_MAX/16) + +/**   * @brief Internals of DBusMessage   *    * Object representing a message received from or to be sent to @@ -49,14 +56,12 @@ struct DBusMessage  {    int refcount; /**< Reference count */ -  unsigned char *header; /**< Header network data, stored -                          * separately from body so we can -                          * independently realloc it. -                          */ -  int header_len;        /**< Length of header data. */ +  DBusString header; /**< Header network data, stored +                      * separately from body so we can +                      * independently realloc it. +                      */ -  unsigned char *body;   /**< Body network data. */ -  int body_len;          /**< Length of body data. */ +  DBusString body;   /**< Body network data. */    unsigned int locked : 1; /**< Message being sent, no modifications allowed. */  }; @@ -69,23 +74,17 @@ struct DBusMessage   *   * @param message the message.   * @param header return location for message header data. - * @param header_len return location for header length in bytes.   * @param body return location for message body data. - * @param body_len return location for body length in bytes.   */  void  _dbus_message_get_network_data (DBusMessage          *message, -                                const unsigned char **header, -                                int                  *header_len, -                                const unsigned char **body, -                                int                  *body_len) +                                const DBusString    **header, +                                const DBusString    **body)  {    _dbus_assert (message->locked); -  *header = message->header; -  *header_len = message->header_len; -  *body = message->body; -  *body_len = message->body_len; +  *header = &message->header; +  *body = &message->body;  }  /** @@ -143,11 +142,25 @@ dbus_message_new (void)    message->refcount = 1; +  if (!_dbus_string_init (&message->header, _DBUS_MAX_MESSAGE_LENGTH)) +    { +      dbus_free (message); +      return NULL; +    } + +  if (!_dbus_string_init (&message->body, _DBUS_MAX_MESSAGE_LENGTH)) +    { +      _dbus_string_free (&message->header); +      dbus_free (message); +      return NULL; +    } +      /* We need to decide what a message contains. ;-) */ -  message->header = _dbus_strdup ("H"); -  message->header_len = 2; -  message->body = _dbus_strdup ("Body"); -  message->body_len = 5; +  /* (not bothering to check failure of these appends) */ +  _dbus_string_append (&message->header, "H"); +  _dbus_string_append_byte (&message->header, '\0'); +  _dbus_string_append (&message->body, "Body"); +  _dbus_string_append_byte (&message->body, '\0');    return message;  } @@ -180,6 +193,8 @@ dbus_message_unref (DBusMessage *message)    message->refcount -= 1;    if (message->refcount == 0)      { +      _dbus_string_free (&message->header); +      _dbus_string_free (&message->body);        dbus_free (message);      } @@ -212,12 +227,9 @@ dbus_message_unref (DBusMessage *message)  struct DBusMessageLoader  {    int refcount;        /**< Reference count. */ -   -  int allocated;       /**< Allocated size of "data" */ -  int length;          /**< Used size of "data" */ - -  unsigned char *data; /**< Buffered data. */ +  DBusString data;     /**< Buffered data */ +      DBusList *messages;  /**< Complete messages. */    unsigned int buffer_outstanding : 1; /**< Someone is using the buffer to read */ @@ -251,14 +263,15 @@ _dbus_message_loader_new (void)      return NULL;    loader->refcount = 1;   -   -  /* Header, plus room for averagish other fields */ -  loader->allocated = INITIAL_LOADER_DATA_LEN; -  loader->data = dbus_malloc (loader->allocated); -  if (loader->data == NULL) -    loader->allocated = 0; -   -  loader->length = 0; + +  if (!_dbus_string_init (&loader->data, _DBUS_INT_MAX)) +    { +      dbus_free (loader); +      return NULL; +    } + +  /* preallocate the buffer for speed, ignore failure */ +  (void) _dbus_string_set_length (&loader->data, INITIAL_LOADER_DATA_LEN);    return loader;  } @@ -290,7 +303,7 @@ _dbus_message_loader_unref (DBusMessageLoader *loader)                            (DBusForeachFunction) dbus_message_unref,                            NULL);        _dbus_list_clear (&loader->messages); -      dbus_free (loader->data); +      _dbus_string_free (&loader->data);        dbus_free (loader);      }  } @@ -309,50 +322,17 @@ _dbus_message_loader_unref (DBusMessageLoader *loader)   * or reallocs.   *    * @param loader the message loader. - * @param buffer address to store the buffer. - * @param buffer_len address to store the buffer length. - * @returns #FALSE if no buffer can be allocated. + * @param buffer the buffer   */ -dbus_bool_t +void  _dbus_message_loader_get_buffer (DBusMessageLoader  *loader, -                                 unsigned char     **buffer, -                                 int                *buffer_len) +                                 DBusString        **buffer)  {    _dbus_assert (!loader->buffer_outstanding); -   -#define MIN_BUFSIZE INITIAL_LOADER_DATA_LEN -   -  if ((loader->length + MIN_BUFSIZE) >= loader->allocated) -    { -      unsigned char *buf; -      int new_allocated; - -      /* double (and add MIN_BUFSIZE, in case allocated == 0) */ -      new_allocated = MIN_BUFSIZE + loader->allocated * 2; - -      if (new_allocated <= loader->allocated) -        { -          /* ugh, overflow. Maybe someone is trying to screw us. */ -          /* (we could overflow so far that new_allocated > loader->allocated -           *  but nothing should break in that case) -           */ -          return FALSE; -        } -       -      buf = dbus_realloc (loader->data, new_allocated); -      if (buf == NULL) -        return FALSE; - -      loader->data = buf; -      loader->allocated = new_allocated; -    } -  *buffer = loader->data + loader->length; -  *buffer_len = loader->allocated - loader->length; +  *buffer = &loader->data;    loader->buffer_outstanding = TRUE; - -  return TRUE;  }  /** @@ -367,24 +347,23 @@ _dbus_message_loader_get_buffer (DBusMessageLoader  *loader,   */  void  _dbus_message_loader_return_buffer (DBusMessageLoader  *loader, -                                    unsigned char      *buffer, +                                    DBusString         *buffer,                                      int                 bytes_read)  {    _dbus_assert (loader->buffer_outstanding); +  _dbus_assert (buffer == &loader->data);    /* FIXME fake implementation just creates a message for every 7     * bytes. The real implementation will pass ownership of -   * loader->data to new messages, to avoid memcpy.  We can also +   * loader->data bytes to new messages, to avoid memcpy.  We can also     * smart-realloc loader->data to shrink it if it's too big, though     * _dbus_message_loader_get_buffer() could strategically arrange for     * that to usually not happen.     */ -   -  loader->length += bytes_read;    loader->buffer_outstanding = FALSE; -  while (loader->length >= 7) +  while (_dbus_string_get_length (&loader->data) >= 7)      {        DBusMessage *message; @@ -394,10 +373,9 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,        _dbus_list_append (&loader->messages, message); -      memmove (loader->data, loader->data + 7, -               loader->length - 7); -      loader->length -= 7; - +      _dbus_string_delete (&loader->data, +                           0, 7); +              _dbus_verbose ("Loaded message %p\n", message);      }  } diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c index 277e00a6..c58923b9 100644 --- a/dbus/dbus-server-unix.c +++ b/dbus/dbus-server-unix.c @@ -27,10 +27,6 @@  #include "dbus-connection-internal.h"  #include <sys/types.h>  #include <unistd.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <errno.h> -#include <fcntl.h>  /**   * @defgroup DBusServerUnix DBusServer implementations for UNIX @@ -132,14 +128,13 @@ unix_handle_watch (DBusServer  *server,        listen_fd = dbus_watch_get_fd (watch); -    retry: -      client_fd = accept (listen_fd, NULL, NULL); +      client_fd = _dbus_accept_unix_socket (listen_fd);        if (client_fd < 0)          { -          if (errno == EINTR) -            goto retry; -          else if (errno == EAGAIN || errno == EWOULDBLOCK) +          /* EINTR handled for us */ +           +          if (errno == EAGAIN || errno == EWOULDBLOCK)              _dbus_verbose ("No client available to accept after all\n");            else              _dbus_verbose ("Failed to accept a client connection: %s\n", @@ -247,46 +242,10 @@ _dbus_server_new_for_domain_socket (const char     *path,  {    DBusServer *server;    int listen_fd; -  struct sockaddr_un addr; - -  listen_fd = socket (AF_LOCAL, SOCK_STREAM, 0); +  listen_fd = _dbus_listen_unix_socket (path, result);    if (listen_fd < 0) -    { -      dbus_set_result (result, _dbus_result_from_errno (errno)); -      _dbus_verbose ("Failed to create socket \"%s\": %s\n", -                     path, _dbus_strerror (errno)); -      return NULL; -    } - -  if (!_dbus_set_fd_nonblocking (listen_fd, result)) -    { -      close (listen_fd); -      return NULL; -    } - -  _DBUS_ZERO (addr); -  addr.sun_family = AF_LOCAL; -  strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH); -  addr.sun_path[_DBUS_MAX_SUN_PATH_LENGTH] = '\0'; -   -  if (bind (listen_fd, (struct sockaddr*) &addr, SUN_LEN (&addr)) < 0) -    { -      dbus_set_result (result, _dbus_result_from_errno (errno)); -      _dbus_verbose ("Failed to bind socket \"%s\": %s\n", -                     path, _dbus_strerror (errno)); -      close (listen_fd); -      return NULL; -    } - -  if (listen (listen_fd, 30 /* backlog */) < 0) -    { -      dbus_set_result (result, _dbus_result_from_errno (errno));       -      _dbus_verbose ("Failed to listen on socket \"%s\": %s\n", -                     path, _dbus_strerror (errno)); -      close (listen_fd); -      return NULL; -    } +    return NULL;    server = _dbus_server_new_for_fd (listen_fd);    if (server == NULL) diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 088ca35c..573ed313 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -21,6 +21,7 @@   *   */ +#include "dbus-internals.h"  #include "dbus-string.h"  /* we allow a system header here, for speed/convenience */  #include <string.h> diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h index 4eda5954..b2f99570 100644 --- a/dbus/dbus-string.h +++ b/dbus/dbus-string.h @@ -24,7 +24,8 @@  #ifndef DBUS_STRING_H  #define DBUS_STRING_H -#include <dbus/dbus-internals.h> +#include <config.h> +  #include <dbus/dbus-memory.h>  #include <dbus/dbus-types.h> diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index 4bc3db9d..76b9c5ce 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -21,12 +21,22 @@   *   */ +#include "dbus-internals.h"  #include "dbus-sysdeps.h"  #include <stdlib.h>  #include <string.h>  #include <unistd.h>  #include <stdio.h>  #include <errno.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/un.h> +#ifdef HAVE_WRITEV +#include <sys/uio.h> +#endif +  /**   * @addtogroup DBusInternalsUtils @@ -54,6 +64,324 @@ _dbus_getenv (const char *varname)    return getenv (varname);  } +/** + * Thin wrapper around the read() system call that appends + * the data it reads to the DBusString buffer. It appends + * up to the given count, and returns the same value + * and same errno as read(). The only exception is that + * _dbus_read() handles EINTR for you. + * + * @param fd the file descriptor to read from + * @param buffer the buffer to append data to + * @param count the amount of data to read + * @returns the number of bytes read or -1 + */ +int +_dbus_read (int               fd, +            DBusString       *buffer, +            int               count) +{ +  int bytes_read; +  int start; +  char *data; + +  _dbus_assert (count >= 0); +   +  start = _dbus_string_get_length (buffer); + +  if (!_dbus_string_lengthen (buffer, count)) +    { +      errno = ENOMEM; +      return -1; +    } + +  _dbus_string_get_data_len (buffer, &data, start, count); + + again: +   +  bytes_read = read (fd, data, count); + +  if (bytes_read < 0) +    { +      if (errno == EINTR) +        goto again; +      else +        { +          /* put length back (note that this doesn't actually realloc anything) */ +          _dbus_string_set_length (buffer, start); +          return -1; +        } +    } +  else +    { +      /* put length back (doesn't actually realloc) */ +      _dbus_string_set_length (buffer, start + bytes_read); +      return bytes_read; +    } +} + +/** + * Thin wrapper around the write() system call that writes a part of a + * DBusString and handles EINTR for you. + *  + * @param fd the file descriptor to write + * @param buffer the buffer to write data from + * @param start the first byte in the buffer to write + * @param len the number of bytes to try to write + * @returns the number of bytes written or -1 on error + */ +int +_dbus_write (int               fd, +             const DBusString *buffer, +             int               start, +             int               len) +{ +  const char *data; +  int bytes_written; +   +  _dbus_string_get_const_data_len (buffer, &data, start, len); +   + again: + +  bytes_written = write (fd, data, len); + +  if (errno == EINTR) +    goto again; + +  return bytes_written; +} + +/** + * Like _dbus_write() but will use writev() if possible + * to write both buffers in sequence. The return value + * is the number of bytes written in the first buffer, + * plus the number written in the second. If the first + * buffer is written successfully and an error occurs + * writing the second, the number of bytes in the first + * is returned (i.e. the error is ignored), on systems that + * don't have writev. Handles EINTR for you. + * The second buffer may be #NULL. + * + * @param fd the file descriptor + * @param buffer1 first buffer + * @param start1 first byte to write in first buffer + * @param len1 number of bytes to write from first buffer + * @param buffer2 second buffer, or #NULL + * @param start2 first byte to write in second buffer + * @param len2 number of bytes to write in second buffer + * @returns total bytes written from both buffers, or -1 on error + */ +int +_dbus_write_two (int               fd, +                 const DBusString *buffer1, +                 int               start1, +                 int               len1, +                 const DBusString *buffer2, +                 int               start2, +                 int               len2) +{ +  _dbus_assert (buffer1 != NULL); +  _dbus_assert (start1 >= 0); +  _dbus_assert (start2 >= 0); +  _dbus_assert (len1 >= 0); +  _dbus_assert (len2 >= 0); +   +#ifdef HAVE_WRITEV +  { +    struct iovec vectors[2]; +    const char *data1; +    const char *data2; +    int bytes_written; + +    _dbus_string_get_const_data_len (buffer1, &data1, start1, len1); + +    if (buffer2 != NULL) +      _dbus_string_get_const_data_len (buffer2, &data2, start2, len2); +    else +      { +        data2 = NULL; +        start2 = 0; +        len2 = 0; +      } +    +    vectors[0].iov_base = (char*) data1; +    vectors[0].iov_len = len1; +    vectors[1].iov_base = (char*) data2; +    vectors[1].iov_len = len2; + +  again: +    +    bytes_written = writev (fd, +                            vectors, +                            data2 ? 2 : 1); + +    if (errno == EINTR) +      goto again; +    +    return bytes_written; +  } +#else /* HAVE_WRITEV */ +  { +    int ret1; +     +    ret1 = _dbus_write (fd, buffer1, start1, len1); +    if (ret1 == len1 && buffer2 != NULL) +      { +        ret2 = _dbus_write (fd, buffer2, start2, len2); +        if (ret2 < 0) +          ret2 = 0; /* we can't report an error as the first write was OK */ +        +        return ret1 + ret2; +      } +    else +      return ret1; +  } +#endif /* !HAVE_WRITEV */    +} + +/** + * Creates a socket and connects it to the UNIX domain socket at the + * given path.  The connection fd is returned, and is set up as + * nonblocking. + * + * @param path the path to UNIX domain socket + * @param result return location for error code + * @returns connection file descriptor or -1 on error + */ +int +_dbus_connect_unix_socket (const char     *path, +                           DBusResultCode *result) +{ +  int fd; +  struct sockaddr_un addr;   +   +  fd = socket (AF_LOCAL, SOCK_STREAM, 0); + +  if (fd < 0) +    { +      dbus_set_result (result, +                       _dbus_result_from_errno (errno)); +       +      _dbus_verbose ("Failed to create socket: %s\n", +                     _dbus_strerror (errno));  +       +      return -1; +    } + +  _DBUS_ZERO (addr); +  addr.sun_family = AF_LOCAL; +  strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH); +  addr.sun_path[_DBUS_MAX_SUN_PATH_LENGTH] = '\0'; +   +  if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0) +    {       +      dbus_set_result (result, +                       _dbus_result_from_errno (errno)); + +      _dbus_verbose ("Failed to connect to socket %s: %s\n", +                     path, _dbus_strerror (errno)); + +      close (fd); +      fd = -1; +       +      return -1; +    } + +  if (!_dbus_set_fd_nonblocking (fd, result)) +    { +      close (fd); +      fd = -1; + +      return -1; +    } + +  return fd; +} + +/** + * Creates a socket and binds it to the given path, + * then listens on the socket. The socket is + * set to be nonblocking.  + * + * @param path the socket name + * @param result return location for errors + * @returns the listening file descriptor or -1 on error + */ +int +_dbus_listen_unix_socket (const char     *path, +                          DBusResultCode *result) +{ +  int listen_fd; +  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)); +      _dbus_verbose ("Failed to create socket \"%s\": %s\n", +                     path, _dbus_strerror (errno)); +      return -1; +    } + +  _DBUS_ZERO (addr); +  addr.sun_family = AF_LOCAL; +  strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH); +  addr.sun_path[_DBUS_MAX_SUN_PATH_LENGTH] = '\0'; +   +  if (bind (listen_fd, (struct sockaddr*) &addr, SUN_LEN (&addr)) < 0) +    { +      dbus_set_result (result, _dbus_result_from_errno (errno)); +      _dbus_verbose ("Failed to bind socket \"%s\": %s\n", +                     path, _dbus_strerror (errno)); +      close (listen_fd); +      return -1; +    } + +  if (listen (listen_fd, 30 /* backlog */) < 0) +    { +      dbus_set_result (result, _dbus_result_from_errno (errno));       +      _dbus_verbose ("Failed to listen on socket \"%s\": %s\n", +                     path, _dbus_strerror (errno)); +      close (listen_fd); +      return -1; +    } + +  if (!_dbus_set_fd_nonblocking (listen_fd, result)) +    { +      close (listen_fd); +      return -1; +    } +   +  return listen_fd; +} + +/** + * Accepts a connection on a listening UNIX socket. + * Specific to UNIX domain sockets because we might + * add extra args to this function later to get client + * credentials. Handles EINTR for you. + * + * @param listen_fd the listen file descriptor + * @returns the connection fd of the client, or -1 on error + */ +int +_dbus_accept_unix_socket  (int listen_fd) +{ +  int client_fd; +   + retry: +  client_fd = accept (listen_fd, NULL, NULL); +   +  if (client_fd < 0) +    { +      if (errno == EINTR) +        goto retry; +    } + +  return client_fd; +} +  /** @} */  /** diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 92b782a8..17d96b3d 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -31,6 +31,9 @@   */  #include <string.h> +/* and it would just be annoying to abstract this */ +#include <errno.h> +  DBUS_BEGIN_DECLS;  /* The idea of this file is to encapsulate everywhere that we're @@ -46,6 +49,29 @@ void _dbus_abort (void);  const char* _dbus_getenv (const char *varname); + +int _dbus_read      (int               fd, +                     DBusString       *buffer, +                     int               count); +int _dbus_write     (int               fd, +                     const DBusString *buffer, +                     int               start, +                     int               len); +int _dbus_write_two (int               fd, +                     const DBusString *buffer1, +                     int               start1, +                     int               len1, +                     const DBusString *buffer2, +                     int               start2, +                     int               len2); + +int _dbus_connect_unix_socket (const char     *path, +                               DBusResultCode *result); +int _dbus_listen_unix_socket  (const char     *path, +                               DBusResultCode *result); +int _dbus_accept_unix_socket  (int             listen_fd); + +  DBUS_END_DECLS;  #endif /* DBUS_SYSDEPS_H */ diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c index 869aa33f..975bb71f 100644 --- a/dbus/dbus-transport-unix.c +++ b/dbus/dbus-transport-unix.c @@ -28,13 +28,7 @@  #include "dbus-watch.h"  #include <sys/types.h>  #include <unistd.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <errno.h> -#include <fcntl.h> -#ifdef HAVE_WRITEV -#include <sys/uio.h> -#endif +  /**   * @defgroup DBusTransportUnix DBusTransport implementations for UNIX @@ -99,15 +93,13 @@ do_writing (DBusTransport *transport)    DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;    total = 0; -   - again:    while (_dbus_connection_have_messages_to_send (transport->connection))      {        int bytes_written;        DBusMessage *message; -      const unsigned char *header; -      const unsigned char *body; +      const DBusString *header; +      const DBusString *body;        int header_len, body_len;        if (total > unix_transport->max_bytes_written_per_iteration) @@ -122,42 +114,37 @@ do_writing (DBusTransport *transport)        _dbus_message_lock (message);        _dbus_message_get_network_data (message, -                                      &header, &header_len, -                                      &body, &body_len); +                                      &header, &body); +      header_len = _dbus_string_get_length (header); +      body_len = _dbus_string_get_length (body); +              if (unix_transport->message_bytes_written < header_len)          { -#ifdef HAVE_WRITEV -          struct iovec vectors[2]; - -          vectors[0].iov_base = header + unix_transport->message_bytes_written; -          vectors[0].iov_len = header_len - unix_transport->message_bytes_written; -          vectors[1].iov_base = body; -          vectors[1].iov_len = body_len; -           -          bytes_written = writev (unix_transport->fd, -                                  vectors, _DBUS_N_ELEMENTS (vectors)); -#else -          bytes_written = write (unix_transport->fd, -                                 header + unix_transport->message_bytes_written,  -                                 header_len - unix_transport->message_bytes_written); -#endif +          bytes_written = +            _dbus_write_two (unix_transport->fd, +                             header, +                             unix_transport->message_bytes_written, +                             header_len - unix_transport->message_bytes_written, +                             body, +                             0, body_len);          }        else          { -          bytes_written = write (unix_transport->fd, -                                 body + -                                 (unix_transport->message_bytes_written - header_len),  -                                 body_len - -                                 (unix_transport->message_bytes_written - body_len)); +          bytes_written = +            _dbus_write (unix_transport->fd, +                         body, +                         (unix_transport->message_bytes_written - header_len), +                         body_len - +                         (unix_transport->message_bytes_written - header_len));          }        if (bytes_written < 0)          { -          if (errno == EINTR) -            goto again; -          else if (errno == EAGAIN || -                   errno == EWOULDBLOCK) +          /* EINTR already handled for us */ +           +          if (errno == EAGAIN || +              errno == EWOULDBLOCK)              goto out;            else              { @@ -194,15 +181,15 @@ static void  do_reading (DBusTransport *transport)  {    DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; -  unsigned char *buffer; +  DBusString *buffer;    int buffer_len;    int bytes_read;    int total;    total = 0; -   - again: + again: +      if (total > unix_transport->max_bytes_read_per_iteration)      {        _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n", @@ -210,23 +197,24 @@ do_reading (DBusTransport *transport)        goto out;      } -  if (!_dbus_message_loader_get_buffer (transport->loader, -                                        &buffer, &buffer_len)) -    goto out; /* no memory for a buffer */ +  _dbus_message_loader_get_buffer (transport->loader, +                                   &buffer); + +  buffer_len = _dbus_string_get_length (buffer);   -  bytes_read = read (unix_transport->fd, -                     buffer, buffer_len); +  bytes_read = _dbus_read (unix_transport->fd, +                           buffer, unix_transport->max_bytes_read_per_iteration);    _dbus_message_loader_return_buffer (transport->loader,                                        buffer,                                        bytes_read < 0 ? 0 : bytes_read);    if (bytes_read < 0) -    {       -      if (errno == EINTR) -        goto again; -      else if (errno == EAGAIN || -               errno == EWOULDBLOCK) +    { +      /* EINTR already handled for us */ +       +      if (errno == EAGAIN || +          errno == EWOULDBLOCK)          goto out;        else          { @@ -519,49 +507,10 @@ _dbus_transport_new_for_domain_socket (const char     *path,  {    int fd;    DBusTransport *transport; -  struct sockaddr_un addr; -   -  transport = NULL; -   -  fd = socket (AF_LOCAL, SOCK_STREAM, 0); +  fd = _dbus_connect_unix_socket (path, result);    if (fd < 0) -    { -      dbus_set_result (result, -                       _dbus_result_from_errno (errno)); -       -      _dbus_verbose ("Failed to create socket: %s\n", -                     _dbus_strerror (errno));  -       -      goto out; -    } - -  _DBUS_ZERO (addr); -  addr.sun_family = AF_LOCAL; -  strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH); -  addr.sun_path[_DBUS_MAX_SUN_PATH_LENGTH] = '\0'; -   -  if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0) -    {       -      dbus_set_result (result, -                       _dbus_result_from_errno (errno)); - -      _dbus_verbose ("Failed to connect to socket %s: %s\n", -                     path, _dbus_strerror (errno)); - -      close (fd); -      fd = -1; -       -      goto out; -    } - -  if (!_dbus_set_fd_nonblocking (fd, result)) -    { -      close (fd); -      fd = -1; - -      goto out; -    } +    return NULL;    transport = _dbus_transport_new_for_fd (fd);    if (transport == NULL) @@ -569,10 +518,8 @@ _dbus_transport_new_for_domain_socket (const char     *path,        dbus_set_result (result, DBUS_RESULT_NO_MEMORY);        close (fd);        fd = -1; -      goto out;      } -   - out:   +    return transport;  } diff --git a/test/watch.c b/test/watch.c index df26855c..161ae3a9 100644 --- a/test/watch.c +++ b/test/watch.c @@ -5,6 +5,9 @@  #include <dbus/dbus-list.h>  #undef DBUS_COMPILATION +#include <sys/types.h> +#include <unistd.h> +  /* Cheesy main loop used in test programs.  Any real app would use the   * GLib or Qt or other non-sucky main loops.   */  | 
