summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2002-12-13 03:55:38 +0000
committerHavoc Pennington <hp@redhat.com>2002-12-13 03:55:38 +0000
commit271fa7fc335f332bb2be3beeef735334546c4957 (patch)
tree6c20f827eaa2575b6d94f0eaee5ce975c7061da8
parentd4b870e7f91b7018524f7b85dc00b90cc64453bf (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--ChangeLog14
-rw-r--r--dbus/dbus-message-internal.h13
-rw-r--r--dbus/dbus-message.c140
-rw-r--r--dbus/dbus-server-unix.c53
-rw-r--r--dbus/dbus-string.c1
-rw-r--r--dbus/dbus-string.h3
-rw-r--r--dbus/dbus-sysdeps.c328
-rw-r--r--dbus/dbus-sysdeps.h26
-rw-r--r--dbus/dbus-transport-unix.c135
-rw-r--r--test/watch.c3
10 files changed, 485 insertions, 231 deletions
diff --git a/ChangeLog b/ChangeLog
index f9e61326..7887e8dd 100644
--- 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
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.
*/