summaryrefslogtreecommitdiff
path: root/lib9p/srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/srv.c')
-rw-r--r--lib9p/srv.c66
1 files changed, 40 insertions, 26 deletions
diff --git a/lib9p/srv.c b/lib9p/srv.c
index 32e9a9a..7785e4d 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -366,23 +366,23 @@ static void srv_msglog(struct srv_req *req, enum lib9p_msg_type typ, void *hostm
log_infoln(typ % 2 ? "< " : "> ", (lib9p_msg, &req->basectx, typ, hostmsg));
}
-static ssize_t srv_write_Rmsg(struct srv_req *req, struct lib9p_Rmsg_send_buf *resp) {
- ssize_t r;
+#define srv_nonrespond_error log_errorln
+
+static void srv_write_Rmsg(struct srv_req *req, struct lib9p_Rmsg_send_buf *resp) {
+ size_t_and_error r;
cr_mutex_lock(&req->parent_sess->parent_conn->writelock);
r = io_writev(req->parent_sess->parent_conn->fd, resp->iov, resp->iov_cnt);
cr_mutex_unlock(&req->parent_sess->parent_conn->writelock);
- return r;
+ if (!ERROR_IS_NULL(r.err))
+ srv_nonrespond_error("write: (", r.size_t, ", ", (error, r.err), ")");
}
-#define srv_nonrespond_error log_errorln
-
static void srv_respond_error(struct srv_req *req) {
#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
assert(req->basectx.err_num);
#endif
assert(req->basectx.err_msg[0]);
- ssize_t r;
struct lib9p_msg_Rerror host = {
.tag = req->tag,
.errstr = lib9p_strn(req->basectx.err_msg,
@@ -408,28 +408,29 @@ static void srv_respond_error(struct srv_req *req) {
&net);
srv_msglog(req, LIB9P_TYP_Rerror, &host);
- r = srv_write_Rmsg(req, &net);
- if (r < 0)
- srv_nonrespond_error("write: ", net_strerror(-r));
+ srv_write_Rmsg(req, &net);
}
/* read coroutine *************************************************************/
+/** Return whether to `break`. */
static inline bool srv_read_exactly(lo_interface net_stream_conn fd, uint8_t *buf, size_t goal, size_t *done) {
assert(buf);
assert(goal);
assert(done);
while (*done < goal) {
- ssize_t r = io_read(fd, &buf[*done], goal - *done);
- if (r < 0) {
- srv_nonrespond_error("read: ", net_strerror(-r));
- return true;
- } else if (r == 0) {
- if (*done != 0)
- srv_nonrespond_error("read: unexpected EOF");
+ size_t_or_error r = io_read(fd, &buf[*done], goal - *done);
+ if (r.is_err) {
+ if (r.err.num == E_EOF) {
+ if (*done != 0)
+ srv_nonrespond_error("read: unexpected EOF");
+ } else {
+ srv_nonrespond_error("read: ", (error, r.err));
+ }
+ error_cleanup(&r.err);
return true;
}
- *done += r;
+ *done += r.size_t;
}
return false;
}
@@ -442,16 +443,17 @@ void lib9p_srv_accept_and_read_loop(struct lib9p_srv *srv, lo_interface net_stre
srv->readers++;
for (;;) {
- lo_interface net_stream_conn conn = LO_CALL(listener, accept);
- if (LO_IS_NULL(conn)) {
- srv_nonrespond_error("accept: error");
+ net_stream_conn_or_error r = LO_CALL(listener, accept);
+ if (r.is_err) {
+ srv_nonrespond_error("accept: ", (error, r.err));
+ error_cleanup(&r.err);
srv->readers--;
if (srv->readers == 0)
while (srv->writers > 0)
cr_rpc_send_req(&srv->_reqch, NULL);
return;
}
- lib9p_srv_read(srv, conn);
+ lib9p_srv_read(srv, r.net_stream_conn);
}
}
@@ -517,14 +519,26 @@ void lib9p_srv_read(struct lib9p_srv *srv, lo_interface net_stream_conn _conn) {
/* ...but usually in another coroutine. */
cr_rpc_send_req(&srv->_reqch, &req);
}
- if (map_len(&sess.reqs) == 0)
- io_close(conn.fd);
- else {
- io_close_read(conn.fd);
+ if (map_len(&sess.reqs) == 0) {
+ error err = io_close(conn.fd);
+ if (!ERROR_IS_NULL(err)) {
+ srv_nonrespond_error("conn close: ", (error, err));
+ error_cleanup(&err);
+ }
+ } else {
+ error err = io_close_read(conn.fd);
+ if (!ERROR_IS_NULL(err)) {
+ srv_nonrespond_error("conn close: ", (error, err));
+ error_cleanup(&err);
+ }
sess.closing = true;
cr_pause_and_yield();
assert(map_len(&sess.reqs) == 0);
- io_close_write(conn.fd);
+ err = io_close_write(conn.fd);
+ if (!ERROR_IS_NULL(err)) {
+ srv_nonrespond_error("conn close: ", (error, err));
+ error_cleanup(&err);
+ }
}
assert(map_len(&sess.reqs) == 0);