summaryrefslogtreecommitdiff
path: root/common.c
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2016-01-06 23:37:30 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2016-01-07 22:49:53 +0100
commit376bbea249f17eda9c682ff7153f102990548888 (patch)
tree729daa8fa0d375cbc487a7f866bb4582ab975b50 /common.c
parenta5ac0d24b8fdf4fe06f56987b4b5992a2bda24bf (diff)
downloadxK-376bbea249f17eda9c682ff7153f102990548888.tar.gz
xK-376bbea249f17eda9c682ff7153f102990548888.tar.xz
xK-376bbea249f17eda9c682ff7153f102990548888.zip
Factor out socket_io_try_{read,write}()
To be reused in Lua connection API.
Diffstat (limited to 'common.c')
-rw-r--r--common.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/common.c b/common.c
index 8974f57..a92bae4 100644
--- a/common.c
+++ b/common.c
@@ -95,6 +95,74 @@ xwrite (int fd, const char *data, size_t len, struct error **e)
return true;
}
+// --- Simple network I/O ------------------------------------------------------
+
+// TODO: move to liberty and remove from dwmstatus.c as well
+
+#define SOCKET_IO_OVERFLOW (8 << 20) ///< How large a read buffer can be
+
+enum socket_io_result
+{
+ SOCKET_IO_OK, ///< Completed successfully
+ SOCKET_IO_EOF, ///< Connection shut down by peer
+ SOCKET_IO_ERROR ///< Connection error
+};
+
+static enum socket_io_result
+socket_io_try_read (int socket_fd, struct str *rb, struct error **e)
+{
+ // We allow buffering of a fair amount of data, however within reason,
+ // so that it's not so easy to flood us and cause an allocation failure
+ ssize_t n_read;
+ while (rb->len < SOCKET_IO_OVERFLOW)
+ {
+ str_ensure_space (rb, 4096);
+ n_read = recv (socket_fd, rb->str + rb->len,
+ rb->alloc - rb->len - 1 /* null byte */, 0);
+
+ if (n_read > 0)
+ {
+ rb->str[rb->len += n_read] = '\0';
+ continue;
+ }
+ if (n_read == 0)
+ return SOCKET_IO_EOF;
+
+ if (errno == EAGAIN)
+ return SOCKET_IO_OK;
+ if (errno == EINTR)
+ continue;
+
+ error_set (e, "%s", strerror (errno));
+ return SOCKET_IO_ERROR;
+ }
+ return SOCKET_IO_OK;
+}
+
+static enum socket_io_result
+socket_io_try_write (int socket_fd, struct str *wb, struct error **e)
+{
+ ssize_t n_written;
+ while (wb->len)
+ {
+ n_written = send (socket_fd, wb->str, wb->len, 0);
+ if (n_written >= 0)
+ {
+ str_remove_slice (wb, 0, n_written);
+ continue;
+ }
+
+ if (errno == EAGAIN)
+ return SOCKET_IO_OK;
+ if (errno == EINTR)
+ continue;
+
+ error_set (e, "%s", strerror (errno));
+ return SOCKET_IO_ERROR;
+ }
+ return SOCKET_IO_OK;
+}
+
// --- Logging -----------------------------------------------------------------
static void