2002-12-12 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Fri, 13 Dec 2002 03:55:38 +0000 (03:55 +0000)
committerHavoc Pennington <hp@redhat.com>
Fri, 13 Dec 2002 03:55:38 +0000 (03:55 +0000)
* 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

ChangeLog
dbus/dbus-message-internal.h
dbus/dbus-message.c
dbus/dbus-server-unix.c
dbus/dbus-string.c
dbus/dbus-string.h
dbus/dbus-sysdeps.c
dbus/dbus-sysdeps.h
dbus/dbus-transport-unix.c
test/watch.c

index f9e6132..7887e8d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 5b1aea6..dc36a24 100644 (file)
@@ -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);
index 1e95bec..d86f831 100644 (file)
  */
 
 /**
+ * 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);
     }
 }
index 277e00a..c58923b 100644 (file)
 #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)
index 088ca35..573ed31 100644 (file)
@@ -21,6 +21,7 @@
  *
  */
 
+#include "dbus-internals.h"
 #include "dbus-string.h"
 /* we allow a system header here, for speed/convenience */
 #include <string.h>
index 4eda595..b2f9957 100644 (file)
@@ -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>
 
index 4bc3db9..76b9c5c 100644 (file)
  *
  */
 
+#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;
+}
+
 /** @} */
 
 /**
index 92b782a..17d96b3 100644 (file)
@@ -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 */
index 869aa33..975bb71 100644 (file)
 #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;
 }
 
index df26855..161ae3a 100644 (file)
@@ -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.
  */