diff options
author | Nikias Bassen | 2014-11-12 19:53:06 +0100 |
---|---|---|
committer | Nikias Bassen | 2014-11-12 19:53:06 +0100 |
commit | a3cae2b7a3dfe8120f2a65a1fae8640bb4f095a5 (patch) | |
tree | 855adf6fdeb4dd526ddd549ecb5a5a3bcce5241d /src | |
parent | a5e57e872bb5be8b13d3497f2c07fff8a8e37f3f (diff) | |
download | usbmuxd-a3cae2b7a3dfe8120f2a65a1fae8640bb4f095a5.tar.gz usbmuxd-a3cae2b7a3dfe8120f2a65a1fae8640bb4f095a5.tar.bz2 |
Use non-blocking sockets for client communication
This approach is better than using blocking sockets and select() since
there's no guarantee that send() doesn't block. Plus we're using poll()
anyway so send() and recv() will only be called if the socket is actually
ready for writing/reading.
Diffstat (limited to 'src')
-rw-r--r-- | src/client.c | 23 | ||||
-rw-r--r-- | src/main.c | 9 |
2 files changed, 31 insertions, 1 deletions
diff --git a/src/client.c b/src/client.c index 268c8b9..4ec4025 100644 --- a/src/client.c +++ b/src/client.c @@ -33,6 +33,7 @@ #include <sys/un.h> #include <arpa/inet.h> #include <pthread.h> +#include <fcntl.h> #include <plist/plist.h> @@ -100,12 +101,23 @@ int client_read(struct mux_client *client, void *buffer, uint32_t len) */ int client_write(struct mux_client *client, void *buffer, uint32_t len) { + int sret = -1; + usbmuxd_log(LL_SPEW, "client_write fd %d buf %p len %d", client->fd, buffer, len); if(client->state != CLIENT_CONNECTED) { usbmuxd_log(LL_ERROR, "Attempted to write to client %d not in CONNECTED state", client->fd); return -1; } - return send(client->fd, buffer, len, 0); + + sret = send(client->fd, buffer, len, 0); + if (sret < 0) { + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + usbmuxd_log(LL_ERROR, "ERROR: client_write: fd %d not ready for writing", client->fd); + } else { + usbmuxd_log(LL_ERROR, "ERROR: client_write: sending to fd %d failed: %s", client->fd, strerror(errno)); + } + } + return sret; } /** @@ -150,6 +162,15 @@ int client_accept(int listenfd) return cfd; } + int flags = fcntl(cfd, F_GETFL, 0); + if (flags < 0) { + usbmuxd_log(LL_ERROR, "ERROR: Could not get socket flags!"); + } else { + if (fcntl(cfd, F_SETFL, flags | O_NONBLOCK) < 0) { + usbmuxd_log(LL_ERROR, "ERROR: Could not set socket to non-blocking mode"); + } + } + struct mux_client *client; client = malloc(sizeof(struct mux_client)); memset(client, 0, sizeof(struct mux_client)); @@ -82,6 +82,15 @@ static int create_socket(void) { return -1; } + int flags = fcntl(listenfd, F_GETFL, 0); + if (flags < 0) { + usbmuxd_log(LL_FATAL, "ERROR: Could not get flags for socket"); + } else { + if (fcntl(listenfd, F_SETFL, flags | O_NONBLOCK) < 0) { + usbmuxd_log(LL_FATAL, "ERROR: Could not set socket to non-blocking"); + } + } + bzero(&bind_addr, sizeof(bind_addr)); bind_addr.sun_family = AF_UNIX; strcpy(bind_addr.sun_path, socket_path); |