async: add async_write(), a write primitive to write to a NONBLOCK:ing FD

This commit is contained in:
Daniel Eklöf 2019-11-04 13:45:38 +01:00
parent 60c3ff8737
commit 9ae5c311d1
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 60 additions and 0 deletions

35
async.c Normal file
View file

@ -0,0 +1,35 @@
#include "async.h"
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#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;
}

24
async.h Normal file
View file

@ -0,0 +1,24 @@
#pragma once
#include <stddef.h>
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);

View file

@ -64,6 +64,7 @@ version = custom_target(
executable( executable(
'foot', 'foot',
'async.c', 'async.h',
'base64.c', 'base64.h', 'base64.c', 'base64.h',
'config.c', 'config.h', 'config.c', 'config.h',
'commands.c', 'commands.h', 'commands.c', 'commands.h',