From 271fa7fc335f332bb2be3beeef735334546c4957 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Fri, 13 Dec 2002 03:55:38 +0000 Subject: 2002-12-12 Havoc Pennington * 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 | 14 ++ dbus/dbus-message-internal.h | 13 +- dbus/dbus-message.c | 140 ++++++++---------- dbus/dbus-server-unix.c | 53 +------ dbus/dbus-string.c | 1 + dbus/dbus-string.h | 3 +- dbus/dbus-sysdeps.c | 328 +++++++++++++++++++++++++++++++++++++++++++ dbus/dbus-sysdeps.h | 26 ++++ dbus/dbus-transport-unix.c | 135 ++++++------------ test/watch.c | 3 + 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 + + * 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 * 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 @@ -38,6 +38,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 * @@ -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 #include -#include -#include -#include -#include /** * @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 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 +#include + #include #include 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 #include #include #include #include +#include +#include +#include +#include +#include +#ifdef HAVE_WRITEV +#include +#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 +/* and it would just be annoying to abstract this */ +#include + 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 #include -#include -#include -#include -#include -#ifdef HAVE_WRITEV -#include -#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 #undef DBUS_COMPILATION +#include +#include + /* Cheesy main loop used in test programs. Any real app would use the * GLib or Qt or other non-sucky main loops. */ -- cgit