summaryrefslogtreecommitdiff
path: root/lib9p/srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/srv.c')
-rw-r--r--lib9p/srv.c165
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");
}