From 9ae5c311d1b0cb85e7cbcb86fef91827e9967868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 4 Nov 2019 13:45:38 +0100 Subject: [PATCH] async: add async_write(), a write primitive to write to a NONBLOCK:ing FD --- async.c | 35 +++++++++++++++++++++++++++++++++++ async.h | 24 ++++++++++++++++++++++++ meson.build | 1 + 3 files changed, 60 insertions(+) create mode 100644 async.c create mode 100644 async.h diff --git a/async.c b/async.c new file mode 100644 index 00000000..3ad2a8c6 --- /dev/null +++ b/async.c @@ -0,0 +1,35 @@ +#include "async.h" + +#include +#include +#include + +#define LOG_MODULE "async" +#define LOG_ENABLE_DBG 0 +#include "log.h" + +enum async_write_status +async_write(int fd, const void *_data, size_t len, size_t *idx) +{ + const uint8_t *const data = _data; + size_t left = len - *idx; + + while (left > 0) { + ssize_t ret = write(fd, &data[*idx], left); + + if (ret < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + return ASYNC_WRITE_REMAIN; + + return ASYNC_WRITE_ERR; + } + + LOG_DBG("wrote %zd bytes of %zu (%zu left) to FD=%d", + ret, left, left - ret, fd); + + *idx += ret; + left -= ret; + } + + return ASYNC_WRITE_DONE; +} diff --git a/async.h b/async.h new file mode 100644 index 00000000..876368de --- /dev/null +++ b/async.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +enum async_write_status {ASYNC_WRITE_DONE, ASYNC_WRITE_REMAIN, ASYNC_WRITE_ERR}; + +/* + * Primitive that writes data to a NONBLOCK:ing FD. + * + * _data: points to the beginning of the buffer + * len: total size of the data buffer + * idx: pointer to byte offset into data buffer - writing starts here. + * + * Thus, the total amount of data to write is (len - *idx). *idx is + * updated such that it points to the next unwritten byte in the data + * buffer. + * + * I.e. if the return value is: + * - ASYNC_WRITE_DONE, then the *idx == len. + * - ASYNC_WRITE_REMAIN, then *idx < len + * - ASYNC_WRITE_ERR, there was an error, and no data was written + */ +enum async_write_status async_write( + int fd, const void *data, size_t len, size_t *idx); diff --git a/meson.build b/meson.build index 8fed58bb..7e8758df 100644 --- a/meson.build +++ b/meson.build @@ -64,6 +64,7 @@ version = custom_target( executable( 'foot', + 'async.c', 'async.h', 'base64.c', 'base64.h', 'config.c', 'config.h', 'commands.c', 'commands.h',