summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib9p/9P2000.txt37
-rw-r--r--lib9p/9P2000.u.txt21
-rw-r--r--lib9p/include/lib9p/_types.h38
-rw-r--r--lib9p/types.c36
-rwxr-xr-xlib9p/types.gen2
5 files changed, 102 insertions, 32 deletions
diff --git a/lib9p/9P2000.txt b/lib9p/9P2000.txt
index da9b223..3fb9e51 100644
--- a/lib9p/9P2000.txt
+++ b/lib9p/9P2000.txt
@@ -30,18 +30,37 @@ d = "len[4] len*(dat[1])"
# string (u16le `n`, then `n` bytes of UTF-8)
s = "len[2] len*(utf8[1])"
+# "d"? mode - (file permissions and attributes)
+bitfield dm 32
+ 31/DIR
+ 30/APPEND
+ 29/EXCL
+ # DMMOUNT has been around in Plan 9 forever, but is
+ # undocumented, and is explicitly excluded from the 9P2000
+ # draft RFC. As I understand it, DMMOUNT indicates that the
+ # file is mounted by the kernel as a 9P transport; that the
+ # kernel has a lock on doing I/O on it, so userspace can't do
+ # I/O on it.
+ 28/_PLAN9_MOUNT
+ 27/AUTH
+ 26/TMP
+ #...
+ 8/OWNER_R
+ 7/OWNER_W
+ 6/OWNER_X
+ 5/GROUP_R
+ 4/GROUP_W
+ 3/GROUP_X
+ 2/OTHER_R
+ 1/OTHER_W
+ 0/OTHER_X
+
# QID Type (see qid below)
bitfield qt 8
7/DIR
6/APPEND
5/EXCL
- # QTMOUNT has been around in Plan 9 forever, but is
- # undocumented, and is explicitly excluded from the 9P2000
- # draft RFC. As I understand it, QTMOUNT indicates that the
- # file is mounted by the kernel as a 9P transport; that the
- # kernel has a lock on doing I/O on it, so userspace can't do
- # I/O on it.
- 4/_PLAN9_MOUNT
+ 4/_PLAN9_MOUNT # see DMMOUNT above
3/AUTH
# Fun historical fact: QTTMP was a relatively late addition to
# Plan 9, in 2003-12.
@@ -73,7 +92,7 @@ stat = "stat_size[2]"
"kern_type[2]"
"kern_dev[4]"
"file_qid[qid]"
- "file_mode[4]"
+ "file_mode[dm]"
"file_atime[4]"
"file_mtime[4]"
"file_size[8]"
@@ -117,7 +136,7 @@ bitfield o 8
111/Rwalk = "nwqid[2] nwqid*(wqid[qid])"
112/Topen = "fid[4] mode[o]"
113/Ropen = "qid[qid] iounit[4]"
-114/Tcreate = "fid[4] name[s] perm[4] mode[o]"
+114/Tcreate = "fid[4] name[s] perm[dm] mode[o]"
115/Rcreate = "qid[qid] iounit[4]"
116/Tread = "fid[4] offset[8] count[4]"
117/Rread = "data[d]" # for directories data is the sequence "cnt*(entries[stat])"
diff --git a/lib9p/9P2000.u.txt b/lib9p/9P2000.u.txt
index 29fd2d8..3958a92 100644
--- a/lib9p/9P2000.u.txt
+++ b/lib9p/9P2000.u.txt
@@ -19,19 +19,10 @@ Tauth += "n_uname[4]"
Rerror += "errno[4]"
-qt += 1/SYMLINK
+dm += 23/DEVICE
+ 21/NAMEDPIPE
+ 20/SOCKET
+ 19/SETUID
+ 18/SETGID
-# DMDIR = 1<<31
-# DMAPPEND = 1<<30
-# DMEXCL = 1<<29
-# DMMOUNT = 1<<28
-# DMAUTH = 1<<27
-# DMTMP = 1<<26
-# # = 1<<25
-# # = 1<<24
-# DMDEVICE = 1<<23 # .u
-# # = 1<<22
-# DMNAMEDPIPE = 1<<21 # .u
-# DMSOCKET = 1<<20 # .u
-# DMSETUID = 1<<19 # .u
-# DMSETGID = 1<<18 # .u
+qt += 1/SYMLINK
diff --git a/lib9p/include/lib9p/_types.h b/lib9p/include/lib9p/_types.h
index d853cf3..e22404c 100644
--- a/lib9p/include/lib9p/_types.h
+++ b/lib9p/include/lib9p/_types.h
@@ -19,6 +19,40 @@ const char *lib9p_version_str(enum lib9p_version);
/* non-message types **********************************************************/
+typedef uint32_t lib9p_dm_t;
+#define LIB9P_DM_DIR ((lib9p_dm_t)(1<<31))
+#define LIB9P_DM_APPEND ((lib9p_dm_t)(1<<30))
+#define LIB9P_DM_EXCL ((lib9p_dm_t)(1<<29))
+#define _LIB9P_DM_PLAN9_MOUNT ((lib9p_dm_t)(1<<28))
+#define LIB9P_DM_AUTH ((lib9p_dm_t)(1<<27))
+#define LIB9P_DM_TMP ((lib9p_dm_t)(1<<26))
+#define _LIB9P_DM_UNUSED_25 ((lib9p_dm_t)(1<<25))
+#define _LIB9P_DM_UNUSED_24 ((lib9p_dm_t)(1<<24))
+#define LIB9P_DM_DEVICE ((lib9p_dm_t)(1<<23)) /* 9P2000.u */
+#define _LIB9P_DM_UNUSED_22 ((lib9p_dm_t)(1<<22))
+#define LIB9P_DM_NAMEDPIPE ((lib9p_dm_t)(1<<21)) /* 9P2000.u */
+#define LIB9P_DM_SOCKET ((lib9p_dm_t)(1<<20)) /* 9P2000.u */
+#define LIB9P_DM_SETUID ((lib9p_dm_t)(1<<19)) /* 9P2000.u */
+#define LIB9P_DM_SETGID ((lib9p_dm_t)(1<<18)) /* 9P2000.u */
+#define _LIB9P_DM_UNUSED_17 ((lib9p_dm_t)(1<<17))
+#define _LIB9P_DM_UNUSED_16 ((lib9p_dm_t)(1<<16))
+#define _LIB9P_DM_UNUSED_15 ((lib9p_dm_t)(1<<15))
+#define _LIB9P_DM_UNUSED_14 ((lib9p_dm_t)(1<<14))
+#define _LIB9P_DM_UNUSED_13 ((lib9p_dm_t)(1<<13))
+#define _LIB9P_DM_UNUSED_12 ((lib9p_dm_t)(1<<12))
+#define _LIB9P_DM_UNUSED_11 ((lib9p_dm_t)(1<<11))
+#define _LIB9P_DM_UNUSED_10 ((lib9p_dm_t)(1<<10))
+#define _LIB9P_DM_UNUSED_9 ((lib9p_dm_t)(1<<9))
+#define LIB9P_DM_OWNER_R ((lib9p_dm_t)(1<<8))
+#define LIB9P_DM_OWNER_W ((lib9p_dm_t)(1<<7))
+#define LIB9P_DM_OWNER_X ((lib9p_dm_t)(1<<6))
+#define LIB9P_DM_GROUP_R ((lib9p_dm_t)(1<<5))
+#define LIB9P_DM_GROUP_W ((lib9p_dm_t)(1<<4))
+#define LIB9P_DM_GROUP_X ((lib9p_dm_t)(1<<3))
+#define LIB9P_DM_OTHER_R ((lib9p_dm_t)(1<<2))
+#define LIB9P_DM_OTHER_W ((lib9p_dm_t)(1<<1))
+#define LIB9P_DM_OTHER_X ((lib9p_dm_t)(1<<0))
+
typedef uint8_t lib9p_qt_t;
#define LIB9P_QT_DIR ((lib9p_qt_t)(1<<7))
#define LIB9P_QT_APPEND ((lib9p_qt_t)(1<<6))
@@ -65,7 +99,7 @@ struct lib9p_stat {
uint16_t kern_type;
uint32_t kern_dev;
struct lib9p_qid file_qid;
- uint32_t file_mode;
+ lib9p_dm_t file_mode;
uint32_t file_atime;
uint32_t file_mtime;
uint64_t file_size;
@@ -187,7 +221,7 @@ struct lib9p_msg_Ropen {
struct lib9p_msg_Tcreate {
uint32_t fid;
struct lib9p_s name;
- uint32_t perm;
+ lib9p_dm_t perm;
lib9p_o_t mode;
};
diff --git a/lib9p/types.c b/lib9p/types.c
index 50ac1cf..2d0bb1b 100644
--- a/lib9p/types.c
+++ b/lib9p/types.c
@@ -343,6 +343,22 @@ 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] = {
+ [LIB9P_VER_9P2000] = 0b11111100000000000000000111111111,
+ [LIB9P_VER_9P2000_e] = 0b11111100000000000000000111111111,
+ [LIB9P_VER_9P2000_u] = 0b11111100101111000000000111111111,
+ };
+ lib9p_dm_t mask = 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 false;
+}
+
static ALWAYS_INLINE bool validate_qt(struct _validate_ctx *ctx) {
if (validate_1(ctx))
return true;
@@ -370,7 +386,7 @@ static ALWAYS_INLINE bool validate_stat(struct _validate_ctx *ctx) {
|| validate_2(ctx)
|| validate_4(ctx)
|| validate_qid(ctx)
- || validate_4(ctx)
+ || validate_dm(ctx)
|| validate_4(ctx)
|| validate_4(ctx)
|| validate_8(ctx)
@@ -465,7 +481,7 @@ static FLATTEN bool validate_Ropen(struct _validate_ctx *ctx) {
static FLATTEN bool validate_Tcreate(struct _validate_ctx *ctx) {
return validate_4(ctx)
|| validate_s(ctx)
- || validate_4(ctx)
+ || validate_dm(ctx)
|| validate_o(ctx);
}
@@ -596,6 +612,10 @@ static ALWAYS_INLINE void unmarshal_s(struct _unmarshal_ctx *ctx, struct lib9p_s
unmarshal_1(ctx, &out->utf8[i]);
}
+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);
}
@@ -613,7 +633,7 @@ static ALWAYS_INLINE void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9
unmarshal_2(ctx, &out->kern_type);
unmarshal_4(ctx, &out->kern_dev);
unmarshal_qid(ctx, &out->file_qid);
- unmarshal_4(ctx, &out->file_mode);
+ unmarshal_dm(ctx, &out->file_mode);
unmarshal_4(ctx, &out->file_atime);
unmarshal_4(ctx, &out->file_mtime);
unmarshal_8(ctx, &out->file_size);
@@ -720,7 +740,7 @@ static FLATTEN void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_m
memset(out, 0, sizeof(*out));
unmarshal_4(ctx, &out->fid);
unmarshal_s(ctx, &out->name);
- unmarshal_4(ctx, &out->perm);
+ unmarshal_dm(ctx, &out->perm);
unmarshal_o(ctx, &out->mode);
}
@@ -894,6 +914,10 @@ static ALWAYS_INLINE bool marshal_s(struct _marshal_ctx *ctx, struct lib9p_s *va
});
}
+static ALWAYS_INLINE bool marshal_dm(struct _marshal_ctx *ctx, lib9p_dm_t *val) {
+ return marshal_4(ctx, (uint32_t *)val);
+}
+
static ALWAYS_INLINE bool marshal_qt(struct _marshal_ctx *ctx, lib9p_qt_t *val) {
return marshal_1(ctx, (uint8_t *)val);
}
@@ -909,7 +933,7 @@ static ALWAYS_INLINE bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_st
|| marshal_2(ctx, &val->kern_type)
|| marshal_4(ctx, &val->kern_dev)
|| marshal_qid(ctx, &val->file_qid)
- || marshal_4(ctx, &val->file_mode)
+ || marshal_dm(ctx, &val->file_mode)
|| marshal_4(ctx, &val->file_atime)
|| marshal_4(ctx, &val->file_mtime)
|| marshal_8(ctx, &val->file_size)
@@ -1007,7 +1031,7 @@ static FLATTEN bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Rop
static FLATTEN bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tcreate *val) {
return marshal_4(ctx, &val->fid)
|| marshal_s(ctx, &val->name)
- || marshal_4(ctx, &val->perm)
+ || marshal_dm(ctx, &val->perm)
|| marshal_o(ctx, &val->mode);
}
diff --git a/lib9p/types.gen b/lib9p/types.gen
index 1b43fa4..3e800e8 100755
--- a/lib9p/types.gen
+++ b/lib9p/types.gen
@@ -238,6 +238,7 @@ def parse_file(
if not isinstance(_bf, Bitfield):
raise NameError(f"Type {repr(_bf.name)} is not a bitfield")
bf = _bf
+ prev = bf
else:
if not isinstance(prev, Bitfield):
raise SyntaxError(
@@ -269,6 +270,7 @@ def parse_file(
if not isinstance(_bf, Bitfield):
raise NameError(f"Type {repr(_bf.name)} is not a bitfield")
bf = _bf
+ prev = bf
else:
if not isinstance(prev, Bitfield):
raise SyntaxError(