diff options
Diffstat (limited to 'lib9p/tests')
-rw-r--r-- | lib9p/tests/client_config/config.h | 19 | ||||
-rwxr-xr-x | lib9p/tests/runtest | 81 | ||||
-rw-r--r-- | lib9p/tests/test_compile.c | 1480 | ||||
-rwxr-xr-x | lib9p/tests/test_compile.c.gen | 4 | ||||
-rw-r--r-- | lib9p/tests/test_compile_config/config.h | 13 | ||||
-rw-r--r-- | lib9p/tests/test_server/CMakeLists.txt | 4 | ||||
-rw-r--r-- | lib9p/tests/test_server/config/config.h | 33 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_flush.c | 131 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_flush.h | 27 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_shutdown.c | 104 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_shutdown.h | 23 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_whoami.c | 153 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_whoami.h | 20 | ||||
-rw-r--r-- | lib9p/tests/test_server/main.c | 191 | ||||
-rwxr-xr-x | lib9p/tests/testclient-p9p | 65 | ||||
-rw-r--r-- | lib9p/tests/testclient-p9p.explog | 106 | ||||
-rw-r--r-- | lib9p/tests/testclient-sess.c | 243 | ||||
-rw-r--r-- | lib9p/tests/testclient-sess.explog | 156 |
18 files changed, 2401 insertions, 452 deletions
diff --git a/lib9p/tests/client_config/config.h b/lib9p/tests/client_config/config.h new file mode 100644 index 0000000..bcf030d --- /dev/null +++ b/lib9p/tests/client_config/config.h @@ -0,0 +1,19 @@ +/* config.h - Compile-time configuration for lib9p test clients + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#define CONFIG_9P_MAX_ERR_SIZE 128 +#define CONFIG_9P_MAX_9P2000_e_WELEM 16 + +#define CONFIG_9P_ENABLE_9P2000 1 /* bool */ +#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */ +#define CONFIG_9P_ENABLE_9P2000_e 1 /* bool */ +#define CONFIG_9P_ENABLE_9P2000_L 1 /* bool */ +#define CONFIG_9P_ENABLE_9P2000_p9p 1 /* bool */ + +#endif /* _CONFIG_H_ */ diff --git a/lib9p/tests/runtest b/lib9p/tests/runtest index 379ea6d..6883391 100755 --- a/lib9p/tests/runtest +++ b/lib9p/tests/runtest @@ -1,65 +1,50 @@ #!/usr/bin/env bash -# lib9p/tests/runtest - Simple tests for the 9P `test_server` +# lib9p/tests/runtest - Test harness for the 9P `test_server` # # Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> # SPDX-License-Identifier: AGPL-3.0-or-later set -euE -o pipefail -set -x -port=$(python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()') -valgrind --error-exitcode=2 ./tests/test_server/test_server "$port" & -server_pid=$! -# shellcheck disable=SC2064 -trap "kill $server_pid || true; wait $server_pid || true" EXIT -server_addr="localhost:${port}" +build_aux=$(realpath --canonicalize-missing -- "${BASH_SOURCE[0]}/../../../build-aux") -client=(9p -a "$server_addr") +if [[ $# != 2 ]]; then + echo >&2 "Usage: $0 CLIENTSCRIPT EXPLOG" + exit 2 +fi +clientscript="$1" +explog="$2" -expect_lines() ( +cleanup=() +cleanup() { { set +x; } &>/dev/null - printf >&2 '+ diff -u expected.txt actual.txt\n' - diff -u <(printf '%s\n' "$@") <(printf '%s\n' "$out") -) - -while [[ -d /proc/$server_pid && "$(readlink /proc/$server_pid/fd/4 2>/dev/null)" != socket:* ]]; do sleep 0.1; done - -out=$("${client[@]}" ls -l '') -expect_lines \ - 'd-r-xr-xr-x M 0 root root 0 Oct 7 2024 Documentation' \ - '--r--r--r-- M 0 root root 166 Oct 7 2024 README.md' \ - '---w--w--w- M 0 root root 0 Oct 7 2024 shutdown' + local i + for ((i = ${#cleanup[@]} - 1; i >= 0; i--)); do + eval "set -x; ${cleanup[$i]}" + { set +x; } &>/dev/null + done +} +trap cleanup EXIT -out=$("${client[@]}" ls -l 'Documentation/') -expect_lines \ - '--r--r--r-- M 0 root root 166 Oct 7 2024 x' +logfile=$(mktemp -t lib9p-log.XXXXXXXXXX) +cleanup+=("rm -f -- ${logfile@Q}") -out=$("${client[@]}" read 'README.md') -expect_lines \ - '<!--' \ - ' README.md - test static file' \ - '' \ - ' Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>' \ - ' SPDX-License-Identifier: AGPL-3.0-or-later' \ - '-->' \ - 'Hello, world!' +port=$(python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()') -out=$("${client[@]}" read 'Documentation/x') -expect_lines \ - '<!--' \ - ' Documentation/x.txt - test static file' \ - '' \ - ' Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>' \ - ' SPDX-License-Identifier: AGPL-3.0-or-later' \ - '-->' \ - 'foo' +set -x -out=$("${client[@]}" stat 'Documentation/x') -expect_lines \ - "'x' 'root' 'root' 'root' q (0000000000000001 1 ) m 0444 at 1728337905 mt 1728337904 l 166 t 0 d 0" +"${build_aux}/valgrind" ./tests/test_server/test_server "$port" "$logfile" & +server_pid=$! +cleanup+=("kill $server_pid || true; wait $server_pid || true") +while [[ -d /proc/$server_pid ]] && ! (readlink /proc/$server_pid/fd/* 2>/dev/null | grep -q ^socket:); do sleep 0.1; done -out=$("${client[@]}" write 'shutdown' <<<1) -expect_lines '' +if [[ "$(head -c2 -- "$clientscript")" == '#!' ]]; then + "$clientscript" "$port" +else + "${build_aux}/valgrind" "$clientscript" "$port" +fi wait "$server_pid" -trap - EXIT +cleanup=("${cleanup[@]::1}") + +diff -u -- <(grep -e '^[<>]' -- "$explog") "$logfile" diff --git a/lib9p/tests/test_compile.c b/lib9p/tests/test_compile.c index 8f2445d..e53b738 100644 --- a/lib9p/tests/test_compile.c +++ b/lib9p/tests/test_compile.c @@ -1,299 +1,1255 @@ /* lib9p/tests/test_compile.c - Generated by lib9p/tests/test_compile.c.gen. DO NOT EDIT! */ -#include <lib9p/9p.h> +#include <lib9p/core.h> int main(void) { [[gnu::unused]] uint64_t x; - x = LIB9P_TAG_NOTAG; - x = LIB9P_FID_NOFID; - x = LIB9P_DM_DIR; +#ifdef LIB9P_B4_FALSE + x = LIB9P_B4_FALSE; +#endif +#ifdef LIB9P_B4_TRUE + x = LIB9P_B4_TRUE; +#endif +#ifdef LIB9P_DM_APPEND x = LIB9P_DM_APPEND; - x = LIB9P_DM_EXCL; - x = _LIB9P_DM_PLAN9_MOUNT; +#endif +#ifdef LIB9P_DM_AUTH x = LIB9P_DM_AUTH; - x = LIB9P_DM_TMP; - x = _LIB9P_DM_UNUSED_25; - x = _LIB9P_DM_UNUSED_24; +#endif +#ifdef LIB9P_DM_DEVICE x = LIB9P_DM_DEVICE; - x = _LIB9P_DM_UNUSED_22; - x = LIB9P_DM_PIPE; - x = LIB9P_DM_SOCKET; - x = LIB9P_DM_SETUID; - x = LIB9P_DM_SETGID; - x = _LIB9P_DM_UNUSED_17; - x = _LIB9P_DM_UNUSED_16; - x = _LIB9P_DM_UNUSED_15; - x = _LIB9P_DM_UNUSED_14; - x = _LIB9P_DM_UNUSED_13; - x = _LIB9P_DM_UNUSED_12; - x = _LIB9P_DM_UNUSED_11; - x = _LIB9P_DM_UNUSED_10; - x = _LIB9P_DM_UNUSED_9; - x = LIB9P_DM_OWNER_R; - x = LIB9P_DM_OWNER_W; - x = LIB9P_DM_OWNER_X; +#endif +#ifdef LIB9P_DM_DIR + x = LIB9P_DM_DIR; +#endif +#ifdef LIB9P_DM_EXCL + x = LIB9P_DM_EXCL; +#endif +#ifdef LIB9P_DM_GROUP_R x = LIB9P_DM_GROUP_R; +#endif +#ifdef LIB9P_DM_GROUP_W x = LIB9P_DM_GROUP_W; +#endif +#ifdef LIB9P_DM_GROUP_X x = LIB9P_DM_GROUP_X; +#endif +#ifdef LIB9P_DM_OTHER_R x = LIB9P_DM_OTHER_R; +#endif +#ifdef LIB9P_DM_OTHER_W x = LIB9P_DM_OTHER_W; +#endif +#ifdef LIB9P_DM_OTHER_X x = LIB9P_DM_OTHER_X; +#endif +#ifdef LIB9P_DM_OWNER_R + x = LIB9P_DM_OWNER_R; +#endif +#ifdef LIB9P_DM_OWNER_W + x = LIB9P_DM_OWNER_W; +#endif +#ifdef LIB9P_DM_OWNER_X + x = LIB9P_DM_OWNER_X; +#endif +#ifdef LIB9P_DM_PERM_MASK x = LIB9P_DM_PERM_MASK; - x = LIB9P_QT_DIR; - x = LIB9P_QT_APPEND; - x = LIB9P_QT_EXCL; - x = _LIB9P_QT_PLAN9_MOUNT; - x = LIB9P_QT_AUTH; - x = LIB9P_QT_TMP; - x = LIB9P_QT_SYMLINK; - x = _LIB9P_QT_UNUSED_0; - x = LIB9P_QT_FILE; - x = LIB9P_NUID_NONUID; - x = _LIB9P_O_UNUSED_7; - x = LIB9P_O_RCLOSE; - x = _LIB9P_O_RESERVED_CEXEC; - x = LIB9P_O_TRUNC; - x = _LIB9P_O_UNUSED_3; - x = _LIB9P_O_UNUSED_2; - x = LIB9P_O_FLAG_MASK; - x = LIB9P_O_MODE_READ; - x = LIB9P_O_MODE_WRITE; - x = LIB9P_O_MODE_RDWR; - x = LIB9P_O_MODE_EXEC; - x = LIB9P_O_MODE_MASK; +#endif +#ifdef LIB9P_DM_PIPE + x = LIB9P_DM_PIPE; +#endif +#ifdef LIB9P_DM_SETGID + x = LIB9P_DM_SETGID; +#endif +#ifdef LIB9P_DM_SETUID + x = LIB9P_DM_SETUID; +#endif +#ifdef LIB9P_DM_SOCKET + x = LIB9P_DM_SOCKET; +#endif +#ifdef LIB9P_DM_TMP + x = LIB9P_DM_TMP; +#endif +#ifdef LIB9P_DT_BLOCK_DEV + x = LIB9P_DT_BLOCK_DEV; +#endif +#ifdef LIB9P_DT_CHAR_DEV + x = LIB9P_DT_CHAR_DEV; +#endif +#ifdef LIB9P_DT_DIRECTORY + x = LIB9P_DT_DIRECTORY; +#endif +#ifdef LIB9P_DT_PIPE + x = LIB9P_DT_PIPE; +#endif +#ifdef LIB9P_DT_REGULAR + x = LIB9P_DT_REGULAR; +#endif +#ifdef LIB9P_DT_SOCKET + x = LIB9P_DT_SOCKET; +#endif +#ifdef LIB9P_DT_SYMLINK + x = LIB9P_DT_SYMLINK; +#endif +#ifdef LIB9P_DT_UNKNOWN + x = LIB9P_DT_UNKNOWN; +#endif +#ifdef LIB9P_ERRNO_L_E2BIG + x = LIB9P_ERRNO_L_E2BIG; +#endif +#ifdef LIB9P_ERRNO_L_EACCES + x = LIB9P_ERRNO_L_EACCES; +#endif +#ifdef LIB9P_ERRNO_L_EADDRINUSE + x = LIB9P_ERRNO_L_EADDRINUSE; +#endif +#ifdef LIB9P_ERRNO_L_EADDRNOTAVAIL + x = LIB9P_ERRNO_L_EADDRNOTAVAIL; +#endif +#ifdef LIB9P_ERRNO_L_EADV + x = LIB9P_ERRNO_L_EADV; +#endif +#ifdef LIB9P_ERRNO_L_EAFNOSUPPORT + x = LIB9P_ERRNO_L_EAFNOSUPPORT; +#endif +#ifdef LIB9P_ERRNO_L_EAGAIN + x = LIB9P_ERRNO_L_EAGAIN; +#endif +#ifdef LIB9P_ERRNO_L_EALREADY + x = LIB9P_ERRNO_L_EALREADY; +#endif +#ifdef LIB9P_ERRNO_L_EBADE + x = LIB9P_ERRNO_L_EBADE; +#endif +#ifdef LIB9P_ERRNO_L_EBADF + x = LIB9P_ERRNO_L_EBADF; +#endif +#ifdef LIB9P_ERRNO_L_EBADFD + x = LIB9P_ERRNO_L_EBADFD; +#endif +#ifdef LIB9P_ERRNO_L_EBADMSG + x = LIB9P_ERRNO_L_EBADMSG; +#endif +#ifdef LIB9P_ERRNO_L_EBADR + x = LIB9P_ERRNO_L_EBADR; +#endif +#ifdef LIB9P_ERRNO_L_EBADRQC + x = LIB9P_ERRNO_L_EBADRQC; +#endif +#ifdef LIB9P_ERRNO_L_EBADSLT + x = LIB9P_ERRNO_L_EBADSLT; +#endif +#ifdef LIB9P_ERRNO_L_EBFONT + x = LIB9P_ERRNO_L_EBFONT; +#endif +#ifdef LIB9P_ERRNO_L_EBUSY + x = LIB9P_ERRNO_L_EBUSY; +#endif +#ifdef LIB9P_ERRNO_L_ECANCELED + x = LIB9P_ERRNO_L_ECANCELED; +#endif +#ifdef LIB9P_ERRNO_L_ECHILD + x = LIB9P_ERRNO_L_ECHILD; +#endif +#ifdef LIB9P_ERRNO_L_ECHRNG + x = LIB9P_ERRNO_L_ECHRNG; +#endif +#ifdef LIB9P_ERRNO_L_ECOMM + x = LIB9P_ERRNO_L_ECOMM; +#endif +#ifdef LIB9P_ERRNO_L_ECONNABORTED + x = LIB9P_ERRNO_L_ECONNABORTED; +#endif +#ifdef LIB9P_ERRNO_L_ECONNREFUSED + x = LIB9P_ERRNO_L_ECONNREFUSED; +#endif +#ifdef LIB9P_ERRNO_L_ECONNRESET + x = LIB9P_ERRNO_L_ECONNRESET; +#endif +#ifdef LIB9P_ERRNO_L_EDEADLK + x = LIB9P_ERRNO_L_EDEADLK; +#endif +#ifdef LIB9P_ERRNO_L_EDESTADDRREQ + x = LIB9P_ERRNO_L_EDESTADDRREQ; +#endif +#ifdef LIB9P_ERRNO_L_EDOM + x = LIB9P_ERRNO_L_EDOM; +#endif +#ifdef LIB9P_ERRNO_L_EDOTDOT + x = LIB9P_ERRNO_L_EDOTDOT; +#endif +#ifdef LIB9P_ERRNO_L_EDQUOT + x = LIB9P_ERRNO_L_EDQUOT; +#endif +#ifdef LIB9P_ERRNO_L_EEXIST + x = LIB9P_ERRNO_L_EEXIST; +#endif +#ifdef LIB9P_ERRNO_L_EFAULT + x = LIB9P_ERRNO_L_EFAULT; +#endif +#ifdef LIB9P_ERRNO_L_EFBIG + x = LIB9P_ERRNO_L_EFBIG; +#endif +#ifdef LIB9P_ERRNO_L_EHOSTDOWN + x = LIB9P_ERRNO_L_EHOSTDOWN; +#endif +#ifdef LIB9P_ERRNO_L_EHOSTUNREACH + x = LIB9P_ERRNO_L_EHOSTUNREACH; +#endif +#ifdef LIB9P_ERRNO_L_EHWPOISON + x = LIB9P_ERRNO_L_EHWPOISON; +#endif +#ifdef LIB9P_ERRNO_L_EIDRM + x = LIB9P_ERRNO_L_EIDRM; +#endif +#ifdef LIB9P_ERRNO_L_EILSEQ + x = LIB9P_ERRNO_L_EILSEQ; +#endif +#ifdef LIB9P_ERRNO_L_EINPROGRESS + x = LIB9P_ERRNO_L_EINPROGRESS; +#endif +#ifdef LIB9P_ERRNO_L_EINTR + x = LIB9P_ERRNO_L_EINTR; +#endif +#ifdef LIB9P_ERRNO_L_EINVAL + x = LIB9P_ERRNO_L_EINVAL; +#endif +#ifdef LIB9P_ERRNO_L_EIO + x = LIB9P_ERRNO_L_EIO; +#endif +#ifdef LIB9P_ERRNO_L_EISCONN + x = LIB9P_ERRNO_L_EISCONN; +#endif +#ifdef LIB9P_ERRNO_L_EISDIR + x = LIB9P_ERRNO_L_EISDIR; +#endif +#ifdef LIB9P_ERRNO_L_EISNAM + x = LIB9P_ERRNO_L_EISNAM; +#endif +#ifdef LIB9P_ERRNO_L_EKEYEXPIRED + x = LIB9P_ERRNO_L_EKEYEXPIRED; +#endif +#ifdef LIB9P_ERRNO_L_EKEYREJECTED + x = LIB9P_ERRNO_L_EKEYREJECTED; +#endif +#ifdef LIB9P_ERRNO_L_EKEYREVOKED + x = LIB9P_ERRNO_L_EKEYREVOKED; +#endif +#ifdef LIB9P_ERRNO_L_EL2HLT + x = LIB9P_ERRNO_L_EL2HLT; +#endif +#ifdef LIB9P_ERRNO_L_EL2NSYNC + x = LIB9P_ERRNO_L_EL2NSYNC; +#endif +#ifdef LIB9P_ERRNO_L_EL3HLT + x = LIB9P_ERRNO_L_EL3HLT; +#endif +#ifdef LIB9P_ERRNO_L_EL3RST + x = LIB9P_ERRNO_L_EL3RST; +#endif +#ifdef LIB9P_ERRNO_L_ELIBACC + x = LIB9P_ERRNO_L_ELIBACC; +#endif +#ifdef LIB9P_ERRNO_L_ELIBBAD + x = LIB9P_ERRNO_L_ELIBBAD; +#endif +#ifdef LIB9P_ERRNO_L_ELIBEXEC + x = LIB9P_ERRNO_L_ELIBEXEC; +#endif +#ifdef LIB9P_ERRNO_L_ELIBMAX + x = LIB9P_ERRNO_L_ELIBMAX; +#endif +#ifdef LIB9P_ERRNO_L_ELIBSCN + x = LIB9P_ERRNO_L_ELIBSCN; +#endif +#ifdef LIB9P_ERRNO_L_ELNRNG + x = LIB9P_ERRNO_L_ELNRNG; +#endif +#ifdef LIB9P_ERRNO_L_ELOOP + x = LIB9P_ERRNO_L_ELOOP; +#endif +#ifdef LIB9P_ERRNO_L_EMEDIUMTYPE + x = LIB9P_ERRNO_L_EMEDIUMTYPE; +#endif +#ifdef LIB9P_ERRNO_L_EMFILE + x = LIB9P_ERRNO_L_EMFILE; +#endif +#ifdef LIB9P_ERRNO_L_EMLINK + x = LIB9P_ERRNO_L_EMLINK; +#endif +#ifdef LIB9P_ERRNO_L_EMSGSIZE + x = LIB9P_ERRNO_L_EMSGSIZE; +#endif +#ifdef LIB9P_ERRNO_L_EMULTIHOP + x = LIB9P_ERRNO_L_EMULTIHOP; +#endif +#ifdef LIB9P_ERRNO_L_ENAMETOOLONG + x = LIB9P_ERRNO_L_ENAMETOOLONG; +#endif +#ifdef LIB9P_ERRNO_L_ENAVAIL + x = LIB9P_ERRNO_L_ENAVAIL; +#endif +#ifdef LIB9P_ERRNO_L_ENETDOWN + x = LIB9P_ERRNO_L_ENETDOWN; +#endif +#ifdef LIB9P_ERRNO_L_ENETRESET + x = LIB9P_ERRNO_L_ENETRESET; +#endif +#ifdef LIB9P_ERRNO_L_ENETUNREACH + x = LIB9P_ERRNO_L_ENETUNREACH; +#endif +#ifdef LIB9P_ERRNO_L_ENFILE + x = LIB9P_ERRNO_L_ENFILE; +#endif +#ifdef LIB9P_ERRNO_L_ENOANO + x = LIB9P_ERRNO_L_ENOANO; +#endif +#ifdef LIB9P_ERRNO_L_ENOBUFS + x = LIB9P_ERRNO_L_ENOBUFS; +#endif +#ifdef LIB9P_ERRNO_L_ENOCSI + x = LIB9P_ERRNO_L_ENOCSI; +#endif +#ifdef LIB9P_ERRNO_L_ENODATA + x = LIB9P_ERRNO_L_ENODATA; +#endif +#ifdef LIB9P_ERRNO_L_ENODEV + x = LIB9P_ERRNO_L_ENODEV; +#endif +#ifdef LIB9P_ERRNO_L_ENOENT + x = LIB9P_ERRNO_L_ENOENT; +#endif +#ifdef LIB9P_ERRNO_L_ENOEXEC + x = LIB9P_ERRNO_L_ENOEXEC; +#endif +#ifdef LIB9P_ERRNO_L_ENOKEY + x = LIB9P_ERRNO_L_ENOKEY; +#endif +#ifdef LIB9P_ERRNO_L_ENOLCK + x = LIB9P_ERRNO_L_ENOLCK; +#endif +#ifdef LIB9P_ERRNO_L_ENOLINK + x = LIB9P_ERRNO_L_ENOLINK; +#endif +#ifdef LIB9P_ERRNO_L_ENOMEDIUM + x = LIB9P_ERRNO_L_ENOMEDIUM; +#endif +#ifdef LIB9P_ERRNO_L_ENOMEM + x = LIB9P_ERRNO_L_ENOMEM; +#endif +#ifdef LIB9P_ERRNO_L_ENOMSG + x = LIB9P_ERRNO_L_ENOMSG; +#endif +#ifdef LIB9P_ERRNO_L_ENONET + x = LIB9P_ERRNO_L_ENONET; +#endif +#ifdef LIB9P_ERRNO_L_ENOPKG + x = LIB9P_ERRNO_L_ENOPKG; +#endif +#ifdef LIB9P_ERRNO_L_ENOPROTOOPT + x = LIB9P_ERRNO_L_ENOPROTOOPT; +#endif +#ifdef LIB9P_ERRNO_L_ENOSPC + x = LIB9P_ERRNO_L_ENOSPC; +#endif +#ifdef LIB9P_ERRNO_L_ENOSR + x = LIB9P_ERRNO_L_ENOSR; +#endif +#ifdef LIB9P_ERRNO_L_ENOSTR + x = LIB9P_ERRNO_L_ENOSTR; +#endif +#ifdef LIB9P_ERRNO_L_ENOSYS + x = LIB9P_ERRNO_L_ENOSYS; +#endif +#ifdef LIB9P_ERRNO_L_ENOTBLK + x = LIB9P_ERRNO_L_ENOTBLK; +#endif +#ifdef LIB9P_ERRNO_L_ENOTCONN + x = LIB9P_ERRNO_L_ENOTCONN; +#endif +#ifdef LIB9P_ERRNO_L_ENOTDIR + x = LIB9P_ERRNO_L_ENOTDIR; +#endif +#ifdef LIB9P_ERRNO_L_ENOTEMPTY + x = LIB9P_ERRNO_L_ENOTEMPTY; +#endif +#ifdef LIB9P_ERRNO_L_ENOTNAM + x = LIB9P_ERRNO_L_ENOTNAM; +#endif +#ifdef LIB9P_ERRNO_L_ENOTRECOVERABLE + x = LIB9P_ERRNO_L_ENOTRECOVERABLE; +#endif +#ifdef LIB9P_ERRNO_L_ENOTSOCK + x = LIB9P_ERRNO_L_ENOTSOCK; +#endif +#ifdef LIB9P_ERRNO_L_ENOTTY + x = LIB9P_ERRNO_L_ENOTTY; +#endif +#ifdef LIB9P_ERRNO_L_ENOTUNIQ + x = LIB9P_ERRNO_L_ENOTUNIQ; +#endif +#ifdef LIB9P_ERRNO_L_ENXIO + x = LIB9P_ERRNO_L_ENXIO; +#endif +#ifdef LIB9P_ERRNO_L_EOPNOTSUPP + x = LIB9P_ERRNO_L_EOPNOTSUPP; +#endif +#ifdef LIB9P_ERRNO_L_EOVERFLOW + x = LIB9P_ERRNO_L_EOVERFLOW; +#endif +#ifdef LIB9P_ERRNO_L_EOWNERDEAD + x = LIB9P_ERRNO_L_EOWNERDEAD; +#endif +#ifdef LIB9P_ERRNO_L_EPERM + x = LIB9P_ERRNO_L_EPERM; +#endif +#ifdef LIB9P_ERRNO_L_EPFNOSUPPORT + x = LIB9P_ERRNO_L_EPFNOSUPPORT; +#endif +#ifdef LIB9P_ERRNO_L_EPIPE + x = LIB9P_ERRNO_L_EPIPE; +#endif +#ifdef LIB9P_ERRNO_L_EPROTO + x = LIB9P_ERRNO_L_EPROTO; +#endif +#ifdef LIB9P_ERRNO_L_EPROTONOSUPPORT + x = LIB9P_ERRNO_L_EPROTONOSUPPORT; +#endif +#ifdef LIB9P_ERRNO_L_EPROTOTYPE + x = LIB9P_ERRNO_L_EPROTOTYPE; +#endif +#ifdef LIB9P_ERRNO_L_ERANGE + x = LIB9P_ERRNO_L_ERANGE; +#endif +#ifdef LIB9P_ERRNO_L_EREMCHG + x = LIB9P_ERRNO_L_EREMCHG; +#endif +#ifdef LIB9P_ERRNO_L_EREMOTE + x = LIB9P_ERRNO_L_EREMOTE; +#endif +#ifdef LIB9P_ERRNO_L_EREMOTEIO + x = LIB9P_ERRNO_L_EREMOTEIO; +#endif +#ifdef LIB9P_ERRNO_L_ERESTART + x = LIB9P_ERRNO_L_ERESTART; +#endif +#ifdef LIB9P_ERRNO_L_ERFKILL + x = LIB9P_ERRNO_L_ERFKILL; +#endif +#ifdef LIB9P_ERRNO_L_EROFS + x = LIB9P_ERRNO_L_EROFS; +#endif +#ifdef LIB9P_ERRNO_L_ESHUTDOWN + x = LIB9P_ERRNO_L_ESHUTDOWN; +#endif +#ifdef LIB9P_ERRNO_L_ESOCKTNOSUPPORT + x = LIB9P_ERRNO_L_ESOCKTNOSUPPORT; +#endif +#ifdef LIB9P_ERRNO_L_ESPIPE + x = LIB9P_ERRNO_L_ESPIPE; +#endif +#ifdef LIB9P_ERRNO_L_ESRCH + x = LIB9P_ERRNO_L_ESRCH; +#endif +#ifdef LIB9P_ERRNO_L_ESRMNT + x = LIB9P_ERRNO_L_ESRMNT; +#endif +#ifdef LIB9P_ERRNO_L_ESTALE + x = LIB9P_ERRNO_L_ESTALE; +#endif +#ifdef LIB9P_ERRNO_L_ESTRPIPE + x = LIB9P_ERRNO_L_ESTRPIPE; +#endif +#ifdef LIB9P_ERRNO_L_ETIME + x = LIB9P_ERRNO_L_ETIME; +#endif +#ifdef LIB9P_ERRNO_L_ETIMEDOUT + x = LIB9P_ERRNO_L_ETIMEDOUT; +#endif +#ifdef LIB9P_ERRNO_L_ETOOMANYREFS + x = LIB9P_ERRNO_L_ETOOMANYREFS; +#endif +#ifdef LIB9P_ERRNO_L_ETXTBSY + x = LIB9P_ERRNO_L_ETXTBSY; +#endif +#ifdef LIB9P_ERRNO_L_EUCLEAN + x = LIB9P_ERRNO_L_EUCLEAN; +#endif +#ifdef LIB9P_ERRNO_L_EUNATCH + x = LIB9P_ERRNO_L_EUNATCH; +#endif +#ifdef LIB9P_ERRNO_L_EUSERS + x = LIB9P_ERRNO_L_EUSERS; +#endif +#ifdef LIB9P_ERRNO_L_EXDEV + x = LIB9P_ERRNO_L_EXDEV; +#endif +#ifdef LIB9P_ERRNO_L_EXFULL + x = LIB9P_ERRNO_L_EXFULL; +#endif +#ifdef LIB9P_ERRNO_NOERROR x = LIB9P_ERRNO_NOERROR; - x = LIB9P_SUPER_MAGIC_V9FS_MAGIC; - x = _LIB9P_LO_UNUSED_31; - x = _LIB9P_LO_UNUSED_30; - x = _LIB9P_LO_UNUSED_29; - x = _LIB9P_LO_UNUSED_28; - x = _LIB9P_LO_UNUSED_27; - x = _LIB9P_LO_UNUSED_26; - x = _LIB9P_LO_UNUSED_25; - x = _LIB9P_LO_UNUSED_24; - x = _LIB9P_LO_UNUSED_23; - x = _LIB9P_LO_UNUSED_22; - x = _LIB9P_LO_UNUSED_21; - x = LIB9P_LO_SYNC; +#endif +#ifdef LIB9P_FID_NOFID + x = LIB9P_FID_NOFID; +#endif +#ifdef LIB9P_GETATTR_ALL + x = LIB9P_GETATTR_ALL; +#endif +#ifdef LIB9P_GETATTR_ATIME + x = LIB9P_GETATTR_ATIME; +#endif +#ifdef LIB9P_GETATTR_BASIC + x = LIB9P_GETATTR_BASIC; +#endif +#ifdef LIB9P_GETATTR_BLOCKS + x = LIB9P_GETATTR_BLOCKS; +#endif +#ifdef LIB9P_GETATTR_BTIME + x = LIB9P_GETATTR_BTIME; +#endif +#ifdef LIB9P_GETATTR_CTIME + x = LIB9P_GETATTR_CTIME; +#endif +#ifdef LIB9P_GETATTR_DATA_VERSION + x = LIB9P_GETATTR_DATA_VERSION; +#endif +#ifdef LIB9P_GETATTR_GEN + x = LIB9P_GETATTR_GEN; +#endif +#ifdef LIB9P_GETATTR_GID + x = LIB9P_GETATTR_GID; +#endif +#ifdef LIB9P_GETATTR_INO + x = LIB9P_GETATTR_INO; +#endif +#ifdef LIB9P_GETATTR_MODE + x = LIB9P_GETATTR_MODE; +#endif +#ifdef LIB9P_GETATTR_MTIME + x = LIB9P_GETATTR_MTIME; +#endif +#ifdef LIB9P_GETATTR_NLINK + x = LIB9P_GETATTR_NLINK; +#endif +#ifdef LIB9P_GETATTR_RDEV + x = LIB9P_GETATTR_RDEV; +#endif +#ifdef LIB9P_GETATTR_SIZE + x = LIB9P_GETATTR_SIZE; +#endif +#ifdef LIB9P_GETATTR_UID + x = LIB9P_GETATTR_UID; +#endif +#ifdef LIB9P_LOCK_FLAGS_BLOCK + x = LIB9P_LOCK_FLAGS_BLOCK; +#endif +#ifdef LIB9P_LOCK_FLAGS_RECLAIM + x = LIB9P_LOCK_FLAGS_RECLAIM; +#endif +#ifdef LIB9P_LOCK_STATUS_BLOCKED + x = LIB9P_LOCK_STATUS_BLOCKED; +#endif +#ifdef LIB9P_LOCK_STATUS_ERROR + x = LIB9P_LOCK_STATUS_ERROR; +#endif +#ifdef LIB9P_LOCK_STATUS_GRACE + x = LIB9P_LOCK_STATUS_GRACE; +#endif +#ifdef LIB9P_LOCK_STATUS_SUCCESS + x = LIB9P_LOCK_STATUS_SUCCESS; +#endif +#ifdef LIB9P_LOCK_TYPE_RDLCK + x = LIB9P_LOCK_TYPE_RDLCK; +#endif +#ifdef LIB9P_LOCK_TYPE_UNLCK + x = LIB9P_LOCK_TYPE_UNLCK; +#endif +#ifdef LIB9P_LOCK_TYPE_WRLCK + x = LIB9P_LOCK_TYPE_WRLCK; +#endif +#ifdef LIB9P_LO_APPEND + x = LIB9P_LO_APPEND; +#endif +#ifdef LIB9P_LO_BSD_FASYNC + x = LIB9P_LO_BSD_FASYNC; +#endif +#ifdef LIB9P_LO_CLOEXEC x = LIB9P_LO_CLOEXEC; - x = LIB9P_LO_NOATIME; - x = LIB9P_LO_NOFOLLOW; - x = LIB9P_LO_DIRECTORY; - x = LIB9P_LO_LARGEFILE; +#endif +#ifdef LIB9P_LO_CREATE + x = LIB9P_LO_CREATE; +#endif +#ifdef LIB9P_LO_DIRECT x = LIB9P_LO_DIRECT; - x = LIB9P_LO_BSD_FASYNC; +#endif +#ifdef LIB9P_LO_DIRECTORY + x = LIB9P_LO_DIRECTORY; +#endif +#ifdef LIB9P_LO_DSYNC x = LIB9P_LO_DSYNC; - x = LIB9P_LO_NONBLOCK; - x = LIB9P_LO_APPEND; - x = LIB9P_LO_TRUNC; - x = LIB9P_LO_NOCTTY; +#endif +#ifdef LIB9P_LO_EXCL x = LIB9P_LO_EXCL; - x = LIB9P_LO_CREATE; - x = _LIB9P_LO_UNUSED_5; - x = _LIB9P_LO_UNUSED_4; - x = _LIB9P_LO_UNUSED_3; - x = _LIB9P_LO_UNUSED_2; +#endif +#ifdef LIB9P_LO_FLAG_MASK x = LIB9P_LO_FLAG_MASK; +#endif +#ifdef LIB9P_LO_LARGEFILE + x = LIB9P_LO_LARGEFILE; +#endif +#ifdef LIB9P_LO_MODE_MASK + x = LIB9P_LO_MODE_MASK; +#endif +#ifdef LIB9P_LO_MODE_NOACCESS + x = LIB9P_LO_MODE_NOACCESS; +#endif +#ifdef LIB9P_LO_MODE_RDONLY x = LIB9P_LO_MODE_RDONLY; - x = LIB9P_LO_MODE_WRONLY; +#endif +#ifdef LIB9P_LO_MODE_RDWR x = LIB9P_LO_MODE_RDWR; - x = LIB9P_LO_MODE_NOACCESS; - x = LIB9P_LO_MODE_MASK; - x = LIB9P_DT_UNKNOWN; - x = LIB9P_DT_PIPE; - x = LIB9P_DT_CHAR_DEV; - x = LIB9P_DT_DIRECTORY; - x = LIB9P_DT_BLOCK_DEV; - x = LIB9P_DT_REGULAR; - x = LIB9P_DT_SYMLINK; - x = LIB9P_DT_SOCKET; - x = _LIB9P_DT_WHITEOUT; - x = _LIB9P_MODE_UNUSED_31; - x = _LIB9P_MODE_UNUSED_30; - x = _LIB9P_MODE_UNUSED_29; - x = _LIB9P_MODE_UNUSED_28; - x = _LIB9P_MODE_UNUSED_27; - x = _LIB9P_MODE_UNUSED_26; - x = _LIB9P_MODE_UNUSED_25; - x = _LIB9P_MODE_UNUSED_24; - x = _LIB9P_MODE_UNUSED_23; - x = _LIB9P_MODE_UNUSED_22; - x = _LIB9P_MODE_UNUSED_21; - x = _LIB9P_MODE_UNUSED_20; - x = _LIB9P_MODE_UNUSED_19; - x = _LIB9P_MODE_UNUSED_18; - x = _LIB9P_MODE_UNUSED_17; - x = _LIB9P_MODE_UNUSED_16; - x = LIB9P_MODE_PERM_SETGROUP; - x = LIB9P_MODE_PERM_SETUSER; - x = LIB9P_MODE_PERM_STICKY; - x = LIB9P_MODE_PERM_OWNER_R; - x = LIB9P_MODE_PERM_OWNER_W; - x = LIB9P_MODE_PERM_OWNER_X; +#endif +#ifdef LIB9P_LO_MODE_WRONLY + x = LIB9P_LO_MODE_WRONLY; +#endif +#ifdef LIB9P_LO_NOATIME + x = LIB9P_LO_NOATIME; +#endif +#ifdef LIB9P_LO_NOCTTY + x = LIB9P_LO_NOCTTY; +#endif +#ifdef LIB9P_LO_NOFOLLOW + x = LIB9P_LO_NOFOLLOW; +#endif +#ifdef LIB9P_LO_NONBLOCK + x = LIB9P_LO_NONBLOCK; +#endif +#ifdef LIB9P_LO_SYNC + x = LIB9P_LO_SYNC; +#endif +#ifdef LIB9P_LO_TRUNC + x = LIB9P_LO_TRUNC; +#endif +#ifdef LIB9P_MODE_FMT_BLOCK_DEV + x = LIB9P_MODE_FMT_BLOCK_DEV; +#endif +#ifdef LIB9P_MODE_FMT_CHAR_DEV + x = LIB9P_MODE_FMT_CHAR_DEV; +#endif +#ifdef LIB9P_MODE_FMT_DIRECTORY + x = LIB9P_MODE_FMT_DIRECTORY; +#endif +#ifdef LIB9P_MODE_FMT_MASK + x = LIB9P_MODE_FMT_MASK; +#endif +#ifdef LIB9P_MODE_FMT_PIPE + x = LIB9P_MODE_FMT_PIPE; +#endif +#ifdef LIB9P_MODE_FMT_REGULAR + x = LIB9P_MODE_FMT_REGULAR; +#endif +#ifdef LIB9P_MODE_FMT_SOCKET + x = LIB9P_MODE_FMT_SOCKET; +#endif +#ifdef LIB9P_MODE_FMT_SYMLINK + x = LIB9P_MODE_FMT_SYMLINK; +#endif +#ifdef LIB9P_MODE_PERM_GROUP_R x = LIB9P_MODE_PERM_GROUP_R; +#endif +#ifdef LIB9P_MODE_PERM_GROUP_W x = LIB9P_MODE_PERM_GROUP_W; +#endif +#ifdef LIB9P_MODE_PERM_GROUP_X x = LIB9P_MODE_PERM_GROUP_X; +#endif +#ifdef LIB9P_MODE_PERM_MASK + x = LIB9P_MODE_PERM_MASK; +#endif +#ifdef LIB9P_MODE_PERM_OTHER_R x = LIB9P_MODE_PERM_OTHER_R; +#endif +#ifdef LIB9P_MODE_PERM_OTHER_W x = LIB9P_MODE_PERM_OTHER_W; +#endif +#ifdef LIB9P_MODE_PERM_OTHER_X x = LIB9P_MODE_PERM_OTHER_X; - x = LIB9P_MODE_PERM_MASK; - x = LIB9P_MODE_FMT_PIPE; - x = LIB9P_MODE_FMT_CHAR_DEV; - x = LIB9P_MODE_FMT_DIRECTORY; - x = LIB9P_MODE_FMT_BLOCK_DEV; - x = LIB9P_MODE_FMT_REGULAR; - x = LIB9P_MODE_FMT_SYMLINK; - x = LIB9P_MODE_FMT_SOCKET; - x = LIB9P_MODE_FMT_MASK; - x = LIB9P_B4_FALSE; - x = LIB9P_B4_TRUE; - x = _LIB9P_GETATTR_UNUSED_63; - x = _LIB9P_GETATTR_UNUSED_62; - x = _LIB9P_GETATTR_UNUSED_61; - x = _LIB9P_GETATTR_UNUSED_60; - x = _LIB9P_GETATTR_UNUSED_59; - x = _LIB9P_GETATTR_UNUSED_58; - x = _LIB9P_GETATTR_UNUSED_57; - x = _LIB9P_GETATTR_UNUSED_56; - x = _LIB9P_GETATTR_UNUSED_55; - x = _LIB9P_GETATTR_UNUSED_54; - x = _LIB9P_GETATTR_UNUSED_53; - x = _LIB9P_GETATTR_UNUSED_52; - x = _LIB9P_GETATTR_UNUSED_51; - x = _LIB9P_GETATTR_UNUSED_50; - x = _LIB9P_GETATTR_UNUSED_49; - x = _LIB9P_GETATTR_UNUSED_48; - x = _LIB9P_GETATTR_UNUSED_47; - x = _LIB9P_GETATTR_UNUSED_46; - x = _LIB9P_GETATTR_UNUSED_45; - x = _LIB9P_GETATTR_UNUSED_44; - x = _LIB9P_GETATTR_UNUSED_43; - x = _LIB9P_GETATTR_UNUSED_42; - x = _LIB9P_GETATTR_UNUSED_41; - x = _LIB9P_GETATTR_UNUSED_40; - x = _LIB9P_GETATTR_UNUSED_39; - x = _LIB9P_GETATTR_UNUSED_38; - x = _LIB9P_GETATTR_UNUSED_37; - x = _LIB9P_GETATTR_UNUSED_36; - x = _LIB9P_GETATTR_UNUSED_35; - x = _LIB9P_GETATTR_UNUSED_34; - x = _LIB9P_GETATTR_UNUSED_33; - x = _LIB9P_GETATTR_UNUSED_32; - x = _LIB9P_GETATTR_UNUSED_31; - x = _LIB9P_GETATTR_UNUSED_30; - x = _LIB9P_GETATTR_UNUSED_29; - x = _LIB9P_GETATTR_UNUSED_28; - x = _LIB9P_GETATTR_UNUSED_27; - x = _LIB9P_GETATTR_UNUSED_26; - x = _LIB9P_GETATTR_UNUSED_25; - x = _LIB9P_GETATTR_UNUSED_24; - x = _LIB9P_GETATTR_UNUSED_23; - x = _LIB9P_GETATTR_UNUSED_22; - x = _LIB9P_GETATTR_UNUSED_21; - x = _LIB9P_GETATTR_UNUSED_20; - x = _LIB9P_GETATTR_UNUSED_19; - x = _LIB9P_GETATTR_UNUSED_18; - x = _LIB9P_GETATTR_UNUSED_17; - x = _LIB9P_GETATTR_UNUSED_16; - x = _LIB9P_GETATTR_UNUSED_15; - x = _LIB9P_GETATTR_UNUSED_14; - x = LIB9P_GETATTR_DATA_VERSION; - x = LIB9P_GETATTR_GEN; - x = LIB9P_GETATTR_BTIME; - x = LIB9P_GETATTR_BLOCKS; - x = LIB9P_GETATTR_SIZE; - x = LIB9P_GETATTR_INO; - x = LIB9P_GETATTR_CTIME; - x = LIB9P_GETATTR_MTIME; - x = LIB9P_GETATTR_ATIME; - x = LIB9P_GETATTR_RDEV; - x = LIB9P_GETATTR_GID; - x = LIB9P_GETATTR_UID; - x = LIB9P_GETATTR_NLINK; - x = LIB9P_GETATTR_MODE; - x = LIB9P_GETATTR_BASIC; - x = LIB9P_GETATTR_ALL; - x = _LIB9P_SETATTR_UNUSED_31; - x = _LIB9P_SETATTR_UNUSED_30; - x = _LIB9P_SETATTR_UNUSED_29; - x = _LIB9P_SETATTR_UNUSED_28; - x = _LIB9P_SETATTR_UNUSED_27; - x = _LIB9P_SETATTR_UNUSED_26; - x = _LIB9P_SETATTR_UNUSED_25; - x = _LIB9P_SETATTR_UNUSED_24; - x = _LIB9P_SETATTR_UNUSED_23; - x = _LIB9P_SETATTR_UNUSED_22; - x = _LIB9P_SETATTR_UNUSED_21; - x = _LIB9P_SETATTR_UNUSED_20; - x = _LIB9P_SETATTR_UNUSED_19; - x = _LIB9P_SETATTR_UNUSED_18; - x = _LIB9P_SETATTR_UNUSED_17; - x = _LIB9P_SETATTR_UNUSED_16; - x = _LIB9P_SETATTR_UNUSED_15; - x = _LIB9P_SETATTR_UNUSED_14; - x = _LIB9P_SETATTR_UNUSED_13; - x = _LIB9P_SETATTR_UNUSED_12; - x = _LIB9P_SETATTR_UNUSED_11; - x = _LIB9P_SETATTR_UNUSED_10; - x = _LIB9P_SETATTR_UNUSED_9; - x = LIB9P_SETATTR_MTIME_SET; +#endif +#ifdef LIB9P_MODE_PERM_OWNER_R + x = LIB9P_MODE_PERM_OWNER_R; +#endif +#ifdef LIB9P_MODE_PERM_OWNER_W + x = LIB9P_MODE_PERM_OWNER_W; +#endif +#ifdef LIB9P_MODE_PERM_OWNER_X + x = LIB9P_MODE_PERM_OWNER_X; +#endif +#ifdef LIB9P_MODE_PERM_SETGROUP + x = LIB9P_MODE_PERM_SETGROUP; +#endif +#ifdef LIB9P_MODE_PERM_SETUSER + x = LIB9P_MODE_PERM_SETUSER; +#endif +#ifdef LIB9P_MODE_PERM_STICKY + x = LIB9P_MODE_PERM_STICKY; +#endif +#ifdef LIB9P_NUID_NONUID + x = LIB9P_NUID_NONUID; +#endif +#ifdef LIB9P_O_FLAG_MASK + x = LIB9P_O_FLAG_MASK; +#endif +#ifdef LIB9P_O_MODE_EXEC + x = LIB9P_O_MODE_EXEC; +#endif +#ifdef LIB9P_O_MODE_MASK + x = LIB9P_O_MODE_MASK; +#endif +#ifdef LIB9P_O_MODE_RDWR + x = LIB9P_O_MODE_RDWR; +#endif +#ifdef LIB9P_O_MODE_READ + x = LIB9P_O_MODE_READ; +#endif +#ifdef LIB9P_O_MODE_WRITE + x = LIB9P_O_MODE_WRITE; +#endif +#ifdef LIB9P_O_RCLOSE + x = LIB9P_O_RCLOSE; +#endif +#ifdef LIB9P_O_TRUNC + x = LIB9P_O_TRUNC; +#endif +#ifdef LIB9P_QT_APPEND + x = LIB9P_QT_APPEND; +#endif +#ifdef LIB9P_QT_AUTH + x = LIB9P_QT_AUTH; +#endif +#ifdef LIB9P_QT_DIR + x = LIB9P_QT_DIR; +#endif +#ifdef LIB9P_QT_EXCL + x = LIB9P_QT_EXCL; +#endif +#ifdef LIB9P_QT_FILE + x = LIB9P_QT_FILE; +#endif +#ifdef LIB9P_QT_SYMLINK + x = LIB9P_QT_SYMLINK; +#endif +#ifdef LIB9P_QT_TMP + x = LIB9P_QT_TMP; +#endif +#ifdef LIB9P_RMSG_MAX_COPY + x = LIB9P_RMSG_MAX_COPY; +#endif +#ifdef LIB9P_RMSG_MAX_IOV + x = LIB9P_RMSG_MAX_IOV; +#endif +#ifdef LIB9P_SETATTR_ATIME + x = LIB9P_SETATTR_ATIME; +#endif +#ifdef LIB9P_SETATTR_ATIME_SET x = LIB9P_SETATTR_ATIME_SET; +#endif +#ifdef LIB9P_SETATTR_CTIME x = LIB9P_SETATTR_CTIME; +#endif +#ifdef LIB9P_SETATTR_GID + x = LIB9P_SETATTR_GID; +#endif +#ifdef LIB9P_SETATTR_MODE + x = LIB9P_SETATTR_MODE; +#endif +#ifdef LIB9P_SETATTR_MTIME x = LIB9P_SETATTR_MTIME; - x = LIB9P_SETATTR_ATIME; +#endif +#ifdef LIB9P_SETATTR_MTIME_SET + x = LIB9P_SETATTR_MTIME_SET; +#endif +#ifdef LIB9P_SETATTR_SIZE x = LIB9P_SETATTR_SIZE; - x = LIB9P_SETATTR_GID; +#endif +#ifdef LIB9P_SETATTR_UID x = LIB9P_SETATTR_UID; - x = LIB9P_SETATTR_MODE; - x = LIB9P_LOCK_TYPE_RDLCK; - x = LIB9P_LOCK_TYPE_WRLCK; - x = LIB9P_LOCK_TYPE_UNLCK; - x = _LIB9P_LOCK_FLAGS_UNUSED_31; - x = _LIB9P_LOCK_FLAGS_UNUSED_30; - x = _LIB9P_LOCK_FLAGS_UNUSED_29; - x = _LIB9P_LOCK_FLAGS_UNUSED_28; - x = _LIB9P_LOCK_FLAGS_UNUSED_27; - x = _LIB9P_LOCK_FLAGS_UNUSED_26; - x = _LIB9P_LOCK_FLAGS_UNUSED_25; - x = _LIB9P_LOCK_FLAGS_UNUSED_24; - x = _LIB9P_LOCK_FLAGS_UNUSED_23; - x = _LIB9P_LOCK_FLAGS_UNUSED_22; - x = _LIB9P_LOCK_FLAGS_UNUSED_21; - x = _LIB9P_LOCK_FLAGS_UNUSED_20; - x = _LIB9P_LOCK_FLAGS_UNUSED_19; - x = _LIB9P_LOCK_FLAGS_UNUSED_18; - x = _LIB9P_LOCK_FLAGS_UNUSED_17; - x = _LIB9P_LOCK_FLAGS_UNUSED_16; - x = _LIB9P_LOCK_FLAGS_UNUSED_15; - x = _LIB9P_LOCK_FLAGS_UNUSED_14; - x = _LIB9P_LOCK_FLAGS_UNUSED_13; - x = _LIB9P_LOCK_FLAGS_UNUSED_12; - x = _LIB9P_LOCK_FLAGS_UNUSED_11; +#endif +#ifdef LIB9P_SUPER_MAGIC_V9FS_MAGIC + x = LIB9P_SUPER_MAGIC_V9FS_MAGIC; +#endif +#ifdef LIB9P_TAG_NOTAG + x = LIB9P_TAG_NOTAG; +#endif +#ifdef LIB9P_TMSG_MAX_COPY + x = LIB9P_TMSG_MAX_COPY; +#endif +#ifdef LIB9P_TMSG_MAX_IOV + x = LIB9P_TMSG_MAX_IOV; +#endif +#ifdef _LIB9P_DM_PLAN9_MOUNT + x = _LIB9P_DM_PLAN9_MOUNT; +#endif +#ifdef _LIB9P_DM_UNUSED_10 + x = _LIB9P_DM_UNUSED_10; +#endif +#ifdef _LIB9P_DM_UNUSED_11 + x = _LIB9P_DM_UNUSED_11; +#endif +#ifdef _LIB9P_DM_UNUSED_12 + x = _LIB9P_DM_UNUSED_12; +#endif +#ifdef _LIB9P_DM_UNUSED_13 + x = _LIB9P_DM_UNUSED_13; +#endif +#ifdef _LIB9P_DM_UNUSED_14 + x = _LIB9P_DM_UNUSED_14; +#endif +#ifdef _LIB9P_DM_UNUSED_15 + x = _LIB9P_DM_UNUSED_15; +#endif +#ifdef _LIB9P_DM_UNUSED_16 + x = _LIB9P_DM_UNUSED_16; +#endif +#ifdef _LIB9P_DM_UNUSED_17 + x = _LIB9P_DM_UNUSED_17; +#endif +#ifdef _LIB9P_DM_UNUSED_22 + x = _LIB9P_DM_UNUSED_22; +#endif +#ifdef _LIB9P_DM_UNUSED_24 + x = _LIB9P_DM_UNUSED_24; +#endif +#ifdef _LIB9P_DM_UNUSED_25 + x = _LIB9P_DM_UNUSED_25; +#endif +#ifdef _LIB9P_DM_UNUSED_9 + x = _LIB9P_DM_UNUSED_9; +#endif +#ifdef _LIB9P_DT_WHITEOUT + x = _LIB9P_DT_WHITEOUT; +#endif +#ifdef _LIB9P_ENABLE_stat + x = _LIB9P_ENABLE_stat; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_14 + x = _LIB9P_GETATTR_UNUSED_14; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_15 + x = _LIB9P_GETATTR_UNUSED_15; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_16 + x = _LIB9P_GETATTR_UNUSED_16; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_17 + x = _LIB9P_GETATTR_UNUSED_17; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_18 + x = _LIB9P_GETATTR_UNUSED_18; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_19 + x = _LIB9P_GETATTR_UNUSED_19; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_20 + x = _LIB9P_GETATTR_UNUSED_20; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_21 + x = _LIB9P_GETATTR_UNUSED_21; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_22 + x = _LIB9P_GETATTR_UNUSED_22; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_23 + x = _LIB9P_GETATTR_UNUSED_23; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_24 + x = _LIB9P_GETATTR_UNUSED_24; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_25 + x = _LIB9P_GETATTR_UNUSED_25; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_26 + x = _LIB9P_GETATTR_UNUSED_26; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_27 + x = _LIB9P_GETATTR_UNUSED_27; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_28 + x = _LIB9P_GETATTR_UNUSED_28; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_29 + x = _LIB9P_GETATTR_UNUSED_29; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_30 + x = _LIB9P_GETATTR_UNUSED_30; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_31 + x = _LIB9P_GETATTR_UNUSED_31; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_32 + x = _LIB9P_GETATTR_UNUSED_32; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_33 + x = _LIB9P_GETATTR_UNUSED_33; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_34 + x = _LIB9P_GETATTR_UNUSED_34; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_35 + x = _LIB9P_GETATTR_UNUSED_35; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_36 + x = _LIB9P_GETATTR_UNUSED_36; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_37 + x = _LIB9P_GETATTR_UNUSED_37; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_38 + x = _LIB9P_GETATTR_UNUSED_38; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_39 + x = _LIB9P_GETATTR_UNUSED_39; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_40 + x = _LIB9P_GETATTR_UNUSED_40; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_41 + x = _LIB9P_GETATTR_UNUSED_41; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_42 + x = _LIB9P_GETATTR_UNUSED_42; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_43 + x = _LIB9P_GETATTR_UNUSED_43; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_44 + x = _LIB9P_GETATTR_UNUSED_44; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_45 + x = _LIB9P_GETATTR_UNUSED_45; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_46 + x = _LIB9P_GETATTR_UNUSED_46; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_47 + x = _LIB9P_GETATTR_UNUSED_47; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_48 + x = _LIB9P_GETATTR_UNUSED_48; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_49 + x = _LIB9P_GETATTR_UNUSED_49; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_50 + x = _LIB9P_GETATTR_UNUSED_50; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_51 + x = _LIB9P_GETATTR_UNUSED_51; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_52 + x = _LIB9P_GETATTR_UNUSED_52; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_53 + x = _LIB9P_GETATTR_UNUSED_53; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_54 + x = _LIB9P_GETATTR_UNUSED_54; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_55 + x = _LIB9P_GETATTR_UNUSED_55; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_56 + x = _LIB9P_GETATTR_UNUSED_56; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_57 + x = _LIB9P_GETATTR_UNUSED_57; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_58 + x = _LIB9P_GETATTR_UNUSED_58; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_59 + x = _LIB9P_GETATTR_UNUSED_59; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_60 + x = _LIB9P_GETATTR_UNUSED_60; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_61 + x = _LIB9P_GETATTR_UNUSED_61; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_62 + x = _LIB9P_GETATTR_UNUSED_62; +#endif +#ifdef _LIB9P_GETATTR_UNUSED_63 + x = _LIB9P_GETATTR_UNUSED_63; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_10 x = _LIB9P_LOCK_FLAGS_UNUSED_10; - x = _LIB9P_LOCK_FLAGS_UNUSED_9; - x = _LIB9P_LOCK_FLAGS_UNUSED_8; - x = _LIB9P_LOCK_FLAGS_UNUSED_7; - x = _LIB9P_LOCK_FLAGS_UNUSED_6; - x = _LIB9P_LOCK_FLAGS_UNUSED_5; - x = _LIB9P_LOCK_FLAGS_UNUSED_4; - x = _LIB9P_LOCK_FLAGS_UNUSED_3; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_11 + x = _LIB9P_LOCK_FLAGS_UNUSED_11; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_12 + x = _LIB9P_LOCK_FLAGS_UNUSED_12; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_13 + x = _LIB9P_LOCK_FLAGS_UNUSED_13; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_14 + x = _LIB9P_LOCK_FLAGS_UNUSED_14; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_15 + x = _LIB9P_LOCK_FLAGS_UNUSED_15; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_16 + x = _LIB9P_LOCK_FLAGS_UNUSED_16; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_17 + x = _LIB9P_LOCK_FLAGS_UNUSED_17; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_18 + x = _LIB9P_LOCK_FLAGS_UNUSED_18; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_19 + x = _LIB9P_LOCK_FLAGS_UNUSED_19; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_2 x = _LIB9P_LOCK_FLAGS_UNUSED_2; - x = LIB9P_LOCK_FLAGS_RECLAIM; - x = LIB9P_LOCK_FLAGS_BLOCK; - x = LIB9P_LOCK_STATUS_SUCCESS; - x = LIB9P_LOCK_STATUS_BLOCKED; - x = LIB9P_LOCK_STATUS_ERROR; - x = LIB9P_LOCK_STATUS_GRACE; - x = LIB9P_TMSG_MAX_IOV; - x = LIB9P_TMSG_MAX_IOV; - x = LIB9P_TMSG_MAX_COPY; - x = LIB9P_TMSG_MAX_COPY; - x = LIB9P_TMSG_MAX_COPY; - x = LIB9P_TMSG_MAX_COPY; - x = LIB9P_TMSG_MAX_COPY; - x = LIB9P_TMSG_MAX_COPY; - x = LIB9P_RMSG_MAX_IOV; - x = LIB9P_RMSG_MAX_IOV; - x = LIB9P_RMSG_MAX_IOV; - x = LIB9P_RMSG_MAX_COPY; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_20 + x = _LIB9P_LOCK_FLAGS_UNUSED_20; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_21 + x = _LIB9P_LOCK_FLAGS_UNUSED_21; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_22 + x = _LIB9P_LOCK_FLAGS_UNUSED_22; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_23 + x = _LIB9P_LOCK_FLAGS_UNUSED_23; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_24 + x = _LIB9P_LOCK_FLAGS_UNUSED_24; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_25 + x = _LIB9P_LOCK_FLAGS_UNUSED_25; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_26 + x = _LIB9P_LOCK_FLAGS_UNUSED_26; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_27 + x = _LIB9P_LOCK_FLAGS_UNUSED_27; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_28 + x = _LIB9P_LOCK_FLAGS_UNUSED_28; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_29 + x = _LIB9P_LOCK_FLAGS_UNUSED_29; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_3 + x = _LIB9P_LOCK_FLAGS_UNUSED_3; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_30 + x = _LIB9P_LOCK_FLAGS_UNUSED_30; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_31 + x = _LIB9P_LOCK_FLAGS_UNUSED_31; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_4 + x = _LIB9P_LOCK_FLAGS_UNUSED_4; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_5 + x = _LIB9P_LOCK_FLAGS_UNUSED_5; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_6 + x = _LIB9P_LOCK_FLAGS_UNUSED_6; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_7 + x = _LIB9P_LOCK_FLAGS_UNUSED_7; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_8 + x = _LIB9P_LOCK_FLAGS_UNUSED_8; +#endif +#ifdef _LIB9P_LOCK_FLAGS_UNUSED_9 + x = _LIB9P_LOCK_FLAGS_UNUSED_9; +#endif +#ifdef _LIB9P_LO_UNUSED_2 + x = _LIB9P_LO_UNUSED_2; +#endif +#ifdef _LIB9P_LO_UNUSED_21 + x = _LIB9P_LO_UNUSED_21; +#endif +#ifdef _LIB9P_LO_UNUSED_22 + x = _LIB9P_LO_UNUSED_22; +#endif +#ifdef _LIB9P_LO_UNUSED_23 + x = _LIB9P_LO_UNUSED_23; +#endif +#ifdef _LIB9P_LO_UNUSED_24 + x = _LIB9P_LO_UNUSED_24; +#endif +#ifdef _LIB9P_LO_UNUSED_25 + x = _LIB9P_LO_UNUSED_25; +#endif +#ifdef _LIB9P_LO_UNUSED_26 + x = _LIB9P_LO_UNUSED_26; +#endif +#ifdef _LIB9P_LO_UNUSED_27 + x = _LIB9P_LO_UNUSED_27; +#endif +#ifdef _LIB9P_LO_UNUSED_28 + x = _LIB9P_LO_UNUSED_28; +#endif +#ifdef _LIB9P_LO_UNUSED_29 + x = _LIB9P_LO_UNUSED_29; +#endif +#ifdef _LIB9P_LO_UNUSED_3 + x = _LIB9P_LO_UNUSED_3; +#endif +#ifdef _LIB9P_LO_UNUSED_30 + x = _LIB9P_LO_UNUSED_30; +#endif +#ifdef _LIB9P_LO_UNUSED_31 + x = _LIB9P_LO_UNUSED_31; +#endif +#ifdef _LIB9P_LO_UNUSED_4 + x = _LIB9P_LO_UNUSED_4; +#endif +#ifdef _LIB9P_LO_UNUSED_5 + x = _LIB9P_LO_UNUSED_5; +#endif +#ifdef _LIB9P_MODE_UNUSED_16 + x = _LIB9P_MODE_UNUSED_16; +#endif +#ifdef _LIB9P_MODE_UNUSED_17 + x = _LIB9P_MODE_UNUSED_17; +#endif +#ifdef _LIB9P_MODE_UNUSED_18 + x = _LIB9P_MODE_UNUSED_18; +#endif +#ifdef _LIB9P_MODE_UNUSED_19 + x = _LIB9P_MODE_UNUSED_19; +#endif +#ifdef _LIB9P_MODE_UNUSED_20 + x = _LIB9P_MODE_UNUSED_20; +#endif +#ifdef _LIB9P_MODE_UNUSED_21 + x = _LIB9P_MODE_UNUSED_21; +#endif +#ifdef _LIB9P_MODE_UNUSED_22 + x = _LIB9P_MODE_UNUSED_22; +#endif +#ifdef _LIB9P_MODE_UNUSED_23 + x = _LIB9P_MODE_UNUSED_23; +#endif +#ifdef _LIB9P_MODE_UNUSED_24 + x = _LIB9P_MODE_UNUSED_24; +#endif +#ifdef _LIB9P_MODE_UNUSED_25 + x = _LIB9P_MODE_UNUSED_25; +#endif +#ifdef _LIB9P_MODE_UNUSED_26 + x = _LIB9P_MODE_UNUSED_26; +#endif +#ifdef _LIB9P_MODE_UNUSED_27 + x = _LIB9P_MODE_UNUSED_27; +#endif +#ifdef _LIB9P_MODE_UNUSED_28 + x = _LIB9P_MODE_UNUSED_28; +#endif +#ifdef _LIB9P_MODE_UNUSED_29 + x = _LIB9P_MODE_UNUSED_29; +#endif +#ifdef _LIB9P_MODE_UNUSED_30 + x = _LIB9P_MODE_UNUSED_30; +#endif +#ifdef _LIB9P_MODE_UNUSED_31 + x = _LIB9P_MODE_UNUSED_31; +#endif +#ifdef _LIB9P_O_RESERVED_CEXEC + x = _LIB9P_O_RESERVED_CEXEC; +#endif +#ifdef _LIB9P_O_UNUSED_2 + x = _LIB9P_O_UNUSED_2; +#endif +#ifdef _LIB9P_O_UNUSED_3 + x = _LIB9P_O_UNUSED_3; +#endif +#ifdef _LIB9P_O_UNUSED_7 + x = _LIB9P_O_UNUSED_7; +#endif +#ifdef _LIB9P_QT_PLAN9_MOUNT + x = _LIB9P_QT_PLAN9_MOUNT; +#endif +#ifdef _LIB9P_QT_UNUSED_0 + x = _LIB9P_QT_UNUSED_0; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_10 + x = _LIB9P_SETATTR_UNUSED_10; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_11 + x = _LIB9P_SETATTR_UNUSED_11; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_12 + x = _LIB9P_SETATTR_UNUSED_12; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_13 + x = _LIB9P_SETATTR_UNUSED_13; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_14 + x = _LIB9P_SETATTR_UNUSED_14; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_15 + x = _LIB9P_SETATTR_UNUSED_15; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_16 + x = _LIB9P_SETATTR_UNUSED_16; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_17 + x = _LIB9P_SETATTR_UNUSED_17; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_18 + x = _LIB9P_SETATTR_UNUSED_18; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_19 + x = _LIB9P_SETATTR_UNUSED_19; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_20 + x = _LIB9P_SETATTR_UNUSED_20; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_21 + x = _LIB9P_SETATTR_UNUSED_21; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_22 + x = _LIB9P_SETATTR_UNUSED_22; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_23 + x = _LIB9P_SETATTR_UNUSED_23; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_24 + x = _LIB9P_SETATTR_UNUSED_24; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_25 + x = _LIB9P_SETATTR_UNUSED_25; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_26 + x = _LIB9P_SETATTR_UNUSED_26; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_27 + x = _LIB9P_SETATTR_UNUSED_27; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_28 + x = _LIB9P_SETATTR_UNUSED_28; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_29 + x = _LIB9P_SETATTR_UNUSED_29; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_30 + x = _LIB9P_SETATTR_UNUSED_30; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_31 + x = _LIB9P_SETATTR_UNUSED_31; +#endif +#ifdef _LIB9P_SETATTR_UNUSED_9 + x = _LIB9P_SETATTR_UNUSED_9; +#endif return 0; } diff --git a/lib9p/tests/test_compile.c.gen b/lib9p/tests/test_compile.c.gen index 47046b3..eb89c54 100755 --- a/lib9p/tests/test_compile.c.gen +++ b/lib9p/tests/test_compile.c.gen @@ -10,10 +10,10 @@ outfile=$2 { echo "/* ${outfile} - Generated by $0. DO NOT EDIT! */" echo - echo "#include <lib9p/9p.h>" + echo "#include <lib9p/core.h>" echo 'int main(void) {' echo ' [[gnu::unused]] uint64_t x;' - sed -nE 's/^\s*#\s*define\s*(\S[^ (]*)\s.*/ x = \1;/p' <"$generated_h" + <"$generated_h" sed -nE 's/^\s*#\s*define\s*(\S[^ (]*)\s.*/\1/p' | LC_COLLATE=C sort -u | sed 's/.*/#ifdef &\n x = &;\n#endif/' echo ' return 0;' echo '}' } >"$outfile" diff --git a/lib9p/tests/test_compile_config/config.h b/lib9p/tests/test_compile_config/config.h index cc8eec1..02cb8e5 100644 --- a/lib9p/tests/test_compile_config/config.h +++ b/lib9p/tests/test_compile_config/config.h @@ -12,17 +12,10 @@ #define CONFIG_9P_MAX_ERR_SIZE 128 #define CONFIG_9P_MAX_9P2000_e_WELEM 16 +/* 9P_SRV *********************************************************************/ + #define CONFIG_9P_SRV_MAX_MSG_SIZE ((4*1024)+24) #define CONFIG_9P_SRV_MAX_HOSTMSG_SIZE CONFIG_9P_SRV_MAX_MSG_SIZE+16 -#define CONFIG_9P_SRV_MAX_FIDS 16 -#define CONFIG_9P_SRV_MAX_REQS 2 -#define CONFIG_9P_SRV_MAX_DEPTH 3 - -#define CONFIG_9P_ENABLE_9P2000 1 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_e 1 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_L 1 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_p9p 1 /* bool */ /* COROUTINE ******************************************************************/ @@ -33,6 +26,6 @@ #define CONFIG_COROUTINE_DEBUG 0 /* bool */ #define CONFIG_COROUTINE_VALGRIND 1 /* bool */ #define CONFIG_COROUTINE_GDB 1 /* bool */ -#define CONFIG_COROUTINE_NUM 2 +#define CONFIG_COROUTINE_NUM 8 #endif /* _CONFIG_H_ */ diff --git a/lib9p/tests/test_server/CMakeLists.txt b/lib9p/tests/test_server/CMakeLists.txt index 5313917..c61d344 100644 --- a/lib9p/tests/test_server/CMakeLists.txt +++ b/lib9p/tests/test_server/CMakeLists.txt @@ -9,6 +9,9 @@ if (PICO_PLATFORM STREQUAL "host") add_library(test_server_objs OBJECT main.c + fs_flush.c + fs_shutdown.c + fs_whoami.c ) target_include_directories(test_server_objs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/config) target_include_directories(test_server_objs PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) @@ -16,7 +19,6 @@ target_link_libraries(test_server_objs libcr libcr_ipc libmisc - lib9p lib9p_util libhw_cr ) diff --git a/lib9p/tests/test_server/config/config.h b/lib9p/tests/test_server/config/config.h index 03143e1..f49894b 100644 --- a/lib9p/tests/test_server/config/config.h +++ b/lib9p/tests/test_server/config/config.h @@ -7,13 +7,23 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -#define _CONFIG_9P_NUM_SOCKS 8 -#define CONFIG_SRV9P_NUM_CONNS _CONFIG_9P_NUM_SOCKS +#define _CONFIG_9P_MAX_CONNS 8 +#define _CONFIG_9P_MAX_REQS (2*_CONFIG_9P_MAX_CONNS) /* 9P *************************************************************************/ #define CONFIG_9P_MAX_ERR_SIZE 128 /* 128 is what Plan 9 4e uses */ +#define CONFIG_9P_ENABLE_9P2000 1 /* bool */ +#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */ +#define CONFIG_9P_ENABLE_9P2000_e 0 /* bool */ +#define CONFIG_9P_ENABLE_9P2000_L 0 /* bool */ +#define CONFIG_9P_ENABLE_9P2000_p9p 0 /* bool */ + +/* 9P_SRV *********************************************************************/ + +#define CONFIG_9P_SRV_DEBUG 1 /* bool */ + /** * This max-msg-size is sized so that a Twrite message can return * 8KiB of data. @@ -38,15 +48,6 @@ * struct padding, (2) array pointers. */ #define CONFIG_9P_SRV_MAX_HOSTMSG_SIZE CONFIG_9P_SRV_MAX_MSG_SIZE+16 -#define CONFIG_9P_SRV_MAX_FIDS 16 -#define CONFIG_9P_SRV_MAX_REQS 2 -#define CONFIG_9P_SRV_MAX_DEPTH 3 - -#define CONFIG_9P_ENABLE_9P2000 1 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_u 1 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_e 0 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_L 0 /* bool */ -#define CONFIG_9P_ENABLE_9P2000_p9p 0 /* bool */ /* COROUTINE ******************************************************************/ @@ -57,10 +58,10 @@ #define CONFIG_COROUTINE_DEBUG 0 /* bool */ #define CONFIG_COROUTINE_VALGRIND 1 /* bool */ #define CONFIG_COROUTINE_GDB 1 /* bool */ -#define CONFIG_COROUTINE_NUM ( \ - 1 /* usb_common */ + \ - 1 /* usb_keyboard */ + \ - CONFIG_SRV9P_NUM_CONNS /* accept+read */ + \ - (CONFIG_9P_SRV_MAX_REQS*CONFIG_SRV9P_NUM_CONNS) /* work+write */ ) +#define CONFIG_COROUTINE_NUM ( \ + 1 /* usb_common */ + \ + 1 /* usb_keyboard */ + \ + _CONFIG_9P_MAX_CONNS /* accept+read */ + \ + _CONFIG_9P_MAX_REQS /* work+write */ ) #endif /* _CONFIG_H_ */ diff --git a/lib9p/tests/test_server/fs_flush.c b/lib9p/tests/test_server/fs_flush.c new file mode 100644 index 0000000..e6408d7 --- /dev/null +++ b/lib9p/tests/test_server/fs_flush.c @@ -0,0 +1,131 @@ +/* lib9p/tests/test_server/fs_flush.c - flush-* API endpoints + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <libmisc/alloc.h> + +#define IMPLEMENTATION_FOR_LIB9P_SRV_H YES /* for ctx->flush_ch */ +#include "fs_flush.h" + +LO_IMPLEMENTATION_C(lib9p_srv_file, struct flush_file, flush_file, static); + +struct flush_fio { + struct flush_file *parent; +}; +LO_IMPLEMENTATION_H(lib9p_srv_fio, struct flush_fio, flush_fio); +LO_IMPLEMENTATION_C(lib9p_srv_fio, struct flush_fio, flush_fio, static); + +/* srv_file *******************************************************************/ + +static void flush_file_free(struct flush_file *self) { + assert(self); +} +static struct lib9p_qid flush_file_qid(struct flush_file *self) { + assert(self); + return (struct lib9p_qid){ + .type = LIB9P_QT_FILE, + .vers = 1, + .path = self->pathnum, + }; +} + +static struct lib9p_srv_stat flush_file_stat(struct flush_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + return (struct lib9p_srv_stat){ + .qid = flush_file_qid(self), + .mode = 0444, + .atime_sec = UTIL9P_ATIME, + .mtime_sec = UTIL9P_MTIME, + .size = 6, + .name = lib9p_str(self->name), + .owner_uid = { .name = lib9p_str("root"), .num = 0 }, + .owner_gid = { .name = lib9p_str("root"), .num = 0 }, + .last_modifier_uid = { .name = lib9p_str("root"), .num = 0 }, + .extension = lib9p_str(NULL), + }; +} +static void flush_file_wstat(struct flush_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_srv_stat) { + assert(self); + assert(ctx); + lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "cannot wstat API file"); +} +static void flush_file_remove(struct flush_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "cannot remove API file"); +} + +LIB9P_SRV_NOTDIR(struct flush_file, flush_file) + +static lo_interface lib9p_srv_fio flush_file_fopen(struct flush_file *self, struct lib9p_srv_ctx *ctx, bool, bool, bool) { + assert(self); + assert(ctx); + + struct flush_fio *ret = heap_alloc(1, struct flush_fio); + ret->parent = self; + + return lo_box_flush_fio_as_lib9p_srv_fio(ret); +} + +/* srv_fio ********************************************************************/ + +static void flush_fio_iofree(struct flush_fio *self) { + assert(self); + free(self); +} + +static struct lib9p_qid flush_fio_qid(struct flush_fio *self) { + assert(self); + return flush_file_qid(self->parent); +} + +static uint32_t flush_fio_iounit(struct flush_fio *self) { + assert(self); + return 0; +} + +static uint32_t flush_fio_pwrite(struct flush_fio *LM_UNUSED(self), + struct lib9p_srv_ctx *LM_UNUSED(ctx), + void *LM_UNUSED(buf), uint32_t LM_UNUSED(byte_count), + uint64_t LM_UNUSED(offset)) { + assert_notreached("not writable"); +} + +static void flush_fio_pread(struct flush_fio *self, struct lib9p_srv_ctx *ctx, + uint32_t byte_count, uint64_t LM_UNUSED(byte_offset), + struct iovec *ret) { + assert(self); + assert(ctx); + assert(ret); + + /* Wait for first Tflush */ + while (!lib9p_srv_flush_requested(ctx)) + cr_yield(); + + /* Wait for the specified number of Tflush (may be higher *or* + * lower than 1; lower would mean that the first Tflush needs + * to be flushed itself). */ + while (cr_chan_num_waiters(&ctx->flush_ch) != self->parent->flush_cnt) + cr_yield(); + + /* Return */ + switch (self->parent->flush_behavior) { + case FLUSH_READ: + *ret = (struct iovec){ + .iov_base = "Sloth\n", + .iov_len = 6 < byte_count ? 6 : byte_count, + }; + break; + case FLUSH_ERROR: + lib9p_srv_acknowledge_flush(ctx); + lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_ECANCELED, "request canceled by flush"); + break; + case FLUSH_SILENT: + lib9p_srv_acknowledge_flush(ctx); + break; + } + cr_yield(); +} diff --git a/lib9p/tests/test_server/fs_flush.h b/lib9p/tests/test_server/fs_flush.h new file mode 100644 index 0000000..a509c4a --- /dev/null +++ b/lib9p/tests/test_server/fs_flush.h @@ -0,0 +1,27 @@ +/* lib9p/tests/test_server/fs_flush.h - flush-* API endpoints + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIB9P_TESTS_TEST_SERVER_FS_FLUSH_H_ +#define _LIB9P_TESTS_TEST_SERVER_FS_FLUSH_H_ + +#include <util9p/static.h> +#include <libhw/host_net.h> + +struct flush_file { + char *name; + uint64_t pathnum; + + unsigned int flush_cnt; + enum { + FLUSH_READ, + FLUSH_ERROR, + FLUSH_SILENT, + } flush_behavior; +}; +LO_IMPLEMENTATION_H(lib9p_srv_file, struct flush_file, flush_file); +#define lo_box_flush_file_as_lib9p_srv_file(obj) util9p_box(flush_file, obj) + +#endif /* _LIB9P_TESTS_TEST_SERVER_FS_FLUSH_H_ */ diff --git a/lib9p/tests/test_server/fs_shutdown.c b/lib9p/tests/test_server/fs_shutdown.c new file mode 100644 index 0000000..d4ae67e --- /dev/null +++ b/lib9p/tests/test_server/fs_shutdown.c @@ -0,0 +1,104 @@ +/* lib9p/tests/test_server/fs_shutdown.c - /shutdown API endpoint + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <libmisc/alloc.h> + +#include "fs_shutdown.h" + +LO_IMPLEMENTATION_C(lib9p_srv_file, struct shutdown_file, shutdown_file, static); + +struct shutdown_fio { + struct shutdown_file *parent; +}; +LO_IMPLEMENTATION_H(lib9p_srv_fio, struct shutdown_fio, shutdown_fio); +LO_IMPLEMENTATION_C(lib9p_srv_fio, struct shutdown_fio, shutdown_fio, static); + +/* srv_file *******************************************************************/ + +static void shutdown_file_free(struct shutdown_file *self) { + assert(self); +} +static struct lib9p_qid shutdown_file_qid(struct shutdown_file *self) { + assert(self); + return (struct lib9p_qid){ + .type = LIB9P_QT_FILE | LIB9P_QT_APPEND, + .vers = 1, + .path = self->pathnum, + }; +} + +static struct lib9p_srv_stat shutdown_file_stat(struct shutdown_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + return (struct lib9p_srv_stat){ + .qid = shutdown_file_qid(self), + .mode = 0222 | LIB9P_DM_APPEND, + .atime_sec = UTIL9P_ATIME, + .mtime_sec = UTIL9P_MTIME, + .size = 0, + .name = lib9p_str(self->name), + .owner_uid = { .name=lib9p_str("root"), .num=0 }, + .owner_gid = { .name=lib9p_str("root"), .num=0 }, + .last_modifier_uid = { .name=lib9p_str("root"), .num=0 }, + .extension = lib9p_str(NULL), + }; +} +static void shutdown_file_wstat(struct shutdown_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_srv_stat) { + assert(self); + assert(ctx); + lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "cannot wstat API file"); +} +static void shutdown_file_remove(struct shutdown_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "cannot remove API file"); +} + +LIB9P_SRV_NOTDIR(struct shutdown_file, shutdown_file) + +static lo_interface lib9p_srv_fio shutdown_file_fopen(struct shutdown_file *self, struct lib9p_srv_ctx *ctx, bool, bool, bool) { + assert(self); + assert(ctx); + + struct shutdown_fio *ret = heap_alloc(1, struct shutdown_fio); + ret->parent = self; + + return lo_box_shutdown_fio_as_lib9p_srv_fio(ret); +} + +/* srv_fio ********************************************************************/ + +static void shutdown_fio_iofree(struct shutdown_fio *self) { + assert(self); + free(self); +} + +static struct lib9p_qid shutdown_fio_qid(struct shutdown_fio *self) { + assert(self); + return shutdown_file_qid(self->parent); +} + +static uint32_t shutdown_fio_iounit(struct shutdown_fio *self) { + assert(self); + return 0; +} + +static uint32_t shutdown_fio_pwrite(struct shutdown_fio *self, struct lib9p_srv_ctx *ctx, void *buf, uint32_t byte_count, uint64_t offset) { + assert(self); + assert(ctx); + assert(buf); + assert(offset == 0); + if (byte_count == 0) + return 0; + for (size_t i = 0; i < self->parent->nlisteners; i++) + LO_CALL(lo_box_hostnet_tcplist_as_net_stream_listener(&self->parent->listeners[i]), close); + return byte_count; +} +static void shutdown_fio_pread(struct shutdown_fio *LM_UNUSED(self), struct lib9p_srv_ctx *LM_UNUSED(ctx), + uint32_t LM_UNUSED(byte_count), uint64_t LM_UNUSED(byte_offset), + struct iovec *LM_UNUSED(ret)) { + assert_notreached("not readable"); +} diff --git a/lib9p/tests/test_server/fs_shutdown.h b/lib9p/tests/test_server/fs_shutdown.h new file mode 100644 index 0000000..65956db --- /dev/null +++ b/lib9p/tests/test_server/fs_shutdown.h @@ -0,0 +1,23 @@ +/* lib9p/tests/test_server/fs_shutdown.h - /shutdown API endpoint + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIB9P_TESTS_TEST_SERVER_FS_SHUTDOWN_H_ +#define _LIB9P_TESTS_TEST_SERVER_FS_SHUTDOWN_H_ + +#include <util9p/static.h> +#include <libhw/host_net.h> + +struct shutdown_file { + char *name; + uint64_t pathnum; + + struct hostnet_tcp_listener *listeners; + size_t nlisteners; +}; +LO_IMPLEMENTATION_H(lib9p_srv_file, struct shutdown_file, shutdown_file); +#define lo_box_shutdown_file_as_lib9p_srv_file(obj) util9p_box(shutdown_file, obj) + +#endif /* _LIB9P_TESTS_TEST_SERVER_FS_SHUTDOWN_H_ */ diff --git a/lib9p/tests/test_server/fs_whoami.c b/lib9p/tests/test_server/fs_whoami.c new file mode 100644 index 0000000..8d9752a --- /dev/null +++ b/lib9p/tests/test_server/fs_whoami.c @@ -0,0 +1,153 @@ +/* lib9p/tests/test_server/fs_whoami.c - /whoami API endpoint + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <stdio.h> /* for snprintf() */ +#include <stdlib.h> /* for realloc(), free() */ + +#include <libmisc/alloc.h> + +#include "fs_whoami.h" + +LO_IMPLEMENTATION_C(lib9p_srv_file, struct whoami_file, whoami_file, static); + +struct whoami_fio { + struct whoami_file *parent; + size_t buf_len; + char *buf; +}; +LO_IMPLEMENTATION_H(lib9p_srv_fio, struct whoami_fio, whoami_fio); +LO_IMPLEMENTATION_C(lib9p_srv_fio, struct whoami_fio, whoami_fio, static); + +size_t whoami_len(struct lib9p_srv_ctx *ctx) { + assert(ctx); + assert(ctx->user); + + size_t len = 0; + uint32_t uid = ctx->user->num; + while (uid) { + len++; + uid /= 10; + } + if (!len) + len++; + len += 2; + len += ctx->user->name.len; + return len; +} + +/* srv_file *******************************************************************/ + +static void whoami_file_free(struct whoami_file *self) { + assert(self); +} +static struct lib9p_qid whoami_file_qid(struct whoami_file *self) { + assert(self); + return (struct lib9p_qid){ + .type = LIB9P_QT_FILE, + .vers = 1, + .path = self->pathnum, + }; +} + +static struct lib9p_srv_stat whoami_file_stat(struct whoami_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + + return (struct lib9p_srv_stat){ + .qid = whoami_file_qid(self), + .mode = 0444, + .atime_sec = UTIL9P_ATIME, + .mtime_sec = UTIL9P_MTIME, + .size = whoami_len(ctx), + .name = lib9p_str(self->name), + .owner_uid = { .name=lib9p_str("root"), .num=0 }, + .owner_gid = { .name=lib9p_str("root"), .num=0 }, + .last_modifier_uid = { .name=lib9p_str("root"), .num=0 }, + .extension = lib9p_str(NULL), + }; +} +static void whoami_file_wstat(struct whoami_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_srv_stat) { + assert(self); + assert(ctx); + lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "cannot wstat API file"); +} +static void whoami_file_remove(struct whoami_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "cannot remove API file"); +} + +LIB9P_SRV_NOTDIR(struct whoami_file, whoami_file) + +static lo_interface lib9p_srv_fio whoami_file_fopen(struct whoami_file *self, struct lib9p_srv_ctx *ctx, bool, bool, bool) { + assert(self); + assert(ctx); + + struct whoami_fio *ret = heap_alloc(1, struct whoami_fio); + ret->parent = self; + ret->buf_len = 0; + ret->buf = NULL; + + return lo_box_whoami_fio_as_lib9p_srv_fio(ret); +} + +/* srv_fio ********************************************************************/ + +static void whoami_fio_iofree(struct whoami_fio *self) { + assert(self); + if (self->buf) + free(self->buf); + free(self); +} + +static struct lib9p_qid whoami_fio_qid(struct whoami_fio *self) { + assert(self); + assert(self->parent); + return whoami_file_qid(self->parent); +} + +static uint32_t whoami_fio_iounit(struct whoami_fio *self) { + assert(self); + return 0; +} + +static uint32_t whoami_fio_pwrite(struct whoami_fio *LM_UNUSED(self), + struct lib9p_srv_ctx *LM_UNUSED(ctx), + void *LM_UNUSED(buf), uint32_t LM_UNUSED(byte_count), + uint64_t LM_UNUSED(offset)) { + assert_notreached("not writable"); +} +static void whoami_fio_pread(struct whoami_fio *self, struct lib9p_srv_ctx *ctx, + uint32_t byte_count, uint64_t byte_offset, + struct iovec *ret) { + assert(self); + assert(ctx); + assert(ret); + + size_t data_size = whoami_len(ctx); + if (self->buf_len < data_size+1) { + self->buf = realloc(self->buf, data_size+1); + self->buf_len = data_size+1; + } + snprintf(self->buf, self->buf_len, "%"PRIu32" %.*s\n", + ctx->user->num, ctx->user->name.len, ctx->user->name.utf8); + + if (byte_offset > (uint64_t)data_size) { + lib9p_error(&ctx->basectx, + LIB9P_ERRNO_L_EINVAL, "offset is past end-of-file length"); + return; + } + + size_t beg_off = (size_t)byte_offset; + size_t end_off = beg_off + (size_t)byte_count; + if (end_off > data_size) + end_off = data_size; + + *ret = (struct iovec){ + .iov_base = &self->buf[beg_off], + .iov_len = end_off-beg_off, + }; +} diff --git a/lib9p/tests/test_server/fs_whoami.h b/lib9p/tests/test_server/fs_whoami.h new file mode 100644 index 0000000..0d3d311 --- /dev/null +++ b/lib9p/tests/test_server/fs_whoami.h @@ -0,0 +1,20 @@ +/* lib9p/tests/test_server/fs_whoami.h - /whoami API endpoint + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIB9P_TESTS_TEST_SERVER_FS_WHOAMI_H_ +#define _LIB9P_TESTS_TEST_SERVER_FS_WHOAMI_H_ + +#include <util9p/static.h> +#include <libhw/host_net.h> + +struct whoami_file { + char *name; + uint64_t pathnum; +}; +LO_IMPLEMENTATION_H(lib9p_srv_file, struct whoami_file, whoami_file); +#define lo_box_whoami_file_as_lib9p_srv_file(obj) util9p_box(whoami_file, obj) + +#endif /* _LIB9P_TESTS_TEST_SERVER_FS_WHOAMI_H_ */ diff --git a/lib9p/tests/test_server/main.c b/lib9p/tests/test_server/main.c index a31c083..d7819eb 100644 --- a/lib9p/tests/test_server/main.c +++ b/lib9p/tests/test_server/main.c @@ -5,6 +5,8 @@ */ #include <error.h> +#include <errno.h> +#include <stdio.h> #include <stdlib.h> /* for atoi() */ #include <lib9p/srv.h> @@ -17,13 +19,19 @@ #include <util9p/static.h> #include "static.h" +#include "fs_flush.h" +#include "fs_shutdown.h" +#include "fs_whoami.h" /* configuration **************************************************************/ #include "config.h" -#ifndef CONFIG_SRV9P_NUM_CONNS - #error config.h must define CONFIG_SRV9P_NUM_CONNS +#ifndef _CONFIG_9P_MAX_CONNS + #error config.h must define _CONFIG_9P_MAX_CONNS +#endif +#ifndef _CONFIG_9P_MAX_REQS + #error config.h must define _CONFIG_9P_MAX_REQS #endif /* globals ********************************************************************/ @@ -34,123 +42,46 @@ const char *hexdig = "0123456789abcdef"; struct { uint16_t port; - struct hostnet_tcp_listener listeners[CONFIG_SRV9P_NUM_CONNS]; + struct hostnet_tcp_listener listeners[_CONFIG_9P_MAX_CONNS]; struct lib9p_srv srv; + FILE *logstream; } globals = { .srv = (struct lib9p_srv){ .rootdir = get_root, }, }; -/* api ************************************************************************/ - -struct api_file { - uint64_t pathnum; -}; -LO_IMPLEMENTATION_H(lib9p_srv_file, struct api_file, api); -LO_IMPLEMENTATION_H(lib9p_srv_fio, struct api_file, api); - -LO_IMPLEMENTATION_C(lib9p_srv_file, struct api_file, api, static); -LO_IMPLEMENTATION_C(lib9p_srv_fio, struct api_file, api, static); - -static void api_free(struct api_file *self) { - assert(self); -} -static struct lib9p_qid api_qid(struct api_file *self) { - assert(self); - return (struct lib9p_qid){ - .type = LIB9P_QT_FILE, - .vers = 1, - .path = self->pathnum, - }; -} - -static struct lib9p_stat api_stat(struct api_file *self, struct lib9p_srv_ctx *ctx) { - assert(self); - assert(ctx); - return (struct lib9p_stat){ - .kern_type = 0, - .kern_dev = 0, - .file_qid = api_qid(self), - .file_mode = 0222, - .file_atime = UTIL9P_ATIME, - .file_mtime = UTIL9P_MTIME, - .file_size = 0, - .file_name = lib9p_str("shutdown"), - .file_owner_uid = lib9p_str("root"), - .file_owner_gid = lib9p_str("root"), - .file_last_modified_uid = lib9p_str("root"), - .file_extension = lib9p_str(NULL), - .file_owner_n_uid = 0, - .file_owner_n_gid = 0, - .file_last_modified_n_uid = 0, - }; -} -static void api_wstat(struct api_file *self, struct lib9p_srv_ctx *ctx, struct lib9p_stat) { - assert(self); - assert(ctx); - lib9p_error(&ctx->basectx, LINUX_EROFS, "cannot wstat API file"); -} -static void api_remove(struct api_file *self, struct lib9p_srv_ctx *ctx) { - assert(self); - assert(ctx); - lib9p_error(&ctx->basectx, LINUX_EROFS, "cannot remove API file"); -} - -LIB9P_SRV_NOTDIR(struct api_file, api) - -static lo_interface lib9p_srv_fio api_fopen(struct api_file *self, struct lib9p_srv_ctx *ctx, bool, bool, bool) { - assert(self); - assert(ctx); - return lo_box_api_as_lib9p_srv_fio(self); -} - -static void api_iofree(struct api_file *self) { - assert(self); -} - -static uint32_t api_iounit(struct api_file *self) { - assert(self); - return 0; -} - -static uint32_t api_pwrite(struct api_file *self, struct lib9p_srv_ctx *ctx, void *buf, uint32_t byte_count, uint64_t LM_UNUSED(offset)) { - assert(self); - assert(ctx); - assert(buf); - if (byte_count == 0) - return 0; - for (int i = 0; i < CONFIG_SRV9P_NUM_CONNS; i++) - LO_CALL(lo_box_hostnet_tcplist_as_net_stream_listener(&globals.listeners[i]), close); - return byte_count; -} -static void api_pread(struct api_file *LM_UNUSED(self), struct lib9p_srv_ctx *LM_UNUSED(ctx), - uint32_t LM_UNUSED(byte_count), uint64_t LM_UNUSED(byte_offset), - struct iovec *LM_UNUSED(ret)) { - assert_notreached("not readable"); -} - -#define lo_box_api_as_lib9p_srv_file(obj) util9p_box(api, obj) - /* file tree ******************************************************************/ -enum { PATH_BASE = __COUNTER__ }; -#define PATH_COUNTER __COUNTER__ - PATH_BASE - -#define STATIC_FILE(STRNAME, SYMNAME) \ - UTIL9P_STATIC_FILE(PATH_COUNTER, STRNAME, \ +#define STATIC_FILE(N, STRNAME, SYMNAME) \ + UTIL9P_STATIC_FILE(N, STRNAME, \ .data_start = _binary_static_##SYMNAME##_start, \ .data_end = _binary_static_##SYMNAME##_end) -#define STATIC_DIR(STRNAME, ...) \ - UTIL9P_STATIC_DIR(PATH_COUNTER, STRNAME, __VA_ARGS__) +#define STATIC_DIR(N, STRNAME, ...) \ + UTIL9P_STATIC_DIR(N, STRNAME, __VA_ARGS__) + +#define API_FILE(N, STRNAME, SYMNAME, ...) \ + lo_box_##SYMNAME##_file_as_lib9p_srv_file(&((struct SYMNAME##_file){ \ + .name = STRNAME, \ + .pathnum = N \ + __VA_OPT__(,) __VA_ARGS__ \ + })) struct lib9p_srv_file root = - STATIC_DIR("", - STATIC_DIR("Documentation", - STATIC_FILE("x", Documentation_x_txt), + STATIC_DIR(1, "", + STATIC_DIR(2, "Documentation", + STATIC_FILE(3, "x", Documentation_x_txt), ), - STATIC_FILE("README.md", README_md), - lo_box_api_as_lib9p_srv_file(&(struct api_file){.pathnum = PATH_COUNTER}), + STATIC_FILE(4, "README.md", README_md), + API_FILE(5, "shutdown", shutdown, + .listeners = globals.listeners, + .nlisteners = LM_ARRAY_LEN(globals.listeners)), + API_FILE(8, "whoami", whoami), + API_FILE(9, "flush-read", flush, .flush_cnt=1, .flush_behavior=FLUSH_READ), + API_FILE(10, "flush-error", flush, .flush_cnt=1, .flush_behavior=FLUSH_ERROR), + API_FILE(11, "flush-silent", flush, .flush_cnt=1, .flush_behavior=FLUSH_SILENT), + API_FILE(12, "flush-slowsilent", flush, .flush_cnt=2, .flush_behavior=FLUSH_SILENT), + API_FILE(13, "flush-slowread", flush, .flush_cnt=0, .flush_behavior=FLUSH_READ), ); static lo_interface lib9p_srv_file get_root(struct lib9p_srv_ctx *LM_UNUSED(ctx), struct lib9p_s LM_UNUSED(treename)) { @@ -165,7 +96,15 @@ static COROUTINE read_cr(void *_i) { hostnet_tcp_listener_init(&globals.listeners[i], globals.port); - lib9p_srv_read_cr(&globals.srv, lo_box_hostnet_tcplist_as_net_stream_listener(&globals.listeners[i])); + lib9p_srv_accept_and_read_loop(&globals.srv, lo_box_hostnet_tcplist_as_net_stream_listener(&globals.listeners[i])); + + cr_end(); +} + +static COROUTINE write_cr(void *) { + cr_begin(); + + lib9p_srv_worker_loop(&globals.srv); cr_end(); } @@ -173,31 +112,57 @@ static COROUTINE read_cr(void *_i) { static COROUTINE init_cr(void *) { cr_begin(); - sleep_for_ms(1); + sleep_for_ms(1); /* test that sleep works */ - for (int i = 0; i < CONFIG_SRV9P_NUM_CONNS; i++) { + for (int i = 0; i < _CONFIG_9P_MAX_CONNS; i++) { char name[] = {'r', 'e', 'a', 'd', '-', hexdig[i], '\0'}; if (!coroutine_add(name, read_cr, &i)) error(1, 0, "coroutine_add(read_cr, &i)"); } - for (int i = 0; i < 2*CONFIG_SRV9P_NUM_CONNS; i++) { + for (int i = 0; i < _CONFIG_9P_MAX_REQS; i++) { char name[] = {'w', 'r', 'i', 't', 'e', '-', hexdig[i], '\0'}; - if (!coroutine_add(name, lib9p_srv_write_cr, &globals.srv)) - error(1, 0, "coroutine_add(lib9p_srv_write_cr, &globals.srv)"); + if (!coroutine_add(name, write_cr, NULL)) + error(1, 0, "coroutine_add(write_cr, NULL)"); } cr_exit(); } +static void log_fct(char character, void *_stream) { + FILE *stream = _stream; + putc(character, stream); + putchar(character); +} + +static void log_msg(struct lib9p_srv_ctx *ctx, enum lib9p_msg_type typ, void *hostmsg) { + /* It sucks that %v trips -Wformat and -Wformat-extra-args + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47781 */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wformat-extra-args" + fmt_fctprintf(log_fct, globals.logstream, + "%c %v\n", typ % 2 ? '<' : '>', + lo_box_lib9p_msg_as_fmt_formatter(&ctx->basectx, typ, hostmsg)); +#pragma GCC diagnostic pop + fflush(globals.logstream); +} + int main(int argc, char *argv[]) { - if (argc != 2) - error(2, 0, "usage: %s PORT_NUMBER", argv[0]); + if (argc != 3) + error(2, 0, "usage: %s PORT_NUMBER LOGFILE", argv[0]); + globals.port = atoi(argv[1]); + globals.logstream = fopen(argv[2], "w"); + if (!globals.logstream) + error(2, errno, "fopen"); + globals.srv.msglog = log_msg; + struct hostclock clock_monotonic = { .clock_id = CLOCK_MONOTONIC, }; bootclock = lo_box_hostclock_as_alarmclock(&clock_monotonic); coroutine_add("init", init_cr, NULL); coroutine_main(); + fclose(globals.logstream); return 0; } diff --git a/lib9p/tests/testclient-p9p b/lib9p/tests/testclient-p9p new file mode 100755 index 0000000..09ce746 --- /dev/null +++ b/lib9p/tests/testclient-p9p @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# lib9p/tests/testclient-p9p - Test the 9P `test_server` against Plan 9 Port's `9p` utility +# +# Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> +# SPDX-License-Identifier: AGPL-3.0-or-later + +set -euE -o pipefail + +if [[ $# != 1 ]]; then + echo >&2 "Usage: $0 SERVER_PORT" + echo >&2 "Usage: ./runtest $0 EXPLOG" + exit 2 +fi + +expect_lines() ( + { set +x; } &>/dev/null + printf >&2 '+ diff -u expected.txt actual.txt\n' + diff -u <(printf '%s\n' "$@") <(printf '%s\n' "$out") +) + +set -x +client=(unshare --user 9p -a "localhost:${1}") + +out=$("${client[@]}" ls -l '') +expect_lines \ + 'd-r-xr-xr-x M 0 root root 0 Oct 7 2024 Documentation' \ + '--r--r--r-- M 0 root root 166 Oct 7 2024 README.md' \ + '--r--r--r-- M 0 root root 6 Oct 7 2024 flush-error' \ + '--r--r--r-- M 0 root root 6 Oct 7 2024 flush-read' \ + '--r--r--r-- M 0 root root 6 Oct 7 2024 flush-silent' \ + '--r--r--r-- M 0 root root 6 Oct 7 2024 flush-slowread' \ + '--r--r--r-- M 0 root root 6 Oct 7 2024 flush-slowsilent' \ + 'a--w--w--w- M 0 root root 0 Oct 7 2024 shutdown' \ + '--r--r--r-- M 0 root root 9 Oct 7 2024 whoami' + +out=$("${client[@]}" ls -l 'Documentation/') +expect_lines \ + '--r--r--r-- M 0 root root 166 Oct 7 2024 x' + +out=$("${client[@]}" read 'README.md') +expect_lines \ + '<!--' \ + ' README.md - test static file' \ + '' \ + ' Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>' \ + ' SPDX-License-Identifier: AGPL-3.0-or-later' \ + '-->' \ + 'Hello, world!' + +out=$("${client[@]}" read 'Documentation/x') +expect_lines \ + '<!--' \ + ' Documentation/x.txt - test static file' \ + '' \ + ' Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>' \ + ' SPDX-License-Identifier: AGPL-3.0-or-later' \ + '-->' \ + 'foo' + +out=$("${client[@]}" stat 'Documentation/x') +expect_lines \ + "'x' 'root' 'root' 'root' q (0000000000000003 1 ) m 0444 at 1728337905 mt 1728337904 l 166 t 0 d 0" + +out=$("${client[@]}" write 'shutdown' <<<1) +expect_lines '' diff --git a/lib9p/tests/testclient-p9p.explog b/lib9p/tests/testclient-p9p.explog new file mode 100644 index 0000000..54f1e4b --- /dev/null +++ b/lib9p/tests/testclient-p9p.explog @@ -0,0 +1,106 @@ +# lib9p/tests/testclient-p9p.explog - Expected 9P logfile of testclient-p9p +# +# Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> +# SPDX-License-Identifier: AGPL-3.0-or-later +> Tversion { tag=NOTAG max_msg_size=8192 version="9P2000" } +< Rversion { tag=NOTAG max_msg_size=4120 version="9P2000" } +> Tauth { tag=0 afid=0 uname="nobody" aname="" unum=0 } +< Rerror { tag=0 errstr="authentication not required" errnum=L_EOPNOTSUPP } +> Tattach { tag=0 fid=0 afid=NOFID uname="nobody" aname="" unum=0 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } +> Twalk { tag=0 fid=0 newfid=1 nwname=0 wname=[ ] } +< Rwalk { tag=0 nwqid=0 wqid=[ ] } +> Tstat { tag=0 fid=1 } +< Rstat { tag=0 stat={ fstype=0 fsdev=0 qid={ type=(DIR) vers=1 path=1 } mode=(DIR|0555) atime=1728337905 mtime=1728337904 length=0 name="" owner_uname="root" owner_gname="root" last_modifier_uname="root" extension="" owner_unum=0 owner_gnum=0 last_modifier_unum=0 } } +> Tclunk { tag=0 fid=1 } +< Rclunk { tag=0 } +> Twalk { tag=0 fid=0 newfid=1 nwname=0 wname=[ ] } +< Rwalk { tag=0 nwqid=0 wqid=[ ] } +> Topen { tag=0 fid=1 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(DIR) vers=1 path=1 } iounit=0 } +> Tread { tag=0 fid=1 offset=0 count=4096 } +< Rread { tag=0 count=648 data=<bytedata> } +> Tread { tag=0 fid=1 offset=648 count=4096 } +< Rread { tag=0 count=0 data="" } +> Tclunk { tag=0 fid=1 } +< Rclunk { tag=0 } +> Tversion { tag=NOTAG max_msg_size=8192 version="9P2000" } +< Rversion { tag=NOTAG max_msg_size=4120 version="9P2000" } +> Tauth { tag=0 afid=0 uname="nobody" aname="" unum=0 } +< Rerror { tag=0 errstr="authentication not required" errnum=L_EOPNOTSUPP } +> Tattach { tag=0 fid=0 afid=NOFID uname="nobody" aname="" unum=0 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } +> Twalk { tag=0 fid=0 newfid=1 nwname=1 wname=[ "Documentation" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(DIR) vers=1 path=2 } ] } +> Tstat { tag=0 fid=1 } +< Rstat { tag=0 stat={ fstype=0 fsdev=0 qid={ type=(DIR) vers=1 path=2 } mode=(DIR|0555) atime=1728337905 mtime=1728337904 length=0 name="Documentation" owner_uname="root" owner_gname="root" last_modifier_uname="root" extension="" owner_unum=0 owner_gnum=0 last_modifier_unum=0 } } +> Tclunk { tag=0 fid=1 } +< Rclunk { tag=0 } +> Twalk { tag=0 fid=0 newfid=1 nwname=1 wname=[ "Documentation" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(DIR) vers=1 path=2 } ] } +> Topen { tag=0 fid=1 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(DIR) vers=1 path=2 } iounit=0 } +> Tread { tag=0 fid=1 offset=0 count=4096 } +< Rread { tag=0 count=62 data=<bytedata> } +> Tread { tag=0 fid=1 offset=62 count=4096 } +< Rread { tag=0 count=0 data="" } +> Tclunk { tag=0 fid=1 } +< Rclunk { tag=0 } +> Tversion { tag=NOTAG max_msg_size=8192 version="9P2000" } +< Rversion { tag=NOTAG max_msg_size=4120 version="9P2000" } +> Tauth { tag=0 afid=0 uname="nobody" aname="" unum=0 } +< Rerror { tag=0 errstr="authentication not required" errnum=L_EOPNOTSUPP } +> Tattach { tag=0 fid=0 afid=NOFID uname="nobody" aname="" unum=0 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } +> Twalk { tag=0 fid=0 newfid=1 nwname=1 wname=[ "README.md" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=4 } ] } +> Topen { tag=0 fid=1 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=4 } iounit=0 } +> Tread { tag=0 fid=1 offset=0 count=4096 } +< Rread { tag=0 count=166 data="<!--\n README.md - test static file\n\n Copyright ("... } +> Tread { tag=0 fid=1 offset=166 count=4096 } +< Rread { tag=0 count=0 data="" } +> Tclunk { tag=0 fid=1 } +< Rclunk { tag=0 } +> Tversion { tag=NOTAG max_msg_size=8192 version="9P2000" } +< Rversion { tag=NOTAG max_msg_size=4120 version="9P2000" } +> Tauth { tag=0 afid=0 uname="nobody" aname="" unum=0 } +< Rerror { tag=0 errstr="authentication not required" errnum=L_EOPNOTSUPP } +> Tattach { tag=0 fid=0 afid=NOFID uname="nobody" aname="" unum=0 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } +> Twalk { tag=0 fid=0 newfid=1 nwname=2 wname=[ "Documentation", "x" ] } +< Rwalk { tag=0 nwqid=2 wqid=[ { type=(DIR) vers=1 path=2 }, { type=(0) vers=1 path=3 } ] } +> Topen { tag=0 fid=1 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=3 } iounit=0 } +> Tread { tag=0 fid=1 offset=0 count=4096 } +< Rread { tag=0 count=166 data="<!--\n Documentation/x.txt - test static file\n\n C"... } +> Tread { tag=0 fid=1 offset=166 count=4096 } +< Rread { tag=0 count=0 data="" } +> Tclunk { tag=0 fid=1 } +< Rclunk { tag=0 } +> Tversion { tag=NOTAG max_msg_size=8192 version="9P2000" } +< Rversion { tag=NOTAG max_msg_size=4120 version="9P2000" } +> Tauth { tag=0 afid=0 uname="nobody" aname="" unum=0 } +< Rerror { tag=0 errstr="authentication not required" errnum=L_EOPNOTSUPP } +> Tattach { tag=0 fid=0 afid=NOFID uname="nobody" aname="" unum=0 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } +> Twalk { tag=0 fid=0 newfid=1 nwname=2 wname=[ "Documentation", "x" ] } +< Rwalk { tag=0 nwqid=2 wqid=[ { type=(DIR) vers=1 path=2 }, { type=(0) vers=1 path=3 } ] } +> Tstat { tag=0 fid=1 } +< Rstat { tag=0 stat={ fstype=0 fsdev=0 qid={ type=(0) vers=1 path=3 } mode=(0444) atime=1728337905 mtime=1728337904 length=166 name="x" owner_uname="root" owner_gname="root" last_modifier_uname="root" extension="" owner_unum=0 owner_gnum=0 last_modifier_unum=0 } } +> Tclunk { tag=0 fid=1 } +< Rclunk { tag=0 } +> Tversion { tag=NOTAG max_msg_size=8192 version="9P2000" } +< Rversion { tag=NOTAG max_msg_size=4120 version="9P2000" } +> Tauth { tag=0 afid=0 uname="nobody" aname="" unum=0 } +< Rerror { tag=0 errstr="authentication not required" errnum=L_EOPNOTSUPP } +> Tattach { tag=0 fid=0 afid=NOFID uname="nobody" aname="" unum=0 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } +> Twalk { tag=0 fid=0 newfid=1 nwname=1 wname=[ "shutdown" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(APPEND) vers=1 path=5 } ] } +> Topen { tag=0 fid=1 mode=(TRUNC|MODE_WRITE) } +< Ropen { tag=0 qid={ type=(APPEND) vers=1 path=5 } iounit=0 } +> Twrite { tag=0 fid=1 offset=0 count=2 data="1\n" } +< Rwrite { tag=0 count=2 } +> Tclunk { tag=0 fid=1 } +< Rclunk { tag=0 } diff --git a/lib9p/tests/testclient-sess.c b/lib9p/tests/testclient-sess.c new file mode 100644 index 0000000..7cb7f97 --- /dev/null +++ b/lib9p/tests/testclient-sess.c @@ -0,0 +1,243 @@ +/* lib9p/tests/testclient-sess.c - Test the 9P `test_server`'s sessions + * + * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <arpa/inet.h> /* for htons(), inet_addr() */ +#include <errno.h> +#include <error.h> +#include <netinet/in.h> /* for struct sockaddr{,_in} */ +#include <stdlib.h> /* for atoi() */ +#include <sys/socket.h> /* for socket(), connect() */ +#include <sys/uio.h> /* for writev() */ +#include <unistd.h> /* for read() */ + +#include <libmisc/assert.h> +#include <libmisc/endian.h> +#include <lib9p/core.h> + +#define MAX_MSG_SIZE (8*1024) + +static void _send9p(int fd, struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body) { + struct lib9p_Tmsg_send_buf buf; + bool err = lib9p_Tmsg_marshal(ctx, typ, body, &buf); + assert(!err); + size_t exp = 0; + for (size_t i = 0; i < buf.iov_cnt; i++) + exp += buf.iov[i].iov_len; + ssize_t act = writev(fd, buf.iov, buf.iov_cnt); + if (act < 0) + error(1, errno, "writev"); + assert((size_t)act == exp); +} + +#define send9p(typ, ...) _send9p(fd, &ctx, LIB9P_TYP_##typ, &((struct lib9p_msg_##typ){ __VA_ARGS__ })) + +static void _recv9p(int fd) { + uint8_t buf[MAX_MSG_SIZE]; + size_t goal = 4; + size_t done = 0; + while (done < goal) { + ssize_t n = read(fd, &buf[done], goal-done); + if (n < 0) + error(1, errno, "read"); + done += n; + } + goal = uint32le_decode(buf); + assert(goal <= MAX_MSG_SIZE); + while (done < goal) { + ssize_t n = read(fd, &buf[done], goal-done); + if (n < 0) + error(1, errno, "read"); + done += n; + } +} + +#define recv9p() _recv9p(fd) + +int main(int argc, char *argv[]) { + if (argc != 2) + error(2, 0, "Usage: %s SERVER_PORT", argv[0]); + uint16_t server_port = atoi(argv[1]); + + union { + struct sockaddr gen; + struct sockaddr_in in; + } server_addr = {}; + server_addr.in.sin_family = AF_INET; + server_addr.in.sin_addr.s_addr = inet_addr("127.0.0.1"); + server_addr.in.sin_port = htons(server_port); + + int fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) + error(1, errno, "socket"); + if (connect(fd, &server_addr.gen, sizeof(server_addr)) < 0) + error(1, errno, "connect"); + + struct lib9p_ctx ctx = { + .max_msg_size = 16*1024, + }; + + struct lib9p_s wname[1]; + + /* numeric downgrade, unknown ext *************************************/ + send9p(Tversion, .tag=0, .max_msg_size=57, .version=lib9p_str("9P2025.x")); + recv9p(); /* Rversion */ + ctx.version = LIB9P_VER_9P2000; + + /* numeric downgrade, known ext ***************************************/ + send9p(Tversion, .tag=0, .max_msg_size=57, .version=lib9p_str("9P2025.u")); + recv9p(); /* Rversion */ + ctx.version = LIB9P_VER_9P2000_u; + + /* ext version, users *************************************************/ + send9p(Tversion, .tag=0, .max_msg_size=(8*1024), .version=lib9p_str("9P2000.u")); + recv9p(); /* Rversion */ + ctx.version = LIB9P_VER_9P2000_u; + send9p(Tattach, .tag=0, .fid=0, .afid=LIB9P_FID_NOFID, .uname=lib9p_str("alice"), .unum=1000, .aname=lib9p_str("")); + recv9p(); /* Rattach */ + send9p(Tattach, .tag=0, .fid=1, .afid=LIB9P_FID_NOFID, .uname=lib9p_str("bob"), .unum=1001, .aname=lib9p_str("")); + recv9p(); /* Rattach */ + wname[0] = lib9p_str("whoami"); send9p(Twalk, .tag=0, .fid=0, .newfid=2, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + wname[0] = lib9p_str("whoami"); send9p(Twalk, .tag=0, .fid=1, .newfid=3, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + send9p(Topen, .tag=0, .fid=2, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Topen, .tag=0, .fid=3, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Tread, .tag=0, .fid=2, .offset=0, .count=100); + recv9p(); /* Rread */ + send9p(Tread, .tag=0, .fid=3, .offset=0, .count=100); + recv9p(); /* Rread */ + + /* walk ***************************************************************/ + send9p(Tversion, .tag=0, .max_msg_size=(8*1024), .version=lib9p_str("9P2000")); + recv9p(); /* Rversion */ + ctx.version = LIB9P_VER_9P2000; + send9p(Tattach, .tag=0, .fid=0, .afid=LIB9P_FID_NOFID, .uname=lib9p_str("nobody"), .aname=lib9p_str("")); + recv9p(); /* Rattach */ + + /* dup */ + send9p(Twalk, .tag=0, .fid=0, .newfid=1, .nwname=0); + recv9p(); /* Rwalk */ + + /* "The walk request carries as arguments an existing fid"... */ + send9p(Twalk, .tag=0, .fid=2, .newfid=3, .nwname=0); + recv9p(); /* Rerror */ + + /* ..."and a proposed newfid"... */ + send9p(Twalk, .tag=0, .fid=1, .newfid=0xffffffff, .nwname=0); + recv9p(); /* Rerror */ + + /* ..."(which must not be in use"... */ + send9p(Twalk, .tag=0, .fid=1, .newfid=0, .nwname=0); + recv9p(); /* Rerror */ + + /* ..."unless it is the same as fid)"... */ + send9p(Twalk, .tag=0, .fid=1, .newfid=1, .nwname=0); + recv9p(); /* Rwalk */ + + /* ... "that the client wishes to associate with the result of + * traversing the directory hierarchy by `walking' the heierarchy using + * the successive path name elements wname."... */ + + /* ..."The fid must represent a directory"... */ + wname[0] = lib9p_str("README.md"); send9p(Twalk, .tag=0, .fid=1, .newfid=2, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + wname[0] = lib9p_str(".."); send9p(Twalk, .tag=0, .fid=2, .newfid=3, .nwname=1, .wname=wname); + recv9p(); /* Rerror */ + + /* ..."unless zero path name elements are specified." */ + send9p(Twalk, .tag=0, .fid=2, .newfid=3, .nwname=0); + recv9p(); /* Rwalk */ + + /* "The fid must be valid in the current session" (tested above)... */ + + /* ..."and must not have been opened for I/O by an open or create + * message."... */ + send9p(Topen, .tag=0, .fid=3, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Twalk, .tag=0, .fid=3, .newfid=4, .nwname=0); + recv9p(); /* Rerror */ + + /* flush **************************************************************/ + send9p(Tversion, .tag=0, .max_msg_size=(8*1024), .version=lib9p_str("9P2000")); + recv9p(); /* Rversion */ + ctx.version = LIB9P_VER_9P2000; + send9p(Tattach, .tag=0, .fid=0, .afid=LIB9P_FID_NOFID, .uname=lib9p_str("nobody"), .aname=lib9p_str("")); + recv9p(); /* Rattach */ + + /* flush, but original response comes back first */ + wname[0] = lib9p_str("flush-read"); send9p(Twalk, .tag=0, .fid=0, .newfid=1, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + send9p(Topen, .tag=0, .fid=1, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Tread, .tag=0, .fid=1, .offset=0, .count=10); + send9p(Tflush, .tag=1, .oldtag=0); + recv9p(); /* Rread */ + recv9p(); /* Rflush */ + + /* flush, original request is aborted with error */ + wname[0] = lib9p_str("flush-error"); send9p(Twalk, .tag=0, .fid=0, .newfid=2, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + send9p(Topen, .tag=0, .fid=2, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Tread, .tag=0, .fid=2, .offset=0, .count=10); + send9p(Tflush, .tag=1, .oldtag=0); + recv9p(); /* Rerror */ + recv9p(); /* Rflush */ + + /* flush, original request is aborted without error */ + wname[0] = lib9p_str("flush-silent"); send9p(Twalk, .tag=0, .fid=0, .newfid=3, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + send9p(Topen, .tag=0, .fid=3, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Tread, .tag=0, .fid=3, .offset=0, .count=10); + send9p(Tflush, .tag=1, .oldtag=0); + recv9p(); /* Rflush */ + + /* multiflush, original request is aborted without error */ + wname[0] = lib9p_str("flush-slowsilent"); send9p(Twalk, .tag=0, .fid=0, .newfid=4, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + send9p(Topen, .tag=0, .fid=4, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Tread, .tag=0, .fid=4, .offset=0, .count=10); + send9p(Tflush, .tag=1, .oldtag=0); + send9p(Tflush, .tag=2, .oldtag=0); + recv9p(); /* Rflush */ + + /* flush, but flush is flushed */ + wname[0] = lib9p_str("flush-slowread"); send9p(Twalk, .tag=0, .fid=0, .newfid=5, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + send9p(Topen, .tag=0, .fid=5, .mode=LIB9P_O_MODE_READ); + recv9p(); /* Ropen */ + send9p(Tread, .tag=0, .fid=5, .offset=0, .count=10); + send9p(Tflush, .tag=1, .oldtag=0); + send9p(Tflush, .tag=2, .oldtag=1); + recv9p(); /* Rflush */ + recv9p(); /* Rread */ + + /* flush, unknown tag */ + send9p(Tflush, .tag=0, .oldtag=99); + recv9p(); /* Rflush */ + + /* flushed by Tversion */ + send9p(Tread, .tag=0, .fid=3, .offset=0, .count=10); + + /* shutdown ***********************************************************/ + send9p(Tversion, .tag=0, .max_msg_size=(8*1024), .version=lib9p_str("9P2000")); + recv9p(); /* Rversion */ + ctx.version = LIB9P_VER_9P2000; + send9p(Tattach, .tag=0, .fid=0, .afid=LIB9P_FID_NOFID, .uname=lib9p_str("nobody"), .aname=lib9p_str("")); + recv9p(); /* Rattach */ + /* check the newfid==fid case */ + wname[0] = lib9p_str("shutdown"); send9p(Twalk, .tag=0, .fid=0, .newfid=0, .nwname=1, .wname=wname); + recv9p(); /* Rwalk */ + send9p(Topen, .tag=0, .fid=0, .mode=LIB9P_O_MODE_WRITE); + recv9p(); /* Ropen */ + send9p(Twrite, .tag=0, .fid=0, .offset=0, .count=2, .data="1\n"); + recv9p(); /* Rwrite */ + return 0; +} diff --git a/lib9p/tests/testclient-sess.explog b/lib9p/tests/testclient-sess.explog new file mode 100644 index 0000000..a3838ac --- /dev/null +++ b/lib9p/tests/testclient-sess.explog @@ -0,0 +1,156 @@ +# lib9p/tests/testclient-sess.explog - Expected 9P logfile of testclient-sess.c +# +# Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> +# SPDX-License-Identifier: AGPL-3.0-or-later + +# numeric downgrade, unknown ext ############################################### +> Tversion { tag=0 max_msg_size=57 version="9P2025.x" } +< Rversion { tag=0 max_msg_size=57 version="9P2000" } + +# numeric downgrade, known ext ################################################# +> Tversion { tag=0 max_msg_size=57 version="9P2025.u" } +< Rversion { tag=0 max_msg_size=57 version="9P2000.u" } + +# ext version, users ########################################################### +> Tversion { tag=0 max_msg_size=8192 version="9P2000.u" } +< Rversion { tag=0 max_msg_size=4120 version="9P2000.u" } +> Tattach { tag=0 fid=0 afid=NOFID uname="alice" aname="" unum=1000 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } +> Tattach { tag=0 fid=1 afid=NOFID uname="bob" aname="" unum=1001 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } +> Twalk { tag=0 fid=0 newfid=2 nwname=1 wname=[ "whoami" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=8 } ] } +> Twalk { tag=0 fid=1 newfid=3 nwname=1 wname=[ "whoami" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=8 } ] } +> Topen { tag=0 fid=2 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=8 } iounit=0 } +> Topen { tag=0 fid=3 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=8 } iounit=0 } +> Tread { tag=0 fid=2 offset=0 count=100 } +< Rread { tag=0 count=11 data="1000 alice\n" } +> Tread { tag=0 fid=3 offset=0 count=100 } +< Rread { tag=0 count=9 data="1001 bob\n" } + +# walk ######################################################################### +> Tversion { tag=0 max_msg_size=8192 version="9P2000" } +< Rversion { tag=0 max_msg_size=4120 version="9P2000" } +> Tattach { tag=0 fid=0 afid=NOFID uname="nobody" aname="" unum=0 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } + +# dup +> Twalk { tag=0 fid=0 newfid=1 nwname=0 wname=[ ] } +< Rwalk { tag=0 nwqid=0 wqid=[ ] } + +# "The walk request carries as arguments an existing fid"... +> Twalk { tag=0 fid=2 newfid=3 nwname=0 wname=[ ] } +< Rerror { tag=0 errstr="bad file number 2" errnum=L_EBADF } + +# ..."and a proposed newfid"... +> Twalk { tag=0 fid=1 newfid=NOFID nwname=0 wname=[ ] } +< Rerror { tag=0 errstr="cannot assign to NOFID" errnum=L_EBADF } + +# ..."(which must not be in use"... +> Twalk { tag=0 fid=1 newfid=0 nwname=0 wname=[ ] } +< Rerror { tag=0 errstr="FID already in use" errnum=L_EBADF } + +# ..."unless it is the same as fid)"... +> Twalk { tag=0 fid=1 newfid=1 nwname=0 wname=[ ] } +< Rwalk { tag=0 nwqid=0 wqid=[ ] } + +# ... "that the client wishes to associate with the result of +# traversing the directory hierarchy by `walking' the heierarchy using +# the successive path name elements wname."... + +# ..."The fid must represent a directory"... +> Twalk { tag=0 fid=1 newfid=2 nwname=1 wname=[ "README.md" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=4 } ] } +> Twalk { tag=0 fid=2 newfid=3 nwname=1 wname=[ ".." ] } +< Rerror { tag=0 errstr="not a directory" errnum=L_ENOTDIR } + +# ..."unless zero path name elements are specified." +> Twalk { tag=0 fid=2 newfid=3 nwname=0 wname=[ ] } +< Rwalk { tag=0 nwqid=0 wqid=[ ] } + +# "The fid must be valid in the current session" (tested above)... + +# ..."and must not have been opened for I/O by an open or create +# message."... +> Topen { tag=0 fid=3 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=4 } iounit=0 } +> Twalk { tag=0 fid=3 newfid=4 nwname=0 wname=[ ] } +< Rerror { tag=0 errstr="cannot walk on FID open for I/O" errnum=L_EALREADY } + +# flush ######################################################################## +> Tversion { tag=0 max_msg_size=8192 version="9P2000" } +< Rversion { tag=0 max_msg_size=4120 version="9P2000" } +> Tattach { tag=0 fid=0 afid=NOFID uname="nobody" aname="" unum=0 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } + +# flush, but original response comes back first +> Twalk { tag=0 fid=0 newfid=1 nwname=1 wname=[ "flush-read" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=9 } ] } +> Topen { tag=0 fid=1 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=9 } iounit=0 } +> Tread { tag=0 fid=1 offset=0 count=10 } +> Tflush { tag=1 oldtag=0 } +< Rread { tag=0 count=6 data="Sloth\n" } +< Rflush { tag=1 } + +# flush, original request is aborted with error +> Twalk { tag=0 fid=0 newfid=2 nwname=1 wname=[ "flush-error" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=10 } ] } +> Topen { tag=0 fid=2 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=10 } iounit=0 } +> Tread { tag=0 fid=2 offset=0 count=10 } +> Tflush { tag=1 oldtag=0 } +< Rerror { tag=0 errstr="request canceled by flush" errnum=L_ECANCELED } +< Rflush { tag=1 } + +# flush, original request is aborted without error +> Twalk { tag=0 fid=0 newfid=3 nwname=1 wname=[ "flush-silent" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=11 } ] } +> Topen { tag=0 fid=3 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=11 } iounit=0 } +> Tread { tag=0 fid=3 offset=0 count=10 } +> Tflush { tag=1 oldtag=0 } +< Rflush { tag=1 } + +# multiflush, original request is aborted without error +> Twalk { tag=0 fid=0 newfid=4 nwname=1 wname=[ "flush-slowsilent" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=12 } ] } +> Topen { tag=0 fid=4 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=12 } iounit=0 } +> Tread { tag=0 fid=4 offset=0 count=10 } +> Tflush { tag=1 oldtag=0 } +> Tflush { tag=2 oldtag=0 } +< Rflush { tag=2 } + +# flush, but flush is flushed +> Twalk { tag=0 fid=0 newfid=5 nwname=1 wname=[ "flush-slowread" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(0) vers=1 path=13 } ] } +> Topen { tag=0 fid=5 mode=(MODE_READ) } +< Ropen { tag=0 qid={ type=(0) vers=1 path=13 } iounit=0 } +> Tread { tag=0 fid=5 offset=0 count=10 } +> Tflush { tag=1 oldtag=0 } +> Tflush { tag=2 oldtag=1 } +< Rflush { tag=2 } +< Rread { tag=0 count=6 data="Sloth\n" } + +# flush, unknown tag +> Tflush { tag=0 oldtag=99 } +< Rflush { tag=0 } + +# flushed by Tversion +> Tread { tag=0 fid=3 offset=0 count=10 } + +# shutdown ##################################################################### +> Tversion { tag=0 max_msg_size=8192 version="9P2000" } +< Rversion { tag=0 max_msg_size=4120 version="9P2000" } +> Tattach { tag=0 fid=0 afid=NOFID uname="nobody" aname="" unum=0 } +< Rattach { tag=0 qid={ type=(DIR) vers=1 path=1 } } +> Twalk { tag=0 fid=0 newfid=0 nwname=1 wname=[ "shutdown" ] } +< Rwalk { tag=0 nwqid=1 wqid=[ { type=(APPEND) vers=1 path=5 } ] } +> Topen { tag=0 fid=0 mode=(MODE_WRITE) } +< Ropen { tag=0 qid={ type=(APPEND) vers=1 path=5 } iounit=0 } +> Twrite { tag=0 fid=0 offset=0 count=2 data="1\n" } +< Rwrite { tag=0 count=2 } |