diff options
-rw-r--r-- | lib9p/srv.c | 316 | ||||
-rw-r--r-- | lib9p/srv_include/lib9p/srv.h | 1 |
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); }; |