summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/srv9p/config/config.h9
-rw-r--r--lib9p/.editorconfig2
-rw-r--r--lib9p/9p.c39
-rw-r--r--lib9p/9p.generated.c1471
-rwxr-xr-xlib9p/idl.gen589
-rw-r--r--lib9p/idl/0000-README.md (renamed from lib9p/idl/00-README.md)0
-rw-r--r--lib9p/idl/1992-9P0.9p.wip53
-rw-r--r--lib9p/idl/1995-9P1.9p.wip52
-rw-r--r--lib9p/idl/1996-Styx.9p.wip15
-rw-r--r--lib9p/idl/2002-9P2000.9p (renamed from lib9p/idl/01-9P2000.9p)4
-rw-r--r--lib9p/idl/2005-9P2000.u.9p (renamed from lib9p/idl/02-9P2000.u.9p)4
-rw-r--r--lib9p/idl/2010-9P2000.L.9p.wip (renamed from lib9p/idl/03-9P2000.L.9p.wip)6
-rw-r--r--lib9p/idl/2012-9P2000.e.9p (renamed from lib9p/idl/02-9P2000.e.9p)4
-rw-r--r--lib9p/include/lib9p/9p.generated.h2
-rw-r--r--lib9p/include/lib9p/9p.h17
-rw-r--r--lib9p/srv.c77
16 files changed, 1710 insertions, 634 deletions
diff --git a/cmd/srv9p/config/config.h b/cmd/srv9p/config/config.h
index ead97e0..96aba1d 100644
--- a/cmd/srv9p/config/config.h
+++ b/cmd/srv9p/config/config.h
@@ -4,9 +4,12 @@
* SPDX-Licence-Identifier: AGPL-3.0-or-later
*/
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
#define CONFIG_NETIO_NUM_CONNS 8
-# define CONFIG_9P_PORT 564
+#define CONFIG_9P_PORT 564
/**
* This max-msg-size is sized so that a Twrite message can return
* 8KiB of data.
@@ -34,6 +37,8 @@
#define CONFIG_9P_MAX_FIDS 16
#define CONFIG_9P_MAX_REQS 2
#define CONFIG_9P_MAX_ERR_SIZE 128 /* 128 is what Plan 9 4e uses */
+#define CONFIG_9P_ENABLE_9P2000_u
+#define CONFIG_9P_ENABLE_9P2000_e
#define CONFIG_COROUTINE_DEFAULT_STACK_SIZE (32*1024)
#define CONFIG_COROUTINE_MEASURE_STACK 1 /* bool */
@@ -44,3 +49,5 @@
1 /* usb_keyboard */ +\
CONFIG_NETIO_NUM_CONNS /* accept+read */ +\
(CONFIG_9P_MAX_REQS*CONFIG_NETIO_NUM_CONNS) /* work+write */ )
+
+#endif /* _CONFIG_H_ */
diff --git a/lib9p/.editorconfig b/lib9p/.editorconfig
index ee1a38f..5243d26 100644
--- a/lib9p/.editorconfig
+++ b/lib9p/.editorconfig
@@ -1,3 +1,3 @@
-[{9p.gen,linux-errno.h.gen}]
+[{idl.gen,linux-errno.h.gen}]
indent_style = space
indent_size = 4
diff --git a/lib9p/9p.c b/lib9p/9p.c
index 8633a44..0e71071 100644
--- a/lib9p/9p.c
+++ b/lib9p/9p.c
@@ -36,24 +36,24 @@ int lib9p_errorf(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *fmt, .
}
ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) {
- /* Header */
+ /* Inspect the first 5 bytes ourselves. */
struct _validate_ctx subctx = {
.ctx = ctx,
.net_size = decode_u32le(net_bytes),
.net_bytes = net_bytes,
- .net_offset = 7,
+ .net_offset = 0,
.host_extra = 0,
};
- if (subctx.net_size < subctx.net_offset)
- return lib9p_error(ctx, LINUX_EBADMSG, "message is too short");
+ if (subctx.net_size < 5)
+ return lib9p_error(ctx, LINUX_EBADMSG, "message is impossibly short");
uint8_t typ = net_bytes[4];
-
- /* Body */
struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ];
if (!vtable.validate)
return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)",
lib9p_msg_type_str(typ), lib9p_version_str(ctx->version));
+
+ /* Now use the message-type-specific vtable to process the whole thing. */
if (vtable.validate(&subctx))
return -1;
assert(subctx.net_offset <= subctx.net_size);
@@ -61,49 +61,36 @@ ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) {
return lib9p_errorf(ctx, LINUX_EBADMSG, "message has %"PRIu32" extra bytes",
subctx.net_size - subctx.net_offset);
+ /* Return. */
ssize_t ret;
if (__builtin_add_overflow(vtable.basesize, subctx.host_extra, &ret))
return lib9p_error(ctx, LINUX_EMSGSIZE, "unmarshalled payload overflows SSIZE_MAX");
-
return ret;
}
void lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
- enum lib9p_msg_type *ret_typ, uint16_t *ret_tag, void *ret_body) {
- /* Header */
+ enum lib9p_msg_type *ret_typ, void *ret_body) {
struct _unmarshal_ctx subctx = {
.ctx = ctx,
.net_bytes = net_bytes,
- .net_offset = 7,
+ .net_offset = 0,
};
- *ret_typ = net_bytes[4];
- *ret_tag = decode_u16le(&net_bytes[5]);
- /* Body */
+ *ret_typ = net_bytes[4];
struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[*ret_typ];
subctx.extra = ret_body + vtable.basesize;
vtable.unmarshal(&subctx, ret_body);
}
-bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, uint16_t tag, void *body,
+bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
uint8_t *ret_bytes) {
- /* Header */
struct _marshal_ctx subctx = {
.ctx = ctx,
.net_bytes = ret_bytes,
- .net_offset = 7,
+ .net_offset = 0,
};
- ret_bytes[4] = typ;
- encode_u16le(tag, &ret_bytes[5]);
- /* Body */
struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ];
- if (vtable.marshal(&subctx, body))
- return true;
-
- /* Header, again */
- encode_u32le(subctx.net_offset, ret_bytes);
-
- return false;
+ return vtable.marshal(&subctx, body);
}
diff --git a/lib9p/9p.generated.c b/lib9p/9p.generated.c
index a93316b..341acd0 100644
--- a/lib9p/9p.generated.c
+++ b/lib9p/9p.generated.c
@@ -1,4 +1,4 @@
-/* Generated by `./lib9p/idl.gen lib9p/idl/01-9P2000.9p lib9p/idl/02-9P2000.e.9p lib9p/idl/02-9P2000.u.9p`. DO NOT EDIT! */
+/* Generated by `./lib9p/idl.gen lib9p/idl/2002-9P2000.9p lib9p/idl/2005-9P2000.u.9p lib9p/idl/2012-9P2000.e.9p`. DO NOT EDIT! */
#include <assert.h>
#include <stdbool.h>
@@ -359,49 +359,45 @@ static ALWAYS_INLINE bool validate_s(struct _validate_ctx *ctx) {
return false;
}
-static ALWAYS_INLINE bool validate_dm(struct _validate_ctx *ctx) {
- if (validate_4(ctx))
- return true;
- static const lib9p_dm_t masks[LIB9P_VER_NUM] = {
+static const lib9p_dm_t dm_masks[LIB9P_VER_NUM] = {
#if defined(CONFIG_9P_ENABLE_9P2000)
- [LIB9P_VER_9P2000] = 0b11101100000000000000000111111111,
+ [LIB9P_VER_9P2000] = 0b11101100000000000000000111111111,
#endif /* defined(CONFIG_9P_ENABLE_9P2000) */
#if defined(CONFIG_9P_ENABLE_9P2000_e)
- [LIB9P_VER_9P2000_e] = 0b11101100000000000000000111111111,
+ [LIB9P_VER_9P2000_e] = 0b11101100000000000000000111111111,
#endif /* defined(CONFIG_9P_ENABLE_9P2000_e) */
#if defined(CONFIG_9P_ENABLE_9P2000_u)
- [LIB9P_VER_9P2000_u] = 0b11101100101111000000000111111111,
+ [LIB9P_VER_9P2000_u] = 0b11101100101111000000000111111111,
#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
- };
- lib9p_dm_t mask = masks[ctx->ctx->version];
+};
+static ALWAYS_INLINE bool validate_dm(struct _validate_ctx *ctx) {
+ if (validate_4(ctx))
+ return true;
+ lib9p_dm_t mask = dm_masks[ctx->ctx->version];
lib9p_dm_t val = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]);
if (val & ~mask)
- return lib9p_errorf(ctx->ctx,
- LINUX_EBADMSG, "unknown bits in dm bitfield: %#04"PRIx32,
- val & ~mask);
+ return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#04"PRIx32, val & ~mask);
return false;
}
-static ALWAYS_INLINE bool validate_qt(struct _validate_ctx *ctx) {
- if (validate_1(ctx))
- return true;
- static const lib9p_qt_t masks[LIB9P_VER_NUM] = {
+static const lib9p_qt_t qt_masks[LIB9P_VER_NUM] = {
#if defined(CONFIG_9P_ENABLE_9P2000)
- [LIB9P_VER_9P2000] = 0b11101100,
+ [LIB9P_VER_9P2000] = 0b11101100,
#endif /* defined(CONFIG_9P_ENABLE_9P2000) */
#if defined(CONFIG_9P_ENABLE_9P2000_e)
- [LIB9P_VER_9P2000_e] = 0b11101100,
+ [LIB9P_VER_9P2000_e] = 0b11101100,
#endif /* defined(CONFIG_9P_ENABLE_9P2000_e) */
#if defined(CONFIG_9P_ENABLE_9P2000_u)
- [LIB9P_VER_9P2000_u] = 0b11101110,
+ [LIB9P_VER_9P2000_u] = 0b11101110,
#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
- };
- lib9p_qt_t mask = masks[ctx->ctx->version];
+};
+static ALWAYS_INLINE bool validate_qt(struct _validate_ctx *ctx) {
+ if (validate_1(ctx))
+ return true;
+ lib9p_qt_t mask = qt_masks[ctx->ctx->version];
lib9p_qt_t val = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]);
if (val & ~mask)
- return lib9p_errorf(ctx->ctx,
- LINUX_EBADMSG, "unknown bits in qt bitfield: %#01"PRIx8,
- val & ~mask);
+ return lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#01"PRIx8, val & ~mask);
return false;
}
@@ -435,33 +431,29 @@ static ALWAYS_INLINE bool validate_stat(struct _validate_ctx *ctx) {
|| ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) )
|| ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) )
#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
-
|| ({ uint32_t exp = ctx->net_offset - _kern_type_offset; (((uint32_t)stat_size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "stat_size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)stat_size, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "stat_size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)stat_size, exp); })
;
}
-static ALWAYS_INLINE bool validate_o(struct _validate_ctx *ctx) {
- if (validate_1(ctx))
- return true;
- static const lib9p_o_t masks[LIB9P_VER_NUM] = {
+static const lib9p_o_t o_masks[LIB9P_VER_NUM] = {
#if defined(CONFIG_9P_ENABLE_9P2000)
- [LIB9P_VER_9P2000] = 0b01010011,
+ [LIB9P_VER_9P2000] = 0b01010011,
#endif /* defined(CONFIG_9P_ENABLE_9P2000) */
#if defined(CONFIG_9P_ENABLE_9P2000_e)
- [LIB9P_VER_9P2000_e] = 0b01010011,
+ [LIB9P_VER_9P2000_e] = 0b01010011,
#endif /* defined(CONFIG_9P_ENABLE_9P2000_e) */
#if defined(CONFIG_9P_ENABLE_9P2000_u)
- [LIB9P_VER_9P2000_u] = 0b01010011,
+ [LIB9P_VER_9P2000_u] = 0b01010011,
#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
- };
- lib9p_o_t mask = masks[ctx->ctx->version];
+};
+static ALWAYS_INLINE bool validate_o(struct _validate_ctx *ctx) {
+ if (validate_1(ctx))
+ return true;
+ lib9p_o_t mask = o_masks[ctx->ctx->version];
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 lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#01"PRIx8, val & ~mask);
return false;
}
@@ -475,14 +467,10 @@ static FLATTEN bool validate_Tversion(struct _validate_ctx *ctx) {
|| validate_tag(ctx)
|| validate_4(ctx)
|| validate_s(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 100; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -496,14 +484,10 @@ static FLATTEN bool validate_Rversion(struct _validate_ctx *ctx) {
|| validate_tag(ctx)
|| validate_4(ctx)
|| validate_s(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 101; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -521,14 +505,10 @@ static FLATTEN bool validate_Tauth(struct _validate_ctx *ctx) {
#if defined(CONFIG_9P_ENABLE_9P2000_u)
|| ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) )
#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 102; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -541,14 +521,10 @@ static FLATTEN bool validate_Rauth(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_qid(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 103; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -567,14 +543,10 @@ static FLATTEN bool validate_Tattach(struct _validate_ctx *ctx) {
#if defined(CONFIG_9P_ENABLE_9P2000_u)
|| ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) )
#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 104; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -587,14 +559,10 @@ static FLATTEN bool validate_Rattach(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_qid(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 105; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -610,14 +578,10 @@ static FLATTEN bool validate_Rerror(struct _validate_ctx *ctx) {
#if defined(CONFIG_9P_ENABLE_9P2000_u)
|| ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && validate_4(ctx) )
#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 107; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -630,14 +594,10 @@ static FLATTEN bool validate_Tflush(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_2(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 108; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -649,14 +609,10 @@ static FLATTEN bool validate_Rflush(struct _validate_ctx *ctx) {
|| (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]); false; }))
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 109; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -673,18 +629,12 @@ static FLATTEN bool validate_Twalk(struct _validate_ctx *ctx) {
|| validate_fid(ctx)
|| (validate_2(ctx) || ({ nwname = decode_u16le(&ctx->net_bytes[ctx->net_offset-2]); false; }))
|| _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_s, sizeof(struct lib9p_s))
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 110; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
|| ({ uint32_t max = 16; (((uint32_t)nwname) > max) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nwname value too large (%"PRIu32" > %"PRIu32")", nwname, max); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nwname value is too large (%"PRIu32" > %"PRIu32")", nwname, max); })
;
}
@@ -699,18 +649,12 @@ static FLATTEN bool validate_Rwalk(struct _validate_ctx *ctx) {
|| validate_tag(ctx)
|| (validate_2(ctx) || ({ nwqid = decode_u16le(&ctx->net_bytes[ctx->net_offset-2]); false; }))
|| _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_qid, sizeof(struct lib9p_qid))
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 111; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
|| ({ uint32_t max = 16; (((uint32_t)nwqid) > max) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nwqid value too large (%"PRIu32" > %"PRIu32")", nwqid, max); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nwqid value is too large (%"PRIu32" > %"PRIu32")", nwqid, max); })
;
}
@@ -724,14 +668,10 @@ static FLATTEN bool validate_Topen(struct _validate_ctx *ctx) {
|| validate_tag(ctx)
|| validate_fid(ctx)
|| validate_o(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 112; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -745,14 +685,10 @@ static FLATTEN bool validate_Ropen(struct _validate_ctx *ctx) {
|| validate_tag(ctx)
|| validate_qid(ctx)
|| validate_4(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 113; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -768,14 +704,10 @@ static FLATTEN bool validate_Tcreate(struct _validate_ctx *ctx) {
|| validate_s(ctx)
|| validate_dm(ctx)
|| validate_o(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 114; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -789,14 +721,10 @@ static FLATTEN bool validate_Rcreate(struct _validate_ctx *ctx) {
|| validate_tag(ctx)
|| validate_qid(ctx)
|| validate_4(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 115; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -811,14 +739,10 @@ static FLATTEN bool validate_Tread(struct _validate_ctx *ctx) {
|| validate_fid(ctx)
|| validate_8(ctx)
|| validate_4(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 116; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -831,14 +755,10 @@ static FLATTEN bool validate_Rread(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_d(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 117; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -853,14 +773,10 @@ static FLATTEN bool validate_Twrite(struct _validate_ctx *ctx) {
|| validate_fid(ctx)
|| validate_8(ctx)
|| validate_d(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 118; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -873,14 +789,10 @@ static FLATTEN bool validate_Rwrite(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_4(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 119; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -893,14 +805,10 @@ static FLATTEN bool validate_Tclunk(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_fid(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 120; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -912,14 +820,10 @@ static FLATTEN bool validate_Rclunk(struct _validate_ctx *ctx) {
|| (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]); false; }))
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 121; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -932,14 +836,10 @@ static FLATTEN bool validate_Tremove(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_fid(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 122; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -951,14 +851,10 @@ static FLATTEN bool validate_Rremove(struct _validate_ctx *ctx) {
|| (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]); false; }))
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 123; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -971,14 +867,10 @@ static FLATTEN bool validate_Tstat(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_fid(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 124; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -994,18 +886,12 @@ static FLATTEN bool validate_Rstat(struct _validate_ctx *ctx) {
|| validate_tag(ctx)
|| (validate_2(ctx) || ({ nstat = decode_u16le(&ctx->net_bytes[ctx->net_offset-2]); false; }))
|| ({ _stat_offset = ctx->net_offset; validate_stat(ctx); })
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 125; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
|| ({ uint32_t exp = ctx->net_offset - _stat_offset; (((uint32_t)nstat) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nstat value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)nstat, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nstat value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)nstat, exp); })
;
}
@@ -1022,18 +908,12 @@ static FLATTEN bool validate_Twstat(struct _validate_ctx *ctx) {
|| validate_fid(ctx)
|| (validate_2(ctx) || ({ nstat = decode_u16le(&ctx->net_bytes[ctx->net_offset-2]); false; }))
|| ({ _stat_offset = ctx->net_offset; validate_stat(ctx); })
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 126; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
|| ({ uint32_t exp = ctx->net_offset - _stat_offset; (((uint32_t)nstat) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nstat value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)nstat, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "nstat value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)nstat, exp); })
;
}
@@ -1045,14 +925,10 @@ static FLATTEN bool validate_Rwstat(struct _validate_ctx *ctx) {
|| (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]); false; }))
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 127; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -1067,14 +943,10 @@ static FLATTEN bool validate_Tsession(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_8(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 150; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -1086,14 +958,10 @@ static FLATTEN bool validate_Rsession(struct _validate_ctx *ctx) {
|| (({ _size_offset = ctx->net_offset; validate_4(ctx); }) || ({ size = decode_u32le(&ctx->net_bytes[ctx->net_offset-4]); false; }))
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 151; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -1108,14 +976,10 @@ static FLATTEN bool validate_Tsread(struct _validate_ctx *ctx) {
|| validate_4(ctx)
|| validate_2(ctx)
|| _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_s, sizeof(struct lib9p_s))
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 152; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -1128,14 +992,10 @@ static FLATTEN bool validate_Rsread(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_d(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 153; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -1151,14 +1011,10 @@ static FLATTEN bool validate_Tswrite(struct _validate_ctx *ctx) {
|| validate_2(ctx)
|| _validate_list(ctx, decode_u16le(&ctx->net_bytes[ctx->net_offset-2]), validate_s, sizeof(struct lib9p_s))
|| validate_d(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
-
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
|| ({ uint32_t exp = 154; (((uint32_t)typ) != exp) &&
-
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
;
}
@@ -1171,14 +1027,1133 @@ static FLATTEN bool validate_Rswrite(struct _validate_ctx *ctx) {
|| (validate_1(ctx) || ({ typ = decode_u8le(&ctx->net_bytes[ctx->net_offset-1]); false; }))
|| validate_tag(ctx)
|| validate_4(ctx)
-
|| ({ uint32_t exp = ctx->net_offset - _size_offset; (((uint32_t)size) != exp) &&
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
+ || ({ uint32_t exp = 155; (((uint32_t)typ) != exp) &&
+ lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+ ;
+}
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_e) */
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "size value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)size, exp); })
+/* unmarshal_* ****************************************************************/
- || ({ uint32_t exp = 155; (((uint32_t)typ) != exp) &&
+static ALWAYS_INLINE void unmarshal_1(struct _unmarshal_ctx *ctx, uint8_t *out) {
+ *out = decode_u8le(&ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 1;
+}
+
+static ALWAYS_INLINE void unmarshal_2(struct _unmarshal_ctx *ctx, uint16_t *out) {
+ *out = decode_u16le(&ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 2;
+}
+
+static ALWAYS_INLINE void unmarshal_4(struct _unmarshal_ctx *ctx, uint32_t *out) {
+ *out = decode_u32le(&ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 4;
+}
+
+static ALWAYS_INLINE void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *out) {
+ *out = decode_u64le(&ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 8;
+}
+
+#if defined(CONFIG_9P_ENABLE_9P2000) || defined(CONFIG_9P_ENABLE_9P2000_e) || defined(CONFIG_9P_ENABLE_9P2000_u)
+static ALWAYS_INLINE void unmarshal_tag(struct _unmarshal_ctx *ctx, lib9p_tag_t *out) {
+ unmarshal_2(ctx, (uint16_t *)out);
+}
+
+static ALWAYS_INLINE void unmarshal_fid(struct _unmarshal_ctx *ctx, lib9p_fid_t *out) {
+ unmarshal_4(ctx, (uint32_t *)out);
+}
+
+static ALWAYS_INLINE void unmarshal_d(struct _unmarshal_ctx *ctx, struct lib9p_d *out) {
+ memset(out, 0, sizeof(*out));
+ unmarshal_4(ctx, &out->len);
+ out->dat = ctx->extra;
+ ctx->extra += sizeof(out->dat[0]) * out->len;
+ for (typeof(out->len) i = 0; i < out->len; i++)
+ unmarshal_1(ctx, (uint8_t *)&out->dat[i]);
+}
+
+static ALWAYS_INLINE void unmarshal_s(struct _unmarshal_ctx *ctx, struct lib9p_s *out) {
+ memset(out, 0, sizeof(*out));
+ unmarshal_2(ctx, &out->len);
+ out->utf8 = ctx->extra;
+ ctx->extra += sizeof(out->utf8[0]) * out->len;
+ for (typeof(out->len) i = 0; i < out->len; i++)
+ unmarshal_1(ctx, (uint8_t *)&out->utf8[i]);
+ ctx->extra++;
+ out->utf8[out->len] = '\0';
+}
+
+static ALWAYS_INLINE void unmarshal_dm(struct _unmarshal_ctx *ctx, lib9p_dm_t *out) {
+ unmarshal_4(ctx, (uint32_t *)out);
+}
+
+static ALWAYS_INLINE void unmarshal_qt(struct _unmarshal_ctx *ctx, lib9p_qt_t *out) {
+ unmarshal_1(ctx, (uint8_t *)out);
+}
+
+static ALWAYS_INLINE void unmarshal_qid(struct _unmarshal_ctx *ctx, struct lib9p_qid *out) {
+ memset(out, 0, sizeof(*out));
+ unmarshal_qt(ctx, &out->type);
+ unmarshal_4(ctx, &out->vers);
+ unmarshal_8(ctx, &out->path);
+}
+
+static ALWAYS_INLINE void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9p_stat *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 2;
+ unmarshal_2(ctx, &out->kern_type);
+ unmarshal_4(ctx, &out->kern_dev);
+ unmarshal_qid(ctx, &out->file_qid);
+ unmarshal_dm(ctx, &out->file_mode);
+ unmarshal_4(ctx, &out->file_atime);
+ unmarshal_4(ctx, &out->file_mtime);
+ unmarshal_8(ctx, &out->file_size);
+ unmarshal_s(ctx, &out->file_name);
+ unmarshal_s(ctx, &out->file_owner_uid);
+ unmarshal_s(ctx, &out->file_owner_gid);
+ unmarshal_s(ctx, &out->file_last_modified_uid);
+#if defined(CONFIG_9P_ENABLE_9P2000_u)
+ if ( (ctx->ctx->version==LIB9P_VER_9P2000_u) ) unmarshal_s(ctx, &out->file_extension);
+ if ( (ctx->ctx->version==LIB9P_VER_9P2000_u) ) unmarshal_4(ctx, &out->file_owner_n_uid);
+ if ( (ctx->ctx->version==LIB9P_VER_9P2000_u) ) unmarshal_4(ctx, &out->file_owner_n_gid);
+ if ( (ctx->ctx->version==LIB9P_VER_9P2000_u) ) unmarshal_4(ctx, &out->file_last_modified_n_uid);
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
+}
+
+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));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_4(ctx, &out->max_msg_size);
+ unmarshal_s(ctx, &out->version);
+}
+
+static FLATTEN void unmarshal_Rversion(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rversion *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_4(ctx, &out->max_msg_size);
+ unmarshal_s(ctx, &out->version);
+}
+
+static FLATTEN void unmarshal_Tauth(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tauth *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->afid);
+ unmarshal_s(ctx, &out->uname);
+ unmarshal_s(ctx, &out->aname);
+#if defined(CONFIG_9P_ENABLE_9P2000_u)
+ if ( (ctx->ctx->version==LIB9P_VER_9P2000_u) ) unmarshal_4(ctx, &out->n_uname);
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
+}
+
+static FLATTEN void unmarshal_Rauth(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rauth *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_qid(ctx, &out->aqid);
+}
+
+static FLATTEN void unmarshal_Tattach(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tattach *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->fid);
+ unmarshal_fid(ctx, &out->afid);
+ unmarshal_s(ctx, &out->uname);
+ unmarshal_s(ctx, &out->aname);
+#if defined(CONFIG_9P_ENABLE_9P2000_u)
+ if ( (ctx->ctx->version==LIB9P_VER_9P2000_u) ) unmarshal_4(ctx, &out->n_uname);
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
+}
+
+static FLATTEN void unmarshal_Rattach(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rattach *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_qid(ctx, &out->qid);
+}
+
+static FLATTEN void unmarshal_Rerror(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rerror *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_s(ctx, &out->ename);
+#if defined(CONFIG_9P_ENABLE_9P2000_u)
+ if ( (ctx->ctx->version==LIB9P_VER_9P2000_u) ) unmarshal_4(ctx, &out->errno);
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
+}
+
+static FLATTEN void unmarshal_Tflush(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tflush *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_2(ctx, &out->oldtag);
+}
+
+static FLATTEN void unmarshal_Rflush(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rflush *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+}
+
+static FLATTEN void unmarshal_Twalk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twalk *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->fid);
+ unmarshal_fid(ctx, &out->newfid);
+ unmarshal_2(ctx, &out->nwname);
+ out->wname = ctx->extra;
+ ctx->extra += sizeof(out->wname[0]) * out->nwname;
+ for (typeof(out->nwname) i = 0; i < out->nwname; i++)
+ unmarshal_s(ctx, &out->wname[i]);
+}
+
+static FLATTEN void unmarshal_Rwalk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwalk *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_2(ctx, &out->nwqid);
+ out->wqid = ctx->extra;
+ ctx->extra += sizeof(out->wqid[0]) * out->nwqid;
+ for (typeof(out->nwqid) i = 0; i < out->nwqid; i++)
+ unmarshal_qid(ctx, &out->wqid[i]);
+}
+
+static FLATTEN void unmarshal_Topen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Topen *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->fid);
+ unmarshal_o(ctx, &out->mode);
+}
+
+static FLATTEN void unmarshal_Ropen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Ropen *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_qid(ctx, &out->qid);
+ unmarshal_4(ctx, &out->iounit);
+}
+
+static FLATTEN void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tcreate *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->fid);
+ unmarshal_s(ctx, &out->name);
+ unmarshal_dm(ctx, &out->perm);
+ unmarshal_o(ctx, &out->mode);
+}
+
+static FLATTEN void unmarshal_Rcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rcreate *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_qid(ctx, &out->qid);
+ unmarshal_4(ctx, &out->iounit);
+}
+
+static FLATTEN void unmarshal_Tread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tread *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->fid);
+ unmarshal_8(ctx, &out->offset);
+ unmarshal_4(ctx, &out->count);
+}
+
+static FLATTEN void unmarshal_Rread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rread *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_d(ctx, &out->data);
+}
+
+static FLATTEN void unmarshal_Twrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twrite *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->fid);
+ unmarshal_8(ctx, &out->offset);
+ unmarshal_d(ctx, &out->data);
+}
+
+static FLATTEN void unmarshal_Rwrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwrite *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_4(ctx, &out->count);
+}
+
+static FLATTEN void unmarshal_Tclunk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tclunk *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->fid);
+}
+
+static FLATTEN void unmarshal_Rclunk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rclunk *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+}
+
+static FLATTEN void unmarshal_Tremove(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tremove *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->fid);
+}
+
+static FLATTEN void unmarshal_Rremove(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rremove *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+}
- lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "typ value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t)typ, exp); })
+static FLATTEN void unmarshal_Tstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tstat *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->fid);
+}
+
+static FLATTEN void unmarshal_Rstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rstat *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ ctx->net_offset += 2;
+ unmarshal_stat(ctx, &out->stat);
+}
+
+static FLATTEN void unmarshal_Twstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twstat *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_fid(ctx, &out->fid);
+ ctx->net_offset += 2;
+ unmarshal_stat(ctx, &out->stat);
+}
+
+static FLATTEN void unmarshal_Rwstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwstat *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+}
+
+#endif /* defined(CONFIG_9P_ENABLE_9P2000) || defined(CONFIG_9P_ENABLE_9P2000_e) || defined(CONFIG_9P_ENABLE_9P2000_u) */
+#if defined(CONFIG_9P_ENABLE_9P2000_e)
+static FLATTEN void unmarshal_Tsession(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tsession *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_8(ctx, &out->key);
+}
+
+static FLATTEN void unmarshal_Rsession(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rsession *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+}
+
+static FLATTEN void unmarshal_Tsread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tsread *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_4(ctx, &out->fid);
+ unmarshal_2(ctx, &out->nwname);
+ out->wname = ctx->extra;
+ ctx->extra += sizeof(out->wname[0]) * out->nwname;
+ for (typeof(out->nwname) i = 0; i < out->nwname; i++)
+ unmarshal_s(ctx, &out->wname[i]);
+}
+
+static FLATTEN void unmarshal_Rsread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rsread *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_d(ctx, &out->data);
+}
+
+static FLATTEN void unmarshal_Tswrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tswrite *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_4(ctx, &out->fid);
+ unmarshal_2(ctx, &out->nwname);
+ out->wname = ctx->extra;
+ ctx->extra += sizeof(out->wname[0]) * out->nwname;
+ for (typeof(out->nwname) i = 0; i < out->nwname; i++)
+ unmarshal_s(ctx, &out->wname[i]);
+ unmarshal_d(ctx, &out->data);
+}
+
+static FLATTEN void unmarshal_Rswrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rswrite *out) {
+ memset(out, 0, sizeof(*out));
+ ctx->net_offset += 4;
+ ctx->net_offset += 1;
+ unmarshal_tag(ctx, &out->tag);
+ unmarshal_4(ctx, &out->count);
+}
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_e) */
+
+/* marshal_* ******************************************************************/
+
+static ALWAYS_INLINE bool _marshal_too_large(struct _marshal_ctx *ctx) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s too large to marshal into %s limit (limit=%"PRIu32")",
+ (ctx->net_bytes[4] % 2 == 0) ? "T-message" : "R-message",
+ ctx->ctx->version ? "negotiated" : ((ctx->net_bytes[4] % 2 == 0) ? "client" : "server"),
+ ctx->ctx->max_msg_size);
+ return true;
+}
+
+static ALWAYS_INLINE bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) {
+ if (ctx->net_offset + 1 > ctx->ctx->max_msg_size)
+ return _marshal_too_large(ctx);
+ ctx->net_bytes[ctx->net_offset] = *val;
+ ctx->net_offset += 1;
+ return false;
+}
+
+static ALWAYS_INLINE bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) {
+ if (ctx->net_offset + 2 > ctx->ctx->max_msg_size)
+ return _marshal_too_large(ctx);
+ encode_u16le(*val, &ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 2;
+ return false;
+}
+
+static ALWAYS_INLINE bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) {
+ if (ctx->net_offset + 4 > ctx->ctx->max_msg_size)
+ return true;
+ encode_u32le(*val, &ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 4;
+ return false;
+}
+
+static ALWAYS_INLINE bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) {
+ if (ctx->net_offset + 8 > ctx->ctx->max_msg_size)
+ return true;
+ encode_u64le(*val, &ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 8;
+ return false;
+}
+
+#if defined(CONFIG_9P_ENABLE_9P2000) || defined(CONFIG_9P_ENABLE_9P2000_e) || defined(CONFIG_9P_ENABLE_9P2000_u)
+static ALWAYS_INLINE bool marshal_tag(struct _marshal_ctx *ctx, lib9p_tag_t *val) {
+ return marshal_2(ctx, (uint16_t *)val);
+}
+
+static ALWAYS_INLINE bool marshal_fid(struct _marshal_ctx *ctx, lib9p_fid_t *val) {
+ return marshal_4(ctx, (uint32_t *)val);
+}
+
+static ALWAYS_INLINE bool marshal_d(struct _marshal_ctx *ctx, struct lib9p_d *val) {
+ return false
+ || marshal_4(ctx, &val->len)
+ || ({ bool err = false;
+ for (typeof(val->len) i = 0; i < val->len && !err; i++)
+ err = marshal_1(ctx, (uint8_t *)&val->dat[i]);
+ err; })
+ ;
+}
+
+static ALWAYS_INLINE bool marshal_s(struct _marshal_ctx *ctx, struct lib9p_s *val) {
+ return false
+ || marshal_2(ctx, &val->len)
+ || ({ bool err = false;
+ for (typeof(val->len) i = 0; i < val->len && !err; i++)
+ err = marshal_1(ctx, (uint8_t *)&val->utf8[i]);
+ err; })
+ ;
+}
+
+static ALWAYS_INLINE bool marshal_dm(struct _marshal_ctx *ctx, lib9p_dm_t *val) {
+ lib9p_dm_t masked_val = *val & dm_masks[ctx->ctx->version];
+ return marshal_4(ctx, (uint32_t *)&masked_val);
+}
+
+static ALWAYS_INLINE bool marshal_qt(struct _marshal_ctx *ctx, lib9p_qt_t *val) {
+ lib9p_qt_t masked_val = *val & qt_masks[ctx->ctx->version];
+ return marshal_1(ctx, (uint8_t *)&masked_val);
+}
+
+static ALWAYS_INLINE bool marshal_qid(struct _marshal_ctx *ctx, struct lib9p_qid *val) {
+ return false
+ || marshal_qt(ctx, &val->type)
+ || marshal_4(ctx, &val->vers)
+ || marshal_8(ctx, &val->path)
+ ;
+}
+
+static ALWAYS_INLINE bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) {
+ uint32_t _stat_size_offset;
+
+ uint32_t _kern_type_offset; return false
+ || ({ _stat_size_offset = ctx->net_offset; ({ ctx->net_offset += 2; false; }); })
+ || ({ _kern_type_offset = ctx->net_offset; marshal_2(ctx, &val->kern_type); })
+ || marshal_4(ctx, &val->kern_dev)
+ || marshal_qid(ctx, &val->file_qid)
+ || marshal_dm(ctx, &val->file_mode)
+ || marshal_4(ctx, &val->file_atime)
+ || marshal_4(ctx, &val->file_mtime)
+ || marshal_8(ctx, &val->file_size)
+ || marshal_s(ctx, &val->file_name)
+ || marshal_s(ctx, &val->file_owner_uid)
+ || marshal_s(ctx, &val->file_owner_gid)
+ || marshal_s(ctx, &val->file_last_modified_uid)
+#if defined(CONFIG_9P_ENABLE_9P2000_u)
+ || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && marshal_s(ctx, &val->file_extension) )
+ || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && marshal_4(ctx, &val->file_owner_n_uid) )
+ || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && marshal_4(ctx, &val->file_owner_n_gid) )
+ || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && marshal_4(ctx, &val->file_last_modified_n_uid) )
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
+ || ({ encode_u16le(ctx->net_offset - _kern_type_offset, &ctx->net_bytes[_stat_size_offset]); false; })
+ ;
+}
+
+static ALWAYS_INLINE bool marshal_o(struct _marshal_ctx *ctx, lib9p_o_t *val) {
+ lib9p_o_t masked_val = *val & o_masks[ctx->ctx->version];
+ return marshal_1(ctx, (uint8_t *)&masked_val);
+}
+
+static FLATTEN bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_Tversion *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_4(ctx, &val->max_msg_size)
+ || marshal_s(ctx, &val->version)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(100, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rversion(struct _marshal_ctx *ctx, struct lib9p_msg_Rversion *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_4(ctx, &val->max_msg_size)
+ || marshal_s(ctx, &val->version)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(101, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Tauth(struct _marshal_ctx *ctx, struct lib9p_msg_Tauth *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->afid)
+ || marshal_s(ctx, &val->uname)
+ || marshal_s(ctx, &val->aname)
+#if defined(CONFIG_9P_ENABLE_9P2000_u)
+ || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && marshal_4(ctx, &val->n_uname) )
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(102, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rauth(struct _marshal_ctx *ctx, struct lib9p_msg_Rauth *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_qid(ctx, &val->aqid)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(103, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Tattach(struct _marshal_ctx *ctx, struct lib9p_msg_Tattach *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->fid)
+ || marshal_fid(ctx, &val->afid)
+ || marshal_s(ctx, &val->uname)
+ || marshal_s(ctx, &val->aname)
+#if defined(CONFIG_9P_ENABLE_9P2000_u)
+ || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && marshal_4(ctx, &val->n_uname) )
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(104, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rattach(struct _marshal_ctx *ctx, struct lib9p_msg_Rattach *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_qid(ctx, &val->qid)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(105, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rerror *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_s(ctx, &val->ename)
+#if defined(CONFIG_9P_ENABLE_9P2000_u)
+ || ( (ctx->ctx->version==LIB9P_VER_9P2000_u) && marshal_4(ctx, &val->errno) )
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(107, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Tflush(struct _marshal_ctx *ctx, struct lib9p_msg_Tflush *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_2(ctx, &val->oldtag)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(108, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rflush(struct _marshal_ctx *ctx, struct lib9p_msg_Rflush *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(109, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Twalk(struct _marshal_ctx *ctx, struct lib9p_msg_Twalk *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->fid)
+ || marshal_fid(ctx, &val->newfid)
+ || marshal_2(ctx, &val->nwname)
+ || ({ bool err = false;
+ for (typeof(val->nwname) i = 0; i < val->nwname && !err; i++)
+ err = marshal_s(ctx, &val->wname[i]);
+ err; })
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(110, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwalk *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_2(ctx, &val->nwqid)
+ || ({ bool err = false;
+ for (typeof(val->nwqid) i = 0; i < val->nwqid && !err; i++)
+ err = marshal_qid(ctx, &val->wqid[i]);
+ err; })
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(111, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Topen *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->fid)
+ || marshal_o(ctx, &val->mode)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(112, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Ropen *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_qid(ctx, &val->qid)
+ || marshal_4(ctx, &val->iounit)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(113, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tcreate *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->fid)
+ || marshal_s(ctx, &val->name)
+ || marshal_dm(ctx, &val->perm)
+ || marshal_o(ctx, &val->mode)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(114, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_qid(ctx, &val->qid)
+ || marshal_4(ctx, &val->iounit)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(115, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Tread(struct _marshal_ctx *ctx, struct lib9p_msg_Tread *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->fid)
+ || marshal_8(ctx, &val->offset)
+ || marshal_4(ctx, &val->count)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(116, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rread(struct _marshal_ctx *ctx, struct lib9p_msg_Rread *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_d(ctx, &val->data)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(117, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Twrite(struct _marshal_ctx *ctx, struct lib9p_msg_Twrite *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->fid)
+ || marshal_8(ctx, &val->offset)
+ || marshal_d(ctx, &val->data)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(118, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rwrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rwrite *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_4(ctx, &val->count)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(119, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Tclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Tclunk *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->fid)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(120, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Rclunk *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(121, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Tremove(struct _marshal_ctx *ctx, struct lib9p_msg_Tremove *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->fid)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(122, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rremove(struct _marshal_ctx *ctx, struct lib9p_msg_Rremove *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(123, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Tstat(struct _marshal_ctx *ctx, struct lib9p_msg_Tstat *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->fid)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(124, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rstat *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ uint32_t _nstat_offset;
+
+ uint32_t _stat_offset; return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || ({ _nstat_offset = ctx->net_offset; ({ ctx->net_offset += 2; false; }); })
+ || ({ _stat_offset = ctx->net_offset; marshal_stat(ctx, &val->stat); })
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(125, &ctx->net_bytes[_typ_offset]); false; })
+ || ({ encode_u16le(ctx->net_offset - _stat_offset, &ctx->net_bytes[_nstat_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Twstat(struct _marshal_ctx *ctx, struct lib9p_msg_Twstat *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ uint32_t _nstat_offset;
+
+ uint32_t _stat_offset; return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_fid(ctx, &val->fid)
+ || ({ _nstat_offset = ctx->net_offset; ({ ctx->net_offset += 2; false; }); })
+ || ({ _stat_offset = ctx->net_offset; marshal_stat(ctx, &val->stat); })
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(126, &ctx->net_bytes[_typ_offset]); false; })
+ || ({ encode_u16le(ctx->net_offset - _stat_offset, &ctx->net_bytes[_nstat_offset]); false; })
;
}
+
+static FLATTEN bool marshal_Rwstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rwstat *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(127, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+#endif /* defined(CONFIG_9P_ENABLE_9P2000) || defined(CONFIG_9P_ENABLE_9P2000_e) || defined(CONFIG_9P_ENABLE_9P2000_u) */
+#if defined(CONFIG_9P_ENABLE_9P2000_e)
+static FLATTEN bool marshal_Tsession(struct _marshal_ctx *ctx, struct lib9p_msg_Tsession *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_8(ctx, &val->key)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(150, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rsession(struct _marshal_ctx *ctx, struct lib9p_msg_Rsession *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(151, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Tsread(struct _marshal_ctx *ctx, struct lib9p_msg_Tsread *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_4(ctx, &val->fid)
+ || marshal_2(ctx, &val->nwname)
+ || ({ bool err = false;
+ for (typeof(val->nwname) i = 0; i < val->nwname && !err; i++)
+ err = marshal_s(ctx, &val->wname[i]);
+ err; })
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(152, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rsread(struct _marshal_ctx *ctx, struct lib9p_msg_Rsread *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_d(ctx, &val->data)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(153, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Tswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Tswrite *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_4(ctx, &val->fid)
+ || marshal_2(ctx, &val->nwname)
+ || ({ bool err = false;
+ for (typeof(val->nwname) i = 0; i < val->nwname && !err; i++)
+ err = marshal_s(ctx, &val->wname[i]);
+ err; })
+ || marshal_d(ctx, &val->data)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(154, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+static FLATTEN bool marshal_Rswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rswrite *val) {
+ uint32_t _size_offset;
+ uint32_t _typ_offset;
+ return false
+ || ({ _size_offset = ctx->net_offset; ({ ctx->net_offset += 4; false; }); })
+ || ({ _typ_offset = ctx->net_offset; ({ ctx->net_offset += 1; false; }); })
+ || marshal_tag(ctx, &val->tag)
+ || marshal_4(ctx, &val->count)
+ || ({ encode_u32le(ctx->net_offset - _size_offset, &ctx->net_bytes[_size_offset]); false; })
+ || ({ encode_u8le(155, &ctx->net_bytes[_typ_offset]); false; })
+ ;
+}
+
+/* vtables ********************************************************************/
+
+#define _MSG(typ) [LIB9P_TYP_##typ] = { \
+ .basesize = sizeof(struct lib9p_msg_##typ), \
+ .validate = validate_##typ, \
+ .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \
+ .marshal = (_marshal_fn_t)marshal_##typ, \
+ }
+
+struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = {
+ [LIB9P_VER_unknown] = { .msgs = {
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Rerror),
+ }},
#endif /* defined(CONFIG_9P_ENABLE_9P2000_e) */
+#if defined(CONFIG_9P_ENABLE_9P2000)
+ [LIB9P_VER_9P2000] = { .msgs = {
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Tauth),
+ _MSG(Rauth),
+ _MSG(Tattach),
+ _MSG(Rattach),
+ _MSG(Rerror),
+ _MSG(Tflush),
+ _MSG(Rflush),
+ _MSG(Twalk),
+ _MSG(Rwalk),
+ _MSG(Topen),
+ _MSG(Ropen),
+ _MSG(Tcreate),
+ _MSG(Rcreate),
+ _MSG(Tread),
+ _MSG(Rread),
+ _MSG(Twrite),
+ _MSG(Rwrite),
+ _MSG(Tclunk),
+ _MSG(Rclunk),
+ _MSG(Tremove),
+ _MSG(Rremove),
+ _MSG(Tstat),
+ _MSG(Rstat),
+ _MSG(Twstat),
+ _MSG(Rwstat),
+ }},
+#endif /* defined(CONFIG_9P_ENABLE_9P2000) */
+#if defined(CONFIG_9P_ENABLE_9P2000_e)
+ [LIB9P_VER_9P2000_e] = { .msgs = {
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Tauth),
+ _MSG(Rauth),
+ _MSG(Tattach),
+ _MSG(Rattach),
+ _MSG(Rerror),
+ _MSG(Tflush),
+ _MSG(Rflush),
+ _MSG(Twalk),
+ _MSG(Rwalk),
+ _MSG(Topen),
+ _MSG(Ropen),
+ _MSG(Tcreate),
+ _MSG(Rcreate),
+ _MSG(Tread),
+ _MSG(Rread),
+ _MSG(Twrite),
+ _MSG(Rwrite),
+ _MSG(Tclunk),
+ _MSG(Rclunk),
+ _MSG(Tremove),
+ _MSG(Rremove),
+ _MSG(Tstat),
+ _MSG(Rstat),
+ _MSG(Twstat),
+ _MSG(Rwstat),
+ _MSG(Tsession),
+ _MSG(Rsession),
+ _MSG(Tsread),
+ _MSG(Rsread),
+ _MSG(Tswrite),
+ _MSG(Rswrite),
+ }},
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_e) */
+#if defined(CONFIG_9P_ENABLE_9P2000_u)
+ [LIB9P_VER_9P2000_u] = { .msgs = {
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Tauth),
+ _MSG(Rauth),
+ _MSG(Tattach),
+ _MSG(Rattach),
+ _MSG(Rerror),
+ _MSG(Tflush),
+ _MSG(Rflush),
+ _MSG(Twalk),
+ _MSG(Rwalk),
+ _MSG(Topen),
+ _MSG(Ropen),
+ _MSG(Tcreate),
+ _MSG(Rcreate),
+ _MSG(Tread),
+ _MSG(Rread),
+ _MSG(Twrite),
+ _MSG(Rwrite),
+ _MSG(Tclunk),
+ _MSG(Rclunk),
+ _MSG(Tremove),
+ _MSG(Rremove),
+ _MSG(Tstat),
+ _MSG(Rstat),
+ _MSG(Twstat),
+ _MSG(Rwstat),
+ }},
+#endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */
+};
diff --git a/lib9p/idl.gen b/lib9p/idl.gen
index 1f5e48c..8e7639a 100755
--- a/lib9p/idl.gen
+++ b/lib9p/idl.gen
@@ -17,6 +17,7 @@ from typing import Callable, Final, Literal, TypeAlias, TypeVar, cast
# Types ########################################################################
+
class Primitive(enum.Enum):
u8 = 1
u16 = 2
@@ -128,7 +129,7 @@ class StructMember:
# from left-to-right when parsing
cnt: str | None = None
name: str
- typ: 'Type'
+ typ: "Type"
max: Expr
val: Expr
@@ -174,7 +175,7 @@ class Message(Struct):
Type: TypeAlias = Primitive | Number | Bitfield | Struct | Message
-#type Type = Primitive | Number | Bitfield | Struct | Message # Change to this once we have Python 3.13
+# type Type = Primitive | Number | Bitfield | Struct | Message # Change to this once we have Python 3.13
T = TypeVar("T", Number, Bitfield, Struct, Message)
# Parse *.9p ###################################################################
@@ -234,6 +235,8 @@ def parse_expr(expr: str) -> Expr:
ret = Expr()
for tok in re.split("([-+])", expr):
if tok == "-" or tok == "+":
+ # I, for the life of me, do not understand why I need this
+ # cast() to keep mypy happy.
ret.tokens += [ExprOp(cast(Literal["-", "+"], tok))]
elif re.fullmatch("[0-9]+", tok):
ret.tokens += [ExprLit(int(tok))]
@@ -451,8 +454,10 @@ def parse_file(
# Generate C ###################################################################
+idprefix = "lib9p_"
+
-def c_ver_enum(idprefix: str, ver: str) -> str:
+def c_ver_enum(ver: str) -> str:
return f"{idprefix.upper()}VER_{ver.replace('.', '_')}"
@@ -462,15 +467,13 @@ def c_ver_ifdef(versions: set[str]) -> str:
)
-def c_ver_cond(idprefix: str, versions: set[str]) -> str:
+def c_ver_cond(versions: set[str]) -> str:
if len(versions) == 1:
- return f"(ctx->ctx->version=={c_ver_enum(idprefix, next(v for v in versions))})"
- return (
- "( " + (" || ".join(c_ver_cond(idprefix, {v}) for v in sorted(versions))) + " )"
- )
+ return f"(ctx->ctx->version=={c_ver_enum(next(v for v in versions))})"
+ return "( " + (" || ".join(c_ver_cond({v}) for v in sorted(versions))) + " )"
-def c_typename(idprefix: str, typ: Type) -> str:
+def c_typename(typ: Type) -> str:
match typ:
case Primitive():
return f"uint{typ.value*8}_t"
@@ -517,6 +520,7 @@ def ifdef_push(n: int, _newval: str) -> str:
ret += f"#if {newval}\n"
return ret
+
def ifdef_pop(n: int) -> str:
global _ifdef_stack
ret = ""
@@ -527,7 +531,7 @@ def ifdef_pop(n: int) -> str:
return ret
-def gen_h(idprefix: str, versions: set[str], typs: list[Type]) -> str:
+def gen_h(versions: set[str], typs: list[Type]) -> str:
global _ifdef_stack
_ifdef_stack = []
@@ -550,10 +554,10 @@ enum {idprefix}version {{
for ver in fullversions:
if ver in versions:
ret += ifdef_push(1, c_ver_ifdef({ver}))
- ret += f"\t{c_ver_enum(idprefix, ver)},"
+ ret += f"\t{c_ver_enum(ver)},"
ret += (" " * (verwidth - len(ver))) + ' /* "' + ver.split()[0] + '" */\n'
ret += ifdef_pop(0)
- ret += f"\t{c_ver_enum(idprefix, 'NUM')},\n"
+ ret += f"\t{c_ver_enum('NUM')},\n"
ret += "};\n"
ret += "\n"
ret += f"const char *{idprefix}version_str(enum {idprefix}version);\n"
@@ -566,9 +570,9 @@ enum {idprefix}version {{
ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
match typ:
case Number():
- ret += f"typedef {c_typename(idprefix, typ.prim)} {c_typename(idprefix, typ)};\n"
+ ret += f"typedef {c_typename(typ.prim)} {c_typename(typ)};\n"
case Bitfield():
- ret += f"typedef {c_typename(idprefix, typ.prim)} {c_typename(idprefix, typ)};\n"
+ ret += f"typedef {c_typename(typ.prim)} {c_typename(typ)};\n"
names = [
*reversed(
[typ.bits[n] or f" {n}" for n in range(0, len(typ.bits))]
@@ -584,28 +588,36 @@ enum {idprefix}version {{
ret += "\n"
elif name.startswith(" "):
ret += ifdef_push(2, c_ver_ifdef(typ.in_versions))
- sp = ' '*(len('# define ')+len(idprefix)+len(typ.name)+1+namewidth+2-len("/* unused"))
- ret += f"/* unused{sp}(({c_typename(idprefix, typ)})(1<<{name[1:]})) */\n"
+ sp = " " * (
+ len("# define ")
+ + len(idprefix)
+ + len(typ.name)
+ + 1
+ + namewidth
+ + 2
+ - len("/* unused")
+ )
+ ret += f"/* unused{sp}(({c_typename(typ)})(1<<{name[1:]})) */\n"
else:
ret += ifdef_push(2, c_ver_ifdef(typ.names[name].in_versions))
if name.startswith("_"):
c_name = f"_{idprefix.upper()}{typ.name.upper()}_{name[1:]}"
else:
c_name = f"{idprefix.upper()}{typ.name.upper()}_{name}"
- sp1 = ' ' if _ifdef_stack[-1] else ''
- sp2 = ' ' if _ifdef_stack[-1] else ' '
- sp3 = ' '*(2+namewidth-len(name))
- ret += f"#{sp1}define{sp2}{c_name}{sp3}(({c_typename(idprefix, typ)})({typ.names[name].val}))\n"
+ sp1 = " " if _ifdef_stack[-1] else ""
+ sp2 = " " if _ifdef_stack[-1] else " "
+ sp3 = " " * (2 + namewidth - len(name))
+ ret += f"#{sp1}define{sp2}{c_name}{sp3}(({c_typename(typ)})({typ.names[name].val}))\n"
ret += ifdef_pop(1)
case Struct():
- typewidth = max(len(c_typename(idprefix, m.typ)) for m in typ.members)
+ typewidth = max(len(c_typename(m.typ)) for m in typ.members)
- ret += c_typename(idprefix, typ) + " {\n"
+ ret += c_typename(typ) + " {\n"
for member in typ.members:
if member.val:
continue
ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- c_type = c_typename(idprefix, member.typ)
+ c_type = c_typename(member.typ)
if (typ.name in ["d", "s"]) and member.cnt: # SPECIAL
c_type = "char"
ret += f"\t{c_type.ljust(typewidth)} {'*' if member.cnt else ' '}{member.name};\n"
@@ -630,19 +642,19 @@ enum {idprefix}version {{
for msg in [msg for msg in typs if isinstance(msg, Message)]:
ret += "\n"
ret += ifdef_push(1, c_ver_ifdef(msg.in_versions))
- ret += c_typename(idprefix, msg) + " {"
+ ret += c_typename(msg) + " {"
if not msg.members:
ret += "};\n"
continue
ret += "\n"
- typewidth = max(len(c_typename(idprefix, m.typ)) for m in msg.members)
+ typewidth = max(len(c_typename(m.typ)) for m in msg.members)
for member in msg.members:
if member.val:
continue
ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- ret += f"\t{c_typename(idprefix, member.typ).ljust(typewidth)} {'*' if member.cnt else ' '}{member.name};\n"
+ ret += f"\t{c_typename(member.typ).ljust(typewidth)} {'*' if member.cnt else ' '}{member.name};\n"
ret += ifdef_pop(1)
ret += "};\n"
ret += ifdef_pop(0)
@@ -665,7 +677,7 @@ def c_expr(expr: Expr) -> str:
return " ".join(ret)
-def gen_c(idprefix: str, versions: set[str], typs: list[Type]) -> str:
+def gen_c(versions: set[str], typs: list[Type]) -> str:
global _ifdef_stack
_ifdef_stack = []
@@ -692,17 +704,17 @@ def gen_c(idprefix: str, versions: set[str], typs: list[Type]) -> str:
ret += f"""
/* strings ********************************************************************/
-static const char *version_strs[{c_ver_enum(idprefix, 'NUM')}] = {{
+static const char *version_strs[{c_ver_enum('NUM')}] = {{
"""
for ver in ["unknown", *sorted(versions)]:
if ver in versions:
ret += ifdef_push(1, c_ver_ifdef({ver}))
- ret += f'\t[{c_ver_enum(idprefix, ver)}] = "{ver}",\n'
+ ret += f'\t[{c_ver_enum(ver)}] = "{ver}",\n'
ret += ifdef_pop(0)
ret += "};\n"
ret += f"""
const char *{idprefix}version_str(enum {idprefix}version ver) {{
- assert(0 <= ver && ver < {c_ver_enum(idprefix, 'NUM')});
+ assert(0 <= ver && ver < {c_ver_enum('NUM')});
return version_strs[ver];
}}
@@ -764,6 +776,23 @@ static ALWAYS_INLINE bool _validate_list(struct _validate_ctx *ctx,
argfn = unused if (isinstance(typ, Struct) and not typ.members) else used
ret += "\n"
ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
+
+ if isinstance(typ, Bitfield):
+ ret += f"static const {c_typename(typ)} {typ.name}_masks[{c_ver_enum('NUM')}] = {{\n"
+ verwidth = max(len(ver) for ver in versions)
+ for ver in sorted(versions):
+ ret += ifdef_push(2, c_ver_ifdef({ver}))
+ ret += (
+ f"\t[{c_ver_enum(ver)}]{' '*(verwidth-len(ver))} = 0b"
+ + "".join(
+ "1" if typ.bit_is_valid(bitname, ver) else "0"
+ for bitname in reversed(typ.bits)
+ )
+ + ",\n"
+ )
+ ret += ifdef_pop(1)
+ ret += "};\n"
+
ret += f"static {inline} bool validate_{typ.name}(struct _validate_ctx *{argfn('ctx')}) {{\n"
if typ.name == "d": # SPECIAL
@@ -797,28 +826,12 @@ static ALWAYS_INLINE bool _validate_list(struct _validate_ctx *ctx,
case Bitfield():
ret += f"\t if (validate_{typ.static_size}(ctx))\n"
ret += "\t\treturn true;\n"
- ret += f"\tstatic const {c_typename(idprefix, typ)} masks[{c_ver_enum(idprefix, 'NUM')}] = {{\n"
- verwidth = max(len(ver) for ver in versions)
- for ver in sorted(versions):
- ret += ifdef_push(2, c_ver_ifdef({ver}))
- ret += (
- f"\t\t[{c_ver_enum(idprefix, ver)}]{' '*(verwidth-len(ver))} = 0b"
- + "".join(
- "1" if typ.bit_is_valid(bitname, ver) else "0"
- for bitname in reversed(typ.bits)
- )
- + ",\n"
- )
- ret += ifdef_pop(1)
- ret += "\t};\n"
ret += (
- f"\t{c_typename(idprefix, typ)} mask = masks[ctx->ctx->version];\n"
+ f"\t{c_typename(typ)} mask = {typ.name}_masks[ctx->ctx->version];\n"
)
- ret += f"\t{c_typename(idprefix, typ)} val = decode_u{typ.static_size*8}le(&ctx->net_bytes[ctx->net_offset-{typ.static_size}]);\n"
+ ret += f"\t{c_typename(typ)} val = decode_u{typ.static_size*8}le(&ctx->net_bytes[ctx->net_offset-{typ.static_size}]);\n"
ret += f"\tif (val & ~mask)\n"
- ret += "\t\treturn lib9p_errorf(ctx->ctx,\n"
- ret += f'\t\t LINUX_EBADMSG, "unknown bits in {typ.name} bitfield: %#0{typ.static_size}"PRIx{typ.static_size*8},\n'
- ret += "\t\t val & ~mask);\n"
+ ret += f'\t\treturn lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "unknown bits in {typ.name} bitfield: %#0{typ.static_size}"PRIx{typ.static_size*8}, val & ~mask);\n'
ret += "\treturn false;\n"
case Struct(): # and Message()
if len(typ.members) == 0:
@@ -826,14 +839,14 @@ static ALWAYS_INLINE bool _validate_list(struct _validate_ctx *ctx,
ret += "}\n"
continue
- # Pass 1
+ # Pass 1 - declare value variables
for member in typ.members:
if member.max or member.val:
ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- ret += f"\t{c_typename(idprefix, member.typ)} {member.name};\n"
+ ret += f"\t{c_typename(member.typ)} {member.name};\n"
ret += ifdef_pop(1)
- # Pass 2
+ # Pass 2 - declare offset variables
mark_offset: set[str] = set()
for member in typ.members:
for tok in [*member.max.tokens, *member.val.tokens]:
@@ -842,17 +855,17 @@ static ALWAYS_INLINE bool _validate_list(struct _validate_ctx *ctx,
ret += f"\tuint32_t _{tok.name[1:]}_offset;\n"
mark_offset.add(tok.name[1:])
- # Pass 3
+ # Pass 3 - main pass
ret += "\treturn false\n"
prev_size: int | None = None
for member in typ.members:
ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
ret += f"\t || "
if member.in_versions != typ.in_versions:
- ret += "( " + c_ver_cond(idprefix, member.in_versions) + " && "
+ ret += "( " + c_ver_cond(member.in_versions) + " && "
if member.cnt is not None:
assert prev_size
- ret += f"_validate_list(ctx, decode_u{prev_size*8}le(&ctx->net_bytes[ctx->net_offset-{prev_size}]), validate_{member.typ.name}, sizeof({c_typename(idprefix, member.typ)}))"
+ ret += f"_validate_list(ctx, decode_u{prev_size*8}le(&ctx->net_bytes[ctx->net_offset-{prev_size}]), validate_{member.typ.name}, sizeof({c_typename(member.typ)}))"
else:
if member.max or member.val:
ret += "("
@@ -871,252 +884,244 @@ static ALWAYS_INLINE bool _validate_list(struct _validate_ctx *ctx,
ret += "\n"
prev_size = member.static_size
- # Pass 4
+ # Pass 4 - validate ,max= and ,val= constraints
for member in typ.members:
if member.max:
ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- ret += f"\n\t || ({{ uint32_t max = {c_expr(member.max)}; (((uint32_t){member.name}) > max) &&\n"
- ret += f'\n\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value too large (%"PRIu32" > %"PRIu32")", {member.name}, max); }})\n'
+ ret += f"\t || ({{ uint32_t max = {c_expr(member.max)}; (((uint32_t){member.name}) > max) &&\n"
+ ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value is too large (%"PRIu32" > %"PRIu32")", {member.name}, max); }})\n'
if member.val:
ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
- ret += f"\n\t || ({{ uint32_t exp = {c_expr(member.val)}; (((uint32_t){member.name}) != exp) &&\n"
- ret += f'\n\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t){member.name}, exp); }})\n'
+ ret += f"\t || ({{ uint32_t exp = {c_expr(member.val)}; (((uint32_t){member.name}) != exp) &&\n"
+ ret += f'\t lib9p_errorf(ctx->ctx, LINUX_EBADMSG, "{member.name} value is wrong (actual:%"PRIu32" != correct:%"PRIu32")", (uint32_t){member.name}, exp); }})\n'
ret += ifdef_pop(1)
ret += "\t ;\n"
ret += "}\n"
ret += ifdef_pop(0)
- # # unmarshal_* ##############################################################
- # ret += """
- # /* unmarshal_* ****************************************************************/
-
- # static ALWAYS_INLINE void unmarshal_1(struct _unmarshal_ctx *ctx, uint8_t *out) {
- # *out = decode_u8le(&ctx->net_bytes[ctx->net_offset]);
- # ctx->net_offset += 1;
- # }
-
- # static ALWAYS_INLINE void unmarshal_2(struct _unmarshal_ctx *ctx, uint16_t *out) {
- # *out = decode_u16le(&ctx->net_bytes[ctx->net_offset]);
- # ctx->net_offset += 2;
- # }
-
- # static ALWAYS_INLINE void unmarshal_4(struct _unmarshal_ctx *ctx, uint32_t *out) {
- # *out = decode_u32le(&ctx->net_bytes[ctx->net_offset]);
- # ctx->net_offset += 4;
- # }
-
- # static ALWAYS_INLINE void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *out) {
- # *out = decode_u64le(&ctx->net_bytes[ctx->net_offset]);
- # ctx->net_offset += 8;
- # }
- # """
- # for typ in typs:
- # inline = (
- # " FLATTEN"
- # if (isinstance(typ, Struct) and typ.msgid is not None)
- # else " ALWAYS_INLINE"
- # )
- # argfn = unused if (isinstance(typ, Struct) and not typ.members) else used
- # ret += "\n"
- # ret += f"static{inline} void unmarshal_{typ.name}(struct _unmarshal_ctx *{argfn('ctx')}, {c_typename(idprefix, typ)} *out) {{\n"
- # match typ:
- # case Bitfield():
- # ret += f"\tunmarshal_{typ.static_size}(ctx, (uint{typ.static_size*8}_t *)out);\n"
- # case Struct():
- # ret += "\tmemset(out, 0, sizeof(*out));\n"
-
- # if typ.members:
- # struct_versions = typ.members[0].ver
- # for member in typ.members:
- # if member.valexpr:
- # ret += f"\tctx->net_offset += {member.static_size};\n"
- # continue
- # ret += "\t"
- # prefix = "\t"
- # if member.ver != struct_versions:
- # ret += "if ( " + c_ver_cond(idprefix, member.ver) + " ) "
- # prefix = "\t\t"
- # if member.cnt:
- # if member.ver != struct_versions:
- # ret += f"{{\n{prefix}"
- # ret += f"out->{member.name} = ctx->extra;\n"
- # ret += f"{prefix}ctx->extra += sizeof(out->{member.name}[0]) * out->{member.cnt};\n"
- # ret += f"{prefix}for (typeof(out->{member.cnt}) i = 0; i < out->{member.cnt}; i++)\n"
- # if typ.name in ["d", "s"]: # SPECIAL
- # ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, (uint8_t *)&out->{member.name}[i]);\n"
- # else:
- # ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, &out->{member.name}[i]);\n"
- # if member.ver != struct_versions:
- # ret += "\t}\n"
- # else:
- # ret += (
- # f"unmarshal_{member.typ.name}(ctx, &out->{member.name});\n"
- # )
- # if typ.name == "s": # SPECIAL
- # ret += "\tctx->extra++;\n"
- # ret += "\tout->utf8[out->len] = '\\0';\n"
- # ret += "}\n"
-
- # # marshal_* ################################################################
- # ret += """
- # /* marshal_* ******************************************************************/
-
- # static ALWAYS_INLINE bool _marshal_too_large(struct _marshal_ctx *ctx) {
- # lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s too large to marshal into %s limit (limit=%"PRIu32")",
- # (ctx->net_bytes[4] % 2 == 0) ? "T-message" : "R-message",
- # ctx->ctx->version ? "negotiated" : ((ctx->net_bytes[4] % 2 == 0) ? "client" : "server"),
- # ctx->ctx->max_msg_size);
- # return true;
- # }
-
- # static ALWAYS_INLINE bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) {
- # if (ctx->net_offset + 1 > ctx->ctx->max_msg_size)
- # return _marshal_too_large(ctx);
- # ctx->net_bytes[ctx->net_offset] = *val;
- # ctx->net_offset += 1;
- # return false;
- # }
-
- # static ALWAYS_INLINE bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) {
- # if (ctx->net_offset + 2 > ctx->ctx->max_msg_size)
- # return _marshal_too_large(ctx);
- # encode_u16le(*val, &ctx->net_bytes[ctx->net_offset]);
- # ctx->net_offset += 2;
- # return false;
- # }
-
- # static ALWAYS_INLINE bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) {
- # if (ctx->net_offset + 4 > ctx->ctx->max_msg_size)
- # return true;
- # encode_u32le(*val, &ctx->net_bytes[ctx->net_offset]);
- # ctx->net_offset += 4;
- # return false;
- # }
-
- # static ALWAYS_INLINE bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) {
- # if (ctx->net_offset + 8 > ctx->ctx->max_msg_size)
- # return true;
- # encode_u64le(*val, &ctx->net_bytes[ctx->net_offset]);
- # ctx->net_offset += 8;
- # return false;
- # }
- # """
- # for typ in typs:
- # inline = (
- # " FLATTEN"
- # if (isinstance(typ, Struct) and typ.msgid is not None)
- # else " ALWAYS_INLINE"
- # )
- # argfn = unused if (isinstance(typ, Struct) and not typ.members) else used
- # ret += "\n"
- # ret += f"static{inline} bool marshal_{typ.name}(struct _marshal_ctx *{argfn('ctx')}, {c_typename(idprefix, typ)} *{argfn('val')}) {{"
- # match typ:
- # case Bitfield():
- # ret += "\n"
- # ret += f"\treturn marshal_{typ.static_size}(ctx, (uint{typ.static_size*8}_t *)val);\n"
- # case Struct():
- # if len(typ.members) == 0:
- # ret += "\n\treturn false;\n"
- # ret += "}\n"
- # continue
-
- # mark_offset = set()
- # for member in typ.members:
- # if member.valexpr:
- # if member.name not in mark_offset:
- # ret += f"\n\tuint32_t _{member.name}_offset;"
- # mark_offset.add(member.name)
- # for tok in member.valexpr:
- # if (
- # isinstance(tok, ExprVal)
- # and tok.name.startswith("&")
- # and tok.name[1:] not in mark_offset
- # ):
- # ret += f"\n\tuint32_t _{tok.name[1:]}_offset;"
- # mark_offset.add(tok.name[1:])
-
- # prefix0 = "\treturn "
- # prefix1 = "\t || "
- # prefix2 = "\t "
-
- # struct_versions = typ.members[0].ver
- # prefix = prefix0
- # for member in typ.members:
- # ret += f"\n{prefix}"
- # if member.ver != struct_versions:
- # ret += "( " + c_ver_cond(idprefix, member.ver) + " && "
- # if member.name in mark_offset:
- # ret += f"({{ _{member.name}_offset = ctx->net_offset; "
- # if member.cnt:
- # ret += "({"
- # ret += f"\n{prefix2}\tbool err = false;"
- # ret += f"\n{prefix2}\tfor (typeof(val->{member.cnt}) i = 0; i < val->{member.cnt} && !err; i++)"
- # if typ.name in ["d", "s"]: # SPECIAL
- # ret += f"\n{prefix2}\t\terr = marshal_{member.typ.name}(ctx, (uint8_t *)&val->{member.name}[i]);"
- # else:
- # ret += f"\n{prefix2}\t\terr = marshal_{member.typ.name}(ctx, &val->{member.name}[i]);"
- # ret += f"\n{prefix2}\terr;"
- # ret += f"\n{prefix2}}})"
- # elif member.valexpr:
- # assert member.static_size
- # ret += (
- # f"({{ ctx->net_offset += {member.static_size}; false; }})"
- # )
- # else:
- # ret += f"marshal_{member.typ.name}(ctx, &val->{member.name})"
- # if member.name in mark_offset:
- # ret += "; })"
- # if member.ver != struct_versions:
- # ret += " )"
- # prefix = prefix1
-
- # for member in typ.members:
- # if member.valexpr:
- # assert member.static_size
- # ret += f"\n{prefix}"
- # ret += f"({{ encode_u{member.static_size*8}le("
- # for tok in member.valexpr:
- # match tok:
- # case ExprOp():
- # ret += f" {tok.op}"
- # case ExprVal(name="end"):
- # ret += " ctx->net_offset"
- # case ExprVal():
- # ret += f" _{tok.name[1:]}_offset"
- # ret += f", &ctx->net_bytes[_{member.name}_offset]); false; }})"
-
- # ret += ";\n"
- # ret += "}\n"
-
- # # vtables ##################################################################
- # ret += f"""
- # /* vtables ********************************************************************/
-
- # #define _MSG(typ) [{idprefix.upper()}TYP_##typ] = {{ \\
- # .basesize = sizeof(struct {idprefix}msg_##typ), \\
- # .validate = validate_##typ, \\
- # .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \\
- # .marshal = (_marshal_fn_t)marshal_##typ, \\
- # }}
-
- # struct _vtable_version _{idprefix}vtables[{c_ver_enum(idprefix, 'NUM')}] = {{
- # """
-
- # ret += f"\t[{c_ver_enum(idprefix, 'unknown')}] = {{ .msgs = {{\n"
- # for msg in just_structs_msg(typs):
- # if msg.name in ["Tversion", "Rversion", "Rerror"]: # SPECIAL
- # ret += f"\t\t_MSG({msg.name}),\n"
- # ret += "\t}},\n"
-
- # for ver in sorted(versions):
- # ret += f"\t[{c_ver_enum(idprefix, ver)}] = {{ .msgs = {{\n"
- # for msg in just_structs_msg(typs):
- # if ver not in msg.msgver:
- # continue
- # ret += f"\t\t_MSG({msg.name}),\n"
- # ret += "\t}},\n"
- # ret += "};\n"
+ # unmarshal_* ##############################################################
+ ret += """
+/* unmarshal_* ****************************************************************/
+
+static ALWAYS_INLINE void unmarshal_1(struct _unmarshal_ctx *ctx, uint8_t *out) {
+ *out = decode_u8le(&ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 1;
+}
+
+static ALWAYS_INLINE void unmarshal_2(struct _unmarshal_ctx *ctx, uint16_t *out) {
+ *out = decode_u16le(&ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 2;
+}
+
+static ALWAYS_INLINE void unmarshal_4(struct _unmarshal_ctx *ctx, uint32_t *out) {
+ *out = decode_u32le(&ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 4;
+}
+
+static ALWAYS_INLINE void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *out) {
+ *out = decode_u64le(&ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 8;
+}
+"""
+ for typ in typs:
+ inline = "FLATTEN" if isinstance(typ, Message) else "ALWAYS_INLINE"
+ argfn = unused if (isinstance(typ, Struct) and not typ.members) else used
+ ret += "\n"
+ ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
+ ret += f"static {inline} void unmarshal_{typ.name}(struct _unmarshal_ctx *{argfn('ctx')}, {c_typename(typ)} *out) {{\n"
+ match typ:
+ case Number():
+ ret += f"\tunmarshal_{typ.prim.name}(ctx, ({c_typename(typ.prim)} *)out);\n"
+ case Bitfield():
+ ret += f"\tunmarshal_{typ.prim.name}(ctx, ({c_typename(typ.prim)} *)out);\n"
+ case Struct():
+ ret += "\tmemset(out, 0, sizeof(*out));\n"
+
+ for member in typ.members:
+ ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
+ if member.val:
+ ret += f"\tctx->net_offset += {member.static_size};\n"
+ continue
+ ret += "\t"
+
+ prefix = "\t"
+ if member.in_versions != typ.in_versions:
+ ret += "if ( " + c_ver_cond(member.in_versions) + " ) "
+ prefix = "\t\t"
+ if member.cnt:
+ if member.in_versions != typ.in_versions:
+ ret += "{\n"
+ ret += prefix
+ ret += f"out->{member.name} = ctx->extra;\n"
+ ret += f"{prefix}ctx->extra += sizeof(out->{member.name}[0]) * out->{member.cnt};\n"
+ ret += f"{prefix}for (typeof(out->{member.cnt}) i = 0; i < out->{member.cnt}; i++)\n"
+ if typ.name in ["d", "s"]: # SPECIAL
+ ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, (uint8_t *)&out->{member.name}[i]);\n"
+ else:
+ ret += f"{prefix}\tunmarshal_{member.typ.name}(ctx, &out->{member.name}[i]);\n"
+ if member.in_versions != typ.in_versions:
+ ret += "\t}\n"
+ else:
+ ret += (
+ f"unmarshal_{member.typ.name}(ctx, &out->{member.name});\n"
+ )
+ if typ.name == "s": # SPECIAL
+ ret += "\tctx->extra++;\n"
+ ret += "\tout->utf8[out->len] = '\\0';\n"
+ ret += ifdef_pop(1)
+ ret += "}\n"
+ ret += ifdef_pop(0)
+
+ # marshal_* ################################################################
+ ret += """
+/* marshal_* ******************************************************************/
+
+static ALWAYS_INLINE bool _marshal_too_large(struct _marshal_ctx *ctx) {
+ lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s too large to marshal into %s limit (limit=%"PRIu32")",
+ (ctx->net_bytes[4] % 2 == 0) ? "T-message" : "R-message",
+ ctx->ctx->version ? "negotiated" : ((ctx->net_bytes[4] % 2 == 0) ? "client" : "server"),
+ ctx->ctx->max_msg_size);
+ return true;
+}
+
+static ALWAYS_INLINE bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) {
+ if (ctx->net_offset + 1 > ctx->ctx->max_msg_size)
+ return _marshal_too_large(ctx);
+ ctx->net_bytes[ctx->net_offset] = *val;
+ ctx->net_offset += 1;
+ return false;
+}
+
+static ALWAYS_INLINE bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) {
+ if (ctx->net_offset + 2 > ctx->ctx->max_msg_size)
+ return _marshal_too_large(ctx);
+ encode_u16le(*val, &ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 2;
+ return false;
+}
+
+static ALWAYS_INLINE bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) {
+ if (ctx->net_offset + 4 > ctx->ctx->max_msg_size)
+ return true;
+ encode_u32le(*val, &ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 4;
+ return false;
+}
+
+static ALWAYS_INLINE bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) {
+ if (ctx->net_offset + 8 > ctx->ctx->max_msg_size)
+ return true;
+ encode_u64le(*val, &ctx->net_bytes[ctx->net_offset]);
+ ctx->net_offset += 8;
+ return false;
+}
+"""
+ for typ in typs:
+ inline = "FLATTEN" if isinstance(typ, Message) else "ALWAYS_INLINE"
+ argfn = unused if (isinstance(typ, Struct) and not typ.members) else used
+ ret += "\n"
+ ret += ifdef_push(1, c_ver_ifdef(typ.in_versions))
+ ret += f"static {inline} bool marshal_{typ.name}(struct _marshal_ctx *{argfn('ctx')}, {c_typename(typ)} *{argfn('val')}) {{\n"
+ match typ:
+ case Number():
+ ret += f"\treturn marshal_{typ.prim.name}(ctx, ({c_typename(typ.prim)} *)val);\n"
+ case Bitfield():
+ ret += f"\t{c_typename(typ)} masked_val = *val & {typ.name}_masks[ctx->ctx->version];\n"
+ ret += f"\treturn marshal_{typ.prim.name}(ctx, ({c_typename(typ.prim)} *)&masked_val);\n"
+ case Struct():
+ if len(typ.members) == 0:
+ ret += "\treturn false;\n"
+ ret += "}\n"
+ continue
+
+ # Pass 1 - declare offset variables
+ mark_offset = set()
+ for member in typ.members:
+ if member.val:
+ if member.name not in mark_offset:
+ ret += f"\tuint32_t _{member.name}_offset;\n"
+ mark_offset.add(member.name)
+ for tok in member.val.tokens:
+ if isinstance(tok, ExprSym) and tok.name.startswith("&"):
+ if tok.name[1:] not in mark_offset:
+ ret += f"\n\tuint32_t _{tok.name[1:]}_offset;"
+ mark_offset.add(tok.name[1:])
+
+ # Pass 2 - main pass
+ ret += "\treturn false\n"
+ for member in typ.members:
+ ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
+ ret += "\t || "
+ if member.in_versions != typ.in_versions:
+ ret += "( " + c_ver_cond(member.in_versions) + " && "
+ if member.name in mark_offset:
+ ret += f"({{ _{member.name}_offset = ctx->net_offset; "
+ if member.cnt:
+ ret += "({ bool err = false;\n"
+ ret += f"\t for (typeof(val->{member.cnt}) i = 0; i < val->{member.cnt} && !err; i++)\n"
+ ret += "\t \terr = "
+ if typ.name in ["d", "s"]: # SPECIAL
+ # Special-case is that we cast from `char` to `uint8_t`.
+ ret += f"marshal_{member.typ.name}(ctx, (uint8_t *)&val->{member.name}[i]);\n"
+ else:
+ ret += f"marshal_{member.typ.name}(ctx, &val->{member.name}[i]);\n"
+ ret += f"\t err; }})"
+ elif member.val:
+ # Just increment net_offset, don't actually marsha anything (yet).
+ assert member.static_size
+ ret += (
+ f"({{ ctx->net_offset += {member.static_size}; false; }})"
+ )
+ else:
+ ret += f"marshal_{member.typ.name}(ctx, &val->{member.name})"
+ if member.name in mark_offset:
+ ret += "; })"
+ if member.in_versions != typ.in_versions:
+ ret += " )"
+ ret += "\n"
+
+ # Pass 3 - marshal ,val= members
+ for member in typ.members:
+ if member.val:
+ assert member.static_size
+ ret += ifdef_push(2, c_ver_ifdef(member.in_versions))
+ ret += f"\t || ({{ encode_u{member.static_size*8}le({c_expr(member.val)}, &ctx->net_bytes[_{member.name}_offset]); false; }})\n"
+
+ ret += ifdef_pop(1)
+ ret += "\t ;\n"
+ ret += "}\n"
+
+ # vtables ##################################################################
+ ret += f"""
+/* vtables ********************************************************************/
+
+#define _MSG(typ) [{idprefix.upper()}TYP_##typ] = {{ \\
+ .basesize = sizeof(struct {idprefix}msg_##typ), \\
+ .validate = validate_##typ, \\
+ .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \\
+ .marshal = (_marshal_fn_t)marshal_##typ, \\
+ }}
+
+struct _vtable_version _{idprefix}vtables[{c_ver_enum('NUM')}] = {{
+"""
+
+ ret += f"\t[{c_ver_enum('unknown')}] = {{ .msgs = {{\n"
+ for msg in [msg for msg in typs if isinstance(msg, Message)]:
+ if msg.name in ["Tversion", "Rversion", "Rerror"]: # SPECIAL
+ ret += f"\t\t_MSG({msg.name}),\n"
+ ret += "\t}},\n"
+
+ for ver in sorted(versions):
+ ret += ifdef_push(1, c_ver_ifdef({ver}))
+ ret += f"\t[{c_ver_enum(ver)}] = {{ .msgs = {{\n"
+ for msg in [msg for msg in typs if isinstance(msg, Message)]:
+ if ver not in msg.in_versions:
+ continue
+ ret += f"\t\t_MSG({msg.name}),\n"
+ ret += "\t}},\n"
+ ret += ifdef_pop(0)
+ ret += "};\n"
############################################################################
return ret
@@ -1165,6 +1170,6 @@ if __name__ == "__main__":
versions, typs = parser.all()
outdir = os.path.normpath(os.path.join(sys.argv[0], ".."))
with open(os.path.join(outdir, "include/lib9p/9p.generated.h"), "w") as fh:
- fh.write(gen_h("lib9p_", versions, typs))
+ fh.write(gen_h(versions, typs))
with open(os.path.join(outdir, "9p.generated.c"), "w") as fh:
- fh.write(gen_c("lib9p_", versions, typs))
+ fh.write(gen_c(versions, typs))
diff --git a/lib9p/idl/00-README.md b/lib9p/idl/0000-README.md
index f53acf9..f53acf9 100644
--- a/lib9p/idl/00-README.md
+++ b/lib9p/idl/0000-README.md
diff --git a/lib9p/idl/1992-9P0.9p.wip b/lib9p/idl/1992-9P0.9p.wip
new file mode 100644
index 0000000..c8db485
--- /dev/null
+++ b/lib9p/idl/1992-9P0.9p.wip
@@ -0,0 +1,53 @@
+# 1992-9P0.9p - Definitions of 9P0 (Plan 9 1st ed) messages
+#
+# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-Licence-Identifier: AGPL-3.0-or-later
+
+# https://man.cat-v.org/plan_9_1st_ed/5/
+version "9P0"
+
+# tag - identify a request/response pair
+num tag = 2
+
+# file identifier - like a UNIX file-descriptor
+num fid = 2
+
+# uni"Q"ue "ID"entification
+struct qid = "path[4] version[4]"
+
+# a nul-padded string
+struct name = 28*(txt[1])
+
+msg Tnop = "typ[1,val=TODO] tag[tag,val=0xFFFF]"
+msg Rnop = "typ[1,val=TODO] tag[tag,val=0xFFFF]"
+msg Tsession = "typ[1,val=TODO] tag[tag,val=0xFFFF]"
+msg Rsession = "typ[1,val=TODO] tag[tag,val=0xFFFF]"
+msg Rerror = "typ[1,val=TODO] tag[tag] ename[64]"
+msg Tflush = "typ[1,val=TODO] tag[tag] oldtag[tag]"
+msg Rflush = "typ[1,val=TODO] tag[tag]"
+msg Tauth = "typ[1,val=TODO] tag[tag] fid[fid] uid[28] chal[36]"
+msg Rauth = "typ[1,val=TODO] tag[tag] fid[fid] chal[30]"
+msg Tattach = "typ[1,val=TODO] tag[tag] fid[fid] uid[28] aname[28] auth[28]"
+msg Rattach = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
+msg Tclone = "typ[1,val=TODO] tag[tag] fid[fid] newfid[fid]"
+msg Rclone = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Tclwalk = "typ[1,val=TODO] tag[tag] fid[fid] newfid[fid] name[28]"
+msg Rclwalk = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
+msg Twalk = "typ[1,val=TODO] tag[tag] fid[fid] name[28]"
+msg Rwalk = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
+msg Topen = "typ[1,val=TODO] tag[tag] fid[fid] mode[1]"
+msg Ropen = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
+msg Tcreate = "typ[1,val=TODO] tag[tag] fid[fid] name[28] perm[4] mode[1]"
+msg Rcreate = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
+msg Tread = "typ[1,val=TODO] tag[tag] fid[fid] offset[8] count[2,max=8192]"
+msg Rread = "typ[1,val=TODO] tag[tag] fid[fid] count[2,max=8192] pad[1] count*(data[1])"
+msg Twrite = "typ[1,val=TODO] tag[tag] fid[fid] offset[8] count[2,max=8192] pad[1] count*(data[1])"
+msg Rwrite = "typ[1,val=TODO] tag[tag] fid[fid] count[2,max=8192]"
+msg Tclunk = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Rclunk = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Tremove = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Rremove = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Tstat = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Rstat = "typ[1,val=TODO] tag[tag] fid[fid] stat[116]"
+msg Twstat = "typ[1,val=TODO] tag[tag] fid[fid] stat[116]"
+msg Rwstat = "typ[1,val=TODO] tag[tag] fid[fid]"
diff --git a/lib9p/idl/1995-9P1.9p.wip b/lib9p/idl/1995-9P1.9p.wip
new file mode 100644
index 0000000..2f4ed93
--- /dev/null
+++ b/lib9p/idl/1995-9P1.9p.wip
@@ -0,0 +1,52 @@
+# 1995-9P1.9p - Definitions of 9P1 (Plan 9 2nd ed and 3rd ed) messages
+#
+# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-Licence-Identifier: AGPL-3.0-or-later
+
+# https://man.cat-v.org/plan_9_2nd_ed/5/
+# https://man.cat-v.org/plan_9_3rd_ed/5/
+version "9P1"
+
+# tag - identify a request/response pair
+num tag = 2
+
+# file identifier - like a UNIX file-descriptor
+num fid = 2
+
+# uni"Q"ue "ID"entification
+struct qid = "path[4] version[4]"
+
+# a nul-padded string
+struct name = 28*(txt[1])
+
+msg Tnop = "typ[1,val=TODO] tag[tag,val=0xFFFF]"
+msg Rnop = "typ[1,val=TODO] tag[tag,val=0xFFFF]"
+msg Tsession = "typ[1,val=TODO] tag[tag,val=0xFFFF] chal[8]"
+msg Rsession = "typ[1,val=TODO] tag[tag,val=0xFFFF] chal[8] authid[28] authdom[48]"
+msg Rerror = "typ[1,val=TODO] tag[tag] ename[64]"
+msg Tflush = "typ[1,val=TODO] tag[tag] oldtag[tag]"
+msg Rflush = "typ[1,val=TODO] tag[tag]"
+msg Tattach = "typ[1,val=TODO] tag[tag] fid[fid] uid[28] aname[28] ticket[72] auth[13]"
+msg Rattach = "typ[1,val=TODO] tag[tag] fid[fid] qid[8] rauth[13]"
+msg Tclone = "typ[1,val=TODO] tag[tag] fid[fid] newfid[fid]"
+msg Rclone = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Tclwalk = "typ[1,val=TODO] tag[tag] fid[fid] newfid[fid] name[28]"
+msg Rclwalk = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
+msg Twalk = "typ[1,val=TODO] tag[tag] fid[fid] name[28]"
+msg Rwalk = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
+msg Topen = "typ[1,val=TODO] tag[tag] fid[fid] mode[1]"
+msg Ropen = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
+msg Tcreate = "typ[1,val=TODO] tag[tag] fid[fid] name[28] perm[4] mode[1]"
+msg Rcreate = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
+msg Tread = "typ[1,val=TODO] tag[tag] fid[fid] offset[8] count[2,max=8192]"
+msg Rread = "typ[1,val=TODO] tag[tag] fid[fid] count[2,max=8192] pad[1] count*(data[1])"
+msg Twrite = "typ[1,val=TODO] tag[tag] fid[fid] offset[8] count[2,max=8192] pad[1] count*(data[1])"
+msg Rwrite = "typ[1,val=TODO] tag[tag] fid[fid] count[2,max=8192]"
+msg Tclunk = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Rclunk = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Tremove = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Rremove = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Tstat = "typ[1,val=TODO] tag[tag] fid[fid]"
+msg Rstat = "typ[1,val=TODO] tag[tag] fid[fid] stat[116]"
+msg Twstat = "typ[1,val=TODO] tag[tag] fid[fid] stat[116]"
+msg Rwstat = "typ[1,val=TODO] tag[tag] fid[fid]"
diff --git a/lib9p/idl/1996-Styx.9p.wip b/lib9p/idl/1996-Styx.9p.wip
new file mode 100644
index 0000000..599abc8
--- /dev/null
+++ b/lib9p/idl/1996-Styx.9p.wip
@@ -0,0 +1,15 @@
+# 1996-Styx.9p - Definitions of Styx messages
+#
+# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-Licence-Identifier: AGPL-3.0-or-later
+
+# Styx was a variant of the 9P protocol used by the Inferno operating
+# system. Message framing looks like 9P1 (1995), but semantics look
+# more like 9P2000 (2002). I am not sure whether there are Styx
+# protocol differences between Inferno 1e, 2e, or 3e (4e adopted
+# 9P2000).
+#
+# - 1996 beta
+# - 1997 1.0
+# - 1999 2nd ed
+# - 2001 3rd ed
diff --git a/lib9p/idl/01-9P2000.9p b/lib9p/idl/2002-9P2000.9p
index 426a8c6..ba1382e 100644
--- a/lib9p/idl/01-9P2000.9p
+++ b/lib9p/idl/2002-9P2000.9p
@@ -1,4 +1,4 @@
-# 01-9P2000.9p - Definitions of 9P2000 messages
+# 2002-9P2000.9p - Definitions of 9P2000 messages
#
# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-Licence-Identifier: AGPL-3.0-or-later
@@ -19,7 +19,7 @@ version "9P2000"
# tag - identify a request/response pair
num tag = 2
-# file identifier
+# file identifier - like a UNIX file-descriptor
num fid = 4
# data - u32le `n`, then `n` bytes of data
diff --git a/lib9p/idl/02-9P2000.u.9p b/lib9p/idl/2005-9P2000.u.9p
index d3ca6f0..a47e9db 100644
--- a/lib9p/idl/02-9P2000.u.9p
+++ b/lib9p/idl/2005-9P2000.u.9p
@@ -1,4 +1,4 @@
-# 02-9P2000.u.9p - Definitions of 9P2000.u messages
+# 2005-9P2000.u.9p - Definitions of 9P2000.u messages
#
# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-Licence-Identifier: AGPL-3.0-or-later
@@ -8,7 +8,7 @@
# https://github.com/ericvh/9p-rfc/blob/master/9p2000.u.xml
version "9P2000.u"
-from ./01-9P2000.9p import *
+from ./2002-9P2000.9p import *
struct stat += "file_extension[s]"
"file_owner_n_uid[4]"
diff --git a/lib9p/idl/03-9P2000.L.9p.wip b/lib9p/idl/2010-9P2000.L.9p.wip
index 62186f9..a0de883 100644
--- a/lib9p/idl/03-9P2000.L.9p.wip
+++ b/lib9p/idl/2010-9P2000.L.9p.wip
@@ -1,4 +1,4 @@
-# 9P2000.L.txt - Definitions of 9P2000.L messages
+# 2010-9P2000.L.9p - Definitions of 9P2000.L messages
#
# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-Licence-Identifier: AGPL-3.0-or-later
@@ -7,8 +7,8 @@
# https://github.com/chaos/diod/blob/master/protocol.md
version "9P2000.L"
-from ./01-9P2000.9p import *
-from ./02-9P2000.u.9p import Tauth, Tattach
+from ./2002-9P2000.9p import *
+from ./2005-9P2000.u.9p import Tauth, Tattach
#msg Tlerror = "size[4,val=end-&size] typ[1,val=6] tag[tag] illegal" # analogous to 106/Terror
msg Rlerror = "size[4,val=end-&size] typ[1,val=7] tag[tag] ecode[4]" # analogous to 107/Rerror
diff --git a/lib9p/idl/02-9P2000.e.9p b/lib9p/idl/2012-9P2000.e.9p
index b91b2c5..2f88a60 100644
--- a/lib9p/idl/02-9P2000.e.9p
+++ b/lib9p/idl/2012-9P2000.e.9p
@@ -1,4 +1,4 @@
-# 02-9P2000e.e.9p - Definitions of 9P2000.e messages
+# 2012-9P2000.e.9p - Definitions of 9P2000.e messages
#
# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-Licence-Identifier: AGPL-3.0-or-later
@@ -8,7 +8,7 @@
# https://github.com/cloudozer/ling/blob/master/doc/9p2000e.md
version "9P2000.e"
-from ./01-9P2000.9p import *
+from ./2002-9P2000.9p import *
msg Tsession = "size[4,val=end-&size] typ[1,val=150] tag[tag] key[8]"
msg Rsession = "size[4,val=end-&size] typ[1,val=151] tag[tag]"
diff --git a/lib9p/include/lib9p/9p.generated.h b/lib9p/include/lib9p/9p.generated.h
index 2fb7a3e..6248ec7 100644
--- a/lib9p/include/lib9p/9p.generated.h
+++ b/lib9p/include/lib9p/9p.generated.h
@@ -1,4 +1,4 @@
-/* Generated by `./lib9p/idl.gen lib9p/idl/01-9P2000.9p lib9p/idl/02-9P2000.e.9p lib9p/idl/02-9P2000.u.9p`. DO NOT EDIT! */
+/* Generated by `./lib9p/idl.gen lib9p/idl/2002-9P2000.9p lib9p/idl/2005-9P2000.u.9p lib9p/idl/2012-9P2000.e.9p`. DO NOT EDIT! */
#ifndef _LIB9P_9P_H_
# error Do not include <lib9p/9p.generated.h> directly; include <lib9p/9p.h> instead
diff --git a/lib9p/include/lib9p/9p.h b/lib9p/include/lib9p/9p.h
index 616a0e1..3ad52f1 100644
--- a/lib9p/include/lib9p/9p.h
+++ b/lib9p/include/lib9p/9p.h
@@ -11,7 +11,6 @@
#include <stdbool.h>
#include <sys/types.h> /* for ssize_t */
-#include <lib9p/9p.generated.h>
#include <lib9p/linux-errno.h>
/* configuration **************************************************************/
@@ -21,9 +20,14 @@
#ifndef CONFIG_9P_MAX_ERR_SIZE
# error config.h must define CONFIG_9P_MAX_ERR_SIZE
#endif
+#ifndef CONFIG_9P_ENABLE_9P2000
+# define CONFIG_9P_ENABLE_9P2000
+#endif
/******************************************************************************/
+#include <lib9p/9p.generated.h> /* *after* config.h */
+
#define LIB9P_NOTAG ((uint16_t)~0U)
#define LIB9P_NOFID ((uint32_t)~0U)
@@ -85,21 +89,22 @@ ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes);
* @param net_bytes : the complete message, starting with the "size[4]"
*
* @return ret_typ : the mesage type
- * @return ret_tag : the message-ID tag
* @return ret_body : the message body, must be at least lib9p_validate() bytes
*/
void lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
- enum lib9p_msg_type *ret_typ, uint16_t *ret_tag, void *ret_body);
+ enum lib9p_msg_type *ret_typ, void *ret_body);
/**
* Marshal a `struct lib9p_msg_{typ}` structure into a byte-array.
*
* lib9p_marshal does no validation; it trusts that the programmer
- * won't give it garbage input.
+ * won't give it garbage input. However, just as it doesn't marshal
+ * struct fields that aren't in ctx->version, it won't marshal
+ * bitfield bits that aren't in ctx->version; it applies a
+ * version-specific mask to bitfields.
*
* @param ctx : negotiated protocol parameters, where to record errors
* @param typ : the message type
- * @param tag : the message-ID tag
* @param msg : the message to encode
*
* @return ret_bytes : the buffer to encode to, must be at be at least lib9p_ctx_max_msg_size(ctx) bytes
@@ -107,7 +112,7 @@ void lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
*
* @errno LINUX_ERANGE: reply does not fit in ctx->max_msg_size
*/
-bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, uint16_t tag, void *body,
+bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
uint8_t *ret_bytes);
#endif _LIB9P_9P_H_
diff --git a/lib9p/srv.c b/lib9p/srv.c
index 5af0971..9d1b4ed 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -81,9 +81,8 @@ static uint32_t rerror_overhead_for_version(enum lib9p_version version,
bool e;
e = lib9p_marshal(&empty_ctx, LIB9P_TYP_Rerror,
- 0, /* tag */
&empty_error, /* host_body */
- scratch); /* net_bytes */
+ scratch); /* net_bytes */
assert(!e);
uint32_t min_msg_size = decode_u32le(scratch);
@@ -105,6 +104,7 @@ static void respond_error(struct _lib9p_srv_req *req) {
ssize_t r;
struct lib9p_msg_Rerror host = {
+ .tag = req->tag,
.ename = {
.len = strnlen(req->ctx.basectx.err_msg,
CONFIG_9P_MAX_ERR_SIZE),
@@ -123,7 +123,7 @@ static void respond_error(struct _lib9p_srv_req *req) {
host.ename.len = sess->max_msg_size - sess->rerror_overhead;
lib9p_marshal(&req->ctx.basectx, LIB9P_TYP_Rerror,
- req->tag, &host, req->net_bytes);
+ &host, req->net_bytes);
cr_mutex_lock(&sess->parent_conn->writelock);
r = netio_write(sess->parent_conn->fd,
@@ -345,7 +345,7 @@ static void handle_message(struct _lib9p_srv_req *ctx) {
goto write;
}
lib9p_unmarshal(&ctx->ctx.basectx, ctx->net_bytes,
- &typ, &ctx->tag, host_req);
+ &typ, host_req);
/* Handle it. */
tmessage_handlers[typ](ctx, (void *)host_req, (void *)host_resp);
@@ -354,7 +354,7 @@ static void handle_message(struct _lib9p_srv_req *ctx) {
if (lib9p_ctx_has_error(&ctx->ctx.basectx))
respond_error(ctx);
else {
- if (lib9p_marshal(&ctx->ctx.basectx, typ+1, ctx->tag, host_resp,
+ if (lib9p_marshal(&ctx->ctx.basectx, typ+1, host_resp,
ctx->net_bytes))
goto write;
@@ -440,12 +440,17 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx,
ctx->parent_sess->rerror_overhead = min_msg_size;
}
+#define handler_common(ctx, req, resp) do { \
+ assert(ctx); \
+ assert(req); \
+ assert(resp); \
+ resp->tag = req->tag; \
+ } while (0)
+
static void handle_Tauth(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Tauth *req,
struct lib9p_msg_Rauth *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
ctx->ctx.uid = req->n_uname;
ctx->ctx.uname = req->uname.utf8;
@@ -465,9 +470,7 @@ 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);
+ handler_common(ctx, req, resp);
ctx->ctx.uid = req->n_uname;
ctx->ctx.uname = req->uname.utf8;
@@ -543,9 +546,7 @@ static void handle_Tattach(struct _lib9p_srv_req *ctx,
static void handle_Tflush(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Tflush *req,
struct lib9p_msg_Rflush *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);;
lib9p_error(&ctx->ctx.basectx,
LINUX_EOPNOTSUPP, "flush not yet implemented");
@@ -554,9 +555,7 @@ static void handle_Tflush(struct _lib9p_srv_req *ctx,
static void handle_Twalk(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Twalk *req,
struct lib9p_msg_Rwalk *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
struct lib9p_srv_file **dirpp = fidmap_load(&ctx->parent_sess->fids, req->fid);
if (!dirpp) {
@@ -627,9 +626,7 @@ static void handle_Twalk(struct _lib9p_srv_req *ctx,
static void handle_Topen(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Topen *req,
struct lib9p_msg_Ropen *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);;
lib9p_error(&ctx->ctx.basectx,
LINUX_EOPNOTSUPP, "open not yet implemented");
@@ -638,9 +635,7 @@ static void handle_Topen(struct _lib9p_srv_req *ctx,
static void handle_Tcreate(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Tcreate *req,
struct lib9p_msg_Rcreate *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
lib9p_error(&ctx->ctx.basectx,
LINUX_EOPNOTSUPP, "create not yet implemented");
@@ -649,9 +644,7 @@ static void handle_Tcreate(struct _lib9p_srv_req *ctx,
static void handle_Tread(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Tread *req,
struct lib9p_msg_Rread *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
lib9p_error(&ctx->ctx.basectx,
LINUX_EOPNOTSUPP, "read not yet implemented");
@@ -660,9 +653,7 @@ static void handle_Tread(struct _lib9p_srv_req *ctx,
static void handle_Twrite(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Twrite *req,
struct lib9p_msg_Rwrite *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
lib9p_error(&ctx->ctx.basectx,
LINUX_EOPNOTSUPP, "write not yet implemented");
@@ -671,9 +662,7 @@ static void handle_Twrite(struct _lib9p_srv_req *ctx,
static void handle_Tclunk(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Tclunk *req,
struct lib9p_msg_Rclunk *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
struct lib9p_srv_file **filepp = fidmap_load(&ctx->parent_sess->fids, req->fid);
if (!filepp) {
@@ -689,9 +678,7 @@ static void handle_Tclunk(struct _lib9p_srv_req *ctx,
static void handle_Tremove(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Tremove *req,
struct lib9p_msg_Rremove *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
lib9p_error(&ctx->ctx.basectx,
LINUX_EOPNOTSUPP, "remove not yet implemented");
@@ -700,9 +687,7 @@ static void handle_Tremove(struct _lib9p_srv_req *ctx,
static void handle_Tstat(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Tstat *req,
struct lib9p_msg_Rstat *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
struct lib9p_srv_file **filepp = fidmap_load(&ctx->parent_sess->fids, req->fid);
if (!filepp) {
@@ -717,9 +702,7 @@ static void handle_Tstat(struct _lib9p_srv_req *ctx,
static void handle_Twstat(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Twstat *req,
struct lib9p_msg_Rwstat *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);;
lib9p_error(&ctx->ctx.basectx,
LINUX_EOPNOTSUPP, "wstat not yet implemented");
@@ -728,9 +711,7 @@ static void handle_Twstat(struct _lib9p_srv_req *ctx,
static void handle_Tsession(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Tsession *req,
struct lib9p_msg_Rsession *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
lib9p_error(&ctx->ctx.basectx,
LINUX_EOPNOTSUPP, "session not yet implemented");
@@ -739,9 +720,7 @@ static void handle_Tsession(struct _lib9p_srv_req *ctx,
static void handle_Tsread(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Tsread *req,
struct lib9p_msg_Rsread *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
lib9p_error(&ctx->ctx.basectx,
LINUX_EOPNOTSUPP, "sread not yet implemented");
@@ -750,9 +729,7 @@ static void handle_Tsread(struct _lib9p_srv_req *ctx,
static void handle_Tswrite(struct _lib9p_srv_req *ctx,
struct lib9p_msg_Tswrite *req,
struct lib9p_msg_Rswrite *resp) {
- assert(ctx);
- assert(req);
- assert(resp);
+ handler_common(ctx, req, resp);
lib9p_error(&ctx->ctx.basectx,
LINUX_EOPNOTSUPP, "swrite not yet implemented");