diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-02 20:29:01 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-02 20:29:01 -0600 |
commit | ba8f3ddba03ab93158c93f77ef98137e1dd6e8e9 (patch) | |
tree | 6a502f012e52d6186dccd05c659e7cddd3c4b73f /lib9p | |
parent | 48ec9be1eba930b06050262a1a651d794c31bc11 (diff) |
lib9p: add O_* flags
Diffstat (limited to 'lib9p')
-rw-r--r-- | lib9p/9P2000.txt | 24 | ||||
-rw-r--r-- | lib9p/include/lib9p/_types.h | 20 | ||||
-rw-r--r-- | lib9p/types.c | 31 | ||||
-rwxr-xr-x | lib9p/types.gen | 2 |
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( |