summaryrefslogtreecommitdiff
path: root/lib9p
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-02 20:29:01 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-10-02 20:29:01 -0600
commitba8f3ddba03ab93158c93f77ef98137e1dd6e8e9 (patch)
tree6a502f012e52d6186dccd05c659e7cddd3c4b73f /lib9p
parent48ec9be1eba930b06050262a1a651d794c31bc11 (diff)
lib9p: add O_* flags
Diffstat (limited to 'lib9p')
-rw-r--r--lib9p/9P2000.txt24
-rw-r--r--lib9p/include/lib9p/_types.h20
-rw-r--r--lib9p/types.c31
-rwxr-xr-xlib9p/types.gen2
4 files changed, 63 insertions, 14 deletions
diff --git a/lib9p/9P2000.txt b/lib9p/9P2000.txt
index d90175b..da9b223 100644
--- a/lib9p/9P2000.txt
+++ b/lib9p/9P2000.txt
@@ -52,8 +52,8 @@ bitfield qt 8
# of the type for a plain file."
FILE=0
-# uniQue IDentification - "two files on the same server hierarchy are
-# the same if and only if their qids are the same"
+# uni"Q"ue "ID"entification - "two files on the same server hierarchy
+# are the same if and only if their qids are the same"
#
# - "path" is a unique uint64_t that does most of the work in the
# above statement about files being the same if their QIDs are the
@@ -82,6 +82,22 @@ stat = "stat_size[2]"
"file_owner_gid[s]"
"file_last_modified_uid[s]"
+# "O"pen flags (flags to pass to Topen and Tcreate)
+bitfield o 8
+ 0/_rwx_0 # low bit of the 2-bit READ/WRITE/RDWR/EXEC enum
+ 1/_rwx_1 # high bit of the 2-bit READ/WRITE/RDWR/EXEC enum
+ #2/unused
+ #3/unused
+ 4/TRUNC
+ #5/unused
+ 6/RCLOSE # remove-on-close
+ #7/unused
+
+ READ = 0
+ WRITE = 1
+ RDWR = 2
+ EXEC = 3
+
# In the 9P protocol, each message has a type, and message types come
# in pairs (except "Rerror"); "T" and "R"; "T" messages are
# client->server requests, and "R" messages are server->client
@@ -99,9 +115,9 @@ stat = "stat_size[2]"
109/Rflush = ""
110/Twalk = "fid[4] newfid[4] nwname[2] nwname*(wname[s])"
111/Rwalk = "nwqid[2] nwqid*(wqid[qid])"
-112/Topen = "fid[4] mode[1]"
+112/Topen = "fid[4] mode[o]"
113/Ropen = "qid[qid] iounit[4]"
-114/Tcreate = "fid[4] name[s] perm[4] mode[1]"
+114/Tcreate = "fid[4] name[s] perm[4] mode[o]"
115/Rcreate = "qid[qid] iounit[4]"
116/Tread = "fid[4] offset[8] count[4]"
117/Rread = "data[d]" # for directories data is the sequence "cnt*(entries[stat])"
diff --git a/lib9p/include/lib9p/_types.h b/lib9p/include/lib9p/_types.h
index 8f9595e..d853cf3 100644
--- a/lib9p/include/lib9p/_types.h
+++ b/lib9p/include/lib9p/_types.h
@@ -30,6 +30,20 @@ typedef uint8_t lib9p_qt_t;
#define _LIB9P_QT_UNUSED_0 ((lib9p_qt_t)(1<<0))
#define LIB9P_QT_FILE ((lib9p_qt_t)(0))
+typedef uint8_t lib9p_o_t;
+#define _LIB9P_O_UNUSED_7 ((lib9p_o_t)(1<<7))
+#define LIB9P_O_RCLOSE ((lib9p_o_t)(1<<6))
+#define _LIB9P_O_UNUSED_5 ((lib9p_o_t)(1<<5))
+#define LIB9P_O_TRUNC ((lib9p_o_t)(1<<4))
+#define _LIB9P_O_UNUSED_3 ((lib9p_o_t)(1<<3))
+#define _LIB9P_O_UNUSED_2 ((lib9p_o_t)(1<<2))
+#define _LIB9P_O_rwx_1 ((lib9p_o_t)(1<<1))
+#define _LIB9P_O_rwx_0 ((lib9p_o_t)(1<<0))
+#define LIB9P_O_READ ((lib9p_o_t)(0))
+#define LIB9P_O_WRITE ((lib9p_o_t)(1))
+#define LIB9P_O_RDWR ((lib9p_o_t)(2))
+#define LIB9P_O_EXEC ((lib9p_o_t)(3))
+
struct lib9p_d {
uint32_t len;
uint8_t *dat;
@@ -161,8 +175,8 @@ struct lib9p_msg_Rwalk {
};
struct lib9p_msg_Topen {
- uint32_t fid;
- uint8_t mode;
+ uint32_t fid;
+ lib9p_o_t mode;
};
struct lib9p_msg_Ropen {
@@ -174,7 +188,7 @@ struct lib9p_msg_Tcreate {
uint32_t fid;
struct lib9p_s name;
uint32_t perm;
- uint8_t mode;
+ lib9p_o_t mode;
};
struct lib9p_msg_Rcreate {
diff --git a/lib9p/types.c b/lib9p/types.c
index 18dcbfe..50ac1cf 100644
--- a/lib9p/types.c
+++ b/lib9p/types.c
@@ -384,6 +384,17 @@ static ALWAYS_INLINE bool validate_stat(struct _validate_ctx *ctx) {
|| ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) );
}
+static ALWAYS_INLINE bool validate_o(struct _validate_ctx *ctx) {
+ if (validate_1(ctx))
+ return true;
+ static const lib9p_o_t mask = 0b01010011;
+ lib9p_o_t val = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]);
+ if (val & ~mask)
+ return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#01"PRIx8,
+ val & ~mask);
+ return false;
+}
+
static FLATTEN bool validate_Tversion(struct _validate_ctx *ctx) {
return validate_4(ctx)
|| validate_s(ctx);
@@ -443,7 +454,7 @@ static FLATTEN bool validate_Rwalk(struct _validate_ctx *ctx) {
static FLATTEN bool validate_Topen(struct _validate_ctx *ctx) {
return validate_4(ctx)
- || validate_1(ctx);
+ || validate_o(ctx);
}
static FLATTEN bool validate_Ropen(struct _validate_ctx *ctx) {
@@ -455,7 +466,7 @@ static FLATTEN bool validate_Tcreate(struct _validate_ctx *ctx) {
return validate_4(ctx)
|| validate_s(ctx)
|| validate_4(ctx)
- || validate_1(ctx);
+ || validate_o(ctx);
}
static FLATTEN bool validate_Rcreate(struct _validate_ctx *ctx) {
@@ -616,6 +627,10 @@ static ALWAYS_INLINE void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9
if ( (ctx->ctx->version==LIB9P_VER_9P2000_u) ) unmarshal_4(ctx, &out->file_last_modified_n_uid);
}
+static ALWAYS_INLINE void unmarshal_o(struct _unmarshal_ctx *ctx, lib9p_o_t *out) {
+ unmarshal_1(ctx, (uint8_t *)out);
+}
+
static FLATTEN void unmarshal_Tversion(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tversion *out) {
memset(out, 0, sizeof(*out));
unmarshal_4(ctx, &out->max_msg_size);
@@ -692,7 +707,7 @@ static FLATTEN void unmarshal_Rwalk(struct _unmarshal_ctx *ctx, struct lib9p_msg
static FLATTEN void unmarshal_Topen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Topen *out) {
memset(out, 0, sizeof(*out));
unmarshal_4(ctx, &out->fid);
- unmarshal_1(ctx, &out->mode);
+ unmarshal_o(ctx, &out->mode);
}
static FLATTEN void unmarshal_Ropen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Ropen *out) {
@@ -706,7 +721,7 @@ static FLATTEN void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_m
unmarshal_4(ctx, &out->fid);
unmarshal_s(ctx, &out->name);
unmarshal_4(ctx, &out->perm);
- unmarshal_1(ctx, &out->mode);
+ unmarshal_o(ctx, &out->mode);
}
static FLATTEN void unmarshal_Rcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rcreate *out) {
@@ -908,6 +923,10 @@ static ALWAYS_INLINE bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_st
|| ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && marshal_4(ctx, &val->file_last_modified_n_uid) );
}
+static ALWAYS_INLINE bool marshal_o(struct _marshal_ctx *ctx, lib9p_o_t *val) {
+ return marshal_1(ctx, (uint8_t *)val);
+}
+
static FLATTEN bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_Tversion *val) {
return marshal_4(ctx, &val->max_msg_size)
|| marshal_s(ctx, &val->version);
@@ -977,7 +996,7 @@ static FLATTEN bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwa
static FLATTEN bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Topen *val) {
return marshal_4(ctx, &val->fid)
- || marshal_1(ctx, &val->mode);
+ || marshal_o(ctx, &val->mode);
}
static FLATTEN bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Ropen *val) {
@@ -989,7 +1008,7 @@ static FLATTEN bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_T
return marshal_4(ctx, &val->fid)
|| marshal_s(ctx, &val->name)
|| marshal_4(ctx, &val->perm)
- || marshal_1(ctx, &val->mode);
+ || marshal_o(ctx, &val->mode);
}
static FLATTEN bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate *val) {
diff --git a/lib9p/types.gen b/lib9p/types.gen
index c793d20..1b43fa4 100755
--- a/lib9p/types.gen
+++ b/lib9p/types.gen
@@ -137,7 +137,7 @@ re_structspec = (
re_structspec_cont = r'\s+"(?P<members>[^"]*)"'
re_bitfieldspec = r"bitfield\s+(?P<name>\S+)\s+(?P<size>[0-9]+)"
re_bitfieldspec_bit = r"(?:\s+|(?P<bitfield>\S+)\s*\+=\s*)(?P<bit>[0-9]+)/(?P<name>\S+)"
-re_bitfieldspec_alias = r"(?:\s+|(?P<bitfield>\S+)\s*\+=\s*)(?P<name>\S+)=(?P<val>.*)"
+re_bitfieldspec_alias = r"(?:\s+|(?P<bitfield>\S+)\s*\+=\s*)(?P<name>\S+)\s*=\s*(?P<val>.*)"
def parse_file(