diff options
Diffstat (limited to 'lib9p/idl')
-rw-r--r-- | lib9p/idl/1992-9P0.9p.wip | 2 | ||||
-rw-r--r-- | lib9p/idl/1996-Styx.9p.wip | 2 | ||||
-rw-r--r-- | lib9p/idl/2002-9P2000.9p | 2 | ||||
-rw-r--r-- | lib9p/idl/2003-9P2000.p9p.9p | 2 | ||||
-rw-r--r-- | lib9p/idl/2005-9P2000.u.9p | 2 | ||||
-rw-r--r-- | lib9p/idl/2010-9P2000.L.9p | 165 | ||||
-rwxr-xr-x | lib9p/idl/2010-9P2000.L.9p.gen | 282 | ||||
-rw-r--r-- | lib9p/idl/__init__.py | 20 |
8 files changed, 459 insertions, 18 deletions
diff --git a/lib9p/idl/1992-9P0.9p.wip b/lib9p/idl/1992-9P0.9p.wip index a434ba2..c9432c9 100644 --- a/lib9p/idl/1992-9P0.9p.wip +++ b/lib9p/idl/1992-9P0.9p.wip @@ -107,7 +107,7 @@ msg Rnop = "typ[1,val=51] tag[tag,val=0xFFFF]" msg Tsession = "typ[1,val=52] tag[tag,val=0xFFFF]" msg Rsession = "typ[1,val=53] tag[tag,val=0xFFFF]" #msg Terror = "typ[1,val=54] illegal" -msg Rerror = "typ[1,val=55] tag[tag] ename[errstr]" +msg Rerror = "typ[1,val=55] tag[tag] errstr[errstr]" msg Tflush = "typ[1,val=56] tag[tag] oldtag[tag]" msg Rflush = "typ[1,val=57] tag[tag]" msg Tattach = "typ[1,val=58] tag[tag] fid[fid] uid[name] aname[name] auth[auth_ticket] 13*(pad[1])" # Pad to allow auth_tickets up to 28 bytes. diff --git a/lib9p/idl/1996-Styx.9p.wip b/lib9p/idl/1996-Styx.9p.wip index 3cb3774..143be83 100644 --- a/lib9p/idl/1996-Styx.9p.wip +++ b/lib9p/idl/1996-Styx.9p.wip @@ -28,7 +28,7 @@ from ./1992-9P1.9p import tag, fid, qid, name, errstr, o, ch, stat msg Tnop = "typ[1,val=0] tag[tag,val=0xFFFF]" msg Rnop = "typ[1,val=1] tag[tag,val=0xFFFF]" #msg Terror = "typ[1,val=2] illegal" -msg Rerror = "typ[1,val=3] tag[tag] ename[errstr]" +msg Rerror = "typ[1,val=3] tag[tag] errstr[errstr]" msg Tflush = "typ[1,val=4] tag[tag] oldtag[tag]" msg Rflush = "typ[1,val=5] tag[tag]" msg Tclone = "typ[1,val=6] tag[tag] fid[fid] newfid[fid]" diff --git a/lib9p/idl/2002-9P2000.9p b/lib9p/idl/2002-9P2000.9p index 2b51612..13393c6 100644 --- a/lib9p/idl/2002-9P2000.9p +++ b/lib9p/idl/2002-9P2000.9p @@ -137,7 +137,7 @@ msg Rauth = "size[4,val=end-&size] typ[1,val=103] tag[tag] aqid[qid]" msg Tattach = "size[4,val=end-&size] typ[1,val=104] tag[tag] fid[fid] afid[fid] uname[s] aname[s]" msg Rattach = "size[4,val=end-&size] typ[1,val=105] tag[tag] qid[qid]" #msg Terror = "size[4,val=end-&size] typ[1,val=106] tag[tag] illegal" -msg Rerror = "size[4,val=end-&size] typ[1,val=107] tag[tag] ename[s]" +msg Rerror = "size[4,val=end-&size] typ[1,val=107] tag[tag] errstr[s]" msg Tflush = "size[4,val=end-&size] typ[1,val=108] tag[tag] oldtag[2]" msg Rflush = "size[4,val=end-&size] typ[1,val=109] tag[tag]" msg Twalk = "size[4,val=end-&size] typ[1,val=110] tag[tag] fid[fid] newfid[fid] nwname[2,max=16] nwname*(wname[s])" diff --git a/lib9p/idl/2003-9P2000.p9p.9p b/lib9p/idl/2003-9P2000.p9p.9p index 3f6a524..1d1c307 100644 --- a/lib9p/idl/2003-9P2000.p9p.9p +++ b/lib9p/idl/2003-9P2000.p9p.9p @@ -27,7 +27,7 @@ from ./2002-9P2000.9p import * # e.g. you replace syscall:`open()` with lib9pclient:`fsopen()`). # # "Unfortunately", programs in plan9port must deal both with 9P files -# and native "Unix" files; and need to turn an 9P FID into a native +# and native "Unix" files; and need to turn a 9P FID into a native # file descriptor. To do this, the `9pserve` program and lib9pclient # add an extension call to 9P2000: Topenfd/Ropenfd/fsopenfd(). # diff --git a/lib9p/idl/2005-9P2000.u.9p b/lib9p/idl/2005-9P2000.u.9p index 6c2f2dc..1d630f9 100644 --- a/lib9p/idl/2005-9P2000.u.9p +++ b/lib9p/idl/2005-9P2000.u.9p @@ -25,7 +25,7 @@ struct stat += "file_extension[s]" msg Tauth += "n_uid[nuid]" msg Tattach += "n_uid[nuid]" -msg Rerror += "errno[errno]" +msg Rerror += "errnum[errno]" bitfield dm += "bit 23=DEVICE" "bit 21=PIPE" diff --git a/lib9p/idl/2010-9P2000.L.9p b/lib9p/idl/2010-9P2000.L.9p index d81a15b..5eb7d5c 100644 --- a/lib9p/idl/2010-9P2000.L.9p +++ b/lib9p/idl/2010-9P2000.L.9p @@ -1,3 +1,6 @@ +# lib9p/idl/2010-9P2000.L.9p - Generated by `lib9p/idl/2010-9P2000.L.9p.gen 3rd-party/linux-errno.txt`. DO NOT EDIT! +# 3rd-party/linux-errno.txt - Generated from lib9p/linux-errno.txt.gen and linux.git v6.14. DO NOT EDIT! + # lib9p/idl/2010-9P2000.L.9p - Definitions of 9P2000.L messages # # Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> @@ -8,12 +11,149 @@ # https://github.com/chaos/diod/blob/master/src/libnpfs/protocol.h version "9P2000.L" +# low-level types ############################################################## + from ./2002-9P2000.9p import tag, fid, s, qt, qid -from ./2002-9P2000.9p import Rerror -from ./2002-9P2000.9p import Tversion, Rversion, Tflush, Rflush, Twalk, Rwalk, Tread, Rread, Twrite, Rwrite, Tclunk, Rclunk, Tremove, Rremove -from ./2005-9P2000.u.9p import nuid, errno, Tauth, Rauth, Tattach, Rattach +from ./2005-9P2000.u.9p import nuid, errno -#num errno += # TODO +# BUG: The definitions of errno are not defined in the 9P2000.L +# protocol spec, and Linux kernel errno values vary by architecture. +# Most architectures share a "generic" list, but a handful (as of +# Linux v6.14, Alpha, MIPS, PA-RISC, PowerPC, and SPARC) have their +# own numbers. This IDL file lists the generic numbers. +# +# https://github.com/chaos/diod/issues/35 +num errno += "L_EPERM = 1" # Operation not permitted + "L_ENOENT = 2" # No such file or directory + "L_ESRCH = 3" # No such process + "L_EINTR = 4" # Interrupted system call + "L_EIO = 5" # I/O error + "L_ENXIO = 6" # No such device or address + "L_E2BIG = 7" # Argument list too long + "L_ENOEXEC = 8" # Exec format error + "L_EBADF = 9" # Bad file number + "L_ECHILD = 10" # No child processes + "L_EAGAIN = 11" # Try again + "L_ENOMEM = 12" # Out of memory + "L_EACCES = 13" # Permission denied + "L_EFAULT = 14" # Bad address + "L_ENOTBLK = 15" # Block device required + "L_EBUSY = 16" # Device or resource busy + "L_EEXIST = 17" # File exists + "L_EXDEV = 18" # Cross-device link + "L_ENODEV = 19" # No such device + "L_ENOTDIR = 20" # Not a directory + "L_EISDIR = 21" # Is a directory + "L_EINVAL = 22" # Invalid argument + "L_ENFILE = 23" # File table overflow + "L_EMFILE = 24" # Too many open files + "L_ENOTTY = 25" # Not a typewriter + "L_ETXTBSY = 26" # Text file busy + "L_EFBIG = 27" # File too large + "L_ENOSPC = 28" # No space left on device + "L_ESPIPE = 29" # Illegal seek + "L_EROFS = 30" # Read-only file system + "L_EMLINK = 31" # Too many links + "L_EPIPE = 32" # Broken pipe + "L_EDOM = 33" # Math argument out of domain of func + "L_ERANGE = 34" # Math result not representable + "L_EDEADLK = 35" # Resource deadlock would occur + "L_ENAMETOOLONG = 36" # File name too long + "L_ENOLCK = 37" # No record locks available + "L_ENOSYS = 38" # Invalid system call number + "L_ENOTEMPTY = 39" # Directory not empty + "L_ELOOP = 40" # Too many symbolic links encountered + "L_ENOMSG = 42" # No message of desired type + "L_EIDRM = 43" # Identifier removed + "L_ECHRNG = 44" # Channel number out of range + "L_EL2NSYNC = 45" # Level 2 not synchronized + "L_EL3HLT = 46" # Level 3 halted + "L_EL3RST = 47" # Level 3 reset + "L_ELNRNG = 48" # Link number out of range + "L_EUNATCH = 49" # Protocol driver not attached + "L_ENOCSI = 50" # No CSI structure available + "L_EL2HLT = 51" # Level 2 halted + "L_EBADE = 52" # Invalid exchange + "L_EBADR = 53" # Invalid request descriptor + "L_EXFULL = 54" # Exchange full + "L_ENOANO = 55" # No anode + "L_EBADRQC = 56" # Invalid request code + "L_EBADSLT = 57" # Invalid slot + "L_EBFONT = 59" # Bad font file format + "L_ENOSTR = 60" # Device not a stream + "L_ENODATA = 61" # No data available + "L_ETIME = 62" # Timer expired + "L_ENOSR = 63" # Out of streams resources + "L_ENONET = 64" # Machine is not on the network + "L_ENOPKG = 65" # Package not installed + "L_EREMOTE = 66" # Object is remote + "L_ENOLINK = 67" # Link has been severed + "L_EADV = 68" # Advertise error + "L_ESRMNT = 69" # Srmount error + "L_ECOMM = 70" # Communication error on send + "L_EPROTO = 71" # Protocol error + "L_EMULTIHOP = 72" # Multihop attempted + "L_EDOTDOT = 73" # RFS specific error + "L_EBADMSG = 74" # Not a data message + "L_EOVERFLOW = 75" # Value too large for defined data type + "L_ENOTUNIQ = 76" # Name not unique on network + "L_EBADFD = 77" # File descriptor in bad state + "L_EREMCHG = 78" # Remote address changed + "L_ELIBACC = 79" # Can not access a needed shared library + "L_ELIBBAD = 80" # Accessing a corrupted shared library + "L_ELIBSCN = 81" # .lib section in a.out corrupted + "L_ELIBMAX = 82" # Attempting to link in too many shared libraries + "L_ELIBEXEC = 83" # Cannot exec a shared library directly + "L_EILSEQ = 84" # Illegal byte sequence + "L_ERESTART = 85" # Interrupted system call should be restarted + "L_ESTRPIPE = 86" # Streams pipe error + "L_EUSERS = 87" # Too many users + "L_ENOTSOCK = 88" # Socket operation on non-socket + "L_EDESTADDRREQ = 89" # Destination address required + "L_EMSGSIZE = 90" # Message too long + "L_EPROTOTYPE = 91" # Protocol wrong type for socket + "L_ENOPROTOOPT = 92" # Protocol not available + "L_EPROTONOSUPPORT = 93" # Protocol not supported + "L_ESOCKTNOSUPPORT = 94" # Socket type not supported + "L_EOPNOTSUPP = 95" # Operation not supported on transport endpoint + "L_EPFNOSUPPORT = 96" # Protocol family not supported + "L_EAFNOSUPPORT = 97" # Address family not supported by protocol + "L_EADDRINUSE = 98" # Address already in use + "L_EADDRNOTAVAIL = 99" # Cannot assign requested address + "L_ENETDOWN = 100" # Network is down + "L_ENETUNREACH = 101" # Network is unreachable + "L_ENETRESET = 102" # Network dropped connection because of reset + "L_ECONNABORTED = 103" # Software caused connection abort + "L_ECONNRESET = 104" # Connection reset by peer + "L_ENOBUFS = 105" # No buffer space available + "L_EISCONN = 106" # Transport endpoint is already connected + "L_ENOTCONN = 107" # Transport endpoint is not connected + "L_ESHUTDOWN = 108" # Cannot send after transport endpoint shutdown + "L_ETOOMANYREFS = 109" # Too many references: cannot splice + "L_ETIMEDOUT = 110" # Connection timed out + "L_ECONNREFUSED = 111" # Connection refused + "L_EHOSTDOWN = 112" # Host is down + "L_EHOSTUNREACH = 113" # No route to host + "L_EALREADY = 114" # Operation already in progress + "L_EINPROGRESS = 115" # Operation now in progress + "L_ESTALE = 116" # Stale file handle + "L_EUCLEAN = 117" # Structure needs cleaning + "L_ENOTNAM = 118" # Not a XENIX named type file + "L_ENAVAIL = 119" # No XENIX semaphores available + "L_EISNAM = 120" # Is a named type file + "L_EREMOTEIO = 121" # Remote I/O error + "L_EDQUOT = 122" # Quota exceeded + "L_ENOMEDIUM = 123" # No medium found + "L_EMEDIUMTYPE = 124" # Wrong medium type + "L_ECANCELED = 125" # Operation Canceled + "L_ENOKEY = 126" # Required key not available + "L_EKEYEXPIRED = 127" # Key has expired + "L_EKEYREVOKED = 128" # Key has been revoked + "L_EKEYREJECTED = 129" # Key was rejected by service + "L_EOWNERDEAD = 130" # Owner died + "L_ENOTRECOVERABLE = 131" # State not recoverable + "L_ERFKILL = 132" # Operation not possible due to RF-kill + "L_EHWPOISON = 133" # Memory page has hardware error num super_magic = 4 # See <linux/magic.h> (linux.git include/uapi/linux/magic.h). @@ -168,8 +308,23 @@ num lock_status = 1 "ERROR=2" "GRACE=3" +# 9P2000 Operations (.L subset) ################################################ + +from ./2002-9P2000.9p import Tversion, Rversion +from ./2002-9P2000.9p import Tflush, Rflush +from ./2002-9P2000.9p import Twalk, Rwalk +from ./2002-9P2000.9p import Tread, Rread, Twrite, Rwrite +from ./2002-9P2000.9p import Tclunk, Rclunk +from ./2002-9P2000.9p import Tremove, Rremove + +# 9P2000.u Operations (.L subset) ############################################## + +from ./2005-9P2000.u.9p import Tattach, Rattach, Tauth, Rauth + +# 9P2000.L Operations ########################################################## + #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[errno]" # analogous to 107/Rerror +msg Rlerror = "size[4,val=end-&size] typ[1,val=7] tag[tag] errnum[errno]" # analogous to 107/Rerror msg Tstatfs = "size[4,val=end-&size] typ[1,val=8] tag[tag] fid[fid]" msg Rstatfs = "size[4,val=end-&size] typ[1,val=9] tag[tag]" # Description | statfs | statvfs "type[super_magic]" # Type of filesystem | f_type | - diff --git a/lib9p/idl/2010-9P2000.L.9p.gen b/lib9p/idl/2010-9P2000.L.9p.gen new file mode 100755 index 0000000..cb32585 --- /dev/null +++ b/lib9p/idl/2010-9P2000.L.9p.gen @@ -0,0 +1,282 @@ +#!/usr/bin/env python +# lib9p/idl/2010-9P2000.L.9p.gen - Generate definitions of 9P2000.L messages +import sys + +print( + f"# lib9p/idl/2010-9P2000.L.9p - Generated by `{' '.join(sys.argv)}`. DO NOT EDIT!" +) +errnos: dict[str, tuple[int, str]] = {} +with open(sys.argv[1], "r", encoding="utf-8") as fh: + for line in fh: + if line.startswith("#"): + print(line) + continue + _num, _name, _desc = line.split(maxsplit=2) + errnos[_name] = (int(_num), _desc.strip()) +print( + """ +# lib9p/idl/2010-9P2000.L.9p - Definitions of 9P2000.L messages +# +# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> +# SPDX-License-Identifier: AGPL-3.0-or-later + +# "9P2000.L" Linux extension +# https://github.com/chaos/diod/blob/master/protocol.md +# https://github.com/chaos/diod/blob/master/src/libnpfs/protocol.h +version "9P2000.L" + +# low-level types ############################################################## + +from ./2002-9P2000.9p import tag, fid, s, qt, qid +from ./2005-9P2000.u.9p import nuid, errno + +# BUG: The definitions of errno are not defined in the 9P2000.L +# protocol spec, and Linux kernel errno values vary by architecture. +# Most architectures share a "generic" list, but a handful (as of +# Linux v6.14, Alpha, MIPS, PA-RISC, PowerPC, and SPARC) have their +# own numbers. This IDL file lists the generic numbers. +# +# https://github.com/chaos/diod/issues/35 +""".strip() +) + +prefix = "num errno += " +namelen = max(len(name) for name in errnos) +numlen = max(len(str(num)) for (num, desc) in errnos.values()) +for name, (num, desc) in errnos.items(): + print(f'{prefix}"L_{name:<{namelen}} = {num:>{numlen}}" # {desc}') + prefix = " " * len(prefix) +print() + +print( + """ +num super_magic = 4 + # See <linux/magic.h> (linux.git include/uapi/linux/magic.h). + # + # To quote `util-linux.git:include/statfs_magic.h`: + # "Unfortunately, Linux kernel header file <linux/magic.h> is + # incomplete mess and kernel returns by statfs f_type many numbers + # that are nowhere specified (in API)." + # + # util-linux <statfs_magic.h> is also incomplete. As is the + # statfs(2) man-page. + # + # I'm working on a patchset to the kernel to get <linux/magic.h> + # to be complete, but in the mean-time I'm just not going to + # bother with putting a list here. + # + # TODO + "V9FS_MAGIC=0x01021997" + +# "L"inux "O"pen flags (flags to pass to Tlopen and Tlcreate) +# +# The values are not specified in in protocol.md, but are specified in +# protocol.h (and are different than the Linux kernel's values, which +# vary by architecture). +bitfield lo = 4 + "bit 0=num(MODE)" # low bit of the 2-bit RDONLY/WRONLY/RDWR/NOACCESS enum + "bit 1=num(MODE)" # high bit of the 2-bit RDONLY/WRONLY/RDWR/NOACCESS enum + #"bit 2=unused" + #"bit 3=unused" + #"bit 4=unused" + #"bit 5=unused" + "bit 6=CREATE" + "bit 7=EXCL" + "bit 8=NOCTTY" + "bit 9=TRUNC" + "bit 10=APPEND" + "bit 11=NONBLOCK" + "bit 12=DSYNC" + "bit 13=BSD_FASYNC" + "bit 14=DIRECT" + "bit 15=LARGEFILE" + "bit 16=DIRECTORY" + "bit 17=NOFOLLOW" + "bit 18=NOATIME" + "bit 19=CLOEXEC" + "bit 20=SYNC" + + "num(MODE) RDONLY = 0" + "num(MODE) WRONLY = 1" + "num(MODE) RDWR = 2" + "num(MODE) NOACCESS = 3" + + "mask FLAG = 0b111111111111111000000" + +# "D"irentry "T"ype +# +# These match the Linux kernel's values. +num dt = 1 + "UNKNOWN = 0" + "PIPE = 1" + "CHAR_DEV = 2" + "DIRECTORY = 4" + "BLOCK_DEV = 6" # proof it's not a bitfield + "REGULAR = 8" + "SYMLINK = 10" # proof it's not a bitfield + "SOCKET = 12" # proof it's not a bitfield + "_WHITEOUT = 14" # proof it's not a bitfield + +# Mode +# +# These match the Linux kernel's values. Why is this 32-bits wide +# instead of just 16? Who knows? +bitfield mode = 4 + #... + "bit 15=num(FMT)" # bit of the 4-bit FMT_ enum + "bit 14=num(FMT)" # bit of the 4-bit FMT_ enum + "bit 13=num(FMT)" # bit of the 4-bit FMT_ enum + "bit 12=num(FMT)" # bit of the 4-bit FMT_ enum + #... + "bit 11=PERM_SETGROUP" + "bit 10=PERM_SETUSER" + "bit 9=PERM_STICKY" + "bit 8=PERM_OWNER_R" + "bit 7=PERM_OWNER_W" + "bit 6=PERM_OWNER_X" + "bit 5=PERM_GROUP_R" + "bit 4=PERM_GROUP_W" + "bit 3=PERM_GROUP_X" + "bit 2=PERM_OTHER_R" + "bit 1=PERM_OTHER_W" + "bit 0=PERM_OTHER_X" + + "num(FMT) PIPE = dt.PIPE<<12" + "num(FMT) CHAR_DEV = dt.CHAR_DEV<<12" + "num(FMT) DIRECTORY = dt.DIRECTORY<<12" + "num(FMT) BLOCK_DEV = dt.BLOCK_DEV<<12" + "num(FMT) REGULAR = dt.REGULAR<<12" + "num(FMT) SYMLINK = dt.SYMLINK<<12" + "num(FMT) SOCKET = dt.SOCKET<<12" + + "mask PERM = 07777" # PERM_* + +# A boolean value that is for some reason 4 bytes wide. +num b4 = 4 + "FALSE=0" + "TRUE=1" + # all other values are true also + +bitfield getattr = 8 + "bit 0=MODE" + "bit 1=NLINK" + "bit 2=UID" + "bit 3=GID" + "bit 4=RDEV" + "bit 5=ATIME" + "bit 6=MTIME" + "bit 7=CTIME" + "bit 8=INO" + "bit 9=SIZE" + "bit 10=BLOCKS" + + "bit 11=BTIME" + "bit 12=GEN" + "bit 13=DATA_VERSION" + + "alias BASIC=0x000007ff" # Mask for fields up to BLOCKS + "alias ALL =0x00003fff" # Mask for All fields above + +bitfield setattr = 4 + "bit 0=MODE" + "bit 1=UID" + "bit 2=GID" + "bit 3=SIZE" + "bit 4=ATIME" + "bit 5=MTIME" + "bit 6=CTIME" + "bit 7=ATIME_SET" + "bit 8=MTIME_SET" + +num lock_type = 1 + "RDLCK=0" + "WRLCK=1" + "UNLCK=2" + +bitfield lock_flags = 4 + "bit 0=BLOCK" + "bit 1=RECLAIM" + +num lock_status = 1 + "SUCCESS=0" + "BLOCKED=1" + "ERROR=2" + "GRACE=3" + +# 9P2000 Operations (.L subset) ################################################ + +from ./2002-9P2000.9p import Tversion, Rversion +from ./2002-9P2000.9p import Tflush, Rflush +from ./2002-9P2000.9p import Twalk, Rwalk +from ./2002-9P2000.9p import Tread, Rread, Twrite, Rwrite +from ./2002-9P2000.9p import Tclunk, Rclunk +from ./2002-9P2000.9p import Tremove, Rremove + +# 9P2000.u Operations (.L subset) ############################################## + +from ./2005-9P2000.u.9p import Tattach, Rattach, Tauth, Rauth + +# 9P2000.L Operations ########################################################## + +#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] errnum[errno]" # analogous to 107/Rerror +msg Tstatfs = "size[4,val=end-&size] typ[1,val=8] tag[tag] fid[fid]" +msg Rstatfs = "size[4,val=end-&size] typ[1,val=9] tag[tag]" # Description | statfs | statvfs + "type[super_magic]" # Type of filesystem | f_type | - + "bsize[4]" # Block size in bytes | f_bsize | f_bsize + # - # Fragment size in bytes | f_frsize (since Linux 2.6) | f_frsize + "blocks[8]" # Size of FS in f_frsize units | f_blocks | f_blocks + "bfree[8]" # Number of free blocks | f_bfree | f_bfree + "bavail[8]" # Number of free blocks for unprivileged users | f_bavail | b_avail + "files[8]" # Number of inodes | f_files | f_files + "ffree[8]" # Number of free inodes | f_ffree | f_ffree + # - # Number of free inodes for unprivileged users | - | f_favail + "fsid[8]" # Filesystem instance ID | f_fsid | f_fsid + # - # Mount flags | f_flags (since Linux 2.6.36) | f_flag + "namelen[4]" # Maximum filename length | f_namemax | f_namemax +msg Tlopen = "size[4,val=end-&size] typ[1,val=12] tag[tag] fid[fid] flags[lo]" # analogous to 112/Topen +msg Rlopen = "size[4,val=end-&size] typ[1,val=13] tag[tag] qid[qid] iounit[4]" # analogous to 113/Ropen +msg Tlcreate = "size[4,val=end-&size] typ[1,val=14] tag[tag] fid[fid] name[s] flags[lo] mode[mode] gid[nuid]" # analogous to 114/Tcreate +msg Rlcreate = "size[4,val=end-&size] typ[1,val=15] tag[tag] qid[qid] iounit[4]" # analogous to 115/Rcreate +msg Tsymlink = "size[4,val=end-&size] typ[1,val=16] tag[tag] fid[fid] name[s] symtgt[s] gid[nuid]" +msg Rsymlink = "size[4,val=end-&size] typ[1,val=17] tag[tag] qid[qid]" +msg Tmknod = "size[4,val=end-&size] typ[1,val=18] tag[tag] dfid[fid] name[s] mode[mode] major[4] minor[4] gid[nuid]" +msg Rmknod = "size[4,val=end-&size] typ[1,val=19] tag[tag] qid[qid]" +msg Trename = "size[4,val=end-&size] typ[1,val=20] tag[tag] fid[fid] dfid[fid] name[s]" +msg Rrename = "size[4,val=end-&size] typ[1,val=21] tag[tag]" +msg Treadlink = "size[4,val=end-&size] typ[1,val=22] tag[tag] fid[fid]" +msg Rreadlink = "size[4,val=end-&size] typ[1,val=23] tag[tag] target[s]" +msg Tgetattr = "size[4,val=end-&size] typ[1,val=24] tag[tag] fid[fid] request_mask[getattr]" +msg Rgetattr = "size[4,val=end-&size] typ[1,val=25] tag[tag] valid[getattr] qid[qid] mode[mode] uid[nuid] gid[nuid] nlink[8]" + "rdev[8] filesize[8] blksize[8] blocks[8]" + "atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8]" + "ctime_sec[8] ctime_nsec[8] btime_sec[8] btime_nsec[8]" + "gen[8] data_version[8]" +msg Tsetattr = "size[4,val=end-&size] typ[1,val=26] tag[tag] fid[fid] valid[setattr] mode[mode] uid[nuid] gid[nuid] filesize[8] atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8]" +msg Rsetattr = "size[4,val=end-&size] typ[1,val=27] tag[tag]" +#... +msg Txattrwalk = "size[4,val=end-&size] typ[1,val=30] tag[tag] fid[fid] newfid[fid] name[s]" +msg Rxattrwalk = "size[4,val=end-&size] typ[1,val=31] tag[tag] attr_size[8]" +msg Txattrcreate = "size[4,val=end-&size] typ[1,val=32] tag[tag] fid[fid] name[s] attr_size[8] flags[4]" +msg Rxattrcreate = "size[4,val=end-&size] typ[1,val=33] tag[tag]" +#... +msg Treaddir = "size[4,val=end-&size] typ[1,val=40] tag[tag] fid[fid] offset[8] count[4]" +msg Rreaddir = "size[4,val=end-&size] typ[1,val=41] tag[tag] count[4] count*(data[1])" # data is "qid[qid] offset[8] type[dt] name[s]" +#... +msg Tfsync = "size[4,val=end-&size] typ[1,val=50] tag[tag] fid[fid] datasync[b4]" +msg Rfsync = "size[4,val=end-&size] typ[1,val=51] tag[tag]" +msg Tlock = "size[4,val=end-&size] typ[1,val=52] tag[tag] fid[fid] type[lock_type] flags[lock_flags] start[8] length[8] proc_id[4] client_id[s]" +msg Rlock = "size[4,val=end-&size] typ[1,val=53] tag[tag] status[lock_status]" +msg Tgetlock = "size[4,val=end-&size] typ[1,val=54] tag[tag] fid[fid] type[lock_type] start[8] length[8] proc_id[4] client_id[s]" +msg Rgetlock = "size[4,val=end-&size] typ[1,val=55] tag[tag] type[lock_type] start[8] length[8] proc_id[4] client_id[s]" +# ... +msg Tlink = "size[4,val=end-&size] typ[1,val=70] tag[tag] dfid[fid] fid[fid] name[s]" +msg Rlink = "size[4,val=end-&size] typ[1,val=71] tag[tag]" +msg Tmkdir = "size[4,val=end-&size] typ[1,val=72] tag[tag] dfid[fid] name[s] mode[mode] gid[nuid]" +msg Rmkdir = "size[4,val=end-&size] typ[1,val=73] tag[tag] qid[qid]" +msg Trenameat = "size[4,val=end-&size] typ[1,val=74] tag[tag] olddirfid[fid] oldname[s] newdirfid[fid] newname[s]" +msg Rrenameat = "size[4,val=end-&size] typ[1,val=75] tag[tag]" +msg Tunlinkat = "size[4,val=end-&size] typ[1,val=76] tag[tag] dirfd[fid] name[s] flags[4]" +msg Runlinkat = "size[4,val=end-&size] typ[1,val=77] tag[tag]" +""".strip() +) diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py index 2d09217..3133cc4 100644 --- a/lib9p/idl/__init__.py +++ b/lib9p/idl/__init__.py @@ -647,17 +647,16 @@ def re_string(grpname: str) -> str: re_line_version = f"version\\s+{re_string('version')}" re_line_import = f"from\\s+(?P<file>\\S+)\\s+import\\s+(?P<syms>{re_impname}(?:\\s*,\\s*{re_impname})*)" re_line_num = f"num\\s+(?P<name>{re_symname})\\s*=\\s*(?P<prim>{re_priname})" +re_line_num_ = f"num\\s+(?P<name>{re_symname})\\s*\\+=\\s*{re_string('spec')}" re_line_bitfield = f"bitfield\\s+(?P<name>{re_symname})\\s*=\\s*(?P<prim>{re_priname})" -re_line_bitfield_ = ( - f"bitfield\\s+(?P<name>{re_symname})\\s*\\+=\\s*{re_string('member')}" -) +re_line_bitfield_ = f"bitfield\\s+(?P<name>{re_symname})\\s*\\+=\\s*{re_string('spec')}" re_line_struct = ( f"struct\\s+(?P<name>{re_symname})\\s*(?P<op>\\+?=)\\s*{re_string('members')}" ) re_line_msg = ( f"msg\\s+(?P<name>{re_msgname})\\s*(?P<op>\\+?=)\\s*{re_string('members')}" ) -re_line_cont = f"\\s+{re_string('specs')}" # could be bitfield/struct/msg +re_line_cont = f"\\s+{re_string('spec')}" # could be bitfield/struct/msg def parse_file( @@ -741,6 +740,11 @@ def parse_file( raise ValueError(f"duplicate type name {num.typname!r}") env[num.typname] = num prev = num + elif m := re.fullmatch(re_line_num_, line): + num = get_type(env, m.group("name"), Number) + parse_numspec(env, version, num, m.group("spec")) + + prev = num elif m := re.fullmatch(re_line_bitfield, line): prim = env[m.group("prim")] assert isinstance(prim, Primitive) @@ -754,7 +758,7 @@ def parse_file( prev = bf elif m := re.fullmatch(re_line_bitfield_, line): bf = get_type(env, m.group("name"), Bitfield) - parse_bitspec(env, version, bf, m.group("member")) + parse_bitspec(env, version, bf, m.group("spec")) prev = bf elif m := re.fullmatch(re_line_struct, line): @@ -798,11 +802,11 @@ def parse_file( elif m := re.fullmatch(re_line_cont, line): match prev: case Bitfield(): - parse_bitspec(env, version, prev, m.group("specs")) + parse_bitspec(env, version, prev, m.group("spec")) case Number(): - parse_numspec(env, version, prev, m.group("specs")) + parse_numspec(env, version, prev, m.group("spec")) case Struct(): # and Message() - parse_members(version, env, prev, m.group("specs")) + parse_members(version, env, prev, m.group("spec")) case _: raise SyntaxError( "continuation line must come after a bitfield, struct, or msg line" |