summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib9p/srv.c316
-rw-r--r--lib9p/srv_include/lib9p/srv.h1
2 files changed, 175 insertions, 142 deletions
diff --git a/lib9p/srv.c b/lib9p/srv.c
index 9adaefa..edb39ba 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -597,8 +597,7 @@ void lib9p_srv_worker_loop(struct lib9p_srv *srv) {
#define _HANDLER_PROTO(typ) \
static void handle_T##typ(struct srv_req *, \
- struct lib9p_msg_T##typ *, \
- struct lib9p_msg_R##typ *)
+ struct lib9p_msg_T##typ *)
_HANDLER_PROTO(version);
_HANDLER_PROTO(auth);
_HANDLER_PROTO(attach);
@@ -621,16 +620,17 @@ _HANDLER_PROTO(sread);
_HANDLER_PROTO(swrite);
#endif
-typedef void (*tmessage_handler)(struct srv_req *, void *, void *);
+typedef void (*tmessage_handler)(struct srv_req *, void *);
void lib9p_srv_worker(struct srv_req *ctx) {
uint8_t *host_req = NULL;
- uint8_t host_resp[CONFIG_9P_SRV_MAX_HOSTMSG_SIZE];
/* Unmarshal it. *****************************************************/
ssize_t host_size = lib9p_Tmsg_validate(&ctx->basectx, ctx->net_bytes);
- if (host_size < 0)
- goto write;
+ if (host_size < 0) {
+ srv_respond_error(ctx);
+ goto release;
+ }
host_req = calloc(1, host_size);
assert(host_req);
enum lib9p_msg_type typ;
@@ -668,24 +668,11 @@ void lib9p_srv_worker(struct srv_req *ctx) {
assert_notreached("lib9p_Tmsg_validate() should have rejected unknown typ");
}
#pragma GCC diagnostic pop
- handler(ctx, (void *)host_req, (void *)host_resp);
+ handler(ctx, (void *)host_req);
+ assert(ctx->responded);
- /* Write the response. ***********************************************/
- write:
- if (lib9p_ctx_has_error(&ctx->basectx)) {
- srv_respond_error(ctx);
- } else if (ctx->flush_acknowledged) {
- /* do nothing */
- } else {
- struct lib9p_Rmsg_send_buf net_resp;
- if (lib9p_Rmsg_marshal(&ctx->basectx,
- typ+1, host_resp,
- &net_resp))
- goto write;
- srv_msglog(ctx, typ+1, &host_resp);
- srv_write_Rmsg(ctx, &net_resp);
- }
/* Release resources. ************************************************/
+ release:
map_del(&ctx->parent_sess->reqs, ctx->tag);
size_t nwaiters;
while ((nwaiters = cr_chan_num_waiters(&ctx->flush_ch))) {
@@ -700,19 +687,41 @@ void lib9p_srv_worker(struct srv_req *ctx) {
free(ctx->net_bytes);
}
+static inline void _srv_respond(struct srv_req *ctx, enum lib9p_msg_type resp_typ, void *host_resp) {
+ assert(!ctx->responded);
+ if (lib9p_ctx_has_error(&ctx->basectx)) {
+ error:
+ srv_respond_error(ctx);
+ } else if (ctx->flush_acknowledged) {
+ /* do nothing */
+ } else {
+ assert(host_resp);
+ struct lib9p_Rmsg_send_buf net_resp;
+ if (lib9p_Rmsg_marshal(&ctx->basectx,
+ resp_typ, host_resp,
+ &net_resp))
+ goto error;
+ srv_msglog(ctx, resp_typ, host_resp);
+ srv_write_Rmsg(ctx, &net_resp);
+ }
+ ctx->responded = true;
+}
+#define srv_respond(CTX, TYP, HOST_RESP) do { \
+ struct lib9p_msg_R##TYP *_host_resp = HOST_RESP; \
+ _srv_respond(CTX, LIB9P_TYP_R##TYP, _host_resp); \
+} while (0)
+
/* handle_T* ******************************************************************/
-#define srv_handler_common(ctx, req, resp) do { \
- assert(ctx); \
- assert(req); \
- assert(resp); \
- resp->tag = req->tag; \
- } while (0)
+#define srv_handler_common(ctx, typ, req) \
+ assert(ctx); \
+ assert(req); \
+ struct lib9p_msg_T##typ *_typecheck_req [[gnu::unused]] = req; \
+ struct lib9p_msg_R##typ resp = { .tag = ctx->tag }
static void handle_Tversion(struct srv_req *ctx,
- struct lib9p_msg_Tversion *req,
- struct lib9p_msg_Rversion *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tversion *req) {
+ srv_handler_common(ctx, version, req);
enum lib9p_version version = LIB9P_VER_unknown;
@@ -745,15 +754,15 @@ static void handle_Tversion(struct srv_req *ctx,
lib9p_errorf(&ctx->basectx,
LIB9P_ERRNO_L_EDOM, "requested max_msg_size is less than minimum for %s (%"PRIu32" < %"PRIu32")",
lib9p_version_str(version), req->max_msg_size, min_msg_size);
- return;
+ goto tversion_return;
}
- resp->version = lib9p_str((char *)lib9p_version_str(version)); /* cast to discard "const" qualifier */
+ resp.version = lib9p_str((char *)lib9p_version_str(version)); /* cast to discard "const" qualifier */
#if CONFIG_9P_ENABLE_9P2000_p9p
if (version == LIB9P_VER_9P2000_p9p)
- resp->version = lib9p_str("9P2000");
+ resp.version = lib9p_str("9P2000");
#endif
- resp->max_msg_size = (CONFIG_9P_SRV_MAX_MSG_SIZE < req->max_msg_size)
+ resp.max_msg_size = (CONFIG_9P_SRV_MAX_MSG_SIZE < req->max_msg_size)
? CONFIG_9P_SRV_MAX_MSG_SIZE
: req->max_msg_size;
@@ -775,27 +784,27 @@ static void handle_Tversion(struct srv_req *ctx,
if (map_len(&ctx->parent_sess->fids)) {
/* Close all FIDs. */
MAP_FOREACH(&ctx->parent_sess->fids, fid, fidinfo) {
- handle_Tclunk(ctx,
- &(struct lib9p_msg_Tclunk){.fid = fid},
- &(struct lib9p_msg_Rclunk){});
+ srv_fid_del(ctx, fid, false);
}
}
/* Replace the old session with the new session. */
ctx->parent_sess->version = version;
- ctx->parent_sess->max_msg_size = resp->max_msg_size;
+ ctx->parent_sess->max_msg_size = resp.max_msg_size;
+
+ tversion_return:
+ srv_respond(ctx, version, &resp);
}
static void handle_Tauth(struct srv_req *ctx,
- struct lib9p_msg_Tauth *req,
- struct lib9p_msg_Rauth *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tauth *req) {
+ srv_handler_common(ctx, auth, req);
struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv;
if (!srv->auth) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EOPNOTSUPP, "authentication not required");
- return;
+ goto tauth_return;
}
ctx->user = srv_userid_new(req->uname, req->n_uid);
@@ -807,17 +816,19 @@ static void handle_Tauth(struct srv_req *ctx,
if (lib9p_ctx_has_error(&ctx->basectx))
ctx->user = srv_userid_decref(ctx->user);
+
+ tauth_return:
+ srv_respond(ctx, auth, &resp);
}
static void handle_Tattach(struct srv_req *ctx,
- struct lib9p_msg_Tattach *req,
- struct lib9p_msg_Rattach *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tattach *req) {
+ srv_handler_common(ctx, attach, req);
if (req->fid == LIB9P_FID_NOFID) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EBADF, "cannot assign to NOFID");
- return;
+ goto tattach_return;
}
struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv;
@@ -849,13 +860,13 @@ static void handle_Tattach(struct srv_req *ctx,
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EACCES, "FID provided as auth-file has not completed authentication");
if (lib9p_ctx_has_error(&ctx->basectx))
- return;
+ goto tattach_return;
ctx->user = srv_userid_incref(afid->user);
} else {
if (req->afid != LIB9P_FID_NOFID) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EACCES, "FID provided as auth-file, but no auth-file is required");
- return;
+ goto tattach_return;
}
ctx->user = srv_userid_new(req->uname, req->n_uid);
}
@@ -863,10 +874,8 @@ static void handle_Tattach(struct srv_req *ctx,
/* 1. File object */
lo_interface lib9p_srv_file root_file = srv->rootdir(ctx, req->aname);
assert(LO_IS_NULL(root_file) == lib9p_ctx_has_error(&ctx->basectx));
- if (lib9p_ctx_has_error(&ctx->basectx)) {
- ctx->user = srv_userid_decref(ctx->user);
- return;
- }
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ goto tattach_return;
struct lib9p_qid root_qid = LO_CALL(root_file, qid);
assert(srv_qid_filetype(root_qid) == SRV_FILETYPE_DIR);
@@ -877,19 +886,19 @@ static void handle_Tattach(struct srv_req *ctx,
/* 3. fidinfo */
if (!srv_fid_store(ctx, req->fid, root_pathinfo, false)) {
srv_path_decref(ctx, root_qid.path);
- ctx->user = srv_userid_decref(ctx->user);
- return;
+ goto tattach_return;
}
- ctx->user = srv_userid_decref(ctx->user);
- resp->qid = root_qid;
- return;
+ resp.qid = root_qid;
+ tattach_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, attach, &resp);
}
static void handle_Tflush(struct srv_req *ctx,
- struct lib9p_msg_Tflush *req,
- struct lib9p_msg_Rflush *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tflush *req) {
+ srv_handler_common(ctx, flush, req);
struct srv_req **oldreqp = map_load(&ctx->parent_sess->reqs, req->oldtag);
if (oldreqp) {
@@ -907,29 +916,29 @@ static void handle_Tflush(struct srv_req *ctx,
break;
}
}
+ srv_respond(ctx, flush, &resp);
}
static void handle_Twalk(struct srv_req *ctx,
- struct lib9p_msg_Twalk *req,
- struct lib9p_msg_Rwalk *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Twalk *req) {
+ srv_handler_common(ctx, walk, req);
if (req->newfid == LIB9P_FID_NOFID) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EBADF, "cannot assign to NOFID");
- return;
+ goto twalk_return;
}
struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
lib9p_errorf(&ctx->basectx,
LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ goto twalk_return;
}
if (fidinfo->flags & FIDFLAG_OPEN) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EALREADY, "cannot walk on FID open for I/O");
- return;
+ goto twalk_return;
}
ctx->user = srv_userid_incref(fidinfo->user);
@@ -937,8 +946,9 @@ static void handle_Twalk(struct srv_req *ctx,
assert(pathinfo);
pathinfo->gc_refcount++;
- resp->wqid = (struct lib9p_qid *)(&resp[1]);
- for (resp->nwqid = 0; resp->nwqid < req->nwname; resp->nwqid++) {
+ struct lib9p_qid _resp_qid[16];
+ resp.wqid = _resp_qid;
+ for (resp.nwqid = 0; resp.nwqid < req->nwname; resp.nwqid++) {
if (pathinfo->type != SRV_FILETYPE_DIR) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_ENOTDIR, "not a directory");
@@ -946,12 +956,12 @@ static void handle_Twalk(struct srv_req *ctx,
}
struct srv_pathinfo *new_pathinfo;
- if (lib9p_str_eq(req->wname[resp->nwqid], lib9p_str(".."))) {
+ if (lib9p_str_eq(req->wname[resp.nwqid], lib9p_str(".."))) {
new_pathinfo = map_load(&ctx->parent_sess->paths, pathinfo->parent_dir);
assert(new_pathinfo);
new_pathinfo->gc_refcount++;
} else {
- lo_interface lib9p_srv_file member_file = LO_CALL(pathinfo->file, dwalk, ctx, req->wname[resp->nwqid]);
+ lo_interface lib9p_srv_file member_file = LO_CALL(pathinfo->file, dwalk, ctx, req->wname[resp.nwqid]);
assert(LO_IS_NULL(member_file) == lib9p_ctx_has_error(&ctx->basectx));
if (lib9p_ctx_has_error(&ctx->basectx))
break;
@@ -972,39 +982,41 @@ static void handle_Twalk(struct srv_req *ctx,
}
}
- resp->wqid[resp->nwqid] = LO_CALL(new_pathinfo->file, qid);
+ resp.wqid[resp.nwqid] = LO_CALL(new_pathinfo->file, qid);
srv_path_decref(ctx, LO_CALL(pathinfo->file, qid).path);
pathinfo = new_pathinfo;
}
- if (resp->nwqid == req->nwname) {
+ if (resp.nwqid == req->nwname) {
if (!srv_fid_store(ctx, req->newfid, pathinfo, req->newfid == req->fid))
srv_path_decref(ctx, LO_CALL(pathinfo->file, qid).path);
} else {
assert(lib9p_ctx_has_error(&ctx->basectx));
srv_path_decref(ctx, LO_CALL(pathinfo->file, qid).path);
- if (resp->nwqid > 0)
+ if (resp.nwqid > 0)
lib9p_ctx_clear_error(&ctx->basectx);
}
- ctx->user = srv_userid_decref(ctx->user);
+ twalk_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, walk, &resp);
}
static void handle_Topen(struct srv_req *ctx,
- struct lib9p_msg_Topen *req,
- struct lib9p_msg_Ropen *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Topen *req) {
+ srv_handler_common(ctx, open, req);
/* Check that the FID is valid for this. */
struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
lib9p_errorf(&ctx->basectx,
LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ goto topen_return;
}
if (fidinfo->flags & FIDFLAG_OPEN) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EALREADY, "FID is already open");
- return;
+ goto topen_return;
}
if (fidinfo->type == SRV_FILETYPE_DIR) {
if ( ((req->mode & LIB9P_O_MODE_MASK) != LIB9P_O_MODE_READ) ||
@@ -1012,7 +1024,7 @@ static void handle_Topen(struct srv_req *ctx,
(req->mode & LIB9P_O_RCLOSE) ) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EISDIR, "directories cannot be written, executed, truncated, or removed-on-close");
- return;
+ goto topen_return;
}
}
ctx->user = srv_userid_incref(fidinfo->user);
@@ -1116,25 +1128,28 @@ static void handle_Topen(struct srv_req *ctx,
fidflags |= FIDFLAG_OPEN_W;
pathinfo->io_refcount++;
fidinfo->flags = fidflags;
- resp->qid = qid;
- resp->iounit = iounit;
+ resp.qid = qid;
+ resp.iounit = iounit;
topen_return:
- ctx->user = srv_userid_decref(ctx->user);
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, open, &resp);
}
static void handle_Tcreate(struct srv_req *ctx,
- struct lib9p_msg_Tcreate *req,
- struct lib9p_msg_Rcreate *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tcreate *req) {
+ srv_handler_common(ctx, create, req);
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EOPNOTSUPP, "create not (yet?) implemented");
+
+ srv_respond(ctx, create, &resp);
}
static void handle_Tread(struct srv_req *ctx,
- struct lib9p_msg_Tread *req,
- struct lib9p_msg_Rread *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tread *req) {
+ srv_handler_common(ctx, read, req);
+ char *heap = NULL;
/* TODO: serialize simultaneous reads to the same FID */
@@ -1143,12 +1158,12 @@ static void handle_Tread(struct srv_req *ctx,
if (!fidinfo) {
lib9p_errorf(&ctx->basectx,
LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ goto tread_return;
}
if (!(fidinfo->flags & FIDFLAG_OPEN_R)) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EINVAL, "FID not open for reading");
- return;
+ goto tread_return;
}
/* Do it. */
@@ -1165,20 +1180,19 @@ static void handle_Tread(struct srv_req *ctx,
lib9p_errorf(&ctx->basectx,
LIB9P_ERRNO_L_EINVAL, "invalid offset (must be 0 or %"PRIu64"): %"PRIu64,
fidinfo->dir.off, req->offset);
- ctx->user = srv_userid_decref(ctx->user);
- return;
+ goto tread_return;
}
/* Do it. */
- resp->data = (char *)(&resp[1]);
- size_t num = LO_CALL(fidinfo->dir.io, dread, ctx, (uint8_t *)resp->data, req->count, idx);
+ resp.data = heap = malloc(req->count); /* TODO: cap req->count */
+ size_t num = LO_CALL(fidinfo->dir.io, dread, ctx, (uint8_t *)resp.data, req->count, idx);
/* Translate object-count back to byte-count. */
uint32_t len = 0;
for (size_t i = 0; i < num; i++) {
uint32_t i_len;
- lib9p_stat_validate(&ctx->basectx, req->count, &((uint8_t *)resp->data)[len], &i_len, NULL);
+ lib9p_stat_validate(&ctx->basectx, req->count, &((uint8_t *)resp.data)[len], &i_len, NULL);
len += i_len;
}
- resp->count = len;
+ resp.count = len;
/* Remember. */
fidinfo->dir.idx = idx+num;
fidinfo->dir.off = req->offset + len;
@@ -1187,23 +1201,27 @@ static void handle_Tread(struct srv_req *ctx,
struct iovec iov;
LO_CALL(fidinfo->file.io, pread, ctx, req->count, req->offset, &iov);
if (!lib9p_ctx_has_error(&ctx->basectx) && !ctx->flush_acknowledged) {
- resp->count = iov.iov_len;
- resp->data = iov.iov_base;
- if (resp->count > req->count)
- resp->count = req->count;
+ resp.count = iov.iov_len;
+ resp.data = iov.iov_base;
+ if (resp.count > req->count)
+ resp.count = req->count;
}
break;
case SRV_FILETYPE_AUTH:
assert_notreached("TODO: auth not yet implemented");
break;
}
- ctx->user = srv_userid_decref(ctx->user);
+ tread_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, read, &resp);
+ if (heap)
+ free(heap);
}
static void handle_Twrite(struct srv_req *ctx,
- struct lib9p_msg_Twrite *req,
- struct lib9p_msg_Rwrite *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Twrite *req) {
+ srv_handler_common(ctx, write, req);
/* TODO: serialize simultaneous writes to the same FID */
@@ -1212,122 +1230,136 @@ static void handle_Twrite(struct srv_req *ctx,
if (!fidinfo) {
lib9p_errorf(&ctx->basectx,
LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ goto twrite_return;
}
if (!(fidinfo->flags & FIDFLAG_OPEN_W)) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EINVAL, "FID not open for writing");
- return;
+ goto twrite_return;
}
if (fidinfo->flags & FIDFLAG_APPEND)
req->offset = 0;
/* Do it. */
ctx->user = srv_userid_incref(fidinfo->user);
- resp->count = LO_CALL(fidinfo->file.io, pwrite, ctx, req->data, req->count, req->offset);
- ctx->user = srv_userid_decref(ctx->user);
+ resp.count = LO_CALL(fidinfo->file.io, pwrite, ctx, req->data, req->count, req->offset);
+ twrite_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, write, &resp);
}
static void handle_Tclunk(struct srv_req *ctx,
- struct lib9p_msg_Tclunk *req,
- struct lib9p_msg_Rclunk *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tclunk *req) {
+ srv_handler_common(ctx, clunk, req);
struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
lib9p_errorf(&ctx->basectx,
LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ goto tclunk_return;
}
ctx->user = srv_userid_incref(fidinfo->user);
srv_fid_del(ctx, req->fid, false);
- ctx->user = srv_userid_decref(ctx->user);
+ tclunk_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, clunk, &resp);
}
static void handle_Tremove(struct srv_req *ctx,
- struct lib9p_msg_Tremove *req,
- struct lib9p_msg_Rremove *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tremove *req) {
+ srv_handler_common(ctx, remove, req);
struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
lib9p_errorf(&ctx->basectx,
LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ goto tremove_return;
}
ctx->user = srv_userid_incref(fidinfo->user);
srv_fid_del(ctx, req->fid, true);
- ctx->user = srv_userid_decref(ctx->user);
+ tremove_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, remove, &resp);
}
static void handle_Tstat(struct srv_req *ctx,
- struct lib9p_msg_Tstat *req,
- struct lib9p_msg_Rstat *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tstat *req) {
+ srv_handler_common(ctx, stat, req);
struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
lib9p_errorf(&ctx->basectx,
LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ goto tstat_return;
}
struct srv_pathinfo *pathinfo = map_load(&ctx->parent_sess->paths, fidinfo->path);
assert(pathinfo);
ctx->user = srv_userid_incref(fidinfo->user);
- resp->stat = LO_CALL(pathinfo->file, stat, ctx);
+ resp.stat = LO_CALL(pathinfo->file, stat, ctx);
if (!lib9p_ctx_has_error(&ctx->basectx))
- lib9p_stat_assert(resp->stat);
- ctx->user = srv_userid_decref(ctx->user);
+ lib9p_stat_assert(resp.stat);
+ tstat_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, stat, &resp);
}
static void handle_Twstat(struct srv_req *ctx,
- struct lib9p_msg_Twstat *req,
- struct lib9p_msg_Rwstat *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Twstat *req) {
+ srv_handler_common(ctx, wstat, req);
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EOPNOTSUPP, "wstat not (yet?) implemented");
+
+ srv_respond(ctx, wstat, &resp);
}
#if CONFIG_9P_ENABLE_9P2000_p9p
static void handle_Topenfd(struct srv_req *ctx,
- struct lib9p_msg_Topenfd *req,
- struct lib9p_msg_Ropenfd *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Topenfd *req) {
+ srv_handler_common(ctx, openfd, req);
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EOPNOTSUPP, "openfd not (yet?) implemented");
+
+ srv_respond(ctx, openfd, &resp);
}
#endif
#if CONFIG_9P_ENABLE_9P2000_e
static void handle_Tsession(struct srv_req *ctx,
- struct lib9p_msg_Tsession *req,
- struct lib9p_msg_Rsession *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tsession *req) {
+ srv_handler_common(ctx, session, req);
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EOPNOTSUPP, "session not (yet?) implemented");
+
+ srv_respond(ctx, session, &resp);
}
static void handle_Tsread(struct srv_req *ctx,
- struct lib9p_msg_Tsread *req,
- struct lib9p_msg_Rsread *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tsread *req) {
+ srv_handler_common(ctx, sread, req);
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EOPNOTSUPP, "sread not (yet?) implemented");
+
+ srv_respond(ctx, sread, &resp);
}
static void handle_Tswrite(struct srv_req *ctx,
- struct lib9p_msg_Tswrite *req,
- struct lib9p_msg_Rswrite *resp) {
- srv_handler_common(ctx, req, resp);
+ struct lib9p_msg_Tswrite *req) {
+ srv_handler_common(ctx, swrite, req);
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EOPNOTSUPP, "swrite not (yet?) implemented");
+
+ srv_respond(ctx, swrite, &resp);
}
#endif
diff --git a/lib9p/srv_include/lib9p/srv.h b/lib9p/srv_include/lib9p/srv.h
index 5b44e79..cc73634 100644
--- a/lib9p/srv_include/lib9p/srv.h
+++ b/lib9p/srv_include/lib9p/srv.h
@@ -47,6 +47,7 @@ struct lib9p_srv_ctx {
uint8_t *net_bytes;
_lib9p_srv_flush_ch_t flush_ch;
bool flush_acknowledged;
+ bool responded;
END_PRIVATE(LIB9P_SRV_H);
};