diff options
Diffstat (limited to 'lib9p/srv.c')
-rw-r--r-- | lib9p/srv.c | 165 |
1 files changed, 120 insertions, 45 deletions
diff --git a/lib9p/srv.c b/lib9p/srv.c index 7dca9ec..84b3ae8 100644 --- a/lib9p/srv.c +++ b/lib9p/srv.c @@ -17,7 +17,7 @@ #define NAME fidmap #define KEY_T uint32_t -#define VAL_T struct lib9p_srv_file +#define VAL_T struct lib9p_srv_file * #define CAP CONFIG_9P_MAX_FIDS #include "map.h" @@ -368,6 +368,10 @@ static void handle_message(struct _lib9p_srv_req *ctx) { static void handle_Tversion(struct _lib9p_srv_req *ctx, struct lib9p_msg_Tversion *req, struct lib9p_msg_Rversion *resp) { + assert(ctx); + assert(req); + assert(resp); + enum lib9p_version version = LIB9P_VER_unknown; if (req->version.len >= 6 && @@ -422,10 +426,11 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx, if (ctx->parent_sess->fids.len) { /* Close all FIDs. */ uint32_t fid; - struct lib9p_srv_file *fptr; - MAP_FOREACH(&ctx->parent_sess->fids, fid, fptr) { - fptr->vtable.free(&ctx->ctx, fptr->impldata); - fidmap_del(&ctx->parent_sess->fids, fid); + struct lib9p_srv_file **filepp __attribute__((unused)); + MAP_FOREACH(&ctx->parent_sess->fids, fid, filepp) { + handle_Tclunk(ctx, + &(struct lib9p_msg_Tclunk){.fid = fid}, + &(struct lib9p_msg_Rclunk){}); } } @@ -437,7 +442,11 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx, static void handle_Tauth(struct _lib9p_srv_req *ctx, struct lib9p_msg_Tauth *req, - struct lib9p_msg_Rauth *UNUSED(resp)) { + struct lib9p_msg_Rauth *resp) { + assert(ctx); + assert(req); + assert(resp); + ctx->ctx.uid = req->n_uname; ctx->ctx.uname = req->uname.utf8; struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv; @@ -456,6 +465,10 @@ static void handle_Tauth(struct _lib9p_srv_req *ctx, static void handle_Tattach(struct _lib9p_srv_req *ctx, struct lib9p_msg_Tattach *req, struct lib9p_msg_Rattach *resp) { + assert(ctx); + assert(req); + assert(resp); + ctx->ctx.uid = req->n_uname; ctx->ctx.uname = req->uname.utf8; struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv; @@ -501,117 +514,179 @@ static void handle_Tattach(struct _lib9p_srv_req *ctx, return; } - struct lib9p_srv_file rootdir = srv->rootdir(&ctx->ctx, req->aname.utf8); + struct lib9p_srv_file *rootdir = srv->rootdir(&ctx->ctx, req->aname.utf8); if (lib9p_ctx_has_error(&ctx->ctx.basectx)) return; + rootdir->_parent_dir = rootdir; - struct lib9p_stat stat = rootdir.vtable.stat(&ctx->ctx, rootdir.impldata); - if (lib9p_ctx_has_error(&ctx->ctx.basectx)) { - if (rootdir.vtable.free) - rootdir.vtable.free(&ctx->ctx, rootdir.impldata); + if (!fidmap_store(&ctx->parent_sess->fids, req->fid, rootdir)) { + lib9p_error(&ctx->ctx.basectx, + LINUX_EMFILE, "too many open files"); + if (rootdir->vtable->free) + rootdir->vtable->free(&ctx->ctx, rootdir); return; } - struct lib9p_srv_file *rootdir_ptr = fidmap_store(&ctx->parent_sess->fids, req->fid, rootdir); - if (!rootdir_ptr) { - lib9p_error(&ctx->ctx.basectx, - LINUX_EMFILE, "too many open files"); - if (rootdir.vtable.free) - rootdir.vtable.free(&ctx->ctx, rootdir.impldata); + struct lib9p_stat stat = rootdir->vtable->stat(&ctx->ctx, rootdir); + if (lib9p_ctx_has_error(&ctx->ctx.basectx)) { + handle_Tclunk(ctx, + &(struct lib9p_msg_Tclunk){.fid = req->fid}, + &(struct lib9p_msg_Rclunk){}); return; } + resp->qid = stat.file_qid; return; } static void handle_Tflush(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tflush *UNUSED(req), - struct lib9p_msg_Rflush *UNUSED(resp)) { + struct lib9p_msg_Tflush *req, + struct lib9p_msg_Rflush *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "flush not yet implemented"); } static void handle_Twalk(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Twalk *UNUSED(req), - struct lib9p_msg_Rwalk *UNUSED(resp)) { + struct lib9p_msg_Twalk *req, + struct lib9p_msg_Rwalk *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "walk not yet implemented"); } static void handle_Topen(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Topen *UNUSED(req), - struct lib9p_msg_Ropen *UNUSED(resp)) { + struct lib9p_msg_Topen *req, + struct lib9p_msg_Ropen *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "open not yet implemented"); } static void handle_Tcreate(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tcreate *UNUSED(req), - struct lib9p_msg_Rcreate *UNUSED(resp)) { + struct lib9p_msg_Tcreate *req, + struct lib9p_msg_Rcreate *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "create not yet implemented"); } static void handle_Tread(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tread *UNUSED(req), - struct lib9p_msg_Rread *UNUSED(resp)) { + struct lib9p_msg_Tread *req, + struct lib9p_msg_Rread *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "read not yet implemented"); } static void handle_Twrite(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Twrite *UNUSED(req), - struct lib9p_msg_Rwrite *UNUSED(resp)) { + struct lib9p_msg_Twrite *req, + struct lib9p_msg_Rwrite *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "write not yet implemented"); } static void handle_Tclunk(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tclunk *UNUSED(req), - struct lib9p_msg_Rclunk *UNUSED(resp)) { - lib9p_error(&ctx->ctx.basectx, - LINUX_EOPNOTSUPP, "clunk not yet implemented"); + struct lib9p_msg_Tclunk *req, + struct lib9p_msg_Rclunk *resp) { + assert(ctx); + assert(req); + assert(resp); + + struct lib9p_srv_file **filepp = fidmap_load(&ctx->parent_sess->fids, req->fid); + if (!filepp) { + lib9p_errorf(&ctx->ctx.basectx, + LINUX_EBADF, "bad file number %"PRIu32, req->fid); + return; + } + + if ((*filepp)->vtable->free) + (*filepp)->vtable->free(&ctx->ctx, *filepp); + fidmap_del(&ctx->parent_sess->fids, req->fid); } static void handle_Tremove(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tremove *UNUSED(req), - struct lib9p_msg_Rremove *UNUSED(resp)) { + struct lib9p_msg_Tremove *req, + struct lib9p_msg_Rremove *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "remove not yet implemented"); } static void handle_Tstat(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tstat *UNUSED(req), - struct lib9p_msg_Rstat *UNUSED(resp)) { + struct lib9p_msg_Tstat *req, + struct lib9p_msg_Rstat *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "stat not yet implemented"); } static void handle_Twstat(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Twstat *UNUSED(req), - struct lib9p_msg_Rwstat *UNUSED(resp)) { + struct lib9p_msg_Twstat *req, + struct lib9p_msg_Rwstat *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "wstat not yet implemented"); } static void handle_Tsession(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tsession *UNUSED(req), - struct lib9p_msg_Rsession *UNUSED(resp)) { + struct lib9p_msg_Tsession *req, + struct lib9p_msg_Rsession *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "session not yet implemented"); } static void handle_Tsread(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tsread *UNUSED(req), - struct lib9p_msg_Rsread *UNUSED(resp)) { + struct lib9p_msg_Tsread *req, + struct lib9p_msg_Rsread *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "sread not yet implemented"); } static void handle_Tswrite(struct _lib9p_srv_req *ctx, - struct lib9p_msg_Tswrite *UNUSED(req), - struct lib9p_msg_Rswrite *UNUSED(resp)) { + struct lib9p_msg_Tswrite *req, + struct lib9p_msg_Rswrite *resp) { + assert(ctx); + assert(req); + assert(resp); + lib9p_error(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "swrite not yet implemented"); } |