lander/lnm/src/loop/lnm_loop_io.c

78 lines
1.8 KiB
C

#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "lnm/loop.h"
#include "lnm/loop_internal.h"
void lnm_loop_conn_io_req(lnm_loop *l, lnm_loop_conn *conn) {
do {
// Move remaining data to front of buffer
memmove(conn->r.buf, &conn->r.buf[conn->r.read],
conn->r.size - conn->r.read);
conn->r.size -= conn->r.read;
conn->r.read = 0;
ssize_t res;
size_t cap = LNM_LOOP_BUF_SIZE - conn->r.size;
do {
res = read(conn->fd, &conn->r.buf[conn->r.size], cap);
} while (res < 0 && errno == EINTR);
// Read can't be performed without blocking; we come back later
if (res < 0 && errno == EAGAIN) {
return;
}
if (res <= 0) {
conn->state = lnm_loop_state_end;
return;
}
conn->r.size += res;
l->data_read(conn);
} while (conn->state == lnm_loop_state_req);
}
void lnm_loop_conn_io_res(lnm_loop *l, lnm_loop_conn *conn) {
do {
l->data_write(conn);
ssize_t res;
do {
res = write(conn->fd, conn->w.buf, conn->w.size);
} while (res < 0 && errno == EINTR);
// Write can't be performed without blocking; we come back later
if (res < 0 && errno == EAGAIN) {
return;
}
if (res < 0) {
conn->state = lnm_loop_state_end;
return;
}
// Move remaining data to front of buffer. Doing this here gives the data
// writer function more space to work with
memmove(conn->w.buf, &conn->w.buf[res], conn->w.size - res);
conn->w.size -= res;
} while (conn->state == lnm_loop_state_res);
}
void lnm_loop_conn_io(lnm_loop *l, lnm_loop_conn *conn) {
switch (conn->state) {
case lnm_loop_state_req:
lnm_loop_conn_io_req(l, conn);
break;
case lnm_loop_state_res:
lnm_loop_conn_io_res(l, conn);
break;
default:;
}
}