summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig54
-rw-r--r--3rd-party/linux-errno.txt2
-rw-r--r--CMakeLists.txt2
-rw-r--r--GNUmakefile72
-rw-r--r--PLAN.md14
-rw-r--r--README.md6
-rwxr-xr-xbuild-aux/embed-sources.h.gen4
-rwxr-xr-xbuild-aux/lint-bin15
-rwxr-xr-xbuild-aux/lint-generic7
-rwxr-xr-xbuild-aux/lint-h6
-rw-r--r--build-aux/measurestack/app_plugins.py56
-rwxr-xr-xbuild-aux/valgrind16
-rw-r--r--cmd/sbc_harness/CMakeLists.txt2
-rw-r--r--cmd/sbc_harness/config/config.h39
-rw-r--r--cmd/sbc_harness/config/tusb_config.h4
-rw-r--r--cmd/sbc_harness/fs_harness_flash_bin.c43
-rw-r--r--cmd/sbc_harness/fs_harness_uptime_txt.c43
-rw-r--r--cmd/sbc_harness/main.c26
-rw-r--r--cmd/sbc_harness/usb_keyboard.c6
-rw-r--r--cmd/sbc_harness/usb_keyboard.h4
-rw-r--r--gdb-helpers/libcr.py142
-rw-r--r--lib9p/CMakeLists.txt68
-rw-r--r--lib9p/core.c (renamed from lib9p/9p.c)29
-rwxr-xr-xlib9p/core.gen (renamed from lib9p/proto.gen)8
-rw-r--r--lib9p/core_gen/__init__.py (renamed from lib9p/protogen/__init__.py)8
-rw-r--r--lib9p/core_gen/c.py (renamed from lib9p/protogen/c.py)45
-rw-r--r--lib9p/core_gen/c9util.py (renamed from lib9p/protogen/c9util.py)2
-rw-r--r--lib9p/core_gen/c_format.py (renamed from lib9p/protogen/c_format.py)44
-rw-r--r--lib9p/core_gen/c_marshal.py (renamed from lib9p/protogen/c_marshal.py)4
-rw-r--r--lib9p/core_gen/c_unmarshal.py (renamed from lib9p/protogen/c_unmarshal.py)2
-rw-r--r--lib9p/core_gen/c_validate.py (renamed from lib9p/protogen/c_validate.py)16
-rw-r--r--lib9p/core_gen/cutil.py (renamed from lib9p/protogen/cutil.py)2
-rw-r--r--lib9p/core_gen/h.py (renamed from lib9p/protogen/h.py)21
-rw-r--r--lib9p/core_gen/idlutil.py (renamed from lib9p/protogen/idlutil.py)42
-rw-r--r--lib9p/core_generated.c (renamed from lib9p/9p.generated.c)1659
-rw-r--r--lib9p/core_include/lib9p/_core_generated.h (renamed from lib9p/include/lib9p/9p.generated.h)989
-rw-r--r--lib9p/core_include/lib9p/core.h (renamed from lib9p/include/lib9p/9p.h)70
-rw-r--r--lib9p/core_tables.c (renamed from lib9p/tables.c)20
-rw-r--r--lib9p/core_tables.h (renamed from lib9p/tables.h)12
-rw-r--r--lib9p/core_utf8.h (renamed from lib9p/utf8.h)8
-rw-r--r--lib9p/idl/0000-uninitialized.9p13
-rw-r--r--lib9p/idl/1992-9P0.9p.wip2
-rw-r--r--lib9p/idl/1996-Styx.9p.wip2
-rw-r--r--lib9p/idl/2002-9P2000.9p34
-rw-r--r--lib9p/idl/2003-9P2000.p9p.9p2
-rw-r--r--lib9p/idl/2005-9P2000.u.9p14
-rw-r--r--lib9p/idl/2010-9P2000.L.9p165
-rwxr-xr-xlib9p/idl/2010-9P2000.L.9p.gen282
-rw-r--r--lib9p/idl/__init__.py20
-rw-r--r--lib9p/include/lib9p/linux-errno.h139
-rwxr-xr-xlib9p/include/lib9p/linux-errno.h.gen38
-rw-r--r--lib9p/include/lib9p/srv.h179
-rwxr-xr-xlib9p/linux-errno.txt.gen (renamed from build-aux/linux-errno.txt.gen)4
-rw-r--r--lib9p/map.h114
-rw-r--r--lib9p/srv.c1684
-rw-r--r--lib9p/srv_include/lib9p/srv.h305
-rw-r--r--lib9p/tests/client_config/config.h19
-rwxr-xr-xlib9p/tests/runtest81
-rw-r--r--lib9p/tests/test_compile.c1480
-rwxr-xr-xlib9p/tests/test_compile.c.gen4
-rw-r--r--lib9p/tests/test_compile_config/config.h13
-rw-r--r--lib9p/tests/test_server/CMakeLists.txt4
-rw-r--r--lib9p/tests/test_server/config/config.h33
-rw-r--r--lib9p/tests/test_server/fs_flush.c131
-rw-r--r--lib9p/tests/test_server/fs_flush.h27
-rw-r--r--lib9p/tests/test_server/fs_shutdown.c104
-rw-r--r--lib9p/tests/test_server/fs_shutdown.h23
-rw-r--r--lib9p/tests/test_server/fs_whoami.c153
-rw-r--r--lib9p/tests/test_server/fs_whoami.h20
-rw-r--r--lib9p/tests/test_server/main.c191
-rwxr-xr-xlib9p/tests/testclient-p9p65
-rw-r--r--lib9p/tests/testclient-p9p.explog106
-rw-r--r--lib9p/tests/testclient-sess.c243
-rw-r--r--lib9p/tests/testclient-sess.explog156
-rw-r--r--lib9p_util/CMakeLists.txt2
-rw-r--r--lib9p_util/static.c126
-rw-r--r--libcr/CMakeLists.txt2
-rw-r--r--libcr/tests/test_matrix.c6
-rw-r--r--libcr_ipc/CMakeLists.txt12
-rw-r--r--libcr_ipc/chan.c146
-rw-r--r--libcr_ipc/include/libcr_ipc/_linkedlist.h99
-rw-r--r--libcr_ipc/include/libcr_ipc/chan.h237
-rw-r--r--libcr_ipc/include/libcr_ipc/mutex.h46
-rw-r--r--libcr_ipc/include/libcr_ipc/owned_mutex.h79
-rw-r--r--libcr_ipc/include/libcr_ipc/rpc.h263
-rw-r--r--libcr_ipc/include/libcr_ipc/rwmutex.h78
-rw-r--r--libcr_ipc/include/libcr_ipc/select.h85
-rw-r--r--libcr_ipc/include/libcr_ipc/sema.h67
-rw-r--r--libcr_ipc/mutex.c44
-rw-r--r--libcr_ipc/rpc.c84
-rw-r--r--libcr_ipc/rwmutex.c98
-rw-r--r--libcr_ipc/select.c102
-rw-r--r--libcr_ipc/sema.c62
-rw-r--r--libcr_ipc/tests/config.h4
-rw-r--r--libcr_ipc/tests/test_chan.c22
-rw-r--r--libcr_ipc/tests/test_mutex.c37
-rw-r--r--libcr_ipc/tests/test_rpc.c26
-rw-r--r--libcr_ipc/tests/test_rwmutex.c88
-rw-r--r--libcr_ipc/tests/test_select.c89
-rw-r--r--libcr_ipc/tests/test_sema.c22
-rw-r--r--libfmt/libmisc.c4
-rw-r--r--libhw_cr/host_net.c3
-rw-r--r--libhw_cr/host_util.c2
-rw-r--r--libhw_cr/host_util.h2
-rw-r--r--libhw_cr/rp2040_hwspi.c8
-rw-r--r--libhw_cr/rp2040_include/libhw/rp2040_hwspi.h2
-rw-r--r--libhw_cr/rp2040_include/libhw/w5500.h2
-rw-r--r--libhw_cr/w5500.c6
-rw-r--r--libhw_cr/w5500_ll.h6
-rw-r--r--libmisc/CMakeLists.txt3
-rw-r--r--libmisc/include/libmisc/alloc.h26
-rw-r--r--libmisc/include/libmisc/assert.h17
-rw-r--r--libmisc/include/libmisc/linkedlist.h108
-rw-r--r--libmisc/include/libmisc/macro.h17
-rw-r--r--libmisc/include/libmisc/map.h146
-rw-r--r--libmisc/include/libmisc/rand.h2
-rw-r--r--libmisc/linkedlist.c64
-rw-r--r--libmisc/map.c230
-rw-r--r--libmisc/tests/test_map.c60
-rw-r--r--libmisc/tests/test_private.c2
-rw-r--r--libusb/CMakeLists.txt2
-rw-r--r--libusb/include/libusb/tusb_helpers.h2
-rwxr-xr-xlibusb/include/libusb/tusb_helpers.h.gen21
-rw-r--r--notes.md4
124 files changed, 8190 insertions, 3937 deletions
diff --git a/.editorconfig b/.editorconfig
index f907b33..c632054 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -15,6 +15,8 @@ indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true
+# By well-known name ###########################################################
+
[*.{c,h}]
_mode = c
@@ -27,20 +29,6 @@ _mode = cmake
[*.md]
_mode = markdown
-[*.9p{,.wip}]
-_mode = 9p
-
-[{lib9p/tests/test_server/static.h.gen,build-aux/embed-sources.h.gen,build-aux/lint-{generic,unknown},lib9p/tests/test_compile.c.gen}]
-_mode = sh
-
-[{build-aux/lint-h,build-aux/lint-bin,build-aux/get-dscname,build-aux/linux-errno.txt.gen,libusb/include/libusb/tusb_helpers.h.gen,lib9p/tests/runtest}]
-_mode = bash
-
-[{lib9p/proto.gen,lib9p/include/lib9p/linux-errno.h.gen,build-aux/stack.c.gen}]
-_mode = python3
-indent_style = space
-indent_size = 4
-
[*.py]
_mode = python3
indent_style = space
@@ -49,11 +37,43 @@ indent_size = 4
[requirements.txt]
_mode = pip
-[**/Documentation/**.txt]
-_mode = man-cat
-
[{.editorconfig,.gitmodules,.pylintrc}]
_mode = ini
[.gitignore]
_mode = gitignore
+
+# By specific filename (non-lib9p) #############################################
+
+[{build-aux/lint-{generic,unknown},build-aux/embed-sources.h.gen}]
+_mode = sh
+
+[{build-aux/lint-{bin,h},build-aux/get-dscname,build-aux/valgrind,libusb/include/libusb/tusb_helpers.h.gen}]
+_mode = bash
+
+[build-aux/stack.c.gen]
+_mode = python3
+indent_style = space
+indent_size = 4
+
+[**/Documentation/**.txt]
+_mode = man-cat
+
+# By specific filename (lib9p) #################################################
+
+[lib9p/idl/*.9p{,.wip}]
+_mode = 9p-idl
+
+[lib9p/tests/*.explog]
+_mode = 9p-log
+
+[{lib9p/tests/test_server/static.h.gen,lib9p/tests/test_compile.c.gen}]
+_mode = sh
+
+[{lib9p/linux-errno.txt.gen,lib9p/tests/runtest,lib9p/tests/testclient-p9p}]
+_mode = bash
+
+[{lib9p/core.gen,lib9p/idl/2010-9P2000.L.9p.gen}]
+_mode = python3
+indent_style = space
+indent_size = 4
diff --git a/3rd-party/linux-errno.txt b/3rd-party/linux-errno.txt
index 839efc2..5b450f0 100644
--- a/3rd-party/linux-errno.txt
+++ b/3rd-party/linux-errno.txt
@@ -1,4 +1,4 @@
-# 3rd-party/linux-errno.txt - Generated from build-aux/linux-errno.txt.gen and linux.git v6.7. DO NOT EDIT!
+# 3rd-party/linux-errno.txt - Generated from lib9p/linux-errno.txt.gen and linux.git v6.14. DO NOT EDIT!
1 EPERM Operation not permitted
2 ENOENT No such file or directory
3 ESRCH No such process
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 22756c1..9fa048f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -112,7 +112,7 @@ function(add_lib_test arg_libname arg_testname)
target_include_directories("${arg_testname}" PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests)
add_test(
NAME "${arg_libname}/${arg_testname}"
- COMMAND valgrind --error-exitcode=2 "./${arg_testname}"
+ COMMAND "${CMAKE_SOURCE_DIR}/build-aux/valgrind" "./${arg_testname}"
)
endif()
endfunction()
diff --git a/GNUmakefile b/GNUmakefile
index f6ff6c3..8636973 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -34,19 +34,19 @@ generate/files += 3rd-party/COPYING.newlib.txt
cp $< $@
generate/files += 3rd-party/linux-errno.txt
-3rd-party/linux-errno.txt: build-aux/linux-errno.txt.gen
+3rd-party/linux-errno.txt: lib9p/linux-errno.txt.gen
$< $(linux.git) $@
-generate/files += lib9p/include/lib9p/linux-errno.h
-lib9p/include/lib9p/linux-errno.h: %: %.gen 3rd-party/linux-errno.txt
+generate/files += lib9p/idl/2010-9P2000.L.9p
+lib9p/idl/2010-9P2000.L.9p: %: %.gen 3rd-party/linux-errno.txt
$^ >$@
-generate/files += lib9p/9p.generated.c lib9p/include/lib9p/9p.generated.h
-lib9p/9p.generated.c lib9p/include/lib9p/9p.generated.h &: lib9p/proto.gen lib9p/idl/__init__.py lib9p/protogen lib9p/protogen/*.py lib9p/idl lib9p/idl/*.9p
- $< $(filter %.9p,$^)
+generate/files += lib9p/core_generated.c lib9p/core_include/lib9p/_core_generated.h
+lib9p/core_generated.c lib9p/core_include/lib9p/_core_generated.h &: lib9p/core.gen lib9p/idl/__init__.py lib9p/core_gen lib9p/core_gen/*.py lib9p/idl lib9p/idl/2010-9P2000.L.9p lib9p/idl/*.9p
+ $< $(sort $(filter %.9p,$^))
generate/files += lib9p/tests/test_compile.c
-lib9p/tests/test_compile.c: %: %.gen lib9p/include/lib9p/9p.generated.h
+lib9p/tests/test_compile.c: %: %.gen lib9p/core_include/lib9p/_core_generated.h
$^ $@
generate/files += libusb/include/libusb/tusb_helpers.h 3rd-party/MS-LCID.pdf 3rd-party/MS-LCID.txt
@@ -78,9 +78,6 @@ generate-clean:
platforms := rp2040 host # $(shell sed -nE 's/if *\(PICO_PLATFORM STREQUAL "(.*)"\)/\1/p' cmd/*/CMakeLists.txt)
build_types = Debug Release RelWithDebInfo MinSizeRel
-export CTEST_PARALLEL_LEVEL = 0
-export CTEST_OUTPUT_ON_FAILURE = 1
-
build: $(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/build))
.PHONY: build
@@ -91,12 +88,12 @@ $(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/build)): build/%
$(MAKE) -C $(<D)
.PHONY: $(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/build))
-check: build
- $(MAKE) -j1 -k INNER=t $(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/check))
+check:
+ $(MAKE) -k INNER=t $(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/check))
.PHONY: check
-$(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/check)): build/%/check: build/%/Makefile
- $(MAKE) -C $(<D) test
+$(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/check)): build/%/check: build/%/build
+ +cd $(@D) && ctest --output-on-failure $(if $(filter --jobserver-auth=%,$(MAKEFLAGS)),--parallel)
.PHONY: $(foreach t,$(build_types),$(foreach p,$(platforms),build/$p-$t/check))
# `lint` and `format` ##########################################################
@@ -109,44 +106,47 @@ build-aux/venv: build-aux/requirements.txt
$@/bin/pip install -r $<
touch --no-create $@
-# `lint` ###########
+# `lint` ###############################
+# generic ##########
lint:
$(MAKE) -k INNER=t $(patsubst sources_%,lint/%,$(filter sources_%,$(.VARIABLES)))
# Only lint binaries if the build scripts pass lint.
$(MAKE) INNER=t lint/bin
lint/bin: build build-aux/lint-bin
./build-aux/lint-bin $(foreach t,$(build_types),build/rp2040-$t/cmd/sbc_harness/sbc_harness.elf)
+lint/all: lint/%: build-aux/lint-generic build-aux/get-dscname
+ ./build-aux/lint-generic '%s\n' $(sources_$*)
+lint/unknown: lint/%: build-aux/lint-unknown
+ ./build-aux/lint-unknown $(sources_$*)
+.PHONY: lint lint/%
+# specific #########
+lint/c: lint/%: build-aux/lint-h build-aux/get-dscname
+ ./build-aux/lint-h $(filter %.h,$(sources_$*))
lint/sh lint/bash: lint/%:
shellcheck $(sources_$*)
+ shfmt --diff --case-indent --simplify $(sources_$*)
lint/python3: lint/%: build-aux/venv
./build-aux/venv/bin/mypy --strict --scripts-are-modules $(sources_$*)
./build-aux/venv/bin/black --check $(sources_$*)
./build-aux/venv/bin/isort --check $(sources_$*)
./build-aux/venv/bin/pylint $(sources_$*)
- ! grep -nh 'SPECIAL$$' -- lib9p/proto.gen lib9p/protogen/*.py
+ ! grep -nh 'SPECIAL$$' -- lib9p/core.gen lib9p/core_gen/*.py
./build-aux/venv/bin/pytest $(foreach f,$(sources_python3),$(if $(filter test_%.py,$(notdir $f)),$f))
-lint/c: lint/%: build-aux/lint-h build-aux/get-dscname
- ./build-aux/lint-h $(filter %.h,$(sources_$*))
-lint/make lint/cmake lint/gitignore lint/ini lint/9p lint/markdown lint/pip lint/man-cat: lint/%:
- @:
-lint/unknown: lint/%: build-aux/lint-unknown
- ./build-aux/lint-unknown $(sources_$*)
-lint/all: lint/%: build-aux/lint-generic build-aux/get-dscname
- ./build-aux/lint-generic '%s\n' $(sources_$*)
-.PHONY: lint lint/%
+lint/make lint/cmake lint/gitignore lint/ini lint/9p-idl lint/9p-log lint/markdown lint/pip lint/man-cat: lint/%:
+ @: TODO: Write/adopt linters for these file types
-# `format` #########
+# `format` #############################
+# generic ##########
format:
- $(MAKE) -k INNER=t $(patsubst sources_%,format/%,$(filter-out sources_all,$(filter sources_%,$(.VARIABLES))))
+ $(MAKE) -k INNER=t $(patsubst sources_%,format/%,$(filter-out sources_all sources_unknown,$(filter sources_%,$(.VARIABLES))))
+.PHONY: format format/%
+# specific #########
+format/c: format/%:
+ @: TODO: Adopt a C code-formatter
+format/sh format/bash: format/%:
+ shfmt --write --case-indent --simplify $(sources_$*)
format/python3: format/%: ./build-aux/venv
./build-aux/venv/bin/black $(sources_$*)
./build-aux/venv/bin/isort $(sources_$*)
-format/sh format/bash: format/%
- @:
-format/c: format/%:
- @: TODO: Adopt a C code-formatter
-format/make format/cmake format/gitignore format/ini format/9p format/markdown format/pip format/man-cat: format/%:
- @:
-format/unknown: format/%:
- @:
-.PHONY: format format/%
+format/make format/cmake format/gitignore format/ini format/9p-idl format/9p-log format/markdown format/pip format/man-cat: format/%:
+ @: TODO: Write/adopt formatters for these file types
diff --git a/PLAN.md b/PLAN.md
index 2bae3fd..3201122 100644
--- a/PLAN.md
+++ b/PLAN.md
@@ -1,10 +1,20 @@
<!--
PLAN.md - Misc planning notes
- Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
SPDX-License-Identifier: AGPL-3.0-or-later
-->
+- [ ] syslog on 9p
+- [ ] better 9p-shutdown
+- [ ] PIO-based USB
+- [ ] wire the USB keyboard to 9P
+- [ ] wire uart to 9p
+
+- SDcard to 9p
+- PicoDVI
+- solder up the bus switch
+
- with hardware I have:
1. [X] type "hello world" as a USB keyboard
2. [ ] get networking up (ping)
@@ -19,5 +29,3 @@
1. [ ] PicoDVI hello-world
2. [ ] "PiciDVI" to network
3. [ ] reverse the flow of PicoDVI
-
-https://hackaday.com/2022/08/26/bit-banged-ethernet-on-the-raspberry-pi-pico/
diff --git a/README.md b/README.md
index a1eebb9..4ad8158 100644
--- a/README.md
+++ b/README.md
@@ -77,9 +77,9 @@ protocol over TCP:
- `9P2000` (base protocol): Yes
- `9P2000.u` (Unix extension): Yes, with Linux kernel
architecture-"generic" errnos. This will match the Linux kernel
- errnos on most architectures (but, as of Linux v6.7, not on
- Alpha, MIPS, PA-RISC, PowerPC, or SPARC; I am unsure whether on
- these platforms the kernel's v9fs filesystem driver will map the
+ errnos on most architectures (but, as of Linux v6.14, not on
+ Alpha, MIPS, PA-RISC, PowerPC, or SPARC; unfortunately on these
+ platforms the kernel's v9fs filesystem driver won't map the
"generic" errnos to the architecture-specific errnos for you).
- `9P2000.L` (Linux extension): No, it's an abomination and
unlikely to ever be supported
diff --git a/build-aux/embed-sources.h.gen b/build-aux/embed-sources.h.gen
index 0329496..ee9eb42 100755
--- a/build-aux/embed-sources.h.gen
+++ b/build-aux/embed-sources.h.gen
@@ -6,5 +6,5 @@
nm --format=posix "$@" |
sed -n -E \
- -e 's/(.*_(end|start)) [DR] .*/extern char \1[];/p' \
- -e 's/(.*_size) A .*/extern size_t \1;/p'
+ -e 's/(.*_(end|start)) [DR] .*/extern char \1[];/p' \
+ -e 's/(.*_size) A .*/extern size_t \1;/p'
diff --git a/build-aux/lint-bin b/build-aux/lint-bin
index 78ed19f..91f1612 100755
--- a/build-aux/lint-bin
+++ b/build-aux/lint-bin
@@ -62,7 +62,7 @@ lint_globals() {
cd "$rel_base"
total=0
while read -r symbol addr size source; do
- if (( addr == 0 )); then
+ if ((addr == 0)); then
continue
fi
case "$source" in
@@ -103,8 +103,9 @@ lint_stack() {
fi
done < <(
comm -3 \
- <(sed -En 's/^included: (.*:)?//p' "${in_elffile%.elf}_stack.c" | sort -u) \
- <(readelf_funcs "$in_elffile" | sed -E -e 's/\.part\.[0-9]*$//' -e 's/^__(.*)_veneer$/\1/' | sort -u))
+ <(sed -En 's/^included: (.*:)?//p' "${in_elffile%.elf}_stack.c" | sort -u) \
+ <(readelf_funcs "$in_elffile" | sed -E -e 's/\.part\.[0-9]*$//' -e 's/^__(.*)_veneer$/\1/' | sort -u)
+ )
}
lint_func_blocklist() {
@@ -118,8 +119,8 @@ lint_func_blocklist() {
while read -r func; do
err "$in_elffile" "Contains blocklisted function: ${func}"
done < <(readelf --syms --wide -- "$in_elffile" |
- awk '$4 == "FUNC" { print $8 }' |
- grep -Fx "${blocklist[@]/#/-e}")
+ awk '$4 == "FUNC" { print $8 }' |
+ grep -Fx "${blocklist[@]/#/-e}")
}
main() {
@@ -130,8 +131,8 @@ main() {
{
echo 'Global variables:'
lint_globals "${elf}.map" | sed 's/^/ /'
- } > "${elf%.elf}.lint.globals"
- (lint_stack "$elf") &> "${elf%.elf}.lint.stack"
+ } >"${elf%.elf}.lint.globals"
+ (lint_stack "$elf") &>"${elf%.elf}.lint.stack"
lint_func_blocklist "$elf"
done
diff --git a/build-aux/lint-generic b/build-aux/lint-generic
index 58a65d2..70e814a 100755
--- a/build-aux/lint-generic
+++ b/build-aux/lint-generic
@@ -25,12 +25,17 @@ for filename in "$@"; do
if [ -x "$filename" ] && [ -z "$shebang" ]; then
err "$filename" 'is executable but does not have a shebang'
elif [ -n "$shebang" ] && ! [ -x "$filename" ]; then
- err "$filename" 'has a shebang but is executable'
+ err "$filename" 'has a shebang but is not executable'
fi
if ! grep -E -q 'Copyright \(C\) 202[4-9]((-|, )202[5-9])* Luke T. Shumaker' "$filename"; then
err "$filename" 'is missing a copyright statement'
fi
+ if test -e .git && ! git diff --quiet milestone/2025-01-01 HEAD -- "$filename"; then
+ if ! grep -E -q 'Copyright \(C\) .*2025 Luke T. Shumaker' "$filename"; then
+ err "$filename" 'has an outdated copyright statement'
+ fi
+ fi
if ! grep -q '\sSPDX-License-Identifier[:] ' "$filename"; then
err "$filename" 'is missing an SPDX-License-Identifier'
fi
diff --git a/build-aux/lint-h b/build-aux/lint-h
index 26ac13d..7459032 100755
--- a/build-aux/lint-h
+++ b/build-aux/lint-h
@@ -18,9 +18,9 @@ for filename in "$@"; do
guard=${dscname//'/'/'_'}
guard=${guard//'.'/'_'}
guard="_${guard^^}_"
- if ! { grep -Fxq "#ifndef ${guard}" "$filename" &&
- grep -Fxq "#define ${guard}" "$filename" &&
- grep -Fxq "#endif /* ${guard} */" "$filename"; }; then
+ if ! { grep -Fxq "#ifndef ${guard}" "$filename" &&
+ grep -Fxq "#define ${guard}" "$filename" &&
+ grep -Fxq "#endif /* ${guard} */" "$filename"; }; then
err "$filename" "does not have ${guard} guard"
fi
done
diff --git a/build-aux/measurestack/app_plugins.py b/build-aux/measurestack/app_plugins.py
index 36e661b..bbb0eae 100644
--- a/build-aux/measurestack/app_plugins.py
+++ b/build-aux/measurestack/app_plugins.py
@@ -4,6 +4,7 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
import re
+import subprocess
import typing
from . import analyze, util
@@ -247,8 +248,8 @@ class LibCRIPCPlugin:
return None
if "/chan.c:" in loc and "front->dequeue(" in line:
return [
- QName("_cr_chan_dequeue"),
- QName("_cr_select_dequeue"),
+ QName("cr_chan_dequeue"),
+ QName("cr_select_dequeue"),
], False
return None
@@ -271,9 +272,8 @@ re_lib9p_callee = re.compile(
class Lib9PPlugin:
tmessage_handlers: set[QName] | None
lib9p_msgs: set[str]
- _CONFIG_9P_NUM_SOCKS: int | None
- CONFIG_9P_SRV_MAX_REQS: int | None
- CONFIG_9P_SRV_MAX_DEPTH: int | None
+ _CONFIG_9P_MAX_CONNS: int | None
+ _CONFIG_9P_MAX_REQS: int | None
formatters: typing.Collection[BaseName]
def __init__(
@@ -305,25 +305,25 @@ class Lib9PPlugin:
)
lib9p_generated_c_fname = util.get_zero_or_one(
- lambda fname: fname.endswith("lib9p/9p.generated.c"), arg_c_fnames
+ lambda fname: fname.endswith("lib9p/_core_generated.c"), arg_c_fnames
)
# Read config ##########################################################
def config_h_get(varname: str) -> int | None:
if config_h_fname:
- with open(config_h_fname, "r", encoding="utf-8") as fh:
- for line in fh:
- line = line.rstrip()
- if line.startswith("#define"):
- parts = line.split()
- if parts[1] == varname:
- return int(parts[2])
+ line = subprocess.run(
+ ["cpp"],
+ input=f'#include "{config_h_fname}"\n{varname}\n',
+ check=True,
+ capture_output=True,
+ encoding="utf-8",
+ ).stdout.split("\n")[-2]
+ return int(eval(line)) # pylint: disable=eval-used
return None
- self._CONFIG_9P_NUM_SOCKS = config_h_get("_CONFIG_9P_NUM_SOCKS")
- self.CONFIG_9P_SRV_MAX_REQS = config_h_get("CONFIG_9P_SRV_MAX_REQS")
- self.CONFIG_9P_SRV_MAX_DEPTH = config_h_get("CONFIG_9P_SRV_MAX_DEPTH")
+ self._CONFIG_9P_MAX_CONNS = config_h_get("_CONFIG_9P_MAX_REQS")
+ self._CONFIG_9P_MAX_REQS = config_h_get("_CONFIG_9P_MAX_REQS")
# Read sources #########################################################
@@ -348,12 +348,12 @@ class Lib9PPlugin:
self.lib9p_msgs = lib9p_msgs
def thread_count(self, name: QName) -> int:
- assert self._CONFIG_9P_NUM_SOCKS
- assert self.CONFIG_9P_SRV_MAX_REQS
+ assert self._CONFIG_9P_MAX_CONNS
+ assert self._CONFIG_9P_MAX_REQS
if "read" in str(name.base()):
- return self._CONFIG_9P_NUM_SOCKS
+ return self._CONFIG_9P_MAX_CONNS
if "write" in str(name.base()):
- return self._CONFIG_9P_NUM_SOCKS * self.CONFIG_9P_SRV_MAX_REQS
+ return self._CONFIG_9P_MAX_REQS
return 1
def is_intrhandler(self, name: QName) -> bool:
@@ -405,11 +405,6 @@ class Lib9PPlugin:
self.formatters, self._skipmodel__vfctprintf
),
}
- if isinstance(self.CONFIG_9P_SRV_MAX_DEPTH, int):
- ret[BaseName("srv_util_pathfree")] = analyze.SkipModel(
- self.CONFIG_9P_SRV_MAX_DEPTH,
- self._skipmodel_srv_util_pathfree,
- )
return ret
def _skipmodel__lib9p_validate_unmarshal_marshal(
@@ -423,17 +418,6 @@ class Lib9PPlugin:
return False
return m_caller.group("grp") != m_callee.group("grp")
- def _skipmodel_srv_util_pathfree(
- self, chain: typing.Sequence[QName], call: QName
- ) -> bool:
- assert isinstance(self.CONFIG_9P_SRV_MAX_DEPTH, int)
- if call.base() == BaseName("srv_util_pathfree"):
- return len(chain) >= self.CONFIG_9P_SRV_MAX_DEPTH and all(
- c.base() == BaseName("srv_util_pathfree")
- for c in chain[-self.CONFIG_9P_SRV_MAX_DEPTH :]
- )
- return False
-
def _skipmodel__vfctprintf(
self, chain: typing.Sequence[QName], call: QName
) -> bool:
diff --git a/build-aux/valgrind b/build-aux/valgrind
new file mode 100755
index 0000000..7ad2712
--- /dev/null
+++ b/build-aux/valgrind
@@ -0,0 +1,16 @@
+#!/bin/env bash
+# build-aux/valgrind - Wrapper around valgrind to keep flags consistent
+#
+# Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+exec \
+ valgrind \
+ --fair-sched=yes \
+ --error-exitcode=2 \
+ --leak-check=full \
+ --show-leak-kinds=all \
+ --errors-for-leak-kinds=all \
+ --show-error-list=all \
+ -- \
+ "$@"
diff --git a/cmd/sbc_harness/CMakeLists.txt b/cmd/sbc_harness/CMakeLists.txt
index 678af07..6e722d7 100644
--- a/cmd/sbc_harness/CMakeLists.txt
+++ b/cmd/sbc_harness/CMakeLists.txt
@@ -30,7 +30,7 @@ target_link_libraries(sbc_harness_objs
libusb
libdhcp
libhw_cr
- lib9p
+ lib9p_srv
lib9p_util
)
pico_minimize_runtime(sbc_harness_objs
diff --git a/cmd/sbc_harness/config/config.h b/cmd/sbc_harness/config/config.h
index 5e7bc06..ca23462 100644
--- a/cmd/sbc_harness/config/config.h
+++ b/cmd/sbc_harness/config/config.h
@@ -11,6 +11,9 @@
#define CONFIG_FLASH_DEBUG 1
+#define _CONFIG_9P_MAX_CONNS 3 /* FIXME: bump this back up to 8 */
+#define _CONFIG_9P_MAX_REQS (2*_CONFIG_9P_MAX_CONNS)
+
/* RP2040 *********************************************************************/
#define CONFIG_RP2040_SPI_DEBUG 1 /* bool */
@@ -36,6 +39,18 @@
#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 */
+
+#define CONFIG_9P_SRV_MAX_MSG_SIZE ((4*1024)+24)
+
/**
* This max-msg-size is sized so that a Twrite message can return
* 8KiB of data.
@@ -60,15 +75,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 */
/* DHCP ***********************************************************************/
@@ -92,8 +98,8 @@
extern const size_t CONFIG_COROUTINE_STACK_SIZE_dhcp_cr;
extern const size_t CONFIG_COROUTINE_STACK_SIZE_init_cr;
-extern const size_t CONFIG_COROUTINE_STACK_SIZE_lib9p_srv_write_cr;
extern const size_t CONFIG_COROUTINE_STACK_SIZE_read9p_cr;
+extern const size_t CONFIG_COROUTINE_STACK_SIZE_write9p_cr;
extern const size_t CONFIG_COROUTINE_STACK_SIZE_usb_common_cr;
extern const size_t CONFIG_COROUTINE_STACK_SIZE_usb_keyboard_cr;
extern const size_t CONFIG_COROUTINE_STACK_SIZE_w5500_irq_cr;
@@ -104,12 +110,11 @@ extern const size_t CONFIG_COROUTINE_STACK_SIZE_w5500_irq_cr;
#define CONFIG_COROUTINE_VALGRIND 0 /* bool */
#define CONFIG_COROUTINE_GDB 1 /* bool */
-#define _CONFIG_9P_NUM_SOCKS 3 /* FIXME: bump this back up to 8 */
-#define CONFIG_COROUTINE_NUM ( \
- 1 /* usb_common */ + \
- 1 /* usb_keyboard */ + \
- 1 /* W5500 irq handler */ + \
- _CONFIG_9P_NUM_SOCKS /* 9P accept()+read() */ + \
- (CONFIG_9P_SRV_MAX_REQS*_CONFIG_9P_NUM_SOCKS) /* 9P work+write() */ )
+#define CONFIG_COROUTINE_NUM ( \
+ 1 /* usb_common */ + \
+ 1 /* usb_keyboard */ + \
+ 1 /* W5500 irq handler */ + \
+ _CONFIG_9P_MAX_CONNS /* 9P accept()+read() */ + \
+ _CONFIG_9P_MAX_REQS /* 9P work+write() */ )
#endif /* _CONFIG_H_ */
diff --git a/cmd/sbc_harness/config/tusb_config.h b/cmd/sbc_harness/config/tusb_config.h
index 0a6d3e4..5240311 100644
--- a/cmd/sbc_harness/config/tusb_config.h
+++ b/cmd/sbc_harness/config/tusb_config.h
@@ -1,6 +1,6 @@
/* tusb_config.h - Compile-time configuration for the TinyUSB library
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* SPDX-License-Identifier: MIT
@@ -61,7 +61,7 @@ extern "C" {
TU_BREAKPOINT(); \
return _ret; \
} \
- } while(0)
+ } while (0)
void _libmisc_tu_mess_failed(const char *expr,
const char *file, unsigned int line, const char *func);
diff --git a/cmd/sbc_harness/fs_harness_flash_bin.c b/cmd/sbc_harness/fs_harness_flash_bin.c
index bdb8da4..5920b85 100644
--- a/cmd/sbc_harness/fs_harness_flash_bin.c
+++ b/cmd/sbc_harness/fs_harness_flash_bin.c
@@ -4,6 +4,8 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
+#include <string.h>
+
#include <hardware/flash.h>
#include <hardware/watchdog.h>
@@ -146,40 +148,35 @@ static struct lib9p_qid flash_file_qid(struct flash_file *self) {
};
}
-static struct lib9p_stat flash_file_stat(struct flash_file *self, struct lib9p_srv_ctx *ctx) {
+static struct lib9p_srv_stat flash_file_stat(struct flash_file *self, struct lib9p_srv_ctx *ctx) {
assert(self);
assert(ctx);
- return (struct lib9p_stat){
- .kern_type = 0,
- .kern_dev = 0,
- .file_qid = flash_file_qid(self),
- .file_mode = LIB9P_DM_EXCL|0666,
- .file_atime = UTIL9P_ATIME,
- .file_mtime = UTIL9P_MTIME,
- .file_size = DATA_SIZE,
- .file_name = lib9p_str(self->name),
- .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,
+ return (struct lib9p_srv_stat){
+ .qid = flash_file_qid(self),
+ .mode = LIB9P_DM_EXCL|0666,
+ .atime_sec = UTIL9P_ATIME,
+ .mtime_sec = UTIL9P_MTIME,
+ .size = DATA_SIZE,
+ .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 flash_file_wstat(struct flash_file *self, struct lib9p_srv_ctx *ctx,
- struct lib9p_stat) {
+ struct lib9p_srv_stat) {
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
}
static void flash_file_remove(struct flash_file *self, struct lib9p_srv_ctx *ctx) {
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
}
LIB9P_SRV_NOTDIR(struct flash_file, flash_file);
@@ -233,7 +230,7 @@ static void flash_file_pread(struct flash_file *self, struct lib9p_srv_ctx *ctx,
if (byte_offset > DATA_SIZE) {
lib9p_error(&ctx->basectx,
- LINUX_EINVAL, "offset is past the chip size");
+ LIB9P_ERRNO_L_EINVAL, "offset is past the chip size");
return;
}
@@ -279,14 +276,14 @@ static uint32_t flash_file_pwrite(struct flash_file *self, struct lib9p_srv_ctx
if (byte_offset > DATA_HSIZE) {
lib9p_error(&ctx->basectx,
- LINUX_EINVAL, "offset is past half the chip size");
+ LIB9P_ERRNO_L_EINVAL, "offset is past half the chip size");
return 0;
}
if (byte_count == 0)
return 0;
if (byte_offset == DATA_HSIZE) {
lib9p_error(&ctx->basectx,
- LINUX_EINVAL, "offset is at half the chip size");
+ LIB9P_ERRNO_L_EINVAL, "offset is at half the chip size");
return 0;
}
diff --git a/cmd/sbc_harness/fs_harness_uptime_txt.c b/cmd/sbc_harness/fs_harness_uptime_txt.c
index 9216986..f7b755f 100644
--- a/cmd/sbc_harness/fs_harness_uptime_txt.c
+++ b/cmd/sbc_harness/fs_harness_uptime_txt.c
@@ -5,10 +5,10 @@
*/
#include <stdio.h> /* for snprintf() */
-#include <stdlib.h> /* for malloc(), free() */
#include <libhw/generic/alarmclock.h>
#include <util9p/static.h>
+#include <libmisc/alloc.h> /* for heap_alloc(), free() */
#include "fs_harness_uptime_txt.h"
@@ -38,7 +38,7 @@ static struct lib9p_qid uptime_file_qid(struct uptime_file *self) {
};
}
-static struct lib9p_stat uptime_file_stat(struct uptime_file *self, struct lib9p_srv_ctx *ctx) {
+static struct lib9p_srv_stat uptime_file_stat(struct uptime_file *self, struct lib9p_srv_ctx *ctx) {
assert(self);
assert(ctx);
@@ -52,36 +52,31 @@ static struct lib9p_stat uptime_file_stat(struct uptime_file *self, struct lib9p
size++;
size += 3;
- return (struct lib9p_stat){
- .kern_type = 0,
- .kern_dev = 0,
- .file_qid = uptime_file_qid(self),
- .file_mode = 0444,
- .file_atime = UTIL9P_ATIME,
- .file_mtime = UTIL9P_MTIME,
- .file_size = size,
- .file_name = lib9p_str(self->name),
- .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,
+ return (struct lib9p_srv_stat){
+ .qid = uptime_file_qid(self),
+ .mode = 0444,
+ .atime_sec = UTIL9P_ATIME,
+ .mtime_sec = UTIL9P_MTIME,
+ .size = size,
+ .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 uptime_file_wstat(struct uptime_file *self, struct lib9p_srv_ctx *ctx,
- struct lib9p_stat) {
+ struct lib9p_srv_stat) {
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
}
static void uptime_file_remove(struct uptime_file *self, struct lib9p_srv_ctx *ctx) {
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
}
LIB9P_SRV_NOTDIR(struct uptime_file, uptime_file);
@@ -91,7 +86,7 @@ static lo_interface lib9p_srv_fio uptime_file_fopen(struct uptime_file *self, st
assert(self);
assert(ctx);
- struct uptime_fio *ret = malloc(sizeof(struct uptime_fio));
+ struct uptime_fio *ret = heap_alloc(1, struct uptime_fio);
ret->parent = self;
ret->buf_len = 0;
@@ -130,7 +125,7 @@ static void uptime_fio_pread(struct uptime_fio *self, struct lib9p_srv_ctx *ctx,
if (byte_offset > (uint64_t)self->buf_len) {
lib9p_error(&ctx->basectx,
- LINUX_EINVAL, "offset is past end-of-file length");
+ LIB9P_ERRNO_L_EINVAL, "offset is past end-of-file length");
return;
}
@@ -151,6 +146,6 @@ static uint32_t uptime_fio_pwrite(struct uptime_fio *self, struct lib9p_srv_ctx
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
return 0;
}
diff --git a/cmd/sbc_harness/main.c b/cmd/sbc_harness/main.c
index 25b122c..5630e83 100644
--- a/cmd/sbc_harness/main.c
+++ b/cmd/sbc_harness/main.c
@@ -39,6 +39,13 @@
#include "config.h"
+#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
+
/* file tree ******************************************************************/
enum { PATH_BASE = __COUNTER__ };
@@ -153,13 +160,21 @@ static COROUTINE read9p_cr(void *) {
lo_interface net_iface iface = lo_box_w5500_if_as_net_iface(&globals.dev_w5500);
lo_interface net_stream_listener listener = LO_CALL(iface, tcp_listen, LIB9P_DEFAULT_PORT_9FS);
- lib9p_srv_read_cr(&globals.srv, listener);
+ lib9p_srv_accept_and_read_loop(&globals.srv, listener);
+
+ cr_end();
+}
+
+static COROUTINE write9p_cr(void *) {
+ cr_begin();
+
+ lib9p_srv_worker_loop(&globals.srv);
cr_end();
}
const char *const hexdig = "0123456789ABCDEF";
-static_assert(CONFIG_9P_SRV_MAX_REQS*_CONFIG_9P_NUM_SOCKS <= 16);
+static_assert(_CONFIG_9P_MAX_REQS <= 16);
COROUTINE init_cr(void *) {
cr_begin();
@@ -215,13 +230,13 @@ COROUTINE init_cr(void *) {
coroutine_add("usb_keyboard", usb_keyboard_cr, &globals.keyboard_chan);
//coroutine_add("hello_world", hello_world_cr, &globals.keyboard_chan);
coroutine_add("dhcp", dhcp_cr, NULL);
- for (int i = 0; i < _CONFIG_9P_NUM_SOCKS; i++) {
+ for (int i = 0; i < _CONFIG_9P_MAX_CONNS; i++) {
char name[] = {'r', 'e', 'a', 'd', '-', hexdig[i], '\0'};
coroutine_add(name, read9p_cr, NULL);
}
- for (int i = 0; i < CONFIG_9P_SRV_MAX_REQS*_CONFIG_9P_NUM_SOCKS; i++) {
+ for (int i = 0; i < _CONFIG_9P_MAX_REQS; i++) {
char name[] = {'w', 'r', 'i', 't', 'e', '-', hexdig[i], '\0'};
- coroutine_add(name, lib9p_srv_write_cr, &globals.srv);
+ coroutine_add(name, write9p_cr, NULL);
}
cr_exit();
@@ -234,4 +249,5 @@ int main() {
infof("===================================================================");
coroutine_add("init", init_cr, NULL);
coroutine_main();
+ assert_notreached("all coroutines exited");
}
diff --git a/cmd/sbc_harness/usb_keyboard.c b/cmd/sbc_harness/usb_keyboard.c
index f3cb42d..7dd8a24 100644
--- a/cmd/sbc_harness/usb_keyboard.c
+++ b/cmd/sbc_harness/usb_keyboard.c
@@ -54,8 +54,8 @@ COROUTINE usb_keyboard_cr(void *_chan) {
while (!tud_hid_n_ready(kbd_ifc))
cr_yield();
- if (usb_keyboard_rpc_can_recv_req(chan)) {
- usb_keyboard_rpc_req_t req = usb_keyboard_rpc_recv_req(chan);
+ if (cr_rpc_can_recv_req(chan)) {
+ usb_keyboard_rpc_req_t req = cr_rpc_recv_req(chan);
uint32_t rune = req.req;
modifier = ascii2keycode[rune][0] ? KEYBOARD_MODIFIER_LEFTSHIFT : 0;
@@ -69,7 +69,7 @@ COROUTINE usb_keyboard_cr(void *_chan) {
keycodes[0] = 0;
tud_hid_n_keyboard_report(kbd_ifc, report_id, modifier, keycodes);
- usb_keyboard_rpc_send_resp(req, 1);
+ cr_rpc_send_resp(req, 1);
} else {
modifier = 0;
keycodes[0] = 0;
diff --git a/cmd/sbc_harness/usb_keyboard.h b/cmd/sbc_harness/usb_keyboard.h
index 210014d..cf8483b 100644
--- a/cmd/sbc_harness/usb_keyboard.h
+++ b/cmd/sbc_harness/usb_keyboard.h
@@ -1,6 +1,6 @@
/* sbc_harness/usb_keyboard.h - Implementation of a USB keyboard device
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@@ -12,7 +12,7 @@
#include <libcr/coroutine.h> /* for COROUTINE */
#include <libcr_ipc/rpc.h> /* for CR_RPC_DECLARE */
-CR_RPC_DECLARE(usb_keyboard_rpc, uint32_t, int)
+CR_RPC_DECLARE(usb_keyboard_rpc, uint32_t, int);
void usb_keyboard_init(void);
COROUTINE usb_keyboard_cr(void *arg);
diff --git a/gdb-helpers/libcr.py b/gdb-helpers/libcr.py
index fcfd86e..6f95a81 100644
--- a/gdb-helpers/libcr.py
+++ b/gdb-helpers/libcr.py
@@ -89,6 +89,7 @@ def gdb_longjmp(buf: gdb_JmpBuf) -> None:
class CrGlobals:
+ main: "CrMain"
coroutines: list["CrCoroutine"]
_breakpoint: "CrBreakpoint"
_known_threads: set[gdb.InferiorThread]
@@ -98,6 +99,7 @@ class CrGlobals:
gdb.parse_and_eval("sizeof(coroutine_table)/sizeof(coroutine_table[0])")
)
+ self.main = CrMain(self)
self.coroutines = [CrCoroutine(self, i + 1) for i in range(num)]
self._breakpoint = CrBreakpoint()
@@ -126,35 +128,37 @@ class CrGlobals:
# Ignore thread creation events.
self._known_threads = cur_threads
return
- if self.coroutine_running:
- if not self.coroutine_running.is_selected():
- if gdb_bug_32428:
- print("Must return to running coroutine before continuing.")
- print("Hit ^C twice then run:")
- print(f" cr select {self.coroutine_running.id}")
- while True:
- time.sleep(1)
- assert self.coroutine_running.cont_env
- gdb_longjmp(self.coroutine_running.cont_env)
+ if not self.coroutine_running.is_selected():
+ if gdb_bug_32428:
+ print("Must return to running coroutine before continuing.")
+ print("Hit ^C twice then run:")
+ print(f" cr select {self.coroutine_running.cid}")
+ while True:
+ time.sleep(1)
+ assert self.coroutine_running.cont_env
+ gdb_longjmp(self.coroutine_running.cont_env)
+ self.main.cont_env = None
for cr in self.coroutines:
cr.cont_env = None
def is_valid_cid(self, cid: int) -> bool:
- return 0 < cid <= len(self.coroutines)
+ return (0 < cid <= len(self.coroutines)) and (
+ self.coroutines[cid - 1].state != self.CR_NONE
+ )
@property
- def coroutine_running(self) -> "CrCoroutine | None":
+ def coroutine_running(self) -> "CrMain | CrCoroutine":
cid = int(gdb.parse_and_eval("coroutine_running"))
if not self.is_valid_cid(cid):
- return None
+ return self.main
return self.coroutines[cid - 1]
@property
- def coroutine_selected(self) -> "CrCoroutine | None":
+ def coroutine_selected(self) -> "CrMain | CrCoroutine":
for cr in self.coroutines:
if cr.is_selected():
return cr
- return None
+ return self.main
@property
def CR_NONE(self) -> gdb.Value:
@@ -164,6 +168,35 @@ class CrGlobals:
def CR_RUNNING(self) -> gdb.Value:
return gdb.parse_and_eval("CR_RUNNING")
+ def select(self, cr: "CrMain | CrCoroutine", level: int = -1) -> None:
+ self.coroutine_selected.cont_env = gdb_setjmp()
+
+ if cr.cont_env:
+ gdb_longjmp(cr.cont_env)
+ else:
+ env: gdb_JmpBuf
+ if cr == self.coroutine_running:
+ assert False # cr.cont_env should have been set
+ match cr:
+ case CrMain():
+ env = self.readjmp("&coroutine_main_env")
+ case CrCoroutine():
+ if cr.state == self.CR_RUNNING:
+ env = self.readjmp("&coroutine_add_env")
+ else:
+ env = self.readjmp(f"&coroutine_table[{cr.cid-1}].env")
+ gdb_longjmp(env)
+ cr_select_top_frame()
+
+ @contextlib.contextmanager
+ def with_selected(self, cr: "CrMain | CrCoroutine") -> typing.Iterator[None]:
+ saved_env = gdb_setjmp()
+ self.select(cr)
+ try:
+ yield
+ finally:
+ gdb_longjmp(saved_env)
+
class CrBreakpointUnwinder(gdb.unwinder.Unwinder):
"""Used to temporarily disable unwinding so that
@@ -245,6 +278,22 @@ def cr_select_top_frame() -> None:
break
+class CrMain:
+ cr_globals: CrGlobals
+ cont_env: gdb_JmpBuf | None
+
+ def __init__(self, cr_globals: CrGlobals) -> None:
+ self.cr_globals = cr_globals
+ self.cont_env = None
+
+ @property
+ def cid(self) -> int:
+ return 0
+
+ def is_selected(self) -> bool:
+ return not any(cr.is_selected() for cr in self.cr_globals.coroutines)
+
+
class CrCoroutine:
cr_globals: CrGlobals
cid: int
@@ -256,10 +305,6 @@ class CrCoroutine:
self.cont_env = None
@property
- def id(self) -> int:
- return self.cid
-
- @property
def state(self) -> gdb.Value:
return gdb.parse_and_eval(f"coroutine_table[{self.cid-1}].state")
@@ -272,36 +317,10 @@ class CrCoroutine:
def is_selected(self) -> bool:
sp = int(gdb.parse_and_eval("$sp"))
- lo = int(gdb.parse_and_eval(f"coroutine_table[{self.id-1}].stack"))
- hi = lo + int(gdb.parse_and_eval(f"coroutine_table[{self.id-1}].stack_size"))
+ lo = int(gdb.parse_and_eval(f"coroutine_table[{self.cid-1}].stack"))
+ hi = lo + int(gdb.parse_and_eval(f"coroutine_table[{self.cid-1}].stack_size"))
return lo <= sp < hi
- def select(self, level: int = -1) -> None:
- if self.cr_globals.coroutine_selected:
- self.cr_globals.coroutine_selected.cont_env = gdb_setjmp()
-
- if self.cont_env:
- gdb_longjmp(self.cont_env)
- else:
- env: gdb_JmpBuf
- if self == self.cr_globals.coroutine_running:
- assert False # self.cont_env should have been set
- elif self.state == self.cr_globals.CR_RUNNING:
- env = self.cr_globals.readjmp("&coroutine_add_env")
- else:
- env = self.cr_globals.readjmp(f"&coroutine_table[{self.id-1}].env")
- gdb_longjmp(env)
- cr_select_top_frame()
-
- @contextlib.contextmanager
- def with_selected(self) -> typing.Iterator[None]:
- saved_env = gdb_setjmp()
- self.select()
- try:
- yield
- finally:
- gdb_longjmp(saved_env)
-
# User-facing commands #########################################################
@@ -342,8 +361,11 @@ class CrListCommand(gdb.Command):
rows: list[tuple[str, str, str, str, str]] = [
("", "Id", "Name", "State", "Frame")
]
- for cr in self.cr_globals.coroutines:
- if cr.state == self.cr_globals.CR_NONE:
+ for cid in range(len(self.cr_globals.coroutines) + 1):
+ cr: CrMain | CrCoroutine = (
+ self.cr_globals.coroutines[cid - 1] if cid else self.cr_globals.main
+ )
+ if isinstance(cr, CrCoroutine) and cr.state == self.cr_globals.CR_NONE:
continue
rows += [
(
@@ -353,9 +375,9 @@ class CrListCommand(gdb.Command):
"G" if cr.is_selected() else " ",
]
),
- str(cr.id),
- repr(cr.name),
- str(cr.state),
+ str(cr.cid),
+ repr(cr.name) if isinstance(cr, CrCoroutine) else "-",
+ str(cr.state) if isinstance(cr, CrCoroutine) else "-",
self._pretty_frame(cr, from_tty),
)
]
@@ -382,9 +404,9 @@ class CrListCommand(gdb.Command):
l = l[:maxline]
print(l)
- def _pretty_frame(self, cr: CrCoroutine, from_tty: bool) -> str:
+ def _pretty_frame(self, cr: CrMain | CrCoroutine, from_tty: bool) -> str:
try:
- with cr.with_selected():
+ with self.cr_globals.with_selected(cr):
saved_level = gdb.selected_frame().level()
cr_select_top_frame()
full = gdb.execute("frame", from_tty=from_tty, to_string=True)
@@ -411,16 +433,15 @@ class CrSelectCommand(gdb.Command):
if len(argv) != 1:
raise gdb.GdbError("Usage: cr select COROUTINE")
cr = self._find(argv[0])
- cr.select()
+ self.cr_globals.select(cr)
gdb.execute("frame")
- def _find(self, name: str) -> CrCoroutine:
+ def _find(self, name: str) -> CrMain | CrCoroutine:
if name.isnumeric():
cid = int(name)
- if (
- self.cr_globals.is_valid_cid(cid)
- and self.cr_globals.coroutines[cid - 1].state != self.cr_globals.CR_NONE
- ):
+ if cid == 0:
+ return self.cr_globals.main
+ if self.cr_globals.is_valid_cid(cid):
return self.cr_globals.coroutines[cid - 1]
crs: list[CrCoroutine] = []
for cr in self.cr_globals.coroutines:
@@ -445,6 +466,7 @@ def cr_initialize() -> None:
if _cr_globals:
old = _cr_globals
new = CrGlobals()
+ new.main.cont_env = old.main.cont_env
for i in range(min(len(old.coroutines), len(new.coroutines))):
new.coroutines[i].cont_env = old.coroutines[i].cont_env
old.delete()
diff --git a/lib9p/CMakeLists.txt b/lib9p/CMakeLists.txt
index d433a12..0a5ea3e 100644
--- a/lib9p/CMakeLists.txt
+++ b/lib9p/CMakeLists.txt
@@ -3,27 +3,67 @@
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
-add_library(lib9p INTERFACE)
-target_include_directories(lib9p PUBLIC INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
-target_sources(lib9p INTERFACE
- 9p.generated.c
- 9p.c
- tables.c
- srv.c
+add_library(lib9p_core INTERFACE)
+target_include_directories(lib9p_core PUBLIC INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/core_include)
+target_sources(lib9p_core INTERFACE
+ core.c
+ core_generated.c
+ core_tables.c
)
-target_link_libraries(lib9p INTERFACE
- libcr_ipc
+target_link_libraries(lib9p_core INTERFACE
libfmt
libhw_generic
libmisc
)
+add_library(lib9p_srv INTERFACE)
+target_include_directories(lib9p_srv PUBLIC INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/srv_include)
+target_sources(lib9p_srv INTERFACE
+ srv.c
+)
+target_link_libraries(lib9p_srv INTERFACE
+ lib9p_core
+ libcr_ipc
+)
+
if (ENABLE_TESTS)
add_subdirectory(tests/test_server)
- add_test(
- NAME "lib9p/runtest"
- COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/runtest"
+
+ function(add_lib9p_executable arg_testname)
+ add_executable("${arg_testname}" "tests/${arg_testname}.c")
+ target_link_libraries("${arg_testname}" lib9p_core)
+ target_include_directories("${arg_testname}" PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/tests
+ ${CMAKE_CURRENT_SOURCE_DIR}/tests/client_config
+ )
+ endfunction()
+ function(add_lib9p_test arg_testscript)
+ get_filename_component(tmp_basename "${arg_testscript}" "NAME")
+ add_test(
+ NAME "lib9p/${tmp_basename}"
+ COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tests/runtest" "${arg_testscript}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/${tmp_basename}.explog"
+ )
+ endfunction()
+
+ add_lib9p_test("${CMAKE_CURRENT_SOURCE_DIR}/tests/testclient-p9p")
+
+ add_lib9p_executable("testclient-sess")
+ add_lib9p_test("./testclient-sess")
+
+ set(cfg_matrix
+ "CONFIG_9P_SRV_DEBUG;[0;1]"
+ "CONFIG_9P_ENABLE_9P2000;[0;1]"
+ "CONFIG_9P_ENABLE_9P2000_u;[0;1]"
+ "CONFIG_9P_ENABLE_9P2000_e;[0;1]"
+ "CONFIG_9P_ENABLE_9P2000_L;[0;1]"
+ "CONFIG_9P_ENABLE_9P2000_p9p;[0;1]"
)
- add_lib_test(lib9p test_compile)
- target_include_directories(test_compile PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_compile_config)
+ function(add_compile_test n defs)
+ add_executable("test_compile${n}" "tests/test_compile.c")
+ target_link_libraries("test_compile${n}" lib9p_srv)
+ target_include_directories("test_compile${n}" PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_compile_config)
+ target_compile_definitions("test_compile${n}" PUBLIC "${defs}")
+ # Don't bother running it (don't bother calling add_test())
+ endfunction()
+ apply_matrix(add_compile_test "${cfg_matrix}")
endif()
diff --git a/lib9p/9p.c b/lib9p/core.c
index e7b20b5..cb8ddee 100644
--- a/lib9p/9p.c
+++ b/lib9p/core.c
@@ -1,4 +1,4 @@
-/* lib9p/9p.c - Base 9P protocol utilities for both clients and servers
+/* lib9p/core.c - Base 9P protocol utilities for both clients and servers
*
* Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -10,7 +10,7 @@
#include <libfmt/fmt.h> /* for fmt_vsnprintf() */
-#include <lib9p/9p.h>
+#include <lib9p/core.h>
/* strings ********************************************************************/
@@ -47,7 +47,7 @@ bool lib9p_str_eq(struct lib9p_s a, struct lib9p_s b) {
void lib9p_ctx_clear_error(struct lib9p_ctx *ctx) {
assert(ctx);
-#if CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
ctx->err_num = 0;
#endif
ctx->err_msg[0] = '\0';
@@ -58,22 +58,31 @@ bool lib9p_ctx_has_error(struct lib9p_ctx *ctx) {
return ctx->err_msg[0];
}
-int lib9p_error(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *msg) {
+#undef lib9p_error
+#undef lib9p_errorf
+
+int lib9p_error(struct lib9p_ctx *ctx,
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+ lib9p_errno_t linux_errno,
+#endif
+ char const *msg) {
if (lib9p_ctx_has_error(ctx))
return -1;
strncpy(ctx->err_msg, msg, sizeof(ctx->err_msg));
ctx->err_msg[sizeof(ctx->err_msg)-1] = '\0';
-#if CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
ctx->err_num = linux_errno;
-#else
- (void)(linux_errno);
#endif
return -1;
}
-int lib9p_errorf(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *fmt, ...) {
+int lib9p_errorf(struct lib9p_ctx *ctx,
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+ lib9p_errno_t linux_errno,
+#endif
+ char const *fmt, ...) {
int n;
va_list args;
@@ -85,10 +94,8 @@ int lib9p_errorf(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *f
if ((size_t)(n+1) < sizeof(ctx->err_msg))
memset(&ctx->err_msg[n+1], 0, sizeof(ctx->err_msg)-(n+1));
-#if CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
ctx->err_num = linux_errno;
-#else
- (void)(linux_errno);
#endif
return -1;
diff --git a/lib9p/proto.gen b/lib9p/core.gen
index 60f1347..b30ec31 100755
--- a/lib9p/proto.gen
+++ b/lib9p/core.gen
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# lib9p/proto.gen - Generate C marshalers/unmarshalers for .9p files
-# defining 9P protocol variants.
+# lib9p/core.gen - Generate C marshalers/unmarshalers for .9p files
+# defining 9P protocol variants.
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
@@ -9,7 +9,7 @@ import os.path
import sys
sys.path.insert(0, os.path.normpath(os.path.join(__file__, "..")))
-import protogen # pylint: disable=wrong-import-position
+import core_gen # pylint: disable=wrong-import-position
if __name__ == "__main__":
- protogen.main()
+ core_gen.main()
diff --git a/lib9p/protogen/__init__.py b/lib9p/core_gen/__init__.py
index c2c6173..b0da237 100644
--- a/lib9p/protogen/__init__.py
+++ b/lib9p/core_gen/__init__.py
@@ -1,4 +1,4 @@
-# lib9p/protogen/__init__.py - Generate C marshalers/unmarshalers for
+# lib9p/core_gen/__init__.py - Generate C marshalers/unmarshalers for
# .9p files defining 9P protocol variants
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
@@ -50,8 +50,10 @@ def main() -> None:
versions, typs = parser.all()
outdir = os.path.normpath(os.path.join(sys.argv[0], ".."))
with open(
- os.path.join(outdir, "include/lib9p/9p.generated.h"), "w", encoding="utf-8"
+ os.path.join(outdir, "core_include/lib9p/_core_generated.h"),
+ "w",
+ encoding="utf-8",
) as fh:
fh.write(h.gen_h(versions, typs))
- with open(os.path.join(outdir, "9p.generated.c"), "w", encoding="utf-8") as fh:
+ with open(os.path.join(outdir, "core_generated.c"), "w", encoding="utf-8") as fh:
fh.write(c.gen_c(versions, typs))
diff --git a/lib9p/protogen/c.py b/lib9p/core_gen/c.py
index a6824ce..a300404 100644
--- a/lib9p/protogen/c.py
+++ b/lib9p/core_gen/c.py
@@ -1,4 +1,4 @@
-# lib9p/protogen/c.py - Generate 9p.generated.c
+# lib9p/core_gen/c.py - Generate core_generated.c
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
@@ -31,10 +31,10 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
#include <libmisc/assert.h>
#include <libmisc/endian.h>
-#include <lib9p/9p.h>
+#include <lib9p/core.h>
-#include "tables.h"
-#include "utf8.h"
+#include "core_tables.h"
+#include "core_utf8.h"
"""
# libobj vtables ###########################################################
ret += """
@@ -79,7 +79,9 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
if not isinstance(typ, idl.Bitfield):
continue
ret += "\n"
- ret += cutil.ifdef_push(1, c9util.ver_ifdef(typ.in_versions))
+ ret += cutil.ifdef_push(
+ 1, c9util.ver_ifdef(typ.in_versions - {"unknown"})
+ ) # SPECIAL (initialization)
ret += f"static const {c9util.typename(typ)} {typ.typname}_masks[{c9util.ver_enum('NUM')}] = {{\n"
verwidth = max(len(ver) for ver in versions)
for ver in sorted(versions):
@@ -121,12 +123,17 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
ret += "\n"
ret += f"const struct {c9util.ident('_ver_tentry')} {c9util.ident('_table_ver')}[{c9util.ver_enum('NUM')}] = {{\n"
rerror = next(typ for typ in typs if typ.typname == "Rerror")
- for ver in ["unknown", *sorted(versions)]:
- if ver == "unknown":
- min_msg_size = rerror.min_size("9P2000") # SPECIAL (initialization)
- else:
- ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
- min_msg_size = rerror.min_size(ver)
+ for ver in sorted(versions):
+ # XXX: There are good arguments that min_msg_size should be
+ # something larger than rerror.min_size().
+ # srv.c:respond_error() assumes that min_msg_size is
+ # rerror.min_size(); if you do change min_msg_size to
+ # something larger, then be sure to update respond_error().
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
+ min_msg_size = rerror.min_size(ver)
+ if ver == "9P2000.L": # SPECIAL (9P2000.L)
+ rlerror = next(typ for typ in typs if typ.typname == "Rlerror")
+ min_msg_size = rlerror.min_size(ver)
ret += f'\t[{c9util.ver_enum(ver)}] = {{.name="{ver}", .min_msg_size={min_msg_size}}},\n'
ret += cutil.ifdef_pop(0)
ret += "};\n"
@@ -135,19 +142,14 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
cstruct: str, cname: str, each: str, _range: tuple[int, int, int]
) -> str:
ret = f"const struct {c9util.ident(cstruct)} {c9util.ident(cname)}[{c9util.ver_enum('NUM')}][{hex(len(range(*_range)))}] = {{\n"
- for ver in ["unknown", *sorted(versions)]:
- if ver != "unknown":
- ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
+ for ver in sorted(versions):
+ ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
ret += f"\t[{c9util.ver_enum(ver)}] = {{\n"
for n in range(*_range):
xmsg: idl.Message | None = id2typ.get(n, None)
if xmsg:
- if ver == "unknown": # SPECIAL (initialization)
- if xmsg.typname not in ["Tversion", "Rversion", "Rerror"]:
- xmsg = None
- else:
- if ver not in xmsg.in_versions:
- xmsg = None
+ if ver not in xmsg.in_versions:
+ xmsg = None
if xmsg:
ret += f"\t\t{each}({xmsg.typname}),\n"
ret += "\t},\n"
@@ -186,6 +188,7 @@ def gen_c(versions: set[str], typs: list[idl.UserType]) -> str:
ret += msg_table("_send_tentry", "_table_Rmsg_send", "_MSG_SEND", (1, 0x100, 2))
ret += f"""
+{cutil.ifdef_push(1, c9util.ver_ifdef(next(typ for typ in typs if typ.typname == 'stat').in_versions)).rstrip()}
LM_FLATTEN ssize_t {c9util.ident('_stat_validate')}(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size) {{
\treturn validate_stat(ctx, net_size, net_bytes, ret_net_size);
}}
@@ -195,7 +198,7 @@ LM_FLATTEN void {c9util.ident('_stat_unmarshal')}(struct lib9p_ctx *ctx, uint8_t
LM_FLATTEN bool {c9util.ident('_stat_marshal')}(struct lib9p_ctx *ctx, struct {c9util.ident('stat')} *val, struct _marshal_ret *ret) {{
\treturn marshal_stat(ctx, val, ret);
}}
-"""
+{cutil.ifdef_pop(0)}"""
############################################################################
return ret
diff --git a/lib9p/protogen/c9util.py b/lib9p/core_gen/c9util.py
index cf91951..84fdee4 100644
--- a/lib9p/protogen/c9util.py
+++ b/lib9p/core_gen/c9util.py
@@ -1,4 +1,4 @@
-# lib9p/protogen/c9util.py - Utilities for generating lib9p-specific C
+# lib9p/core_gen/c9util.py - Utilities for generating lib9p-specific C
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib9p/protogen/c_format.py b/lib9p/core_gen/c_format.py
index a1bcbf3..c633fbb 100644
--- a/lib9p/protogen/c_format.py
+++ b/lib9p/core_gen/c_format.py
@@ -1,4 +1,4 @@
-# lib9p/protogen/c_format.py - Generate C pretty-print functions
+# lib9p/core_gen/c_format.py - Generate C pretty-print functions
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
@@ -21,6 +21,19 @@ def bf_numname(typ: idl.Bitfield, num: idl.BitNum, base: str) -> str:
return c9util.Ident(c9util.add_prefix(prefix, base))
+def ext_printf(line: str) -> str:
+ assert line.startswith("\t")
+ assert line.endswith("\n")
+ # It sucks that %v trips -Wformat and -Wformat-extra-args
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47781
+ ret = "#pragma GCC diagnostic push\n"
+ ret += '#pragma GCC diagnostic ignored "-Wformat"\n'
+ ret += '#pragma GCC diagnostic ignored "-Wformat-extra-args"\n'
+ ret += line
+ ret += "#pragma GCC diagnostic pop\n"
+ return ret
+
+
def gen_c_format(versions: set[str], typs: list[idl.UserType]) -> str:
ret = """
/* *_format *******************************************************************/
@@ -92,13 +105,10 @@ def gen_c_format(versions: set[str], typs: list[idl.UserType]) -> str:
ret += "\tif (empty)\n"
ret += "\t\tfmt_state_putchar(state, '0');\n"
ret += "\tfmt_state_putchar(state, ')');\n"
- case idl.Struct(typname="s"): # SPECIAL(string)
- ret += "\t/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47781 */\n"
- ret += "#pragma GCC diagnostic push\n"
- ret += '#pragma GCC diagnostic ignored "-Wformat"\n'
- ret += '#pragma GCC diagnostic ignored "-Wformat-extra-args"\n'
- ret += '\tfmt_state_printf(state, "%.*q", self->len, self->utf8);\n'
- ret += "#pragma GCC diagnostic pop\n"
+ case idl.Struct(typname="s"): # SPECIAL (string)
+ ret += ext_printf(
+ '\tfmt_state_printf(state, "%.*q", self->len, self->utf8);\n'
+ )
case idl.Struct(): # and idl.Message():
if isinstance(typ, idl.Message):
ret += f'\tfmt_state_puts(state, "{typ.typname} {{");\n'
@@ -109,19 +119,29 @@ def gen_c_format(versions: set[str], typs: list[idl.UserType]) -> str:
continue
ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions))
if member.cnt:
- if member.typ.static_size == 1: # SPECIAL (data)
- ret += f'\tfmt_state_puts(state, " {member.membname}=<bytedata>");\n'
- continue
if isinstance(member.cnt, int):
cnt_str = str(member.cnt)
cnt_typ = "size_t"
else:
cnt_str = f"self->{member.cnt.membname}"
cnt_typ = c9util.typename(member.cnt.typ)
+ if member.typ.static_size == 1: # SPECIAL (data)
+ ret += f"\tif (is_valid_utf8_without_nul((uint8_t *)self->{member.membname}, (size_t){cnt_str})) {{\n"
+ ret += ext_printf(
+ f'\t\tfmt_state_printf(state, " {member.membname}=%.*q%s",\n'
+ f"\t\t\t(int)({cnt_str} < 50 ? {cnt_str} : 50),\n"
+ f"\t\t\t(char *)self->{member.membname},\n"
+ f'\t\t\t{cnt_str} < 50 ? "" : "...");\n'
+ )
+ ret += "\t} else {\n"
+ ret += f'\t\tfmt_state_puts(state, " {member.membname}=<bytedata>");\n'
+ ret += "\t}\n"
+ continue
ret += f'\tfmt_state_puts(state, " {member.membname}=[");\n'
ret += f"\tfor ({cnt_typ} i = 0; i < {cnt_str}; i++) {{\n"
ret += "\t\tif (i)\n"
- ret += '\t\t\tfmt_state_puts(state, ", ");\n'
+ ret += "\t\t\tfmt_state_putchar(state, ',');\n"
+ ret += "\t\tfmt_state_putchar(state, ' ');\n"
if isinstance(member.typ, idl.Primitive):
ret += f'\t\tfmt_state_printf(state, "%"PRIu{member.typ.static_size*8}, self->{member.membname}[i]);\n'
else:
diff --git a/lib9p/protogen/c_marshal.py b/lib9p/core_gen/c_marshal.py
index 4dab864..620bdea 100644
--- a/lib9p/protogen/c_marshal.py
+++ b/lib9p/core_gen/c_marshal.py
@@ -1,4 +1,4 @@
-# lib9p/protogen/c_marshal.py - Generate C marshal functions
+# lib9p/core_gen/c_marshal.py - Generate C marshal functions
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
@@ -381,7 +381,7 @@ def gen_c_marshal(versions: set[str], typs: list[idl.UserType]) -> str:
)
ret += "\tif (needed_size > ctx->max_msg_size) {\n"
if isinstance(typ, idl.Message): # SPECIAL (disable for stat)
- ret += '\t\tlib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",\n'
+ ret += f'\t\tlib9p_errorf(ctx, {c9util.IDENT("ERRNO_L_ERANGE")}, "%s message too large to marshal into %s limit (limit=%"PRIu32")",\n'
ret += f'\t\t\t"{typ.typname}",\n'
ret += f'\t\t\tctx->version ? "negotiated" : "{'client' if typ.msgid % 2 == 0 else 'server'}",\n'
ret += "\t\t\tctx->max_msg_size);\n"
diff --git a/lib9p/protogen/c_unmarshal.py b/lib9p/core_gen/c_unmarshal.py
index 34635f9..1afbe1d 100644
--- a/lib9p/protogen/c_unmarshal.py
+++ b/lib9p/core_gen/c_unmarshal.py
@@ -1,4 +1,4 @@
-# lib9p/protogen/c_unmarshal.py - Generate C unmarshal functions
+# lib9p/core_gen/c_unmarshal.py - Generate C unmarshal functions
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib9p/protogen/c_validate.py b/lib9p/core_gen/c_validate.py
index 535a750..3073ed0 100644
--- a/lib9p/protogen/c_validate.py
+++ b/lib9p/core_gen/c_validate.py
@@ -1,4 +1,4 @@
-# lib9p/protogen/c_validate.py - Generate C validation functions
+# lib9p/core_gen/c_validate.py - Generate C validation functions
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
@@ -57,9 +57,9 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
"\t\t/* If needed-net-size overflowed uint32_t, then\n"
"\t\t * there's no way that actual-net-size will live up to\n"
"\t\t * that. */\n"
- '\t\treturn lib9p_error(ctx, LINUX_EBADMSG, "message is too short for content");\n'
+ f'\t\treturn lib9p_error(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "message is too short for content");\n'
"\tif (net_offset > net_size)\n"
- '\t\treturn lib9p_errorf(ctx, LINUX_EBADMSG, "message is too short for content (%"PRIu32" > %"PRIu32") @ %d", net_offset, net_size, __LINE__);\n'
+ f'\t\treturn lib9p_errorf(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "message is too short for content (%"PRIu32" > %"PRIu32") @ %d", net_offset, net_size, __LINE__);\n'
)
ret += cutil.macro(
"#define VALIDATE_NET_UTF8(n)\n"
@@ -67,7 +67,7 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
"\t\tsize_t len = n;\n"
"\t\tVALIDATE_NET_BYTES(len);\n"
"\t\tif (!is_valid_utf8_without_nul(&net_bytes[net_offset-len], len))\n"
- '\t\t\treturn lib9p_error(ctx, LINUX_EBADMSG, "message contains invalid UTF-8");\n'
+ f'\t\t\treturn lib9p_error(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "message contains invalid UTF-8");\n'
"\t}\n"
)
ret += cutil.macro(
@@ -76,7 +76,7 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
"\t\t/* If needed-host-size overflowed ssize_t, then there's\n"
"\t\t * no way that actual-net-size will live up to\n"
"\t\t * that. */\n"
- '\t\treturn lib9p_error(ctx, LINUX_EBADMSG, "message is too short for content");\n'
+ f'\t\treturn lib9p_error(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "message is too short for content");\n'
)
ret += "#define GET_U8LE(off) (net_bytes[off])\n"
@@ -193,7 +193,7 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
act = f"(uint{nbits}_t)GET_U{nbits}LE({lookup_sym(f'&{child.membname}')})"
exp = f"(uint{nbits}_t)({c9util.idl_expr(child.val, lookup_sym)})"
ret += f"{'\t'*indent_lvl()}if ({act} != {exp})\n"
- ret += f'{"\t"*(indent_lvl()+1)}return lib9p_errorf(ctx, LINUX_EBADMSG, "{path} value is wrong: actual: %"PRIu{nbits}" != correct:%"PRIu{nbits},\n'
+ ret += f'{"\t"*(indent_lvl()+1)}return lib9p_errorf(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "{path} value is wrong: actual: %"PRIu{nbits}" != correct:%"PRIu{nbits},\n'
ret += f"{'\t'*(indent_lvl()+2)}{act}, {exp});\n"
if child.max:
incr_flush()
@@ -208,7 +208,7 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
act = f"(uint{nbits}_t)GET_U{nbits}LE({lookup_sym(f'&{child.membname}')})"
exp = f"(uint{nbits}_t)({c9util.idl_expr(child.max, lookup_sym)})"
ret += f"{'\t'*indent_lvl()}if ({act} > {exp})\n"
- ret += f'{"\t"*(indent_lvl()+1)}return lib9p_errorf(ctx, LINUX_EBADMSG, "{path} value is too large: %"PRIu{nbits}" > %"PRIu{nbits},\n'
+ ret += f'{"\t"*(indent_lvl()+1)}return lib9p_errorf(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "{path} value is too large: %"PRIu{nbits}" > %"PRIu{nbits},\n'
ret += f"{'\t'*(indent_lvl()+2)}{act}, {exp});\n"
if isinstance(child.typ, idl.Bitfield):
incr_flush()
@@ -216,7 +216,7 @@ def gen_c_validate(versions: set[str], typs: list[idl.UserType]) -> str:
nbits = nbytes * 8
act = f"GET_U{nbits}LE({lookup_sym(f'&{child.membname}')})"
ret += f"{'\t'*indent_lvl()}if ({act} & ~{child.typ.typname}_masks[ctx->version])\n"
- ret += f'{"\t"*(indent_lvl()+1)}return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in {child.typ.typname} bitfield: %#0{nbytes*2}"PRIx{nbits},\n'
+ ret += f'{"\t"*(indent_lvl()+1)}return lib9p_errorf(ctx, {c9util.IDENT("ERRNO_L_EBADMSG")}, "unknown bits in {child.typ.typname} bitfield: %#0{nbytes*2}"PRIx{nbits},\n'
ret += f"{'\t'*(indent_lvl()+2)}{act} & ~{child.typ.typname}_masks[ctx->version]);\n"
def handle(
diff --git a/lib9p/protogen/cutil.py b/lib9p/core_gen/cutil.py
index 8df6db9..9183cc4 100644
--- a/lib9p/protogen/cutil.py
+++ b/lib9p/core_gen/cutil.py
@@ -1,4 +1,4 @@
-# lib9p/protogen/cutil.py - Utilities for generating C code
+# lib9p/core_gen/cutil.py - Utilities for generating C code
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/lib9p/protogen/h.py b/lib9p/core_gen/h.py
index 3b33419..ff070c6 100644
--- a/lib9p/protogen/h.py
+++ b/lib9p/core_gen/h.py
@@ -1,4 +1,4 @@
-# lib9p/protogen/h.py - Generate 9p.generated.h
+# lib9p/core_gen/h.py - Generate _core_generated.h
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
@@ -159,14 +159,14 @@ def gen_h(versions: set[str], typs: list[idl.UserType]) -> str:
ret = f"""/* Generated by `{' '.join(sys.argv)}`. DO NOT EDIT! */
-#ifndef _LIB9P_9P_H_
-\t#error Do not include <lib9p/9p.generated.h> directly; include <lib9p/9p.h> instead
+#ifndef _LIB9P_CORE_H_
+\t#error Do not include <lib9p/_core_generated.h> directly; include <lib9p/core.h> instead
#endif
#include <stdint.h> /* for uint{{n}}_t types */
#include <libfmt/fmt.h> /* for fmt_formatter */
-#include <libhw/generic/net.h> /* for struct iovec */
+#include <libhw/generic/io.h> /* for struct iovec */
"""
id2typ: dict[int, idl.Message] = {}
@@ -192,14 +192,21 @@ def gen_h(versions: set[str], typs: list[idl.UserType]) -> str:
ret += "\t#endif\n"
ret += "#endif\n"
+ # SPECIAL (convenience)
+ ret += "\n"
+ ret += f"#define _LIB9P_ENABLE_stat {c9util.ver_ifdef(next(typ for typ in typs if typ.typname == 'stat').in_versions)}\n"
+
ret += f"""
/* enum version ***************************************************************/
enum {c9util.ident('version')} {{
"""
- fullversions = ["unknown = 0", *sorted(versions)]
- verwidth = max(len(v) for v in fullversions)
- for ver in fullversions:
+ xversions = [
+ "unknown = 0",
+ *sorted(v for v in versions if v != "unknown"),
+ ] # SPECIAL (initialization)
+ verwidth = max(len(v) for v in xversions)
+ for ver in xversions:
if ver in versions:
ret += cutil.ifdef_push(1, c9util.ver_ifdef({ver}))
ret += f"\t{c9util.ver_enum(ver)},"
diff --git a/lib9p/protogen/idlutil.py b/lib9p/core_gen/idlutil.py
index dc4d012..e92839a 100644
--- a/lib9p/protogen/idlutil.py
+++ b/lib9p/core_gen/idlutil.py
@@ -1,10 +1,9 @@
-# lib9p/protogen/idlutil.py - Utilities for working with the 9P idl package
+# lib9p/core_gen/idlutil.py - Utilities for working with the 9P idl package
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
import enum
-import graphlib
import typing
import idl
@@ -22,21 +21,40 @@ __all__ = [
def topo_sorted(typs: list[idl.UserType]) -> typing.Iterable[idl.UserType]:
- ts: graphlib.TopologicalSorter[idl.UserType] = graphlib.TopologicalSorter()
+ ret: list[idl.UserType] = []
+ struct_ord: dict[str, int] = {}
+
+ def get_struct_ord(typ: idl.Struct) -> int:
+ nonlocal struct_ord
+ if typ.typname not in struct_ord:
+ deps = [
+ get_struct_ord(member.typ)
+ for member in typ.members
+ if isinstance(member.typ, idl.Struct)
+ ]
+ if len(deps) == 0:
+ struct_ord[typ.typname] = 0
+ else:
+ struct_ord[typ.typname] = 1 + max(deps)
+ return struct_ord[typ.typname]
+
for typ in typs:
match typ:
case idl.Number():
- ts.add(typ)
+ ret.append(typ)
case idl.Bitfield():
- ts.add(typ)
+ ret.append(typ)
case idl.Struct(): # and idl.Message():
- deps = [
- member.typ
- for member in typ.members
- if not isinstance(member.typ, idl.Primitive)
- ]
- ts.add(typ, *deps)
- return ts.static_order()
+ _ = get_struct_ord(typ)
+ for _ord in sorted(set(struct_ord.values())):
+ for typ in typs:
+ if not isinstance(typ, idl.Struct):
+ continue
+ if struct_ord[typ.typname] != _ord:
+ continue
+ ret.append(typ)
+ assert len(ret) == len(typs)
+ return ret
# walk() #######################################################################
diff --git a/lib9p/9p.generated.c b/lib9p/core_generated.c
index b58a485..8539fdf 100644
--- a/lib9p/9p.generated.c
+++ b/lib9p/core_generated.c
@@ -1,4 +1,4 @@
-/* Generated by `lib9p/proto.gen lib9p/idl/2002-9P2000.9p lib9p/idl/2003-9P2000.p9p.9p lib9p/idl/2005-9P2000.u.9p lib9p/idl/2010-9P2000.L.9p lib9p/idl/2012-9P2000.e.9p`. DO NOT EDIT! */
+/* Generated by `lib9p/core.gen lib9p/idl/0000-uninitialized.9p lib9p/idl/2002-9P2000.9p lib9p/idl/2003-9P2000.p9p.9p lib9p/idl/2005-9P2000.u.9p lib9p/idl/2010-9P2000.L.9p lib9p/idl/2012-9P2000.e.9p`. DO NOT EDIT! */
#include <stdbool.h>
#include <stddef.h> /* for size_t */
@@ -8,36 +8,42 @@
#include <libmisc/assert.h>
#include <libmisc/endian.h>
-#include <lib9p/9p.h>
+#include <lib9p/core.h>
-#include "tables.h"
-#include "utf8.h"
+#include "core_tables.h"
+#include "core_utf8.h"
/* libobj vtables *************************************************************/
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
LO_IMPLEMENTATION_C(fmt_formatter, lib9p_tag_t, lib9p_tag, static);
LO_IMPLEMENTATION_C(fmt_formatter, lib9p_fid_t, lib9p_fid, static);
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_s, lib9p_s, static);
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
LO_IMPLEMENTATION_C(fmt_formatter, lib9p_dm_t, lib9p_dm, static);
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
LO_IMPLEMENTATION_C(fmt_formatter, lib9p_qt_t, lib9p_qt, static);
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_qid, lib9p_qid, static);
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_stat, lib9p_stat, static);
LO_IMPLEMENTATION_C(fmt_formatter, lib9p_o_t, lib9p_o, static);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tversion, lib9p_msg_Tversion, static);
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rversion, lib9p_msg_Rversion, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tauth, lib9p_msg_Tauth, static);
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rauth, lib9p_msg_Rauth, static);
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tattach, lib9p_msg_Tattach, static);
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rattach, lib9p_msg_Rattach, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rerror, lib9p_msg_Rerror, static);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Tflush, lib9p_msg_Tflush, static);
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rflush, lib9p_msg_Rflush, static);
LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Twalk, lib9p_msg_Twalk, static);
@@ -159,6 +165,11 @@ LO_IMPLEMENTATION_C(fmt_formatter, struct lib9p_msg_Rswrite, lib9p_msg_Rswrite,
#else
#define _is_ver_9P2000_u(v) false
#endif
+#if CONFIG_9P_ENABLE_unknown
+ #define _is_ver_unknown(v) (v == LIB9P_VER_unknown)
+#else
+ #define _is_ver_unknown(v) false
+#endif
/**
* is_ver(ctx, ver) is essentially `(ctx->version == LIB9P_VER_##ver)`, but
@@ -187,6 +198,9 @@ static const lib9p_dm_t dm_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000_u
[LIB9P_VER_9P2000_u] = 0b11111100101111000000000111111111,
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = 0b11111100000000000000000111111111,
+#endif /* CONFIG_9P_ENABLE_unknown */
};
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
@@ -207,6 +221,9 @@ static const lib9p_qt_t qt_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000_u
[LIB9P_VER_9P2000_u] = 0b11111110,
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = 0b11111100,
+#endif /* CONFIG_9P_ENABLE_unknown */
};
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
@@ -227,6 +244,9 @@ static const lib9p_o_t o_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000_u
[LIB9P_VER_9P2000_u] = 0b01010011,
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = 0b00000000,
+#endif /* CONFIG_9P_ENABLE_unknown */
};
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
@@ -245,6 +265,9 @@ static const lib9p_lo_t lo_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000_u
[LIB9P_VER_9P2000_u] = 0b00000000000000000000000000000000,
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_unknown */
};
static const lib9p_mode_t mode_masks[LIB9P_VER_NUM] = {
@@ -261,6 +284,9 @@ static const lib9p_mode_t mode_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000_u
[LIB9P_VER_9P2000_u] = 0b00000000000000000000000000000000,
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_unknown */
};
static const lib9p_getattr_t getattr_masks[LIB9P_VER_NUM] = {
@@ -277,6 +303,9 @@ static const lib9p_getattr_t getattr_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000_u
[LIB9P_VER_9P2000_u] = 0b0000000000000000000000000000000000000000000000000000000000000000,
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = 0b0000000000000000000000000000000000000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_unknown */
};
static const lib9p_setattr_t setattr_masks[LIB9P_VER_NUM] = {
@@ -293,6 +322,9 @@ static const lib9p_setattr_t setattr_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000_u
[LIB9P_VER_9P2000_u] = 0b00000000000000000000000000000000,
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_unknown */
};
static const lib9p_lock_flags_t lock_flags_masks[LIB9P_VER_NUM] = {
@@ -309,32 +341,35 @@ static const lib9p_lock_flags_t lock_flags_masks[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000_u
[LIB9P_VER_9P2000_u] = 0b00000000000000000000000000000000,
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = 0b00000000000000000000000000000000,
+#endif /* CONFIG_9P_ENABLE_unknown */
};
#endif /* CONFIG_9P_ENABLE_9P2000_L */
/* validate_* *****************************************************************/
-#define VALIDATE_NET_BYTES(n) \
- if (__builtin_add_overflow(net_offset, n, &net_offset)) \
- /* If needed-net-size overflowed uint32_t, then \
- * there's no way that actual-net-size will live up to \
- * that. */ \
- return lib9p_error(ctx, LINUX_EBADMSG, "message is too short for content"); \
- if (net_offset > net_size) \
- return lib9p_errorf(ctx, LINUX_EBADMSG, "message is too short for content (%"PRIu32" > %"PRIu32") @ %d", net_offset, net_size, __LINE__);
-#define VALIDATE_NET_UTF8(n) \
- { \
- size_t len = n; \
- VALIDATE_NET_BYTES(len); \
- if (!is_valid_utf8_without_nul(&net_bytes[net_offset-len], len)) \
- return lib9p_error(ctx, LINUX_EBADMSG, "message contains invalid UTF-8"); \
+#define VALIDATE_NET_BYTES(n) \
+ if (__builtin_add_overflow(net_offset, n, &net_offset)) \
+ /* If needed-net-size overflowed uint32_t, then \
+ * there's no way that actual-net-size will live up to \
+ * that. */ \
+ return lib9p_error(ctx, LIB9P_ERRNO_L_EBADMSG, "message is too short for content"); \
+ if (net_offset > net_size) \
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "message is too short for content (%"PRIu32" > %"PRIu32") @ %d", net_offset, net_size, __LINE__);
+#define VALIDATE_NET_UTF8(n) \
+ { \
+ size_t len = n; \
+ VALIDATE_NET_BYTES(len); \
+ if (!is_valid_utf8_without_nul(&net_bytes[net_offset-len], len)) \
+ return lib9p_error(ctx, LIB9P_ERRNO_L_EBADMSG, "message contains invalid UTF-8"); \
}
#define RESERVE_HOST_BYTES(n) \
if (__builtin_add_overflow(host_size, n, &host_size)) \
/* If needed-host-size overflowed ssize_t, then there's \
* no way that actual-net-size will live up to \
* that. */ \
- return lib9p_error(ctx, LINUX_EBADMSG, "message is too short for content");
+ return lib9p_error(ctx, LIB9P_ERRNO_L_EBADMSG, "message is too short for content");
#define GET_U8LE(off) (net_bytes[off])
#define GET_U16LE(off) uint16le_decode(&net_bytes[off])
#define GET_U32LE(off) uint32le_decode(&net_bytes[off])
@@ -348,14 +383,14 @@ static const lib9p_lock_flags_t lock_flags_masks[LIB9P_VER_NUM] = {
static ssize_t validate_stat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size) {
uint32_t net_offset = 0;
ssize_t host_size = sizeof(struct lib9p_stat);
- uint32_t offsetof_stat_size = net_offset + 0;
- uint32_t offsetof_kern_type = net_offset + 2;
- uint32_t offsetof_file_qid_type = net_offset + 8;
+ uint32_t offsetof__stat_size = net_offset + 0;
+ uint32_t offsetof_fstype = net_offset + 2;
+ uint32_t offsetof_qid_type = net_offset + 8;
VALIDATE_NET_BYTES(21);
- if (GET_U8LE(offsetof_file_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
- GET_U8LE(offsetof_file_qid_type) & ~qt_masks[ctx->version]);
- uint32_t offsetof_file_mode = net_offset + 0;
+ if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
+ uint32_t offsetof_mode = net_offset + 0;
VALIDATE_NET_BYTES(22);
VALIDATE_NET_UTF8(LAST_U16LE());
VALIDATE_NET_BYTES(2);
@@ -372,19 +407,19 @@ static ssize_t validate_stat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
uint32_t offsetof_end = net_offset + 0;
- if ((uint32_t)GET_U32LE(offsetof_stat_size) != (uint32_t)(offsetof_end - offsetof_kern_type))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "stat->stat_size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
- (uint32_t)GET_U32LE(offsetof_stat_size), (uint32_t)(offsetof_end - offsetof_kern_type));
- if (GET_U32LE(offsetof_file_mode) & ~dm_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32,
- GET_U32LE(offsetof_file_mode) & ~dm_masks[ctx->version]);
+ if ((uint32_t)GET_U32LE(offsetof__stat_size) != (uint32_t)(offsetof_end - offsetof_fstype))
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "stat->_stat_size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ (uint32_t)GET_U32LE(offsetof__stat_size), (uint32_t)(offsetof_end - offsetof_fstype));
+ if (GET_U32LE(offsetof_mode) & ~dm_masks[ctx->version])
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32,
+ GET_U32LE(offsetof_mode) & ~dm_masks[ctx->version]);
if (ret_net_size)
*ret_net_size = net_offset;
return (ssize_t)host_size;
}
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static ssize_t validate_Tversion(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) {
uint32_t net_offset = 0;
ssize_t host_size = sizeof(struct lib9p_msg_Tversion);
@@ -394,10 +429,10 @@ static ssize_t validate_Tversion(struct lib9p_ctx *ctx, uint32_t net_size, uint8
VALIDATE_NET_UTF8(LAST_U16LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tversion->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tversion->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(100))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tversion->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tversion->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(100));
return (ssize_t)host_size;
}
@@ -411,14 +446,16 @@ static ssize_t validate_Rversion(struct lib9p_ctx *ctx, uint32_t net_size, uint8
VALIDATE_NET_UTF8(LAST_U16LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rversion->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rversion->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(101))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rversion->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rversion->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(101));
return (ssize_t)host_size;
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static ssize_t validate_Tauth(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) {
uint32_t net_offset = 0;
ssize_t host_size = sizeof(struct lib9p_msg_Tauth);
@@ -435,10 +472,10 @@ static ssize_t validate_Tauth(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tauth->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tauth->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(102))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tauth->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tauth->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(102));
return (ssize_t)host_size;
}
@@ -451,14 +488,14 @@ static ssize_t validate_Rauth(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_aqid_type = net_offset + 7;
VALIDATE_NET_BYTES(20);
if (GET_U8LE(offsetof_aqid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_aqid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rauth->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rauth->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(103))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rauth->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rauth->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(103));
return (ssize_t)host_size;
}
@@ -479,10 +516,10 @@ static ssize_t validate_Tattach(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tattach->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tattach->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(104))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tattach->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tattach->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(104));
return (ssize_t)host_size;
}
@@ -495,18 +532,20 @@ static ssize_t validate_Rattach(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_qid_type = net_offset + 7;
VALIDATE_NET_BYTES(20);
if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rattach->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rattach->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(105))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rattach->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rattach->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(105));
return (ssize_t)host_size;
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static ssize_t validate_Rerror(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) {
uint32_t net_offset = 0;
ssize_t host_size = sizeof(struct lib9p_msg_Rerror);
@@ -521,14 +560,16 @@ static ssize_t validate_Rerror(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
#endif /* CONFIG_9P_ENABLE_9P2000_u */
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rerror->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rerror->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(107))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rerror->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rerror->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(107));
return (ssize_t)host_size;
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static ssize_t validate_Tflush(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes) {
uint32_t net_offset = 0;
ssize_t host_size = sizeof(struct lib9p_msg_Tflush);
@@ -537,10 +578,10 @@ static ssize_t validate_Tflush(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 9;
VALIDATE_NET_BYTES(9);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tflush->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tflush->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(108))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tflush->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tflush->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(108));
return (ssize_t)host_size;
}
@@ -553,10 +594,10 @@ static ssize_t validate_Rflush(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rflush->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rflush->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(109))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rflush->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rflush->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(109));
return (ssize_t)host_size;
}
@@ -575,13 +616,13 @@ static ssize_t validate_Twalk(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
}
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(110))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(110));
if ((uint16_t)GET_U16LE(offsetof_nwname) > (uint16_t)(16))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twalk->nwname value is too large: %"PRIu16" > %"PRIu16,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twalk->nwname value is too large: %"PRIu16" > %"PRIu16,
(uint16_t)GET_U16LE(offsetof_nwname), (uint16_t)(16));
return (ssize_t)host_size;
}
@@ -598,18 +639,18 @@ static ssize_t validate_Rwalk(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_wqid_type = net_offset + 0;
VALIDATE_NET_BYTES(13);
if (GET_U8LE(offsetof_wqid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_wqid_type) & ~qt_masks[ctx->version]);
}
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rwalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(111))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rwalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(111));
if ((uint16_t)GET_U16LE(offsetof_nwqid) > (uint16_t)(16))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwalk->nwqid value is too large: %"PRIu16" > %"PRIu16,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rwalk->nwqid value is too large: %"PRIu16" > %"PRIu16,
(uint16_t)GET_U16LE(offsetof_nwqid), (uint16_t)(16));
return (ssize_t)host_size;
}
@@ -625,13 +666,13 @@ static ssize_t validate_Topen(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 12;
VALIDATE_NET_BYTES(12);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Topen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Topen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(112))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Topen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Topen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(112));
if (GET_U8LE(offsetof_mode) & ~o_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in o bitfield: %#02"PRIx8,
GET_U8LE(offsetof_mode) & ~o_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -644,15 +685,15 @@ static ssize_t validate_Ropen(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_qid_type = net_offset + 7;
VALIDATE_NET_BYTES(20);
if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 4;
VALIDATE_NET_BYTES(4);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Ropen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Ropen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(113))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Ropen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Ropen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(113));
return (ssize_t)host_size;
}
@@ -669,16 +710,16 @@ static ssize_t validate_Tcreate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_end = net_offset + 5;
VALIDATE_NET_BYTES(5);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(114))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(114));
if (GET_U32LE(offsetof_perm) & ~dm_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32,
GET_U32LE(offsetof_perm) & ~dm_masks[ctx->version]);
if (GET_U8LE(offsetof_mode) & ~o_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in o bitfield: %#02"PRIx8,
GET_U8LE(offsetof_mode) & ~o_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -691,15 +732,15 @@ static ssize_t validate_Rcreate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_qid_type = net_offset + 7;
VALIDATE_NET_BYTES(20);
if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 4;
VALIDATE_NET_BYTES(4);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(115))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(115));
return (ssize_t)host_size;
}
@@ -716,16 +757,16 @@ static ssize_t validate_Tread(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 23;
VALIDATE_NET_BYTES(23);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(116))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(116));
if ((uint64_t)GET_U64LE(offsetof_offset) > (uint64_t)(INT64_MAX))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tread->offset value is too large: %"PRIu64" > %"PRIu64,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tread->offset value is too large: %"PRIu64" > %"PRIu64,
(uint64_t)GET_U64LE(offsetof_offset), (uint64_t)(INT64_MAX));
if ((uint32_t)GET_U32LE(offsetof_count) > (uint32_t)(INT32_MAX))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tread->count value is too large: %"PRIu32" > %"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tread->count value is too large: %"PRIu32" > %"PRIu32,
(uint32_t)GET_U32LE(offsetof_count), (uint32_t)(INT32_MAX));
return (ssize_t)host_size;
}
@@ -740,13 +781,13 @@ static ssize_t validate_Rread(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
VALIDATE_NET_BYTES(LAST_U32LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(117))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(117));
if ((uint32_t)GET_U32LE(offsetof_count) > (uint32_t)(INT32_MAX))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rread->count value is too large: %"PRIu32" > %"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rread->count value is too large: %"PRIu32" > %"PRIu32,
(uint32_t)GET_U32LE(offsetof_count), (uint32_t)(INT32_MAX));
return (ssize_t)host_size;
}
@@ -762,16 +803,16 @@ static ssize_t validate_Twrite(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
VALIDATE_NET_BYTES(LAST_U32LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(118))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(118));
if ((uint64_t)GET_U64LE(offsetof_offset) > (uint64_t)(INT64_MAX))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twrite->offset value is too large: %"PRIu64" > %"PRIu64,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twrite->offset value is too large: %"PRIu64" > %"PRIu64,
(uint64_t)GET_U64LE(offsetof_offset), (uint64_t)(INT64_MAX));
if ((uint32_t)GET_U32LE(offsetof_count) > (uint32_t)(INT32_MAX))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twrite->count value is too large: %"PRIu32" > %"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twrite->count value is too large: %"PRIu32" > %"PRIu32,
(uint32_t)GET_U32LE(offsetof_count), (uint32_t)(INT32_MAX));
return (ssize_t)host_size;
}
@@ -785,13 +826,13 @@ static ssize_t validate_Rwrite(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 11;
VALIDATE_NET_BYTES(11);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rwrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(119))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rwrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(119));
if ((uint32_t)GET_U32LE(offsetof_count) > (uint32_t)(INT32_MAX))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwrite->count value is too large: %"PRIu32" > %"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rwrite->count value is too large: %"PRIu32" > %"PRIu32,
(uint32_t)GET_U32LE(offsetof_count), (uint32_t)(INT32_MAX));
return (ssize_t)host_size;
}
@@ -804,10 +845,10 @@ static ssize_t validate_Tclunk(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 11;
VALIDATE_NET_BYTES(11);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tclunk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tclunk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(120))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tclunk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tclunk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(120));
return (ssize_t)host_size;
}
@@ -820,10 +861,10 @@ static ssize_t validate_Rclunk(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rclunk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rclunk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(121))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rclunk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rclunk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(121));
return (ssize_t)host_size;
}
@@ -836,10 +877,10 @@ static ssize_t validate_Tremove(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_end = net_offset + 11;
VALIDATE_NET_BYTES(11);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tremove->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tremove->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(122))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tremove->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tremove->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(122));
return (ssize_t)host_size;
}
@@ -852,10 +893,10 @@ static ssize_t validate_Rremove(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rremove->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rremove->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(123))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rremove->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rremove->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(123));
return (ssize_t)host_size;
}
@@ -870,10 +911,10 @@ static ssize_t validate_Tstat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 11;
VALIDATE_NET_BYTES(11);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(124))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(124));
return (ssize_t)host_size;
}
@@ -885,14 +926,14 @@ static ssize_t validate_Rstat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_typ = net_offset + 4;
uint32_t offsetof_nstat = net_offset + 7;
uint32_t offsetof_stat = net_offset + 9;
- uint32_t offsetof_stat_stat_size = net_offset + 9;
- uint32_t offsetof_stat_kern_type = net_offset + 11;
- uint32_t offsetof_stat_file_qid_type = net_offset + 17;
+ uint32_t offsetof_stat__stat_size = net_offset + 9;
+ uint32_t offsetof_stat_fstype = net_offset + 11;
+ uint32_t offsetof_stat_qid_type = net_offset + 17;
VALIDATE_NET_BYTES(30);
- if (GET_U8LE(offsetof_stat_file_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
- GET_U8LE(offsetof_stat_file_qid_type) & ~qt_masks[ctx->version]);
- uint32_t offsetof_stat_file_mode = net_offset + 0;
+ if (GET_U8LE(offsetof_stat_qid_type) & ~qt_masks[ctx->version])
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ GET_U8LE(offsetof_stat_qid_type) & ~qt_masks[ctx->version]);
+ uint32_t offsetof_stat_mode = net_offset + 0;
VALIDATE_NET_BYTES(22);
VALIDATE_NET_UTF8(LAST_U16LE());
VALIDATE_NET_BYTES(2);
@@ -909,21 +950,21 @@ static ssize_t validate_Rstat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
uint32_t offsetof_stat_end = net_offset + 0;
- if ((uint32_t)GET_U32LE(offsetof_stat_stat_size) != (uint32_t)(offsetof_stat_end - offsetof_stat_kern_type))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstat->stat.stat_size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
- (uint32_t)GET_U32LE(offsetof_stat_stat_size), (uint32_t)(offsetof_stat_end - offsetof_stat_kern_type));
- if (GET_U32LE(offsetof_stat_file_mode) & ~dm_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32,
- GET_U32LE(offsetof_stat_file_mode) & ~dm_masks[ctx->version]);
+ if ((uint32_t)GET_U32LE(offsetof_stat__stat_size) != (uint32_t)(offsetof_stat_end - offsetof_stat_fstype))
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rstat->stat._stat_size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ (uint32_t)GET_U32LE(offsetof_stat__stat_size), (uint32_t)(offsetof_stat_end - offsetof_stat_fstype));
+ if (GET_U32LE(offsetof_stat_mode) & ~dm_masks[ctx->version])
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32,
+ GET_U32LE(offsetof_stat_mode) & ~dm_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(125))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(125));
if ((uint32_t)GET_U32LE(offsetof_nstat) != (uint32_t)(offsetof_end - offsetof_stat))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstat->nstat value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rstat->nstat value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_nstat), (uint32_t)(offsetof_end - offsetof_stat));
return (ssize_t)host_size;
}
@@ -935,14 +976,14 @@ static ssize_t validate_Twstat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_typ = net_offset + 4;
uint32_t offsetof_nstat = net_offset + 11;
uint32_t offsetof_stat = net_offset + 13;
- uint32_t offsetof_stat_stat_size = net_offset + 13;
- uint32_t offsetof_stat_kern_type = net_offset + 15;
- uint32_t offsetof_stat_file_qid_type = net_offset + 21;
+ uint32_t offsetof_stat__stat_size = net_offset + 13;
+ uint32_t offsetof_stat_fstype = net_offset + 15;
+ uint32_t offsetof_stat_qid_type = net_offset + 21;
VALIDATE_NET_BYTES(34);
- if (GET_U8LE(offsetof_stat_file_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
- GET_U8LE(offsetof_stat_file_qid_type) & ~qt_masks[ctx->version]);
- uint32_t offsetof_stat_file_mode = net_offset + 0;
+ if (GET_U8LE(offsetof_stat_qid_type) & ~qt_masks[ctx->version])
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ GET_U8LE(offsetof_stat_qid_type) & ~qt_masks[ctx->version]);
+ uint32_t offsetof_stat_mode = net_offset + 0;
VALIDATE_NET_BYTES(22);
VALIDATE_NET_UTF8(LAST_U16LE());
VALIDATE_NET_BYTES(2);
@@ -959,21 +1000,21 @@ static ssize_t validate_Twstat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
uint32_t offsetof_stat_end = net_offset + 0;
- if ((uint32_t)GET_U32LE(offsetof_stat_stat_size) != (uint32_t)(offsetof_stat_end - offsetof_stat_kern_type))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twstat->stat.stat_size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
- (uint32_t)GET_U32LE(offsetof_stat_stat_size), (uint32_t)(offsetof_stat_end - offsetof_stat_kern_type));
- if (GET_U32LE(offsetof_stat_file_mode) & ~dm_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32,
- GET_U32LE(offsetof_stat_file_mode) & ~dm_masks[ctx->version]);
+ if ((uint32_t)GET_U32LE(offsetof_stat__stat_size) != (uint32_t)(offsetof_stat_end - offsetof_stat_fstype))
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twstat->stat._stat_size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ (uint32_t)GET_U32LE(offsetof_stat__stat_size), (uint32_t)(offsetof_stat_end - offsetof_stat_fstype));
+ if (GET_U32LE(offsetof_stat_mode) & ~dm_masks[ctx->version])
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in dm bitfield: %#08"PRIx32,
+ GET_U32LE(offsetof_stat_mode) & ~dm_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(126))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(126));
if ((uint32_t)GET_U32LE(offsetof_nstat) != (uint32_t)(offsetof_end - offsetof_stat))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Twstat->nstat value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Twstat->nstat value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_nstat), (uint32_t)(offsetof_end - offsetof_stat));
return (ssize_t)host_size;
}
@@ -986,10 +1027,10 @@ static ssize_t validate_Rwstat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rwstat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(127))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rwstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rwstat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(127));
return (ssize_t)host_size;
}
@@ -1005,13 +1046,13 @@ static ssize_t validate_Topenfd(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_end = net_offset + 12;
VALIDATE_NET_BYTES(12);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Topenfd->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Topenfd->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(98))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Topenfd->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Topenfd->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(98));
if (GET_U8LE(offsetof_mode) & ~o_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in o bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in o bitfield: %#02"PRIx8,
GET_U8LE(offsetof_mode) & ~o_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -1024,15 +1065,15 @@ static ssize_t validate_Ropenfd(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_qid_type = net_offset + 7;
VALIDATE_NET_BYTES(20);
if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 8;
VALIDATE_NET_BYTES(8);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Ropenfd->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Ropenfd->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(99))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Ropenfd->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Ropenfd->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(99));
return (ssize_t)host_size;
}
@@ -1047,10 +1088,10 @@ static ssize_t validate_Rlerror(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_end = net_offset + 11;
VALIDATE_NET_BYTES(11);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlerror->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rlerror->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(7))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlerror->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rlerror->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(7));
return (ssize_t)host_size;
}
@@ -1063,10 +1104,10 @@ static ssize_t validate_Tstatfs(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_end = net_offset + 11;
VALIDATE_NET_BYTES(11);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tstatfs->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tstatfs->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(8))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tstatfs->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tstatfs->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(8));
return (ssize_t)host_size;
}
@@ -1079,10 +1120,10 @@ static ssize_t validate_Rstatfs(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_end = net_offset + 67;
VALIDATE_NET_BYTES(67);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstatfs->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rstatfs->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(9))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rstatfs->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rstatfs->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(9));
return (ssize_t)host_size;
}
@@ -1096,13 +1137,13 @@ static ssize_t validate_Tlopen(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 15;
VALIDATE_NET_BYTES(15);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlopen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tlopen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(12))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlopen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tlopen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(12));
if (GET_U32LE(offsetof_flags) & ~lo_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in lo bitfield: %#08"PRIx32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in lo bitfield: %#08"PRIx32,
GET_U32LE(offsetof_flags) & ~lo_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -1115,15 +1156,15 @@ static ssize_t validate_Rlopen(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_qid_type = net_offset + 7;
VALIDATE_NET_BYTES(20);
if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 4;
VALIDATE_NET_BYTES(4);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlopen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rlopen->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(13))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlopen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rlopen->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(13));
return (ssize_t)host_size;
}
@@ -1140,16 +1181,16 @@ static ssize_t validate_Tlcreate(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_end = net_offset + 12;
VALIDATE_NET_BYTES(12);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tlcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(14))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tlcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(14));
if (GET_U32LE(offsetof_flags) & ~lo_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in lo bitfield: %#08"PRIx32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in lo bitfield: %#08"PRIx32,
GET_U32LE(offsetof_flags) & ~lo_masks[ctx->version]);
if (GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32,
GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -1162,15 +1203,15 @@ static ssize_t validate_Rlcreate(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_qid_type = net_offset + 7;
VALIDATE_NET_BYTES(20);
if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 4;
VALIDATE_NET_BYTES(4);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rlcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(15))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rlcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(15));
return (ssize_t)host_size;
}
@@ -1187,10 +1228,10 @@ static ssize_t validate_Tsymlink(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_end = net_offset + 4;
VALIDATE_NET_BYTES(4);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsymlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tsymlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(16))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsymlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tsymlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(16));
return (ssize_t)host_size;
}
@@ -1203,14 +1244,14 @@ static ssize_t validate_Rsymlink(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_qid_type = net_offset + 7;
VALIDATE_NET_BYTES(20);
if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsymlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rsymlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(17))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsymlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rsymlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(17));
return (ssize_t)host_size;
}
@@ -1226,13 +1267,13 @@ static ssize_t validate_Tmknod(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 16;
VALIDATE_NET_BYTES(16);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tmknod->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tmknod->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(18))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tmknod->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tmknod->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(18));
if (GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32,
GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -1245,14 +1286,14 @@ static ssize_t validate_Rmknod(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_qid_type = net_offset + 7;
VALIDATE_NET_BYTES(20);
if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rmknod->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rmknod->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(19))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rmknod->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rmknod->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(19));
return (ssize_t)host_size;
}
@@ -1266,10 +1307,10 @@ static ssize_t validate_Trename(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
VALIDATE_NET_UTF8(LAST_U16LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Trename->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Trename->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(20))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Trename->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Trename->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(20));
return (ssize_t)host_size;
}
@@ -1282,10 +1323,10 @@ static ssize_t validate_Rrename(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rrename->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rrename->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(21))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rrename->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rrename->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(21));
return (ssize_t)host_size;
}
@@ -1298,10 +1339,10 @@ static ssize_t validate_Treadlink(struct lib9p_ctx *ctx, uint32_t net_size, uint
uint32_t offsetof_end = net_offset + 11;
VALIDATE_NET_BYTES(11);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Treadlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Treadlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(22))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Treadlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Treadlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(22));
return (ssize_t)host_size;
}
@@ -1315,10 +1356,10 @@ static ssize_t validate_Rreadlink(struct lib9p_ctx *ctx, uint32_t net_size, uint
VALIDATE_NET_UTF8(LAST_U16LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rreadlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rreadlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(23))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rreadlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rreadlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(23));
return (ssize_t)host_size;
}
@@ -1332,13 +1373,13 @@ static ssize_t validate_Tgetattr(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_end = net_offset + 19;
VALIDATE_NET_BYTES(19);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tgetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tgetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(24))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tgetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tgetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(24));
if (GET_U64LE(offsetof_request_mask) & ~getattr_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in getattr bitfield: %#016"PRIx64,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in getattr bitfield: %#016"PRIx64,
GET_U64LE(offsetof_request_mask) & ~getattr_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -1352,22 +1393,22 @@ static ssize_t validate_Rgetattr(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_qid_type = net_offset + 15;
VALIDATE_NET_BYTES(28);
if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_mode = net_offset + 0;
uint32_t offsetof_end = net_offset + 132;
VALIDATE_NET_BYTES(132);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rgetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rgetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(25))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rgetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rgetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(25));
if (GET_U64LE(offsetof_valid) & ~getattr_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in getattr bitfield: %#016"PRIx64,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in getattr bitfield: %#016"PRIx64,
GET_U64LE(offsetof_valid) & ~getattr_masks[ctx->version]);
if (GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32,
GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -1382,16 +1423,16 @@ static ssize_t validate_Tsetattr(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_end = net_offset + 67;
VALIDATE_NET_BYTES(67);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tsetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(26))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tsetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(26));
if (GET_U32LE(offsetof_valid) & ~setattr_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in setattr bitfield: %#08"PRIx32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in setattr bitfield: %#08"PRIx32,
GET_U32LE(offsetof_valid) & ~setattr_masks[ctx->version]);
if (GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32,
GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -1404,10 +1445,10 @@ static ssize_t validate_Rsetattr(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rsetattr->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(27))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rsetattr->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(27));
return (ssize_t)host_size;
}
@@ -1421,10 +1462,10 @@ static ssize_t validate_Txattrwalk(struct lib9p_ctx *ctx, uint32_t net_size, uin
VALIDATE_NET_UTF8(LAST_U16LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Txattrwalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Txattrwalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(30))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Txattrwalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Txattrwalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(30));
return (ssize_t)host_size;
}
@@ -1437,10 +1478,10 @@ static ssize_t validate_Rxattrwalk(struct lib9p_ctx *ctx, uint32_t net_size, uin
uint32_t offsetof_end = net_offset + 15;
VALIDATE_NET_BYTES(15);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rxattrwalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rxattrwalk->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(31))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rxattrwalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rxattrwalk->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(31));
return (ssize_t)host_size;
}
@@ -1455,10 +1496,10 @@ static ssize_t validate_Txattrcreate(struct lib9p_ctx *ctx, uint32_t net_size, u
uint32_t offsetof_end = net_offset + 12;
VALIDATE_NET_BYTES(12);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Txattrcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Txattrcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(32))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Txattrcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Txattrcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(32));
return (ssize_t)host_size;
}
@@ -1471,10 +1512,10 @@ static ssize_t validate_Rxattrcreate(struct lib9p_ctx *ctx, uint32_t net_size, u
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rxattrcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rxattrcreate->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(33))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rxattrcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rxattrcreate->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(33));
return (ssize_t)host_size;
}
@@ -1487,10 +1528,10 @@ static ssize_t validate_Treaddir(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_end = net_offset + 23;
VALIDATE_NET_BYTES(23);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Treaddir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Treaddir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(40))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Treaddir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Treaddir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(40));
return (ssize_t)host_size;
}
@@ -1504,10 +1545,10 @@ static ssize_t validate_Rreaddir(struct lib9p_ctx *ctx, uint32_t net_size, uint8
VALIDATE_NET_BYTES(LAST_U32LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rreaddir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rreaddir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(41))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rreaddir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rreaddir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(41));
return (ssize_t)host_size;
}
@@ -1520,10 +1561,10 @@ static ssize_t validate_Tfsync(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 15;
VALIDATE_NET_BYTES(15);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tfsync->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tfsync->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(50))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tfsync->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tfsync->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(50));
return (ssize_t)host_size;
}
@@ -1536,10 +1577,10 @@ static ssize_t validate_Rfsync(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rfsync->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rfsync->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(51))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rfsync->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rfsync->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(51));
return (ssize_t)host_size;
}
@@ -1554,13 +1595,13 @@ static ssize_t validate_Tlock(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
VALIDATE_NET_UTF8(LAST_U16LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(52))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(52));
if (GET_U32LE(offsetof_flags) & ~lock_flags_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in lock_flags bitfield: %#08"PRIx32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in lock_flags bitfield: %#08"PRIx32,
GET_U32LE(offsetof_flags) & ~lock_flags_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -1573,10 +1614,10 @@ static ssize_t validate_Rlock(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 8;
VALIDATE_NET_BYTES(8);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(53))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(53));
return (ssize_t)host_size;
}
@@ -1590,10 +1631,10 @@ static ssize_t validate_Tgetlock(struct lib9p_ctx *ctx, uint32_t net_size, uint8
VALIDATE_NET_UTF8(LAST_U16LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tgetlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tgetlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(54))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tgetlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tgetlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(54));
return (ssize_t)host_size;
}
@@ -1607,10 +1648,10 @@ static ssize_t validate_Rgetlock(struct lib9p_ctx *ctx, uint32_t net_size, uint8
VALIDATE_NET_UTF8(LAST_U16LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rgetlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rgetlock->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(55))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rgetlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rgetlock->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(55));
return (ssize_t)host_size;
}
@@ -1624,10 +1665,10 @@ static ssize_t validate_Tlink(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
VALIDATE_NET_UTF8(LAST_U16LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(70))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(70));
return (ssize_t)host_size;
}
@@ -1640,10 +1681,10 @@ static ssize_t validate_Rlink(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rlink->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(71))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rlink->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(71));
return (ssize_t)host_size;
}
@@ -1659,13 +1700,13 @@ static ssize_t validate_Tmkdir(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_end = net_offset + 8;
VALIDATE_NET_BYTES(8);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tmkdir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tmkdir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(72))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tmkdir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tmkdir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(72));
if (GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in mode bitfield: %#08"PRIx32,
GET_U32LE(offsetof_mode) & ~mode_masks[ctx->version]);
return (ssize_t)host_size;
}
@@ -1678,14 +1719,14 @@ static ssize_t validate_Rmkdir(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
uint32_t offsetof_qid_type = net_offset + 7;
VALIDATE_NET_BYTES(20);
if (GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version])
- return lib9p_errorf(ctx, LINUX_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "unknown bits in qt bitfield: %#02"PRIx8,
GET_U8LE(offsetof_qid_type) & ~qt_masks[ctx->version]);
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rmkdir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rmkdir->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(73))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rmkdir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rmkdir->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(73));
return (ssize_t)host_size;
}
@@ -1701,10 +1742,10 @@ static ssize_t validate_Trenameat(struct lib9p_ctx *ctx, uint32_t net_size, uint
VALIDATE_NET_UTF8(LAST_U16LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Trenameat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Trenameat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(74))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Trenameat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Trenameat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(74));
return (ssize_t)host_size;
}
@@ -1717,10 +1758,10 @@ static ssize_t validate_Rrenameat(struct lib9p_ctx *ctx, uint32_t net_size, uint
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rrenameat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rrenameat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(75))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rrenameat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rrenameat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(75));
return (ssize_t)host_size;
}
@@ -1735,10 +1776,10 @@ static ssize_t validate_Tunlinkat(struct lib9p_ctx *ctx, uint32_t net_size, uint
uint32_t offsetof_end = net_offset + 4;
VALIDATE_NET_BYTES(4);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tunlinkat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tunlinkat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(76))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tunlinkat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tunlinkat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(76));
return (ssize_t)host_size;
}
@@ -1751,10 +1792,10 @@ static ssize_t validate_Runlinkat(struct lib9p_ctx *ctx, uint32_t net_size, uint
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Runlinkat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Runlinkat->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(77))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Runlinkat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Runlinkat->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(77));
return (ssize_t)host_size;
}
@@ -1769,10 +1810,10 @@ static ssize_t validate_Tsession(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_end = net_offset + 15;
VALIDATE_NET_BYTES(15);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsession->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tsession->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(150))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsession->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tsession->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(150));
return (ssize_t)host_size;
}
@@ -1785,10 +1826,10 @@ static ssize_t validate_Rsession(struct lib9p_ctx *ctx, uint32_t net_size, uint8
uint32_t offsetof_end = net_offset + 7;
VALIDATE_NET_BYTES(7);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsession->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rsession->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(151))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsession->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rsession->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(151));
return (ssize_t)host_size;
}
@@ -1806,10 +1847,10 @@ static ssize_t validate_Tsread(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
}
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tsread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(152))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tsread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tsread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(152));
return (ssize_t)host_size;
}
@@ -1823,10 +1864,10 @@ static ssize_t validate_Rsread(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t
VALIDATE_NET_BYTES(LAST_U32LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rsread->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(153))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rsread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rsread->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(153));
return (ssize_t)host_size;
}
@@ -1846,10 +1887,10 @@ static ssize_t validate_Tswrite(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
VALIDATE_NET_BYTES(LAST_U32LE());
uint32_t offsetof_end = net_offset + 0;
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tswrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tswrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(154))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Tswrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Tswrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(154));
return (ssize_t)host_size;
}
@@ -1862,10 +1903,10 @@ static ssize_t validate_Rswrite(struct lib9p_ctx *ctx, uint32_t net_size, uint8_
uint32_t offsetof_end = net_offset + 11;
VALIDATE_NET_BYTES(11);
if ((uint32_t)GET_U32LE(offsetof_size) != (uint32_t)(offsetof_end - offsetof_size))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rswrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rswrite->size value is wrong: actual: %"PRIu32" != correct:%"PRIu32,
(uint32_t)GET_U32LE(offsetof_size), (uint32_t)(offsetof_end - offsetof_size));
if ((uint8_t)GET_U8LE(offsetof_typ) != (uint8_t)(155))
- return lib9p_errorf(ctx, LINUX_EBADMSG, "Rswrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EBADMSG, "Rswrite->typ value is wrong: actual: %"PRIu8" != correct:%"PRIu8,
(uint8_t)GET_U8LE(offsetof_typ), (uint8_t)(155));
return (ssize_t)host_size;
}
@@ -1895,36 +1936,36 @@ static void unmarshal_stat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_b
[[gnu::unused]] void *extra = &out[1];
uint32_t net_offset = 0;
net_offset += 2;
- UNMARSHAL_U16LE(ctx, out->kern_type);
- UNMARSHAL_U32LE(ctx, out->kern_dev);
- UNMARSHAL_U8LE(ctx, out->file_qid.type);
- UNMARSHAL_U32LE(ctx, out->file_qid.vers);
- UNMARSHAL_U64LE(ctx, out->file_qid.path);
- UNMARSHAL_U32LE(ctx, out->file_mode);
- UNMARSHAL_U32LE(ctx, out->file_atime);
- UNMARSHAL_U32LE(ctx, out->file_mtime);
- UNMARSHAL_U64LE(ctx, out->file_size);
- UNMARSHAL_U16LE(ctx, out->file_name.len);
- UNMARSHAL_BYTES(ctx, out->file_name.utf8, out->file_name.len);
- UNMARSHAL_U16LE(ctx, out->file_owner_uid.len);
- UNMARSHAL_BYTES(ctx, out->file_owner_uid.utf8, out->file_owner_uid.len);
- UNMARSHAL_U16LE(ctx, out->file_owner_gid.len);
- UNMARSHAL_BYTES(ctx, out->file_owner_gid.utf8, out->file_owner_gid.len);
- UNMARSHAL_U16LE(ctx, out->file_last_modified_uid.len);
- UNMARSHAL_BYTES(ctx, out->file_last_modified_uid.utf8, out->file_last_modified_uid.len);
+ UNMARSHAL_U16LE(ctx, out->fstype);
+ UNMARSHAL_U32LE(ctx, out->fsdev);
+ UNMARSHAL_U8LE(ctx, out->qid.type);
+ UNMARSHAL_U32LE(ctx, out->qid.vers);
+ UNMARSHAL_U64LE(ctx, out->qid.path);
+ UNMARSHAL_U32LE(ctx, out->mode);
+ UNMARSHAL_U32LE(ctx, out->atime);
+ UNMARSHAL_U32LE(ctx, out->mtime);
+ UNMARSHAL_U64LE(ctx, out->length);
+ UNMARSHAL_U16LE(ctx, out->name.len);
+ UNMARSHAL_BYTES(ctx, out->name.utf8, out->name.len);
+ UNMARSHAL_U16LE(ctx, out->owner_uname.len);
+ UNMARSHAL_BYTES(ctx, out->owner_uname.utf8, out->owner_uname.len);
+ UNMARSHAL_U16LE(ctx, out->owner_gname.len);
+ UNMARSHAL_BYTES(ctx, out->owner_gname.utf8, out->owner_gname.len);
+ UNMARSHAL_U16LE(ctx, out->last_modifier_uname.len);
+ UNMARSHAL_BYTES(ctx, out->last_modifier_uname.utf8, out->last_modifier_uname.len);
#if CONFIG_9P_ENABLE_9P2000_u
if (is_ver(ctx, 9P2000_u)) {
- UNMARSHAL_U16LE(ctx, out->file_extension.len);
- UNMARSHAL_BYTES(ctx, out->file_extension.utf8, out->file_extension.len);
- UNMARSHAL_U32LE(ctx, out->file_owner_n_uid);
- UNMARSHAL_U32LE(ctx, out->file_owner_n_gid);
- UNMARSHAL_U32LE(ctx, out->file_last_modified_n_uid);
+ UNMARSHAL_U16LE(ctx, out->extension.len);
+ UNMARSHAL_BYTES(ctx, out->extension.utf8, out->extension.len);
+ UNMARSHAL_U32LE(ctx, out->owner_unum);
+ UNMARSHAL_U32LE(ctx, out->owner_gnum);
+ UNMARSHAL_U32LE(ctx, out->last_modifier_unum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
}
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static void unmarshal_Tversion([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) {
struct lib9p_msg_Tversion *out = out_buf;
[[gnu::unused]] void *extra = &out[1];
@@ -1949,6 +1990,8 @@ static void unmarshal_Rversion([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *n
UNMARSHAL_BYTES(ctx, out->version.utf8, out->version.len);
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static void unmarshal_Tauth([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) {
struct lib9p_msg_Tauth *out = out_buf;
[[gnu::unused]] void *extra = &out[1];
@@ -1963,7 +2006,7 @@ static void unmarshal_Tauth([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_
UNMARSHAL_BYTES(ctx, out->aname.utf8, out->aname.len);
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
if (( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) )) {
- UNMARSHAL_U32LE(ctx, out->n_uid);
+ UNMARSHAL_U32LE(ctx, out->unum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
}
@@ -1995,7 +2038,7 @@ static void unmarshal_Tattach([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *ne
UNMARSHAL_BYTES(ctx, out->aname.utf8, out->aname.len);
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
if (( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) )) {
- UNMARSHAL_U32LE(ctx, out->n_uid);
+ UNMARSHAL_U32LE(ctx, out->unum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
}
@@ -2012,6 +2055,8 @@ static void unmarshal_Rattach([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *ne
UNMARSHAL_U64LE(ctx, out->qid.path);
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static void unmarshal_Rerror([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) {
struct lib9p_msg_Rerror *out = out_buf;
[[gnu::unused]] void *extra = &out[1];
@@ -2019,15 +2064,17 @@ static void unmarshal_Rerror([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net
net_offset += 4;
net_offset += 1;
UNMARSHAL_U16LE(ctx, out->tag);
- UNMARSHAL_U16LE(ctx, out->ename.len);
- UNMARSHAL_BYTES(ctx, out->ename.utf8, out->ename.len);
+ UNMARSHAL_U16LE(ctx, out->errstr.len);
+ UNMARSHAL_BYTES(ctx, out->errstr.utf8, out->errstr.len);
#if CONFIG_9P_ENABLE_9P2000_u
if (is_ver(ctx, 9P2000_u)) {
- UNMARSHAL_U32LE(ctx, out->errno);
+ UNMARSHAL_U32LE(ctx, out->errnum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static void unmarshal_Tflush([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) {
struct lib9p_msg_Tflush *out = out_buf;
[[gnu::unused]] void *extra = &out[1];
@@ -2242,30 +2289,30 @@ static void unmarshal_Rstat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_
UNMARSHAL_U16LE(ctx, out->tag);
net_offset += 2;
net_offset += 2;
- UNMARSHAL_U16LE(ctx, out->stat.kern_type);
- UNMARSHAL_U32LE(ctx, out->stat.kern_dev);
- UNMARSHAL_U8LE(ctx, out->stat.file_qid.type);
- UNMARSHAL_U32LE(ctx, out->stat.file_qid.vers);
- UNMARSHAL_U64LE(ctx, out->stat.file_qid.path);
- UNMARSHAL_U32LE(ctx, out->stat.file_mode);
- UNMARSHAL_U32LE(ctx, out->stat.file_atime);
- UNMARSHAL_U32LE(ctx, out->stat.file_mtime);
- UNMARSHAL_U64LE(ctx, out->stat.file_size);
- UNMARSHAL_U16LE(ctx, out->stat.file_name.len);
- UNMARSHAL_BYTES(ctx, out->stat.file_name.utf8, out->stat.file_name.len);
- UNMARSHAL_U16LE(ctx, out->stat.file_owner_uid.len);
- UNMARSHAL_BYTES(ctx, out->stat.file_owner_uid.utf8, out->stat.file_owner_uid.len);
- UNMARSHAL_U16LE(ctx, out->stat.file_owner_gid.len);
- UNMARSHAL_BYTES(ctx, out->stat.file_owner_gid.utf8, out->stat.file_owner_gid.len);
- UNMARSHAL_U16LE(ctx, out->stat.file_last_modified_uid.len);
- UNMARSHAL_BYTES(ctx, out->stat.file_last_modified_uid.utf8, out->stat.file_last_modified_uid.len);
+ UNMARSHAL_U16LE(ctx, out->stat.fstype);
+ UNMARSHAL_U32LE(ctx, out->stat.fsdev);
+ UNMARSHAL_U8LE(ctx, out->stat.qid.type);
+ UNMARSHAL_U32LE(ctx, out->stat.qid.vers);
+ UNMARSHAL_U64LE(ctx, out->stat.qid.path);
+ UNMARSHAL_U32LE(ctx, out->stat.mode);
+ UNMARSHAL_U32LE(ctx, out->stat.atime);
+ UNMARSHAL_U32LE(ctx, out->stat.mtime);
+ UNMARSHAL_U64LE(ctx, out->stat.length);
+ UNMARSHAL_U16LE(ctx, out->stat.name.len);
+ UNMARSHAL_BYTES(ctx, out->stat.name.utf8, out->stat.name.len);
+ UNMARSHAL_U16LE(ctx, out->stat.owner_uname.len);
+ UNMARSHAL_BYTES(ctx, out->stat.owner_uname.utf8, out->stat.owner_uname.len);
+ UNMARSHAL_U16LE(ctx, out->stat.owner_gname.len);
+ UNMARSHAL_BYTES(ctx, out->stat.owner_gname.utf8, out->stat.owner_gname.len);
+ UNMARSHAL_U16LE(ctx, out->stat.last_modifier_uname.len);
+ UNMARSHAL_BYTES(ctx, out->stat.last_modifier_uname.utf8, out->stat.last_modifier_uname.len);
#if CONFIG_9P_ENABLE_9P2000_u
if (is_ver(ctx, 9P2000_u)) {
- UNMARSHAL_U16LE(ctx, out->stat.file_extension.len);
- UNMARSHAL_BYTES(ctx, out->stat.file_extension.utf8, out->stat.file_extension.len);
- UNMARSHAL_U32LE(ctx, out->stat.file_owner_n_uid);
- UNMARSHAL_U32LE(ctx, out->stat.file_owner_n_gid);
- UNMARSHAL_U32LE(ctx, out->stat.file_last_modified_n_uid);
+ UNMARSHAL_U16LE(ctx, out->stat.extension.len);
+ UNMARSHAL_BYTES(ctx, out->stat.extension.utf8, out->stat.extension.len);
+ UNMARSHAL_U32LE(ctx, out->stat.owner_unum);
+ UNMARSHAL_U32LE(ctx, out->stat.owner_gnum);
+ UNMARSHAL_U32LE(ctx, out->stat.last_modifier_unum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
}
@@ -2280,30 +2327,30 @@ static void unmarshal_Twstat([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net
UNMARSHAL_U32LE(ctx, out->fid);
net_offset += 2;
net_offset += 2;
- UNMARSHAL_U16LE(ctx, out->stat.kern_type);
- UNMARSHAL_U32LE(ctx, out->stat.kern_dev);
- UNMARSHAL_U8LE(ctx, out->stat.file_qid.type);
- UNMARSHAL_U32LE(ctx, out->stat.file_qid.vers);
- UNMARSHAL_U64LE(ctx, out->stat.file_qid.path);
- UNMARSHAL_U32LE(ctx, out->stat.file_mode);
- UNMARSHAL_U32LE(ctx, out->stat.file_atime);
- UNMARSHAL_U32LE(ctx, out->stat.file_mtime);
- UNMARSHAL_U64LE(ctx, out->stat.file_size);
- UNMARSHAL_U16LE(ctx, out->stat.file_name.len);
- UNMARSHAL_BYTES(ctx, out->stat.file_name.utf8, out->stat.file_name.len);
- UNMARSHAL_U16LE(ctx, out->stat.file_owner_uid.len);
- UNMARSHAL_BYTES(ctx, out->stat.file_owner_uid.utf8, out->stat.file_owner_uid.len);
- UNMARSHAL_U16LE(ctx, out->stat.file_owner_gid.len);
- UNMARSHAL_BYTES(ctx, out->stat.file_owner_gid.utf8, out->stat.file_owner_gid.len);
- UNMARSHAL_U16LE(ctx, out->stat.file_last_modified_uid.len);
- UNMARSHAL_BYTES(ctx, out->stat.file_last_modified_uid.utf8, out->stat.file_last_modified_uid.len);
+ UNMARSHAL_U16LE(ctx, out->stat.fstype);
+ UNMARSHAL_U32LE(ctx, out->stat.fsdev);
+ UNMARSHAL_U8LE(ctx, out->stat.qid.type);
+ UNMARSHAL_U32LE(ctx, out->stat.qid.vers);
+ UNMARSHAL_U64LE(ctx, out->stat.qid.path);
+ UNMARSHAL_U32LE(ctx, out->stat.mode);
+ UNMARSHAL_U32LE(ctx, out->stat.atime);
+ UNMARSHAL_U32LE(ctx, out->stat.mtime);
+ UNMARSHAL_U64LE(ctx, out->stat.length);
+ UNMARSHAL_U16LE(ctx, out->stat.name.len);
+ UNMARSHAL_BYTES(ctx, out->stat.name.utf8, out->stat.name.len);
+ UNMARSHAL_U16LE(ctx, out->stat.owner_uname.len);
+ UNMARSHAL_BYTES(ctx, out->stat.owner_uname.utf8, out->stat.owner_uname.len);
+ UNMARSHAL_U16LE(ctx, out->stat.owner_gname.len);
+ UNMARSHAL_BYTES(ctx, out->stat.owner_gname.utf8, out->stat.owner_gname.len);
+ UNMARSHAL_U16LE(ctx, out->stat.last_modifier_uname.len);
+ UNMARSHAL_BYTES(ctx, out->stat.last_modifier_uname.utf8, out->stat.last_modifier_uname.len);
#if CONFIG_9P_ENABLE_9P2000_u
if (is_ver(ctx, 9P2000_u)) {
- UNMARSHAL_U16LE(ctx, out->stat.file_extension.len);
- UNMARSHAL_BYTES(ctx, out->stat.file_extension.utf8, out->stat.file_extension.len);
- UNMARSHAL_U32LE(ctx, out->stat.file_owner_n_uid);
- UNMARSHAL_U32LE(ctx, out->stat.file_owner_n_gid);
- UNMARSHAL_U32LE(ctx, out->stat.file_last_modified_n_uid);
+ UNMARSHAL_U16LE(ctx, out->stat.extension.len);
+ UNMARSHAL_BYTES(ctx, out->stat.extension.utf8, out->stat.extension.len);
+ UNMARSHAL_U32LE(ctx, out->stat.owner_unum);
+ UNMARSHAL_U32LE(ctx, out->stat.owner_gnum);
+ UNMARSHAL_U32LE(ctx, out->stat.last_modifier_unum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
}
@@ -2353,7 +2400,7 @@ static void unmarshal_Rlerror([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *ne
net_offset += 4;
net_offset += 1;
UNMARSHAL_U16LE(ctx, out->tag);
- UNMARSHAL_U32LE(ctx, out->ecode);
+ UNMARSHAL_U32LE(ctx, out->errnum);
}
static void unmarshal_Tstatfs([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out_buf) {
@@ -2965,53 +3012,53 @@ static void unmarshal_Rswrite([[gnu::unused]] struct lib9p_ctx *ctx, uint8_t *ne
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static bool marshal_stat(struct lib9p_ctx *ctx, struct lib9p_stat *val, struct _marshal_ret *ret) {
- uint32_t needed_size = 49 + val->file_name.len + val->file_owner_uid.len + val->file_owner_gid.len + val->file_last_modified_uid.len;
+ uint32_t needed_size = 49 + val->name.len + val->owner_uname.len + val->owner_gname.len + val->last_modifier_uname.len;
#if CONFIG_9P_ENABLE_9P2000_u
if is_ver(ctx, 9P2000_u) {
- needed_size += 14 + val->file_extension.len;
+ needed_size += 14 + val->extension.len;
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
if (needed_size > ctx->max_msg_size) {
return true;
}
uint32_t offsetof_end = needed_size;
- uint32_t offsetof_kern_type = 2;
- MARSHAL_U16LE(ctx, offsetof_end - offsetof_kern_type);
- MARSHAL_U16LE(ctx, val->kern_type);
- MARSHAL_U32LE(ctx, val->kern_dev);
- MARSHAL_U8LE(ctx, val->file_qid.type & qt_masks[ctx->version]);
- MARSHAL_U32LE(ctx, val->file_qid.vers);
- MARSHAL_U64LE(ctx, val->file_qid.path);
- MARSHAL_U32LE(ctx, val->file_mode & dm_masks[ctx->version]);
- MARSHAL_U32LE(ctx, val->file_atime);
- MARSHAL_U32LE(ctx, val->file_mtime);
- MARSHAL_U64LE(ctx, val->file_size);
- MARSHAL_U16LE(ctx, val->file_name.len);
- MARSHAL_BYTES(ctx, val->file_name.utf8, val->file_name.len);
- MARSHAL_U16LE(ctx, val->file_owner_uid.len);
- MARSHAL_BYTES(ctx, val->file_owner_uid.utf8, val->file_owner_uid.len);
- MARSHAL_U16LE(ctx, val->file_owner_gid.len);
- MARSHAL_BYTES(ctx, val->file_owner_gid.utf8, val->file_owner_gid.len);
- MARSHAL_U16LE(ctx, val->file_last_modified_uid.len);
- MARSHAL_BYTES(ctx, val->file_last_modified_uid.utf8, val->file_last_modified_uid.len);
+ uint32_t offsetof_fstype = 2;
+ MARSHAL_U16LE(ctx, offsetof_end - offsetof_fstype);
+ MARSHAL_U16LE(ctx, val->fstype);
+ MARSHAL_U32LE(ctx, val->fsdev);
+ MARSHAL_U8LE(ctx, val->qid.type & qt_masks[ctx->version]);
+ MARSHAL_U32LE(ctx, val->qid.vers);
+ MARSHAL_U64LE(ctx, val->qid.path);
+ MARSHAL_U32LE(ctx, val->mode & dm_masks[ctx->version]);
+ MARSHAL_U32LE(ctx, val->atime);
+ MARSHAL_U32LE(ctx, val->mtime);
+ MARSHAL_U64LE(ctx, val->length);
+ MARSHAL_U16LE(ctx, val->name.len);
+ MARSHAL_BYTES(ctx, val->name.utf8, val->name.len);
+ MARSHAL_U16LE(ctx, val->owner_uname.len);
+ MARSHAL_BYTES(ctx, val->owner_uname.utf8, val->owner_uname.len);
+ MARSHAL_U16LE(ctx, val->owner_gname.len);
+ MARSHAL_BYTES(ctx, val->owner_gname.utf8, val->owner_gname.len);
+ MARSHAL_U16LE(ctx, val->last_modifier_uname.len);
+ MARSHAL_BYTES(ctx, val->last_modifier_uname.utf8, val->last_modifier_uname.len);
#if CONFIG_9P_ENABLE_9P2000_u
if (is_ver(ctx, 9P2000_u)) {
- MARSHAL_U16LE(ctx, val->file_extension.len);
- MARSHAL_BYTES(ctx, val->file_extension.utf8, val->file_extension.len);
- MARSHAL_U32LE(ctx, val->file_owner_n_uid);
- MARSHAL_U32LE(ctx, val->file_owner_n_gid);
- MARSHAL_U32LE(ctx, val->file_last_modified_n_uid);
+ MARSHAL_U16LE(ctx, val->extension.len);
+ MARSHAL_BYTES(ctx, val->extension.utf8, val->extension.len);
+ MARSHAL_U32LE(ctx, val->owner_unum);
+ MARSHAL_U32LE(ctx, val->owner_gnum);
+ MARSHAL_U32LE(ctx, val->last_modifier_unum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
return false;
}
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static bool marshal_Tversion(struct lib9p_ctx *ctx, struct lib9p_msg_Tversion *val, struct _marshal_ret *ret) {
uint32_t needed_size = 13 + val->version.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tversion",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3031,7 +3078,7 @@ static bool marshal_Tversion(struct lib9p_ctx *ctx, struct lib9p_msg_Tversion *v
static bool marshal_Rversion(struct lib9p_ctx *ctx, struct lib9p_msg_Rversion *val, struct _marshal_ret *ret) {
uint32_t needed_size = 13 + val->version.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rversion",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3048,6 +3095,8 @@ static bool marshal_Rversion(struct lib9p_ctx *ctx, struct lib9p_msg_Rversion *v
return false;
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static bool marshal_Tauth(struct lib9p_ctx *ctx, struct lib9p_msg_Tauth *val, struct _marshal_ret *ret) {
uint32_t needed_size = 15 + val->uname.len + val->aname.len;
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
@@ -3056,7 +3105,7 @@ static bool marshal_Tauth(struct lib9p_ctx *ctx, struct lib9p_msg_Tauth *val, st
}
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tauth",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3074,7 +3123,7 @@ static bool marshal_Tauth(struct lib9p_ctx *ctx, struct lib9p_msg_Tauth *val, st
MARSHAL_BYTES_ZEROCOPY(ctx, val->aname.utf8, val->aname.len);
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
if (( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) )) {
- MARSHAL_U32LE(ctx, val->n_uid);
+ MARSHAL_U32LE(ctx, val->unum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
return false;
@@ -3083,7 +3132,7 @@ static bool marshal_Tauth(struct lib9p_ctx *ctx, struct lib9p_msg_Tauth *val, st
static bool marshal_Rauth(struct lib9p_ctx *ctx, struct lib9p_msg_Rauth *val, struct _marshal_ret *ret) {
uint32_t needed_size = 20;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rauth",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3108,7 +3157,7 @@ static bool marshal_Tattach(struct lib9p_ctx *ctx, struct lib9p_msg_Tattach *val
}
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tattach",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3127,7 +3176,7 @@ static bool marshal_Tattach(struct lib9p_ctx *ctx, struct lib9p_msg_Tattach *val
MARSHAL_BYTES_ZEROCOPY(ctx, val->aname.utf8, val->aname.len);
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
if (( is_ver(ctx, 9P2000_L) || is_ver(ctx, 9P2000_u) )) {
- MARSHAL_U32LE(ctx, val->n_uid);
+ MARSHAL_U32LE(ctx, val->unum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
return false;
@@ -3136,7 +3185,7 @@ static bool marshal_Tattach(struct lib9p_ctx *ctx, struct lib9p_msg_Tattach *val
static bool marshal_Rattach(struct lib9p_ctx *ctx, struct lib9p_msg_Rattach *val, struct _marshal_ret *ret) {
uint32_t needed_size = 20;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rattach",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3153,15 +3202,17 @@ static bool marshal_Rattach(struct lib9p_ctx *ctx, struct lib9p_msg_Rattach *val
return false;
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static bool marshal_Rerror(struct lib9p_ctx *ctx, struct lib9p_msg_Rerror *val, struct _marshal_ret *ret) {
- uint32_t needed_size = 9 + val->ename.len;
+ uint32_t needed_size = 9 + val->errstr.len;
#if CONFIG_9P_ENABLE_9P2000_u
if is_ver(ctx, 9P2000_u) {
needed_size += 4;
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rerror",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3172,20 +3223,22 @@ static bool marshal_Rerror(struct lib9p_ctx *ctx, struct lib9p_msg_Rerror *val,
MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
MARSHAL_U8LE(ctx, 107);
MARSHAL_U16LE(ctx, val->tag);
- MARSHAL_U16LE(ctx, val->ename.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->ename.utf8, val->ename.len);
+ MARSHAL_U16LE(ctx, val->errstr.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->errstr.utf8, val->errstr.len);
#if CONFIG_9P_ENABLE_9P2000_u
if (is_ver(ctx, 9P2000_u)) {
- MARSHAL_U32LE(ctx, val->errno);
+ MARSHAL_U32LE(ctx, val->errnum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
return false;
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static bool marshal_Tflush(struct lib9p_ctx *ctx, struct lib9p_msg_Tflush *val, struct _marshal_ret *ret) {
uint32_t needed_size = 9;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tflush",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3203,7 +3256,7 @@ static bool marshal_Tflush(struct lib9p_ctx *ctx, struct lib9p_msg_Tflush *val,
static bool marshal_Rflush(struct lib9p_ctx *ctx, struct lib9p_msg_Rflush *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rflush",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3223,7 +3276,7 @@ static bool marshal_Twalk(struct lib9p_ctx *ctx, struct lib9p_msg_Twalk *val, st
needed_size += 2 + val->wname[i].len;
}
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Twalk",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3247,7 +3300,7 @@ static bool marshal_Twalk(struct lib9p_ctx *ctx, struct lib9p_msg_Twalk *val, st
static bool marshal_Rwalk(struct lib9p_ctx *ctx, struct lib9p_msg_Rwalk *val, struct _marshal_ret *ret) {
uint32_t needed_size = 9 + (val->nwqid)*13;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rwalk",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3272,7 +3325,7 @@ static bool marshal_Rwalk(struct lib9p_ctx *ctx, struct lib9p_msg_Rwalk *val, st
static bool marshal_Topen(struct lib9p_ctx *ctx, struct lib9p_msg_Topen *val, struct _marshal_ret *ret) {
uint32_t needed_size = 12;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Topen",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3291,7 +3344,7 @@ static bool marshal_Topen(struct lib9p_ctx *ctx, struct lib9p_msg_Topen *val, st
static bool marshal_Ropen(struct lib9p_ctx *ctx, struct lib9p_msg_Ropen *val, struct _marshal_ret *ret) {
uint32_t needed_size = 24;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Ropen",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3312,7 +3365,7 @@ static bool marshal_Ropen(struct lib9p_ctx *ctx, struct lib9p_msg_Ropen *val, st
static bool marshal_Tcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Tcreate *val, struct _marshal_ret *ret) {
uint32_t needed_size = 18 + val->name.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tcreate",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3334,7 +3387,7 @@ static bool marshal_Tcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Tcreate *val
static bool marshal_Rcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Rcreate *val, struct _marshal_ret *ret) {
uint32_t needed_size = 24;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rcreate",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3357,7 +3410,7 @@ static bool marshal_Rcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Rcreate *val
static bool marshal_Tread(struct lib9p_ctx *ctx, struct lib9p_msg_Tread *val, struct _marshal_ret *ret) {
uint32_t needed_size = 23;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tread",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3377,7 +3430,7 @@ static bool marshal_Tread(struct lib9p_ctx *ctx, struct lib9p_msg_Tread *val, st
static bool marshal_Rread(struct lib9p_ctx *ctx, struct lib9p_msg_Rread *val, struct _marshal_ret *ret) {
uint32_t needed_size = 11 + val->count;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rread",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3396,7 +3449,7 @@ static bool marshal_Rread(struct lib9p_ctx *ctx, struct lib9p_msg_Rread *val, st
static bool marshal_Twrite(struct lib9p_ctx *ctx, struct lib9p_msg_Twrite *val, struct _marshal_ret *ret) {
uint32_t needed_size = 23 + val->count;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Twrite",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3417,7 +3470,7 @@ static bool marshal_Twrite(struct lib9p_ctx *ctx, struct lib9p_msg_Twrite *val,
static bool marshal_Rwrite(struct lib9p_ctx *ctx, struct lib9p_msg_Rwrite *val, struct _marshal_ret *ret) {
uint32_t needed_size = 11;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rwrite",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3435,7 +3488,7 @@ static bool marshal_Rwrite(struct lib9p_ctx *ctx, struct lib9p_msg_Rwrite *val,
static bool marshal_Tclunk(struct lib9p_ctx *ctx, struct lib9p_msg_Tclunk *val, struct _marshal_ret *ret) {
uint32_t needed_size = 11;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tclunk",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3453,7 +3506,7 @@ static bool marshal_Tclunk(struct lib9p_ctx *ctx, struct lib9p_msg_Tclunk *val,
static bool marshal_Rclunk(struct lib9p_ctx *ctx, struct lib9p_msg_Rclunk *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rclunk",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3470,7 +3523,7 @@ static bool marshal_Rclunk(struct lib9p_ctx *ctx, struct lib9p_msg_Rclunk *val,
static bool marshal_Tremove(struct lib9p_ctx *ctx, struct lib9p_msg_Tremove *val, struct _marshal_ret *ret) {
uint32_t needed_size = 11;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tremove",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3488,7 +3541,7 @@ static bool marshal_Tremove(struct lib9p_ctx *ctx, struct lib9p_msg_Tremove *val
static bool marshal_Rremove(struct lib9p_ctx *ctx, struct lib9p_msg_Rremove *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rremove",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3507,7 +3560,7 @@ static bool marshal_Rremove(struct lib9p_ctx *ctx, struct lib9p_msg_Rremove *val
static bool marshal_Tstat(struct lib9p_ctx *ctx, struct lib9p_msg_Tstat *val, struct _marshal_ret *ret) {
uint32_t needed_size = 11;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tstat",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3523,14 +3576,14 @@ static bool marshal_Tstat(struct lib9p_ctx *ctx, struct lib9p_msg_Tstat *val, st
}
static bool marshal_Rstat(struct lib9p_ctx *ctx, struct lib9p_msg_Rstat *val, struct _marshal_ret *ret) {
- uint32_t needed_size = 58 + val->stat.file_name.len + val->stat.file_owner_uid.len + val->stat.file_owner_gid.len + val->stat.file_last_modified_uid.len;
+ uint32_t needed_size = 58 + val->stat.name.len + val->stat.owner_uname.len + val->stat.owner_gname.len + val->stat.last_modifier_uname.len;
#if CONFIG_9P_ENABLE_9P2000_u
if is_ver(ctx, 9P2000_u) {
- needed_size += 14 + val->stat.file_extension.len;
+ needed_size += 14 + val->stat.extension.len;
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rstat",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3543,52 +3596,52 @@ static bool marshal_Rstat(struct lib9p_ctx *ctx, struct lib9p_msg_Rstat *val, st
MARSHAL_U8LE(ctx, 125);
MARSHAL_U16LE(ctx, val->tag);
MARSHAL_U16LE(ctx, offsetof_end - offsetof_stat);
- uint32_t offsetof_stat_end = 49 + val->stat.file_name.len + val->stat.file_owner_uid.len + val->stat.file_owner_gid.len + val->stat.file_last_modified_uid.len;
+ uint32_t offsetof_stat_end = 49 + val->stat.name.len + val->stat.owner_uname.len + val->stat.owner_gname.len + val->stat.last_modifier_uname.len;
#if CONFIG_9P_ENABLE_9P2000_u
if is_ver(ctx, 9P2000_u) {
- offsetof_stat_end += 14 + val->stat.file_extension.len;
+ offsetof_stat_end += 14 + val->stat.extension.len;
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
- uint32_t offsetof_stat_kern_type = 2;
- MARSHAL_U16LE(ctx, offsetof_stat_end - offsetof_stat_kern_type);
- MARSHAL_U16LE(ctx, val->stat.kern_type);
- MARSHAL_U32LE(ctx, val->stat.kern_dev);
- MARSHAL_U8LE(ctx, val->stat.file_qid.type & qt_masks[ctx->version]);
- MARSHAL_U32LE(ctx, val->stat.file_qid.vers);
- MARSHAL_U64LE(ctx, val->stat.file_qid.path);
- MARSHAL_U32LE(ctx, val->stat.file_mode & dm_masks[ctx->version]);
- MARSHAL_U32LE(ctx, val->stat.file_atime);
- MARSHAL_U32LE(ctx, val->stat.file_mtime);
- MARSHAL_U64LE(ctx, val->stat.file_size);
- MARSHAL_U16LE(ctx, val->stat.file_name.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_name.utf8, val->stat.file_name.len);
- MARSHAL_U16LE(ctx, val->stat.file_owner_uid.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_owner_uid.utf8, val->stat.file_owner_uid.len);
- MARSHAL_U16LE(ctx, val->stat.file_owner_gid.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_owner_gid.utf8, val->stat.file_owner_gid.len);
- MARSHAL_U16LE(ctx, val->stat.file_last_modified_uid.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_last_modified_uid.utf8, val->stat.file_last_modified_uid.len);
+ uint32_t offsetof_stat_fstype = 2;
+ MARSHAL_U16LE(ctx, offsetof_stat_end - offsetof_stat_fstype);
+ MARSHAL_U16LE(ctx, val->stat.fstype);
+ MARSHAL_U32LE(ctx, val->stat.fsdev);
+ MARSHAL_U8LE(ctx, val->stat.qid.type & qt_masks[ctx->version]);
+ MARSHAL_U32LE(ctx, val->stat.qid.vers);
+ MARSHAL_U64LE(ctx, val->stat.qid.path);
+ MARSHAL_U32LE(ctx, val->stat.mode & dm_masks[ctx->version]);
+ MARSHAL_U32LE(ctx, val->stat.atime);
+ MARSHAL_U32LE(ctx, val->stat.mtime);
+ MARSHAL_U64LE(ctx, val->stat.length);
+ MARSHAL_U16LE(ctx, val->stat.name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.name.utf8, val->stat.name.len);
+ MARSHAL_U16LE(ctx, val->stat.owner_uname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.owner_uname.utf8, val->stat.owner_uname.len);
+ MARSHAL_U16LE(ctx, val->stat.owner_gname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.owner_gname.utf8, val->stat.owner_gname.len);
+ MARSHAL_U16LE(ctx, val->stat.last_modifier_uname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.last_modifier_uname.utf8, val->stat.last_modifier_uname.len);
#if CONFIG_9P_ENABLE_9P2000_u
if (is_ver(ctx, 9P2000_u)) {
- MARSHAL_U16LE(ctx, val->stat.file_extension.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_extension.utf8, val->stat.file_extension.len);
- MARSHAL_U32LE(ctx, val->stat.file_owner_n_uid);
- MARSHAL_U32LE(ctx, val->stat.file_owner_n_gid);
- MARSHAL_U32LE(ctx, val->stat.file_last_modified_n_uid);
+ MARSHAL_U16LE(ctx, val->stat.extension.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.extension.utf8, val->stat.extension.len);
+ MARSHAL_U32LE(ctx, val->stat.owner_unum);
+ MARSHAL_U32LE(ctx, val->stat.owner_gnum);
+ MARSHAL_U32LE(ctx, val->stat.last_modifier_unum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
return false;
}
static bool marshal_Twstat(struct lib9p_ctx *ctx, struct lib9p_msg_Twstat *val, struct _marshal_ret *ret) {
- uint32_t needed_size = 62 + val->stat.file_name.len + val->stat.file_owner_uid.len + val->stat.file_owner_gid.len + val->stat.file_last_modified_uid.len;
+ uint32_t needed_size = 62 + val->stat.name.len + val->stat.owner_uname.len + val->stat.owner_gname.len + val->stat.last_modifier_uname.len;
#if CONFIG_9P_ENABLE_9P2000_u
if is_ver(ctx, 9P2000_u) {
- needed_size += 14 + val->stat.file_extension.len;
+ needed_size += 14 + val->stat.extension.len;
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Twstat",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3602,38 +3655,38 @@ static bool marshal_Twstat(struct lib9p_ctx *ctx, struct lib9p_msg_Twstat *val,
MARSHAL_U16LE(ctx, val->tag);
MARSHAL_U32LE(ctx, val->fid);
MARSHAL_U16LE(ctx, offsetof_end - offsetof_stat);
- uint32_t offsetof_stat_end = 49 + val->stat.file_name.len + val->stat.file_owner_uid.len + val->stat.file_owner_gid.len + val->stat.file_last_modified_uid.len;
+ uint32_t offsetof_stat_end = 49 + val->stat.name.len + val->stat.owner_uname.len + val->stat.owner_gname.len + val->stat.last_modifier_uname.len;
#if CONFIG_9P_ENABLE_9P2000_u
if is_ver(ctx, 9P2000_u) {
- offsetof_stat_end += 14 + val->stat.file_extension.len;
+ offsetof_stat_end += 14 + val->stat.extension.len;
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
- uint32_t offsetof_stat_kern_type = 2;
- MARSHAL_U16LE(ctx, offsetof_stat_end - offsetof_stat_kern_type);
- MARSHAL_U16LE(ctx, val->stat.kern_type);
- MARSHAL_U32LE(ctx, val->stat.kern_dev);
- MARSHAL_U8LE(ctx, val->stat.file_qid.type & qt_masks[ctx->version]);
- MARSHAL_U32LE(ctx, val->stat.file_qid.vers);
- MARSHAL_U64LE(ctx, val->stat.file_qid.path);
- MARSHAL_U32LE(ctx, val->stat.file_mode & dm_masks[ctx->version]);
- MARSHAL_U32LE(ctx, val->stat.file_atime);
- MARSHAL_U32LE(ctx, val->stat.file_mtime);
- MARSHAL_U64LE(ctx, val->stat.file_size);
- MARSHAL_U16LE(ctx, val->stat.file_name.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_name.utf8, val->stat.file_name.len);
- MARSHAL_U16LE(ctx, val->stat.file_owner_uid.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_owner_uid.utf8, val->stat.file_owner_uid.len);
- MARSHAL_U16LE(ctx, val->stat.file_owner_gid.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_owner_gid.utf8, val->stat.file_owner_gid.len);
- MARSHAL_U16LE(ctx, val->stat.file_last_modified_uid.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_last_modified_uid.utf8, val->stat.file_last_modified_uid.len);
+ uint32_t offsetof_stat_fstype = 2;
+ MARSHAL_U16LE(ctx, offsetof_stat_end - offsetof_stat_fstype);
+ MARSHAL_U16LE(ctx, val->stat.fstype);
+ MARSHAL_U32LE(ctx, val->stat.fsdev);
+ MARSHAL_U8LE(ctx, val->stat.qid.type & qt_masks[ctx->version]);
+ MARSHAL_U32LE(ctx, val->stat.qid.vers);
+ MARSHAL_U64LE(ctx, val->stat.qid.path);
+ MARSHAL_U32LE(ctx, val->stat.mode & dm_masks[ctx->version]);
+ MARSHAL_U32LE(ctx, val->stat.atime);
+ MARSHAL_U32LE(ctx, val->stat.mtime);
+ MARSHAL_U64LE(ctx, val->stat.length);
+ MARSHAL_U16LE(ctx, val->stat.name.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.name.utf8, val->stat.name.len);
+ MARSHAL_U16LE(ctx, val->stat.owner_uname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.owner_uname.utf8, val->stat.owner_uname.len);
+ MARSHAL_U16LE(ctx, val->stat.owner_gname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.owner_gname.utf8, val->stat.owner_gname.len);
+ MARSHAL_U16LE(ctx, val->stat.last_modifier_uname.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.last_modifier_uname.utf8, val->stat.last_modifier_uname.len);
#if CONFIG_9P_ENABLE_9P2000_u
if (is_ver(ctx, 9P2000_u)) {
- MARSHAL_U16LE(ctx, val->stat.file_extension.len);
- MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.file_extension.utf8, val->stat.file_extension.len);
- MARSHAL_U32LE(ctx, val->stat.file_owner_n_uid);
- MARSHAL_U32LE(ctx, val->stat.file_owner_n_gid);
- MARSHAL_U32LE(ctx, val->stat.file_last_modified_n_uid);
+ MARSHAL_U16LE(ctx, val->stat.extension.len);
+ MARSHAL_BYTES_ZEROCOPY(ctx, val->stat.extension.utf8, val->stat.extension.len);
+ MARSHAL_U32LE(ctx, val->stat.owner_unum);
+ MARSHAL_U32LE(ctx, val->stat.owner_gnum);
+ MARSHAL_U32LE(ctx, val->stat.last_modifier_unum);
}
#endif /* CONFIG_9P_ENABLE_9P2000_u */
return false;
@@ -3642,7 +3695,7 @@ static bool marshal_Twstat(struct lib9p_ctx *ctx, struct lib9p_msg_Twstat *val,
static bool marshal_Rwstat(struct lib9p_ctx *ctx, struct lib9p_msg_Rwstat *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rwstat",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3661,7 +3714,7 @@ static bool marshal_Rwstat(struct lib9p_ctx *ctx, struct lib9p_msg_Rwstat *val,
static bool marshal_Topenfd(struct lib9p_ctx *ctx, struct lib9p_msg_Topenfd *val, struct _marshal_ret *ret) {
uint32_t needed_size = 12;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Topenfd",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3680,7 +3733,7 @@ static bool marshal_Topenfd(struct lib9p_ctx *ctx, struct lib9p_msg_Topenfd *val
static bool marshal_Ropenfd(struct lib9p_ctx *ctx, struct lib9p_msg_Ropenfd *val, struct _marshal_ret *ret) {
uint32_t needed_size = 28;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Ropenfd",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3704,7 +3757,7 @@ static bool marshal_Ropenfd(struct lib9p_ctx *ctx, struct lib9p_msg_Ropenfd *val
static bool marshal_Rlerror(struct lib9p_ctx *ctx, struct lib9p_msg_Rlerror *val, struct _marshal_ret *ret) {
uint32_t needed_size = 11;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rlerror",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3715,14 +3768,14 @@ static bool marshal_Rlerror(struct lib9p_ctx *ctx, struct lib9p_msg_Rlerror *val
MARSHAL_U32LE(ctx, offsetof_end - offsetof_size);
MARSHAL_U8LE(ctx, 7);
MARSHAL_U16LE(ctx, val->tag);
- MARSHAL_U32LE(ctx, val->ecode);
+ MARSHAL_U32LE(ctx, val->errnum);
return false;
}
static bool marshal_Tstatfs(struct lib9p_ctx *ctx, struct lib9p_msg_Tstatfs *val, struct _marshal_ret *ret) {
uint32_t needed_size = 11;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tstatfs",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3740,7 +3793,7 @@ static bool marshal_Tstatfs(struct lib9p_ctx *ctx, struct lib9p_msg_Tstatfs *val
static bool marshal_Rstatfs(struct lib9p_ctx *ctx, struct lib9p_msg_Rstatfs *val, struct _marshal_ret *ret) {
uint32_t needed_size = 67;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rstatfs",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3766,7 +3819,7 @@ static bool marshal_Rstatfs(struct lib9p_ctx *ctx, struct lib9p_msg_Rstatfs *val
static bool marshal_Tlopen(struct lib9p_ctx *ctx, struct lib9p_msg_Tlopen *val, struct _marshal_ret *ret) {
uint32_t needed_size = 15;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tlopen",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3785,7 +3838,7 @@ static bool marshal_Tlopen(struct lib9p_ctx *ctx, struct lib9p_msg_Tlopen *val,
static bool marshal_Rlopen(struct lib9p_ctx *ctx, struct lib9p_msg_Rlopen *val, struct _marshal_ret *ret) {
uint32_t needed_size = 24;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rlopen",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3806,7 +3859,7 @@ static bool marshal_Rlopen(struct lib9p_ctx *ctx, struct lib9p_msg_Rlopen *val,
static bool marshal_Tlcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Tlcreate *val, struct _marshal_ret *ret) {
uint32_t needed_size = 25 + val->name.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tlcreate",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3829,7 +3882,7 @@ static bool marshal_Tlcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Tlcreate *v
static bool marshal_Rlcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Rlcreate *val, struct _marshal_ret *ret) {
uint32_t needed_size = 24;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rlcreate",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3850,7 +3903,7 @@ static bool marshal_Rlcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Rlcreate *v
static bool marshal_Tsymlink(struct lib9p_ctx *ctx, struct lib9p_msg_Tsymlink *val, struct _marshal_ret *ret) {
uint32_t needed_size = 19 + val->name.len + val->symtgt.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tsymlink",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3873,7 +3926,7 @@ static bool marshal_Tsymlink(struct lib9p_ctx *ctx, struct lib9p_msg_Tsymlink *v
static bool marshal_Rsymlink(struct lib9p_ctx *ctx, struct lib9p_msg_Rsymlink *val, struct _marshal_ret *ret) {
uint32_t needed_size = 20;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rsymlink",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3893,7 +3946,7 @@ static bool marshal_Rsymlink(struct lib9p_ctx *ctx, struct lib9p_msg_Rsymlink *v
static bool marshal_Tmknod(struct lib9p_ctx *ctx, struct lib9p_msg_Tmknod *val, struct _marshal_ret *ret) {
uint32_t needed_size = 29 + val->name.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tmknod",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3917,7 +3970,7 @@ static bool marshal_Tmknod(struct lib9p_ctx *ctx, struct lib9p_msg_Tmknod *val,
static bool marshal_Rmknod(struct lib9p_ctx *ctx, struct lib9p_msg_Rmknod *val, struct _marshal_ret *ret) {
uint32_t needed_size = 20;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rmknod",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3937,7 +3990,7 @@ static bool marshal_Rmknod(struct lib9p_ctx *ctx, struct lib9p_msg_Rmknod *val,
static bool marshal_Trename(struct lib9p_ctx *ctx, struct lib9p_msg_Trename *val, struct _marshal_ret *ret) {
uint32_t needed_size = 17 + val->name.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Trename",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3958,7 +4011,7 @@ static bool marshal_Trename(struct lib9p_ctx *ctx, struct lib9p_msg_Trename *val
static bool marshal_Rrename(struct lib9p_ctx *ctx, struct lib9p_msg_Rrename *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rrename",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -3975,7 +4028,7 @@ static bool marshal_Rrename(struct lib9p_ctx *ctx, struct lib9p_msg_Rrename *val
static bool marshal_Treadlink(struct lib9p_ctx *ctx, struct lib9p_msg_Treadlink *val, struct _marshal_ret *ret) {
uint32_t needed_size = 11;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Treadlink",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -3993,7 +4046,7 @@ static bool marshal_Treadlink(struct lib9p_ctx *ctx, struct lib9p_msg_Treadlink
static bool marshal_Rreadlink(struct lib9p_ctx *ctx, struct lib9p_msg_Rreadlink *val, struct _marshal_ret *ret) {
uint32_t needed_size = 9 + val->target.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rreadlink",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4012,7 +4065,7 @@ static bool marshal_Rreadlink(struct lib9p_ctx *ctx, struct lib9p_msg_Rreadlink
static bool marshal_Tgetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Tgetattr *val, struct _marshal_ret *ret) {
uint32_t needed_size = 19;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tgetattr",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4031,7 +4084,7 @@ static bool marshal_Tgetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Tgetattr *v
static bool marshal_Rgetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Rgetattr *val, struct _marshal_ret *ret) {
uint32_t needed_size = 160;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rgetattr",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4070,7 +4123,7 @@ static bool marshal_Rgetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Rgetattr *v
static bool marshal_Tsetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Tsetattr *val, struct _marshal_ret *ret) {
uint32_t needed_size = 67;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tsetattr",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4097,7 +4150,7 @@ static bool marshal_Tsetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Tsetattr *v
static bool marshal_Rsetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Rsetattr *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rsetattr",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4114,7 +4167,7 @@ static bool marshal_Rsetattr(struct lib9p_ctx *ctx, struct lib9p_msg_Rsetattr *v
static bool marshal_Txattrwalk(struct lib9p_ctx *ctx, struct lib9p_msg_Txattrwalk *val, struct _marshal_ret *ret) {
uint32_t needed_size = 17 + val->name.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Txattrwalk",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4135,7 +4188,7 @@ static bool marshal_Txattrwalk(struct lib9p_ctx *ctx, struct lib9p_msg_Txattrwal
static bool marshal_Rxattrwalk(struct lib9p_ctx *ctx, struct lib9p_msg_Rxattrwalk *val, struct _marshal_ret *ret) {
uint32_t needed_size = 15;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rxattrwalk",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4153,7 +4206,7 @@ static bool marshal_Rxattrwalk(struct lib9p_ctx *ctx, struct lib9p_msg_Rxattrwal
static bool marshal_Txattrcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Txattrcreate *val, struct _marshal_ret *ret) {
uint32_t needed_size = 25 + val->name.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Txattrcreate",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4175,7 +4228,7 @@ static bool marshal_Txattrcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Txattrc
static bool marshal_Rxattrcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Rxattrcreate *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rxattrcreate",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4192,7 +4245,7 @@ static bool marshal_Rxattrcreate(struct lib9p_ctx *ctx, struct lib9p_msg_Rxattrc
static bool marshal_Treaddir(struct lib9p_ctx *ctx, struct lib9p_msg_Treaddir *val, struct _marshal_ret *ret) {
uint32_t needed_size = 23;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Treaddir",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4212,7 +4265,7 @@ static bool marshal_Treaddir(struct lib9p_ctx *ctx, struct lib9p_msg_Treaddir *v
static bool marshal_Rreaddir(struct lib9p_ctx *ctx, struct lib9p_msg_Rreaddir *val, struct _marshal_ret *ret) {
uint64_t needed_size = 11 + val->count;
if (needed_size > (uint64_t)(ctx->max_msg_size)) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rreaddir",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4231,7 +4284,7 @@ static bool marshal_Rreaddir(struct lib9p_ctx *ctx, struct lib9p_msg_Rreaddir *v
static bool marshal_Tfsync(struct lib9p_ctx *ctx, struct lib9p_msg_Tfsync *val, struct _marshal_ret *ret) {
uint32_t needed_size = 15;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tfsync",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4250,7 +4303,7 @@ static bool marshal_Tfsync(struct lib9p_ctx *ctx, struct lib9p_msg_Tfsync *val,
static bool marshal_Rfsync(struct lib9p_ctx *ctx, struct lib9p_msg_Rfsync *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rfsync",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4267,7 +4320,7 @@ static bool marshal_Rfsync(struct lib9p_ctx *ctx, struct lib9p_msg_Rfsync *val,
static bool marshal_Tlock(struct lib9p_ctx *ctx, struct lib9p_msg_Tlock *val, struct _marshal_ret *ret) {
uint32_t needed_size = 38 + val->client_id.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tlock",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4292,7 +4345,7 @@ static bool marshal_Tlock(struct lib9p_ctx *ctx, struct lib9p_msg_Tlock *val, st
static bool marshal_Rlock(struct lib9p_ctx *ctx, struct lib9p_msg_Rlock *val, struct _marshal_ret *ret) {
uint32_t needed_size = 8;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rlock",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4310,7 +4363,7 @@ static bool marshal_Rlock(struct lib9p_ctx *ctx, struct lib9p_msg_Rlock *val, st
static bool marshal_Tgetlock(struct lib9p_ctx *ctx, struct lib9p_msg_Tgetlock *val, struct _marshal_ret *ret) {
uint32_t needed_size = 34 + val->client_id.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tgetlock",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4334,7 +4387,7 @@ static bool marshal_Tgetlock(struct lib9p_ctx *ctx, struct lib9p_msg_Tgetlock *v
static bool marshal_Rgetlock(struct lib9p_ctx *ctx, struct lib9p_msg_Rgetlock *val, struct _marshal_ret *ret) {
uint32_t needed_size = 30 + val->client_id.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rgetlock",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4357,7 +4410,7 @@ static bool marshal_Rgetlock(struct lib9p_ctx *ctx, struct lib9p_msg_Rgetlock *v
static bool marshal_Tlink(struct lib9p_ctx *ctx, struct lib9p_msg_Tlink *val, struct _marshal_ret *ret) {
uint32_t needed_size = 17 + val->name.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tlink",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4378,7 +4431,7 @@ static bool marshal_Tlink(struct lib9p_ctx *ctx, struct lib9p_msg_Tlink *val, st
static bool marshal_Rlink(struct lib9p_ctx *ctx, struct lib9p_msg_Rlink *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rlink",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4395,7 +4448,7 @@ static bool marshal_Rlink(struct lib9p_ctx *ctx, struct lib9p_msg_Rlink *val, st
static bool marshal_Tmkdir(struct lib9p_ctx *ctx, struct lib9p_msg_Tmkdir *val, struct _marshal_ret *ret) {
uint32_t needed_size = 21 + val->name.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tmkdir",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4417,7 +4470,7 @@ static bool marshal_Tmkdir(struct lib9p_ctx *ctx, struct lib9p_msg_Tmkdir *val,
static bool marshal_Rmkdir(struct lib9p_ctx *ctx, struct lib9p_msg_Rmkdir *val, struct _marshal_ret *ret) {
uint32_t needed_size = 20;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rmkdir",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4437,7 +4490,7 @@ static bool marshal_Rmkdir(struct lib9p_ctx *ctx, struct lib9p_msg_Rmkdir *val,
static bool marshal_Trenameat(struct lib9p_ctx *ctx, struct lib9p_msg_Trenameat *val, struct _marshal_ret *ret) {
uint32_t needed_size = 19 + val->oldname.len + val->newname.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Trenameat",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4460,7 +4513,7 @@ static bool marshal_Trenameat(struct lib9p_ctx *ctx, struct lib9p_msg_Trenameat
static bool marshal_Rrenameat(struct lib9p_ctx *ctx, struct lib9p_msg_Rrenameat *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rrenameat",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4477,7 +4530,7 @@ static bool marshal_Rrenameat(struct lib9p_ctx *ctx, struct lib9p_msg_Rrenameat
static bool marshal_Tunlinkat(struct lib9p_ctx *ctx, struct lib9p_msg_Tunlinkat *val, struct _marshal_ret *ret) {
uint32_t needed_size = 17 + val->name.len;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tunlinkat",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4498,7 +4551,7 @@ static bool marshal_Tunlinkat(struct lib9p_ctx *ctx, struct lib9p_msg_Tunlinkat
static bool marshal_Runlinkat(struct lib9p_ctx *ctx, struct lib9p_msg_Runlinkat *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Runlinkat",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4517,7 +4570,7 @@ static bool marshal_Runlinkat(struct lib9p_ctx *ctx, struct lib9p_msg_Runlinkat
static bool marshal_Tsession(struct lib9p_ctx *ctx, struct lib9p_msg_Tsession *val, struct _marshal_ret *ret) {
uint32_t needed_size = 15;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tsession",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4535,7 +4588,7 @@ static bool marshal_Tsession(struct lib9p_ctx *ctx, struct lib9p_msg_Tsession *v
static bool marshal_Rsession(struct lib9p_ctx *ctx, struct lib9p_msg_Rsession *val, struct _marshal_ret *ret) {
uint32_t needed_size = 7;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rsession",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4555,7 +4608,7 @@ static bool marshal_Tsread(struct lib9p_ctx *ctx, struct lib9p_msg_Tsread *val,
needed_size += 2 + val->wname[i].len;
}
if (needed_size > (uint64_t)(ctx->max_msg_size)) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tsread",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4578,7 +4631,7 @@ static bool marshal_Tsread(struct lib9p_ctx *ctx, struct lib9p_msg_Tsread *val,
static bool marshal_Rsread(struct lib9p_ctx *ctx, struct lib9p_msg_Rsread *val, struct _marshal_ret *ret) {
uint64_t needed_size = 11 + val->count;
if (needed_size > (uint64_t)(ctx->max_msg_size)) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rsread",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4600,7 +4653,7 @@ static bool marshal_Tswrite(struct lib9p_ctx *ctx, struct lib9p_msg_Tswrite *val
needed_size += 2 + val->wname[i].len;
}
if (needed_size > (uint64_t)(ctx->max_msg_size)) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Tswrite",
ctx->version ? "negotiated" : "client",
ctx->max_msg_size);
@@ -4625,7 +4678,7 @@ static bool marshal_Tswrite(struct lib9p_ctx *ctx, struct lib9p_msg_Tswrite *val
static bool marshal_Rswrite(struct lib9p_ctx *ctx, struct lib9p_msg_Rswrite *val, struct _marshal_ret *ret) {
uint32_t needed_size = 11;
if (needed_size > ctx->max_msg_size) {
- lib9p_errorf(ctx, LINUX_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
+ lib9p_errorf(ctx, LIB9P_ERRNO_L_ERANGE, "%s message too large to marshal into %s limit (limit=%"PRIu32")",
"Rswrite",
ctx->version ? "negotiated" : "server",
ctx->max_msg_size);
@@ -4643,7 +4696,7 @@ static bool marshal_Rswrite(struct lib9p_ctx *ctx, struct lib9p_msg_Rswrite *val
/* *_format *******************************************************************/
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static void lib9p_tag_format(lib9p_tag_t *self, struct fmt_state *state) {
switch (*self) {
case LIB9P_TAG_NOTAG:
@@ -4665,7 +4718,6 @@ static void lib9p_fid_format(lib9p_fid_t *self, struct fmt_state *state) {
}
static void lib9p_s_format(struct lib9p_s *self, struct fmt_state *state) {
- /* 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"
@@ -4673,8 +4725,8 @@ static void lib9p_s_format(struct lib9p_s *self, struct fmt_state *state) {
#pragma GCC diagnostic pop
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static void lib9p_dm_format(lib9p_dm_t *self, struct fmt_state *state) {
bool empty = true;
fmt_state_putchar(state, '(');
@@ -4876,8 +4928,8 @@ static void lib9p_dm_format(lib9p_dm_t *self, struct fmt_state *state) {
fmt_state_putchar(state, ')');
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static void lib9p_qt_format(lib9p_qt_t *self, struct fmt_state *state) {
bool empty = true;
fmt_state_putchar(state, '(');
@@ -4945,41 +4997,41 @@ static void lib9p_qid_format(struct lib9p_qid *self, struct fmt_state *state) {
fmt_state_puts(state, " }");
}
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static void lib9p_stat_format(struct lib9p_stat *self, struct fmt_state *state) {
fmt_state_putchar(state, '{');
- fmt_state_puts(state, " kern_type=");
- fmt_state_printf(state, "%"PRIu16, self->kern_type);
- fmt_state_puts(state, " kern_dev=");
- fmt_state_printf(state, "%"PRIu32, self->kern_dev);
- fmt_state_puts(state, " file_qid=");
- lib9p_qid_format(&self->file_qid, state);
- fmt_state_puts(state, " file_mode=");
- lib9p_dm_format(&self->file_mode, state);
- fmt_state_puts(state, " file_atime=");
- fmt_state_printf(state, "%"PRIu32, self->file_atime);
- fmt_state_puts(state, " file_mtime=");
- fmt_state_printf(state, "%"PRIu32, self->file_mtime);
- fmt_state_puts(state, " file_size=");
- fmt_state_printf(state, "%"PRIu64, self->file_size);
- fmt_state_puts(state, " file_name=");
- lib9p_s_format(&self->file_name, state);
- fmt_state_puts(state, " file_owner_uid=");
- lib9p_s_format(&self->file_owner_uid, state);
- fmt_state_puts(state, " file_owner_gid=");
- lib9p_s_format(&self->file_owner_gid, state);
- fmt_state_puts(state, " file_last_modified_uid=");
- lib9p_s_format(&self->file_last_modified_uid, state);
+ fmt_state_puts(state, " fstype=");
+ fmt_state_printf(state, "%"PRIu16, self->fstype);
+ fmt_state_puts(state, " fsdev=");
+ fmt_state_printf(state, "%"PRIu32, self->fsdev);
+ fmt_state_puts(state, " qid=");
+ lib9p_qid_format(&self->qid, state);
+ fmt_state_puts(state, " mode=");
+ lib9p_dm_format(&self->mode, state);
+ fmt_state_puts(state, " atime=");
+ fmt_state_printf(state, "%"PRIu32, self->atime);
+ fmt_state_puts(state, " mtime=");
+ fmt_state_printf(state, "%"PRIu32, self->mtime);
+ fmt_state_puts(state, " length=");
+ fmt_state_printf(state, "%"PRIu64, self->length);
+ fmt_state_puts(state, " name=");
+ lib9p_s_format(&self->name, state);
+ fmt_state_puts(state, " owner_uname=");
+ lib9p_s_format(&self->owner_uname, state);
+ fmt_state_puts(state, " owner_gname=");
+ lib9p_s_format(&self->owner_gname, state);
+ fmt_state_puts(state, " last_modifier_uname=");
+ lib9p_s_format(&self->last_modifier_uname, state);
#if CONFIG_9P_ENABLE_9P2000_u
- fmt_state_puts(state, " file_extension=");
- lib9p_s_format(&self->file_extension, state);
- fmt_state_puts(state, " file_owner_n_uid=");
- lib9p_nuid_format(&self->file_owner_n_uid, state);
- fmt_state_puts(state, " file_owner_n_gid=");
- lib9p_nuid_format(&self->file_owner_n_gid, state);
- fmt_state_puts(state, " file_last_modified_n_uid=");
- lib9p_nuid_format(&self->file_last_modified_n_uid, state);
+ fmt_state_puts(state, " extension=");
+ lib9p_s_format(&self->extension, state);
+ fmt_state_puts(state, " owner_unum=");
+ lib9p_nuid_format(&self->owner_unum, state);
+ fmt_state_puts(state, " owner_gnum=");
+ lib9p_nuid_format(&self->owner_gnum, state);
+ fmt_state_puts(state, " last_modifier_unum=");
+ lib9p_nuid_format(&self->last_modifier_unum, state);
#endif /* CONFIG_9P_ENABLE_9P2000_u */
fmt_state_puts(state, " }");
}
@@ -5060,7 +5112,7 @@ static void lib9p_o_format(lib9p_o_t *self, struct fmt_state *state) {
}
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static void lib9p_msg_Tversion_format(struct lib9p_msg_Tversion *self, struct fmt_state *state) {
fmt_state_puts(state, "Tversion {");
fmt_state_puts(state, " tag=");
@@ -5083,6 +5135,8 @@ static void lib9p_msg_Rversion_format(struct lib9p_msg_Rversion *self, struct fm
fmt_state_puts(state, " }");
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static void lib9p_msg_Tauth_format(struct lib9p_msg_Tauth *self, struct fmt_state *state) {
fmt_state_puts(state, "Tauth {");
fmt_state_puts(state, " tag=");
@@ -5094,8 +5148,8 @@ static void lib9p_msg_Tauth_format(struct lib9p_msg_Tauth *self, struct fmt_stat
fmt_state_puts(state, " aname=");
lib9p_s_format(&self->aname, state);
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
- fmt_state_puts(state, " n_uid=");
- lib9p_nuid_format(&self->n_uid, state);
+ fmt_state_puts(state, " unum=");
+ lib9p_nuid_format(&self->unum, state);
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
fmt_state_puts(state, " }");
}
@@ -5122,8 +5176,8 @@ static void lib9p_msg_Tattach_format(struct lib9p_msg_Tattach *self, struct fmt_
fmt_state_puts(state, " aname=");
lib9p_s_format(&self->aname, state);
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
- fmt_state_puts(state, " n_uid=");
- lib9p_nuid_format(&self->n_uid, state);
+ fmt_state_puts(state, " unum=");
+ lib9p_nuid_format(&self->unum, state);
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
fmt_state_puts(state, " }");
}
@@ -5137,19 +5191,23 @@ static void lib9p_msg_Rattach_format(struct lib9p_msg_Rattach *self, struct fmt_
fmt_state_puts(state, " }");
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
static void lib9p_msg_Rerror_format(struct lib9p_msg_Rerror *self, struct fmt_state *state) {
fmt_state_puts(state, "Rerror {");
fmt_state_puts(state, " tag=");
lib9p_tag_format(&self->tag, state);
- fmt_state_puts(state, " ename=");
- lib9p_s_format(&self->ename, state);
+ fmt_state_puts(state, " errstr=");
+ lib9p_s_format(&self->errstr, state);
#if CONFIG_9P_ENABLE_9P2000_u
- fmt_state_puts(state, " errno=");
- lib9p_errno_format(&self->errno, state);
+ fmt_state_puts(state, " errnum=");
+ lib9p_errno_format(&self->errnum, state);
#endif /* CONFIG_9P_ENABLE_9P2000_u */
fmt_state_puts(state, " }");
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
static void lib9p_msg_Tflush_format(struct lib9p_msg_Tflush *self, struct fmt_state *state) {
fmt_state_puts(state, "Tflush {");
fmt_state_puts(state, " tag=");
@@ -5179,7 +5237,8 @@ static void lib9p_msg_Twalk_format(struct lib9p_msg_Twalk *self, struct fmt_stat
fmt_state_puts(state, " wname=[");
for (uint16_t i = 0; i < self->nwname; i++) {
if (i)
- fmt_state_puts(state, ", ");
+ fmt_state_putchar(state, ',');
+ fmt_state_putchar(state, ' ');
lib9p_s_format(&self->wname[i], state);
}
fmt_state_puts(state, " ]");
@@ -5195,7 +5254,8 @@ static void lib9p_msg_Rwalk_format(struct lib9p_msg_Rwalk *self, struct fmt_stat
fmt_state_puts(state, " wqid=[");
for (uint16_t i = 0; i < self->nwqid; i++) {
if (i)
- fmt_state_puts(state, ", ");
+ fmt_state_putchar(state, ',');
+ fmt_state_putchar(state, ' ');
lib9p_qid_format(&self->wqid[i], state);
}
fmt_state_puts(state, " ]");
@@ -5273,7 +5333,18 @@ static void lib9p_msg_Rread_format(struct lib9p_msg_Rread *self, struct fmt_stat
lib9p_tag_format(&self->tag, state);
fmt_state_puts(state, " count=");
fmt_state_printf(state, "%"PRIu32, self->count);
- fmt_state_puts(state, " data=<bytedata>");
+ if (is_valid_utf8_without_nul((uint8_t *)self->data, (size_t)self->count)) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
+ fmt_state_printf(state, " data=%.*q%s",
+ (int)(self->count < 50 ? self->count : 50),
+ (char *)self->data,
+ self->count < 50 ? "" : "...");
+#pragma GCC diagnostic pop
+ } else {
+ fmt_state_puts(state, " data=<bytedata>");
+ }
fmt_state_puts(state, " }");
}
@@ -5287,7 +5358,18 @@ static void lib9p_msg_Twrite_format(struct lib9p_msg_Twrite *self, struct fmt_st
fmt_state_printf(state, "%"PRIu64, self->offset);
fmt_state_puts(state, " count=");
fmt_state_printf(state, "%"PRIu32, self->count);
- fmt_state_puts(state, " data=<bytedata>");
+ if (is_valid_utf8_without_nul((uint8_t *)self->data, (size_t)self->count)) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
+ fmt_state_printf(state, " data=%.*q%s",
+ (int)(self->count < 50 ? self->count : 50),
+ (char *)self->data,
+ self->count < 50 ? "" : "...");
+#pragma GCC diagnostic pop
+ } else {
+ fmt_state_puts(state, " data=<bytedata>");
+ }
fmt_state_puts(state, " }");
}
@@ -5413,6 +5495,399 @@ static void lib9p_errno_format(lib9p_errno_t *self, struct fmt_state *state) {
case LIB9P_ERRNO_NOERROR:
fmt_state_puts(state, "NOERROR");
break;
+ case LIB9P_ERRNO_L_EPERM:
+ fmt_state_puts(state, "L_EPERM");
+ break;
+ case LIB9P_ERRNO_L_ENOENT:
+ fmt_state_puts(state, "L_ENOENT");
+ break;
+ case LIB9P_ERRNO_L_ESRCH:
+ fmt_state_puts(state, "L_ESRCH");
+ break;
+ case LIB9P_ERRNO_L_EINTR:
+ fmt_state_puts(state, "L_EINTR");
+ break;
+ case LIB9P_ERRNO_L_EIO:
+ fmt_state_puts(state, "L_EIO");
+ break;
+ case LIB9P_ERRNO_L_ENXIO:
+ fmt_state_puts(state, "L_ENXIO");
+ break;
+ case LIB9P_ERRNO_L_E2BIG:
+ fmt_state_puts(state, "L_E2BIG");
+ break;
+ case LIB9P_ERRNO_L_ENOEXEC:
+ fmt_state_puts(state, "L_ENOEXEC");
+ break;
+ case LIB9P_ERRNO_L_EBADF:
+ fmt_state_puts(state, "L_EBADF");
+ break;
+ case LIB9P_ERRNO_L_ECHILD:
+ fmt_state_puts(state, "L_ECHILD");
+ break;
+ case LIB9P_ERRNO_L_EAGAIN:
+ fmt_state_puts(state, "L_EAGAIN");
+ break;
+ case LIB9P_ERRNO_L_ENOMEM:
+ fmt_state_puts(state, "L_ENOMEM");
+ break;
+ case LIB9P_ERRNO_L_EACCES:
+ fmt_state_puts(state, "L_EACCES");
+ break;
+ case LIB9P_ERRNO_L_EFAULT:
+ fmt_state_puts(state, "L_EFAULT");
+ break;
+ case LIB9P_ERRNO_L_ENOTBLK:
+ fmt_state_puts(state, "L_ENOTBLK");
+ break;
+ case LIB9P_ERRNO_L_EBUSY:
+ fmt_state_puts(state, "L_EBUSY");
+ break;
+ case LIB9P_ERRNO_L_EEXIST:
+ fmt_state_puts(state, "L_EEXIST");
+ break;
+ case LIB9P_ERRNO_L_EXDEV:
+ fmt_state_puts(state, "L_EXDEV");
+ break;
+ case LIB9P_ERRNO_L_ENODEV:
+ fmt_state_puts(state, "L_ENODEV");
+ break;
+ case LIB9P_ERRNO_L_ENOTDIR:
+ fmt_state_puts(state, "L_ENOTDIR");
+ break;
+ case LIB9P_ERRNO_L_EISDIR:
+ fmt_state_puts(state, "L_EISDIR");
+ break;
+ case LIB9P_ERRNO_L_EINVAL:
+ fmt_state_puts(state, "L_EINVAL");
+ break;
+ case LIB9P_ERRNO_L_ENFILE:
+ fmt_state_puts(state, "L_ENFILE");
+ break;
+ case LIB9P_ERRNO_L_EMFILE:
+ fmt_state_puts(state, "L_EMFILE");
+ break;
+ case LIB9P_ERRNO_L_ENOTTY:
+ fmt_state_puts(state, "L_ENOTTY");
+ break;
+ case LIB9P_ERRNO_L_ETXTBSY:
+ fmt_state_puts(state, "L_ETXTBSY");
+ break;
+ case LIB9P_ERRNO_L_EFBIG:
+ fmt_state_puts(state, "L_EFBIG");
+ break;
+ case LIB9P_ERRNO_L_ENOSPC:
+ fmt_state_puts(state, "L_ENOSPC");
+ break;
+ case LIB9P_ERRNO_L_ESPIPE:
+ fmt_state_puts(state, "L_ESPIPE");
+ break;
+ case LIB9P_ERRNO_L_EROFS:
+ fmt_state_puts(state, "L_EROFS");
+ break;
+ case LIB9P_ERRNO_L_EMLINK:
+ fmt_state_puts(state, "L_EMLINK");
+ break;
+ case LIB9P_ERRNO_L_EPIPE:
+ fmt_state_puts(state, "L_EPIPE");
+ break;
+ case LIB9P_ERRNO_L_EDOM:
+ fmt_state_puts(state, "L_EDOM");
+ break;
+ case LIB9P_ERRNO_L_ERANGE:
+ fmt_state_puts(state, "L_ERANGE");
+ break;
+ case LIB9P_ERRNO_L_EDEADLK:
+ fmt_state_puts(state, "L_EDEADLK");
+ break;
+ case LIB9P_ERRNO_L_ENAMETOOLONG:
+ fmt_state_puts(state, "L_ENAMETOOLONG");
+ break;
+ case LIB9P_ERRNO_L_ENOLCK:
+ fmt_state_puts(state, "L_ENOLCK");
+ break;
+ case LIB9P_ERRNO_L_ENOSYS:
+ fmt_state_puts(state, "L_ENOSYS");
+ break;
+ case LIB9P_ERRNO_L_ENOTEMPTY:
+ fmt_state_puts(state, "L_ENOTEMPTY");
+ break;
+ case LIB9P_ERRNO_L_ELOOP:
+ fmt_state_puts(state, "L_ELOOP");
+ break;
+ case LIB9P_ERRNO_L_ENOMSG:
+ fmt_state_puts(state, "L_ENOMSG");
+ break;
+ case LIB9P_ERRNO_L_EIDRM:
+ fmt_state_puts(state, "L_EIDRM");
+ break;
+ case LIB9P_ERRNO_L_ECHRNG:
+ fmt_state_puts(state, "L_ECHRNG");
+ break;
+ case LIB9P_ERRNO_L_EL2NSYNC:
+ fmt_state_puts(state, "L_EL2NSYNC");
+ break;
+ case LIB9P_ERRNO_L_EL3HLT:
+ fmt_state_puts(state, "L_EL3HLT");
+ break;
+ case LIB9P_ERRNO_L_EL3RST:
+ fmt_state_puts(state, "L_EL3RST");
+ break;
+ case LIB9P_ERRNO_L_ELNRNG:
+ fmt_state_puts(state, "L_ELNRNG");
+ break;
+ case LIB9P_ERRNO_L_EUNATCH:
+ fmt_state_puts(state, "L_EUNATCH");
+ break;
+ case LIB9P_ERRNO_L_ENOCSI:
+ fmt_state_puts(state, "L_ENOCSI");
+ break;
+ case LIB9P_ERRNO_L_EL2HLT:
+ fmt_state_puts(state, "L_EL2HLT");
+ break;
+ case LIB9P_ERRNO_L_EBADE:
+ fmt_state_puts(state, "L_EBADE");
+ break;
+ case LIB9P_ERRNO_L_EBADR:
+ fmt_state_puts(state, "L_EBADR");
+ break;
+ case LIB9P_ERRNO_L_EXFULL:
+ fmt_state_puts(state, "L_EXFULL");
+ break;
+ case LIB9P_ERRNO_L_ENOANO:
+ fmt_state_puts(state, "L_ENOANO");
+ break;
+ case LIB9P_ERRNO_L_EBADRQC:
+ fmt_state_puts(state, "L_EBADRQC");
+ break;
+ case LIB9P_ERRNO_L_EBADSLT:
+ fmt_state_puts(state, "L_EBADSLT");
+ break;
+ case LIB9P_ERRNO_L_EBFONT:
+ fmt_state_puts(state, "L_EBFONT");
+ break;
+ case LIB9P_ERRNO_L_ENOSTR:
+ fmt_state_puts(state, "L_ENOSTR");
+ break;
+ case LIB9P_ERRNO_L_ENODATA:
+ fmt_state_puts(state, "L_ENODATA");
+ break;
+ case LIB9P_ERRNO_L_ETIME:
+ fmt_state_puts(state, "L_ETIME");
+ break;
+ case LIB9P_ERRNO_L_ENOSR:
+ fmt_state_puts(state, "L_ENOSR");
+ break;
+ case LIB9P_ERRNO_L_ENONET:
+ fmt_state_puts(state, "L_ENONET");
+ break;
+ case LIB9P_ERRNO_L_ENOPKG:
+ fmt_state_puts(state, "L_ENOPKG");
+ break;
+ case LIB9P_ERRNO_L_EREMOTE:
+ fmt_state_puts(state, "L_EREMOTE");
+ break;
+ case LIB9P_ERRNO_L_ENOLINK:
+ fmt_state_puts(state, "L_ENOLINK");
+ break;
+ case LIB9P_ERRNO_L_EADV:
+ fmt_state_puts(state, "L_EADV");
+ break;
+ case LIB9P_ERRNO_L_ESRMNT:
+ fmt_state_puts(state, "L_ESRMNT");
+ break;
+ case LIB9P_ERRNO_L_ECOMM:
+ fmt_state_puts(state, "L_ECOMM");
+ break;
+ case LIB9P_ERRNO_L_EPROTO:
+ fmt_state_puts(state, "L_EPROTO");
+ break;
+ case LIB9P_ERRNO_L_EMULTIHOP:
+ fmt_state_puts(state, "L_EMULTIHOP");
+ break;
+ case LIB9P_ERRNO_L_EDOTDOT:
+ fmt_state_puts(state, "L_EDOTDOT");
+ break;
+ case LIB9P_ERRNO_L_EBADMSG:
+ fmt_state_puts(state, "L_EBADMSG");
+ break;
+ case LIB9P_ERRNO_L_EOVERFLOW:
+ fmt_state_puts(state, "L_EOVERFLOW");
+ break;
+ case LIB9P_ERRNO_L_ENOTUNIQ:
+ fmt_state_puts(state, "L_ENOTUNIQ");
+ break;
+ case LIB9P_ERRNO_L_EBADFD:
+ fmt_state_puts(state, "L_EBADFD");
+ break;
+ case LIB9P_ERRNO_L_EREMCHG:
+ fmt_state_puts(state, "L_EREMCHG");
+ break;
+ case LIB9P_ERRNO_L_ELIBACC:
+ fmt_state_puts(state, "L_ELIBACC");
+ break;
+ case LIB9P_ERRNO_L_ELIBBAD:
+ fmt_state_puts(state, "L_ELIBBAD");
+ break;
+ case LIB9P_ERRNO_L_ELIBSCN:
+ fmt_state_puts(state, "L_ELIBSCN");
+ break;
+ case LIB9P_ERRNO_L_ELIBMAX:
+ fmt_state_puts(state, "L_ELIBMAX");
+ break;
+ case LIB9P_ERRNO_L_ELIBEXEC:
+ fmt_state_puts(state, "L_ELIBEXEC");
+ break;
+ case LIB9P_ERRNO_L_EILSEQ:
+ fmt_state_puts(state, "L_EILSEQ");
+ break;
+ case LIB9P_ERRNO_L_ERESTART:
+ fmt_state_puts(state, "L_ERESTART");
+ break;
+ case LIB9P_ERRNO_L_ESTRPIPE:
+ fmt_state_puts(state, "L_ESTRPIPE");
+ break;
+ case LIB9P_ERRNO_L_EUSERS:
+ fmt_state_puts(state, "L_EUSERS");
+ break;
+ case LIB9P_ERRNO_L_ENOTSOCK:
+ fmt_state_puts(state, "L_ENOTSOCK");
+ break;
+ case LIB9P_ERRNO_L_EDESTADDRREQ:
+ fmt_state_puts(state, "L_EDESTADDRREQ");
+ break;
+ case LIB9P_ERRNO_L_EMSGSIZE:
+ fmt_state_puts(state, "L_EMSGSIZE");
+ break;
+ case LIB9P_ERRNO_L_EPROTOTYPE:
+ fmt_state_puts(state, "L_EPROTOTYPE");
+ break;
+ case LIB9P_ERRNO_L_ENOPROTOOPT:
+ fmt_state_puts(state, "L_ENOPROTOOPT");
+ break;
+ case LIB9P_ERRNO_L_EPROTONOSUPPORT:
+ fmt_state_puts(state, "L_EPROTONOSUPPORT");
+ break;
+ case LIB9P_ERRNO_L_ESOCKTNOSUPPORT:
+ fmt_state_puts(state, "L_ESOCKTNOSUPPORT");
+ break;
+ case LIB9P_ERRNO_L_EOPNOTSUPP:
+ fmt_state_puts(state, "L_EOPNOTSUPP");
+ break;
+ case LIB9P_ERRNO_L_EPFNOSUPPORT:
+ fmt_state_puts(state, "L_EPFNOSUPPORT");
+ break;
+ case LIB9P_ERRNO_L_EAFNOSUPPORT:
+ fmt_state_puts(state, "L_EAFNOSUPPORT");
+ break;
+ case LIB9P_ERRNO_L_EADDRINUSE:
+ fmt_state_puts(state, "L_EADDRINUSE");
+ break;
+ case LIB9P_ERRNO_L_EADDRNOTAVAIL:
+ fmt_state_puts(state, "L_EADDRNOTAVAIL");
+ break;
+ case LIB9P_ERRNO_L_ENETDOWN:
+ fmt_state_puts(state, "L_ENETDOWN");
+ break;
+ case LIB9P_ERRNO_L_ENETUNREACH:
+ fmt_state_puts(state, "L_ENETUNREACH");
+ break;
+ case LIB9P_ERRNO_L_ENETRESET:
+ fmt_state_puts(state, "L_ENETRESET");
+ break;
+ case LIB9P_ERRNO_L_ECONNABORTED:
+ fmt_state_puts(state, "L_ECONNABORTED");
+ break;
+ case LIB9P_ERRNO_L_ECONNRESET:
+ fmt_state_puts(state, "L_ECONNRESET");
+ break;
+ case LIB9P_ERRNO_L_ENOBUFS:
+ fmt_state_puts(state, "L_ENOBUFS");
+ break;
+ case LIB9P_ERRNO_L_EISCONN:
+ fmt_state_puts(state, "L_EISCONN");
+ break;
+ case LIB9P_ERRNO_L_ENOTCONN:
+ fmt_state_puts(state, "L_ENOTCONN");
+ break;
+ case LIB9P_ERRNO_L_ESHUTDOWN:
+ fmt_state_puts(state, "L_ESHUTDOWN");
+ break;
+ case LIB9P_ERRNO_L_ETOOMANYREFS:
+ fmt_state_puts(state, "L_ETOOMANYREFS");
+ break;
+ case LIB9P_ERRNO_L_ETIMEDOUT:
+ fmt_state_puts(state, "L_ETIMEDOUT");
+ break;
+ case LIB9P_ERRNO_L_ECONNREFUSED:
+ fmt_state_puts(state, "L_ECONNREFUSED");
+ break;
+ case LIB9P_ERRNO_L_EHOSTDOWN:
+ fmt_state_puts(state, "L_EHOSTDOWN");
+ break;
+ case LIB9P_ERRNO_L_EHOSTUNREACH:
+ fmt_state_puts(state, "L_EHOSTUNREACH");
+ break;
+ case LIB9P_ERRNO_L_EALREADY:
+ fmt_state_puts(state, "L_EALREADY");
+ break;
+ case LIB9P_ERRNO_L_EINPROGRESS:
+ fmt_state_puts(state, "L_EINPROGRESS");
+ break;
+ case LIB9P_ERRNO_L_ESTALE:
+ fmt_state_puts(state, "L_ESTALE");
+ break;
+ case LIB9P_ERRNO_L_EUCLEAN:
+ fmt_state_puts(state, "L_EUCLEAN");
+ break;
+ case LIB9P_ERRNO_L_ENOTNAM:
+ fmt_state_puts(state, "L_ENOTNAM");
+ break;
+ case LIB9P_ERRNO_L_ENAVAIL:
+ fmt_state_puts(state, "L_ENAVAIL");
+ break;
+ case LIB9P_ERRNO_L_EISNAM:
+ fmt_state_puts(state, "L_EISNAM");
+ break;
+ case LIB9P_ERRNO_L_EREMOTEIO:
+ fmt_state_puts(state, "L_EREMOTEIO");
+ break;
+ case LIB9P_ERRNO_L_EDQUOT:
+ fmt_state_puts(state, "L_EDQUOT");
+ break;
+ case LIB9P_ERRNO_L_ENOMEDIUM:
+ fmt_state_puts(state, "L_ENOMEDIUM");
+ break;
+ case LIB9P_ERRNO_L_EMEDIUMTYPE:
+ fmt_state_puts(state, "L_EMEDIUMTYPE");
+ break;
+ case LIB9P_ERRNO_L_ECANCELED:
+ fmt_state_puts(state, "L_ECANCELED");
+ break;
+ case LIB9P_ERRNO_L_ENOKEY:
+ fmt_state_puts(state, "L_ENOKEY");
+ break;
+ case LIB9P_ERRNO_L_EKEYEXPIRED:
+ fmt_state_puts(state, "L_EKEYEXPIRED");
+ break;
+ case LIB9P_ERRNO_L_EKEYREVOKED:
+ fmt_state_puts(state, "L_EKEYREVOKED");
+ break;
+ case LIB9P_ERRNO_L_EKEYREJECTED:
+ fmt_state_puts(state, "L_EKEYREJECTED");
+ break;
+ case LIB9P_ERRNO_L_EOWNERDEAD:
+ fmt_state_puts(state, "L_EOWNERDEAD");
+ break;
+ case LIB9P_ERRNO_L_ENOTRECOVERABLE:
+ fmt_state_puts(state, "L_ENOTRECOVERABLE");
+ break;
+ case LIB9P_ERRNO_L_ERFKILL:
+ fmt_state_puts(state, "L_ERFKILL");
+ break;
+ case LIB9P_ERRNO_L_EHWPOISON:
+ fmt_state_puts(state, "L_EHWPOISON");
+ break;
default:
fmt_state_printf(state, "%"PRIu32, *self);
}
@@ -6752,8 +7227,8 @@ static void lib9p_msg_Rlerror_format(struct lib9p_msg_Rlerror *self, struct fmt_
fmt_state_puts(state, "Rlerror {");
fmt_state_puts(state, " tag=");
lib9p_tag_format(&self->tag, state);
- fmt_state_puts(state, " ecode=");
- lib9p_errno_format(&self->ecode, state);
+ fmt_state_puts(state, " errnum=");
+ lib9p_errno_format(&self->errnum, state);
fmt_state_puts(state, " }");
}
@@ -7086,7 +7561,18 @@ static void lib9p_msg_Rreaddir_format(struct lib9p_msg_Rreaddir *self, struct fm
lib9p_tag_format(&self->tag, state);
fmt_state_puts(state, " count=");
fmt_state_printf(state, "%"PRIu32, self->count);
- fmt_state_puts(state, " data=<bytedata>");
+ if (is_valid_utf8_without_nul((uint8_t *)self->data, (size_t)self->count)) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
+ fmt_state_printf(state, " data=%.*q%s",
+ (int)(self->count < 50 ? self->count : 50),
+ (char *)self->data,
+ self->count < 50 ? "" : "...");
+#pragma GCC diagnostic pop
+ } else {
+ fmt_state_puts(state, " data=<bytedata>");
+ }
fmt_state_puts(state, " }");
}
@@ -7289,7 +7775,8 @@ static void lib9p_msg_Tsread_format(struct lib9p_msg_Tsread *self, struct fmt_st
fmt_state_puts(state, " wname=[");
for (uint16_t i = 0; i < self->nwname; i++) {
if (i)
- fmt_state_puts(state, ", ");
+ fmt_state_putchar(state, ',');
+ fmt_state_putchar(state, ' ');
lib9p_s_format(&self->wname[i], state);
}
fmt_state_puts(state, " ]");
@@ -7302,7 +7789,18 @@ static void lib9p_msg_Rsread_format(struct lib9p_msg_Rsread *self, struct fmt_st
lib9p_tag_format(&self->tag, state);
fmt_state_puts(state, " count=");
fmt_state_printf(state, "%"PRIu32, self->count);
- fmt_state_puts(state, " data=<bytedata>");
+ if (is_valid_utf8_without_nul((uint8_t *)self->data, (size_t)self->count)) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
+ fmt_state_printf(state, " data=%.*q%s",
+ (int)(self->count < 50 ? self->count : 50),
+ (char *)self->data,
+ self->count < 50 ? "" : "...");
+#pragma GCC diagnostic pop
+ } else {
+ fmt_state_puts(state, " data=<bytedata>");
+ }
fmt_state_puts(state, " }");
}
@@ -7317,13 +7815,25 @@ static void lib9p_msg_Tswrite_format(struct lib9p_msg_Tswrite *self, struct fmt_
fmt_state_puts(state, " wname=[");
for (uint16_t i = 0; i < self->nwname; i++) {
if (i)
- fmt_state_puts(state, ", ");
+ fmt_state_putchar(state, ',');
+ fmt_state_putchar(state, ' ');
lib9p_s_format(&self->wname[i], state);
}
fmt_state_puts(state, " ]");
fmt_state_puts(state, " count=");
fmt_state_printf(state, "%"PRIu32, self->count);
- fmt_state_puts(state, " data=<bytedata>");
+ if (is_valid_utf8_without_nul((uint8_t *)self->data, (size_t)self->count)) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+#pragma GCC diagnostic ignored "-Wformat-extra-args"
+ fmt_state_printf(state, " data=%.*q%s",
+ (int)(self->count < 50 ? self->count : 50),
+ (char *)self->data,
+ self->count < 50 ? "" : "...");
+#pragma GCC diagnostic pop
+ } else {
+ fmt_state_puts(state, " data=<bytedata>");
+ }
fmt_state_puts(state, " }");
}
@@ -7340,12 +7850,11 @@ static void lib9p_msg_Rswrite_format(struct lib9p_msg_Rswrite *self, struct fmt_
/* tables.h *******************************************************************/
const struct _lib9p_ver_tentry _lib9p_table_ver[LIB9P_VER_NUM] = {
- [LIB9P_VER_unknown] = {.name="unknown", .min_msg_size=9},
#if CONFIG_9P_ENABLE_9P2000
[LIB9P_VER_9P2000] = {.name="9P2000", .min_msg_size=9},
#endif /* CONFIG_9P_ENABLE_9P2000 */
#if CONFIG_9P_ENABLE_9P2000_L
- [LIB9P_VER_9P2000_L] = {.name="9P2000.L", .min_msg_size=9},
+ [LIB9P_VER_9P2000_L] = {.name="9P2000.L", .min_msg_size=11},
#endif /* CONFIG_9P_ENABLE_9P2000_L */
#if CONFIG_9P_ENABLE_9P2000_e
[LIB9P_VER_9P2000_e] = {.name="9P2000.e", .min_msg_size=9},
@@ -7356,6 +7865,9 @@ const struct _lib9p_ver_tentry _lib9p_table_ver[LIB9P_VER_NUM] = {
#if CONFIG_9P_ENABLE_9P2000_u
[LIB9P_VER_9P2000_u] = {.name="9P2000.u", .min_msg_size=13},
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = {.name="unknown", .min_msg_size=9},
+#endif /* CONFIG_9P_ENABLE_unknown */
};
#define _MSG(typ) [LIB9P_TYP_##typ] = { \
@@ -7363,11 +7875,6 @@ const struct _lib9p_ver_tentry _lib9p_table_ver[LIB9P_VER_NUM] = {
.box_as_fmt_formatter = (_box_as_fmt_formatter_fn_t)lo_box_lib9p_msg_##typ##_as_fmt_formatter, \
}
const struct _lib9p_msg_tentry _lib9p_table_msg[LIB9P_VER_NUM][0x100] = {
- [LIB9P_VER_unknown] = {
- _MSG(Tversion),
- _MSG(Rversion),
- _MSG(Rerror),
- },
#if CONFIG_9P_ENABLE_9P2000
[LIB9P_VER_9P2000] = {
_MSG(Tversion),
@@ -7446,7 +7953,6 @@ const struct _lib9p_msg_tentry _lib9p_table_msg[LIB9P_VER_NUM][0x100] = {
_MSG(Rauth),
_MSG(Tattach),
_MSG(Rattach),
- _MSG(Rerror),
_MSG(Tflush),
_MSG(Rflush),
_MSG(Twalk),
@@ -7562,6 +8068,13 @@ const struct _lib9p_msg_tentry _lib9p_table_msg[LIB9P_VER_NUM][0x100] = {
_MSG(Rwstat),
},
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = {
+ _MSG(Tversion),
+ _MSG(Rversion),
+ _MSG(Rerror),
+ },
+#endif /* CONFIG_9P_ENABLE_unknown */
};
#define _MSG_RECV(typ) [LIB9P_TYP_##typ/2] = { \
@@ -7573,9 +8086,6 @@ const struct _lib9p_msg_tentry _lib9p_table_msg[LIB9P_VER_NUM][0x100] = {
}
const struct _lib9p_recv_tentry _lib9p_table_Tmsg_recv[LIB9P_VER_NUM][0x80] = {
- [LIB9P_VER_unknown] = {
- _MSG_RECV(Tversion),
- },
#if CONFIG_9P_ENABLE_9P2000
[LIB9P_VER_9P2000] = {
_MSG_RECV(Tversion),
@@ -7680,13 +8190,14 @@ const struct _lib9p_recv_tentry _lib9p_table_Tmsg_recv[LIB9P_VER_NUM][0x80] = {
_MSG_RECV(Twstat),
},
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = {
+ _MSG_RECV(Tversion),
+ },
+#endif /* CONFIG_9P_ENABLE_unknown */
};
const struct _lib9p_recv_tentry _lib9p_table_Rmsg_recv[LIB9P_VER_NUM][0x80] = {
- [LIB9P_VER_unknown] = {
- _MSG_RECV(Rversion),
- _MSG_RECV(Rerror),
- },
#if CONFIG_9P_ENABLE_9P2000
[LIB9P_VER_9P2000] = {
_MSG_RECV(Rversion),
@@ -7730,7 +8241,6 @@ const struct _lib9p_recv_tentry _lib9p_table_Rmsg_recv[LIB9P_VER_NUM][0x80] = {
_MSG_RECV(Rversion),
_MSG_RECV(Rauth),
_MSG_RECV(Rattach),
- _MSG_RECV(Rerror),
_MSG_RECV(Rflush),
_MSG_RECV(Rwalk),
_MSG_RECV(Rread),
@@ -7797,12 +8307,15 @@ const struct _lib9p_recv_tentry _lib9p_table_Rmsg_recv[LIB9P_VER_NUM][0x80] = {
_MSG_RECV(Rwstat),
},
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = {
+ _MSG_RECV(Rversion),
+ _MSG_RECV(Rerror),
+ },
+#endif /* CONFIG_9P_ENABLE_unknown */
};
const struct _lib9p_send_tentry _lib9p_table_Tmsg_send[LIB9P_VER_NUM][0x80] = {
- [LIB9P_VER_unknown] = {
- _MSG_SEND(Tversion),
- },
#if CONFIG_9P_ENABLE_9P2000
[LIB9P_VER_9P2000] = {
_MSG_SEND(Tversion),
@@ -7907,13 +8420,14 @@ const struct _lib9p_send_tentry _lib9p_table_Tmsg_send[LIB9P_VER_NUM][0x80] = {
_MSG_SEND(Twstat),
},
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = {
+ _MSG_SEND(Tversion),
+ },
+#endif /* CONFIG_9P_ENABLE_unknown */
};
const struct _lib9p_send_tentry _lib9p_table_Rmsg_send[LIB9P_VER_NUM][0x80] = {
- [LIB9P_VER_unknown] = {
- _MSG_SEND(Rversion),
- _MSG_SEND(Rerror),
- },
#if CONFIG_9P_ENABLE_9P2000
[LIB9P_VER_9P2000] = {
_MSG_SEND(Rversion),
@@ -7957,7 +8471,6 @@ const struct _lib9p_send_tentry _lib9p_table_Rmsg_send[LIB9P_VER_NUM][0x80] = {
_MSG_SEND(Rversion),
_MSG_SEND(Rauth),
_MSG_SEND(Rattach),
- _MSG_SEND(Rerror),
_MSG_SEND(Rflush),
_MSG_SEND(Rwalk),
_MSG_SEND(Rread),
@@ -8024,8 +8537,15 @@ const struct _lib9p_send_tentry _lib9p_table_Rmsg_send[LIB9P_VER_NUM][0x80] = {
_MSG_SEND(Rwstat),
},
#endif /* CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_unknown
+ [LIB9P_VER_unknown] = {
+ _MSG_SEND(Rversion),
+ _MSG_SEND(Rerror),
+ },
+#endif /* CONFIG_9P_ENABLE_unknown */
};
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
LM_FLATTEN ssize_t _lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size) {
return validate_stat(ctx, net_size, net_bytes, ret_net_size);
}
@@ -8035,3 +8555,4 @@ LM_FLATTEN void _lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
LM_FLATTEN bool _lib9p_stat_marshal(struct lib9p_ctx *ctx, struct lib9p_stat *val, struct _marshal_ret *ret) {
return marshal_stat(ctx, val, ret);
}
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
diff --git a/lib9p/include/lib9p/9p.generated.h b/lib9p/core_include/lib9p/_core_generated.h
index 7e901a3..4c45b58 100644
--- a/lib9p/include/lib9p/9p.generated.h
+++ b/lib9p/core_include/lib9p/_core_generated.h
@@ -1,13 +1,13 @@
-/* Generated by `lib9p/proto.gen lib9p/idl/2002-9P2000.9p lib9p/idl/2003-9P2000.p9p.9p lib9p/idl/2005-9P2000.u.9p lib9p/idl/2010-9P2000.L.9p lib9p/idl/2012-9P2000.e.9p`. DO NOT EDIT! */
+/* Generated by `lib9p/core.gen lib9p/idl/0000-uninitialized.9p lib9p/idl/2002-9P2000.9p lib9p/idl/2003-9P2000.p9p.9p lib9p/idl/2005-9P2000.u.9p lib9p/idl/2010-9P2000.L.9p lib9p/idl/2012-9P2000.e.9p`. DO NOT EDIT! */
-#ifndef _LIB9P_9P_H_
- #error Do not include <lib9p/9p.generated.h> directly; include <lib9p/9p.h> instead
+#ifndef _LIB9P_CORE_H_
+ #error Do not include <lib9p/_core_generated.h> directly; include <lib9p/core.h> instead
#endif
#include <stdint.h> /* for uint{n}_t types */
#include <libfmt/fmt.h> /* for fmt_formatter */
-#include <libhw/generic/net.h> /* for struct iovec */
+#include <libhw/generic/io.h> /* for struct iovec */
/* config *********************************************************************/
@@ -40,6 +40,12 @@
#error config.h must define CONFIG_9P_ENABLE_9P2000_u
#endif
+#ifndef CONFIG_9P_ENABLE_unknown
+ #error config.h must define CONFIG_9P_ENABLE_unknown
+#endif
+
+#define _LIB9P_ENABLE_stat CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+
/* enum version ***************************************************************/
enum lib9p_version {
@@ -111,14 +117,20 @@ enum lib9p_msg_type { /* uint8_t */
LIB9P_TYP_Topenfd = 98,
LIB9P_TYP_Ropenfd = 99,
#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
LIB9P_TYP_Tversion = 100,
LIB9P_TYP_Rversion = 101,
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
LIB9P_TYP_Tauth = 102,
LIB9P_TYP_Rauth = 103,
LIB9P_TYP_Tattach = 104,
LIB9P_TYP_Rattach = 105,
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
LIB9P_TYP_Rerror = 107,
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
LIB9P_TYP_Tflush = 108,
LIB9P_TYP_Rflush = 109,
LIB9P_TYP_Twalk = 110,
@@ -159,7 +171,7 @@ LO_IMPLEMENTATION_H(fmt_formatter, enum lib9p_msg_type, lib9p_msg_type);
/* payload types **************************************************************/
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
/* size = 2 ; max_iov = 1 ; max_copy = 2 */
typedef uint16_t lib9p_tag_t;
LO_IMPLEMENTATION_H(fmt_formatter, lib9p_tag_t, lib9p_tag);
@@ -170,15 +182,8 @@ typedef uint32_t lib9p_fid_t;
LO_IMPLEMENTATION_H(fmt_formatter, lib9p_fid_t, lib9p_fid);
#define LIB9P_FID_NOFID ((lib9p_fid_t)(UINT32_MAX))
-/* min_size = 2 ; exp_size = 29 ; max_size = 65,537 ; max_iov = 2 ; max_copy = 2 */
-struct lib9p_s {
- uint16_t len;
- [[gnu::nonstring]] char *utf8;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_s, lib9p_s);
-
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_dm_t;
LO_IMPLEMENTATION_H(fmt_formatter, lib9p_dm_t, lib9p_dm);
@@ -222,8 +227,8 @@ LO_IMPLEMENTATION_H(fmt_formatter, lib9p_dm_t, lib9p_dm);
/* masks */
#define LIB9P_DM_PERM_MASK ((lib9p_dm_t)(0b000000000000000000000111111111))
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_qt_t;
LO_IMPLEMENTATION_H(fmt_formatter, lib9p_qt_t, lib9p_qt);
@@ -241,14 +246,7 @@ LO_IMPLEMENTATION_H(fmt_formatter, lib9p_qt_t, lib9p_qt);
/* aliases */
#define LIB9P_QT_FILE ((lib9p_qt_t)(0))
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
-/* size = 4 ; max_iov = 1 ; max_copy = 4 */
-typedef uint32_t lib9p_nuid_t;
-LO_IMPLEMENTATION_H(fmt_formatter, lib9p_nuid_t, lib9p_nuid);
-#define LIB9P_NUID_NONUID ((lib9p_nuid_t)(UINT32_MAX))
-
-#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
/* size = 1 ; max_iov = 1 ; max_copy = 1 */
typedef uint8_t lib9p_o_t;
@@ -274,9 +272,145 @@ LO_IMPLEMENTATION_H(fmt_formatter, lib9p_o_t, lib9p_o);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
/* size = 4 ; max_iov = 1 ; max_copy = 4 */
+typedef uint32_t lib9p_nuid_t;
+LO_IMPLEMENTATION_H(fmt_formatter, lib9p_nuid_t, lib9p_nuid);
+#define LIB9P_NUID_NONUID ((lib9p_nuid_t)(UINT32_MAX))
+
+/* size = 4 ; max_iov = 1 ; max_copy = 4 */
typedef uint32_t lib9p_errno_t;
LO_IMPLEMENTATION_H(fmt_formatter, lib9p_errno_t, lib9p_errno);
-#define LIB9P_ERRNO_NOERROR ((lib9p_errno_t)(0))
+#define LIB9P_ERRNO_NOERROR ((lib9p_errno_t)(0))
+#define LIB9P_ERRNO_L_EPERM ((lib9p_errno_t)(1))
+#define LIB9P_ERRNO_L_ENOENT ((lib9p_errno_t)(2))
+#define LIB9P_ERRNO_L_ESRCH ((lib9p_errno_t)(3))
+#define LIB9P_ERRNO_L_EINTR ((lib9p_errno_t)(4))
+#define LIB9P_ERRNO_L_EIO ((lib9p_errno_t)(5))
+#define LIB9P_ERRNO_L_ENXIO ((lib9p_errno_t)(6))
+#define LIB9P_ERRNO_L_E2BIG ((lib9p_errno_t)(7))
+#define LIB9P_ERRNO_L_ENOEXEC ((lib9p_errno_t)(8))
+#define LIB9P_ERRNO_L_EBADF ((lib9p_errno_t)(9))
+#define LIB9P_ERRNO_L_ECHILD ((lib9p_errno_t)(10))
+#define LIB9P_ERRNO_L_EAGAIN ((lib9p_errno_t)(11))
+#define LIB9P_ERRNO_L_ENOMEM ((lib9p_errno_t)(12))
+#define LIB9P_ERRNO_L_EACCES ((lib9p_errno_t)(13))
+#define LIB9P_ERRNO_L_EFAULT ((lib9p_errno_t)(14))
+#define LIB9P_ERRNO_L_ENOTBLK ((lib9p_errno_t)(15))
+#define LIB9P_ERRNO_L_EBUSY ((lib9p_errno_t)(16))
+#define LIB9P_ERRNO_L_EEXIST ((lib9p_errno_t)(17))
+#define LIB9P_ERRNO_L_EXDEV ((lib9p_errno_t)(18))
+#define LIB9P_ERRNO_L_ENODEV ((lib9p_errno_t)(19))
+#define LIB9P_ERRNO_L_ENOTDIR ((lib9p_errno_t)(20))
+#define LIB9P_ERRNO_L_EISDIR ((lib9p_errno_t)(21))
+#define LIB9P_ERRNO_L_EINVAL ((lib9p_errno_t)(22))
+#define LIB9P_ERRNO_L_ENFILE ((lib9p_errno_t)(23))
+#define LIB9P_ERRNO_L_EMFILE ((lib9p_errno_t)(24))
+#define LIB9P_ERRNO_L_ENOTTY ((lib9p_errno_t)(25))
+#define LIB9P_ERRNO_L_ETXTBSY ((lib9p_errno_t)(26))
+#define LIB9P_ERRNO_L_EFBIG ((lib9p_errno_t)(27))
+#define LIB9P_ERRNO_L_ENOSPC ((lib9p_errno_t)(28))
+#define LIB9P_ERRNO_L_ESPIPE ((lib9p_errno_t)(29))
+#define LIB9P_ERRNO_L_EROFS ((lib9p_errno_t)(30))
+#define LIB9P_ERRNO_L_EMLINK ((lib9p_errno_t)(31))
+#define LIB9P_ERRNO_L_EPIPE ((lib9p_errno_t)(32))
+#define LIB9P_ERRNO_L_EDOM ((lib9p_errno_t)(33))
+#define LIB9P_ERRNO_L_ERANGE ((lib9p_errno_t)(34))
+#define LIB9P_ERRNO_L_EDEADLK ((lib9p_errno_t)(35))
+#define LIB9P_ERRNO_L_ENAMETOOLONG ((lib9p_errno_t)(36))
+#define LIB9P_ERRNO_L_ENOLCK ((lib9p_errno_t)(37))
+#define LIB9P_ERRNO_L_ENOSYS ((lib9p_errno_t)(38))
+#define LIB9P_ERRNO_L_ENOTEMPTY ((lib9p_errno_t)(39))
+#define LIB9P_ERRNO_L_ELOOP ((lib9p_errno_t)(40))
+#define LIB9P_ERRNO_L_ENOMSG ((lib9p_errno_t)(42))
+#define LIB9P_ERRNO_L_EIDRM ((lib9p_errno_t)(43))
+#define LIB9P_ERRNO_L_ECHRNG ((lib9p_errno_t)(44))
+#define LIB9P_ERRNO_L_EL2NSYNC ((lib9p_errno_t)(45))
+#define LIB9P_ERRNO_L_EL3HLT ((lib9p_errno_t)(46))
+#define LIB9P_ERRNO_L_EL3RST ((lib9p_errno_t)(47))
+#define LIB9P_ERRNO_L_ELNRNG ((lib9p_errno_t)(48))
+#define LIB9P_ERRNO_L_EUNATCH ((lib9p_errno_t)(49))
+#define LIB9P_ERRNO_L_ENOCSI ((lib9p_errno_t)(50))
+#define LIB9P_ERRNO_L_EL2HLT ((lib9p_errno_t)(51))
+#define LIB9P_ERRNO_L_EBADE ((lib9p_errno_t)(52))
+#define LIB9P_ERRNO_L_EBADR ((lib9p_errno_t)(53))
+#define LIB9P_ERRNO_L_EXFULL ((lib9p_errno_t)(54))
+#define LIB9P_ERRNO_L_ENOANO ((lib9p_errno_t)(55))
+#define LIB9P_ERRNO_L_EBADRQC ((lib9p_errno_t)(56))
+#define LIB9P_ERRNO_L_EBADSLT ((lib9p_errno_t)(57))
+#define LIB9P_ERRNO_L_EBFONT ((lib9p_errno_t)(59))
+#define LIB9P_ERRNO_L_ENOSTR ((lib9p_errno_t)(60))
+#define LIB9P_ERRNO_L_ENODATA ((lib9p_errno_t)(61))
+#define LIB9P_ERRNO_L_ETIME ((lib9p_errno_t)(62))
+#define LIB9P_ERRNO_L_ENOSR ((lib9p_errno_t)(63))
+#define LIB9P_ERRNO_L_ENONET ((lib9p_errno_t)(64))
+#define LIB9P_ERRNO_L_ENOPKG ((lib9p_errno_t)(65))
+#define LIB9P_ERRNO_L_EREMOTE ((lib9p_errno_t)(66))
+#define LIB9P_ERRNO_L_ENOLINK ((lib9p_errno_t)(67))
+#define LIB9P_ERRNO_L_EADV ((lib9p_errno_t)(68))
+#define LIB9P_ERRNO_L_ESRMNT ((lib9p_errno_t)(69))
+#define LIB9P_ERRNO_L_ECOMM ((lib9p_errno_t)(70))
+#define LIB9P_ERRNO_L_EPROTO ((lib9p_errno_t)(71))
+#define LIB9P_ERRNO_L_EMULTIHOP ((lib9p_errno_t)(72))
+#define LIB9P_ERRNO_L_EDOTDOT ((lib9p_errno_t)(73))
+#define LIB9P_ERRNO_L_EBADMSG ((lib9p_errno_t)(74))
+#define LIB9P_ERRNO_L_EOVERFLOW ((lib9p_errno_t)(75))
+#define LIB9P_ERRNO_L_ENOTUNIQ ((lib9p_errno_t)(76))
+#define LIB9P_ERRNO_L_EBADFD ((lib9p_errno_t)(77))
+#define LIB9P_ERRNO_L_EREMCHG ((lib9p_errno_t)(78))
+#define LIB9P_ERRNO_L_ELIBACC ((lib9p_errno_t)(79))
+#define LIB9P_ERRNO_L_ELIBBAD ((lib9p_errno_t)(80))
+#define LIB9P_ERRNO_L_ELIBSCN ((lib9p_errno_t)(81))
+#define LIB9P_ERRNO_L_ELIBMAX ((lib9p_errno_t)(82))
+#define LIB9P_ERRNO_L_ELIBEXEC ((lib9p_errno_t)(83))
+#define LIB9P_ERRNO_L_EILSEQ ((lib9p_errno_t)(84))
+#define LIB9P_ERRNO_L_ERESTART ((lib9p_errno_t)(85))
+#define LIB9P_ERRNO_L_ESTRPIPE ((lib9p_errno_t)(86))
+#define LIB9P_ERRNO_L_EUSERS ((lib9p_errno_t)(87))
+#define LIB9P_ERRNO_L_ENOTSOCK ((lib9p_errno_t)(88))
+#define LIB9P_ERRNO_L_EDESTADDRREQ ((lib9p_errno_t)(89))
+#define LIB9P_ERRNO_L_EMSGSIZE ((lib9p_errno_t)(90))
+#define LIB9P_ERRNO_L_EPROTOTYPE ((lib9p_errno_t)(91))
+#define LIB9P_ERRNO_L_ENOPROTOOPT ((lib9p_errno_t)(92))
+#define LIB9P_ERRNO_L_EPROTONOSUPPORT ((lib9p_errno_t)(93))
+#define LIB9P_ERRNO_L_ESOCKTNOSUPPORT ((lib9p_errno_t)(94))
+#define LIB9P_ERRNO_L_EOPNOTSUPP ((lib9p_errno_t)(95))
+#define LIB9P_ERRNO_L_EPFNOSUPPORT ((lib9p_errno_t)(96))
+#define LIB9P_ERRNO_L_EAFNOSUPPORT ((lib9p_errno_t)(97))
+#define LIB9P_ERRNO_L_EADDRINUSE ((lib9p_errno_t)(98))
+#define LIB9P_ERRNO_L_EADDRNOTAVAIL ((lib9p_errno_t)(99))
+#define LIB9P_ERRNO_L_ENETDOWN ((lib9p_errno_t)(100))
+#define LIB9P_ERRNO_L_ENETUNREACH ((lib9p_errno_t)(101))
+#define LIB9P_ERRNO_L_ENETRESET ((lib9p_errno_t)(102))
+#define LIB9P_ERRNO_L_ECONNABORTED ((lib9p_errno_t)(103))
+#define LIB9P_ERRNO_L_ECONNRESET ((lib9p_errno_t)(104))
+#define LIB9P_ERRNO_L_ENOBUFS ((lib9p_errno_t)(105))
+#define LIB9P_ERRNO_L_EISCONN ((lib9p_errno_t)(106))
+#define LIB9P_ERRNO_L_ENOTCONN ((lib9p_errno_t)(107))
+#define LIB9P_ERRNO_L_ESHUTDOWN ((lib9p_errno_t)(108))
+#define LIB9P_ERRNO_L_ETOOMANYREFS ((lib9p_errno_t)(109))
+#define LIB9P_ERRNO_L_ETIMEDOUT ((lib9p_errno_t)(110))
+#define LIB9P_ERRNO_L_ECONNREFUSED ((lib9p_errno_t)(111))
+#define LIB9P_ERRNO_L_EHOSTDOWN ((lib9p_errno_t)(112))
+#define LIB9P_ERRNO_L_EHOSTUNREACH ((lib9p_errno_t)(113))
+#define LIB9P_ERRNO_L_EALREADY ((lib9p_errno_t)(114))
+#define LIB9P_ERRNO_L_EINPROGRESS ((lib9p_errno_t)(115))
+#define LIB9P_ERRNO_L_ESTALE ((lib9p_errno_t)(116))
+#define LIB9P_ERRNO_L_EUCLEAN ((lib9p_errno_t)(117))
+#define LIB9P_ERRNO_L_ENOTNAM ((lib9p_errno_t)(118))
+#define LIB9P_ERRNO_L_ENAVAIL ((lib9p_errno_t)(119))
+#define LIB9P_ERRNO_L_EISNAM ((lib9p_errno_t)(120))
+#define LIB9P_ERRNO_L_EREMOTEIO ((lib9p_errno_t)(121))
+#define LIB9P_ERRNO_L_EDQUOT ((lib9p_errno_t)(122))
+#define LIB9P_ERRNO_L_ENOMEDIUM ((lib9p_errno_t)(123))
+#define LIB9P_ERRNO_L_EMEDIUMTYPE ((lib9p_errno_t)(124))
+#define LIB9P_ERRNO_L_ECANCELED ((lib9p_errno_t)(125))
+#define LIB9P_ERRNO_L_ENOKEY ((lib9p_errno_t)(126))
+#define LIB9P_ERRNO_L_EKEYEXPIRED ((lib9p_errno_t)(127))
+#define LIB9P_ERRNO_L_EKEYREVOKED ((lib9p_errno_t)(128))
+#define LIB9P_ERRNO_L_EKEYREJECTED ((lib9p_errno_t)(129))
+#define LIB9P_ERRNO_L_EOWNERDEAD ((lib9p_errno_t)(130))
+#define LIB9P_ERRNO_L_ENOTRECOVERABLE ((lib9p_errno_t)(131))
+#define LIB9P_ERRNO_L_ERFKILL ((lib9p_errno_t)(132))
+#define LIB9P_ERRNO_L_EHWPOISON ((lib9p_errno_t)(133))
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000_L
@@ -559,6 +693,23 @@ LO_IMPLEMENTATION_H(fmt_formatter, lib9p_lock_status_t, lib9p_lock_status);
#define LIB9P_LOCK_STATUS_GRACE ((lib9p_lock_status_t)(3))
#endif /* CONFIG_9P_ENABLE_9P2000_L */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
+/* min_size = 2 ; exp_size = 29 ; max_size = 65,537 ; max_iov = 2 ; max_copy = 2 */
+struct lib9p_s {
+ uint16_t len;
+ [[gnu::nonstring]] char *utf8;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_s, lib9p_s);
+
+/* size = 13 ; max_iov = 1 ; max_copy = 13 */
+struct lib9p_qid {
+ lib9p_qt_t type;
+ uint32_t vers;
+ uint64_t path;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_qid, lib9p_qid);
+
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
/* size = 9 ; max_iov = 1 ; max_copy = 9 */
struct lib9p_msg_Tflush {
@@ -573,6 +724,27 @@ struct lib9p_msg_Rflush {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rflush, lib9p_msg_Rflush);
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+/* size = 12 ; max_iov = 1 ; max_copy = 12 */
+struct lib9p_msg_Topen {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_o_t mode;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Topen, lib9p_msg_Topen);
+
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+/* size = 23 ; max_iov = 1 ; max_copy = 23 */
+struct lib9p_msg_Tread {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ uint64_t offset;
+ uint32_t count;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tread, lib9p_msg_Tread);
+
/* min_size = 11 ; exp_size = 8,203 ; max_size = 2,147,483,658 ; max_iov = 2 ; max_copy = 11 */
struct lib9p_msg_Rread {
lib9p_tag_t tag;
@@ -581,6 +753,16 @@ struct lib9p_msg_Rread {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rread, lib9p_msg_Rread);
+/* min_size = 23 ; exp_size = 8,215 ; max_size = 2,147,483,670 ; max_iov = 2 ; max_copy = 23 */
+struct lib9p_msg_Twrite {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ uint64_t offset;
+ uint32_t count;
+ [[gnu::nonstring]] char *data;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Twrite, lib9p_msg_Twrite);
+
/* size = 11 ; max_iov = 1 ; max_copy = 11 */
struct lib9p_msg_Rwrite {
lib9p_tag_t tag;
@@ -588,12 +770,26 @@ struct lib9p_msg_Rwrite {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rwrite, lib9p_msg_Rwrite);
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
+struct lib9p_msg_Tclunk {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tclunk, lib9p_msg_Tclunk);
+
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rclunk {
lib9p_tag_t tag;
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rclunk, lib9p_msg_Rclunk);
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
+struct lib9p_msg_Tremove {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tremove, lib9p_msg_Tremove);
+
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rremove {
lib9p_tag_t tag;
@@ -602,6 +798,13 @@ LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rremove, lib9p_msg_Rremove);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
+struct lib9p_msg_Tstat {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tstat, lib9p_msg_Tstat);
+
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rwstat {
lib9p_tag_t tag;
@@ -609,13 +812,91 @@ struct lib9p_msg_Rwstat {
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rwstat, lib9p_msg_Rwstat);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000_p9p
+/* size = 12 ; max_iov = 1 ; max_copy = 12 */
+struct lib9p_msg_Topenfd {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_o_t mode;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Topenfd, lib9p_msg_Topenfd);
+
+#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
#if CONFIG_9P_ENABLE_9P2000_L
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
+struct lib9p_msg_Rlerror {
+ lib9p_tag_t tag;
+ lib9p_errno_t errnum;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlerror, lib9p_msg_Rlerror);
+
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
+struct lib9p_msg_Tstatfs {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tstatfs, lib9p_msg_Tstatfs);
+
+/* size = 67 ; max_iov = 1 ; max_copy = 67 */
+struct lib9p_msg_Rstatfs {
+ lib9p_tag_t tag;
+ lib9p_super_magic_t type;
+ uint32_t bsize;
+ uint64_t blocks;
+ uint64_t bfree;
+ uint64_t bavail;
+ uint64_t files;
+ uint64_t ffree;
+ uint64_t fsid;
+ uint32_t namelen;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rstatfs, lib9p_msg_Rstatfs);
+
+/* size = 15 ; max_iov = 1 ; max_copy = 15 */
+struct lib9p_msg_Tlopen {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_lo_t flags;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlopen, lib9p_msg_Tlopen);
+
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rrename {
lib9p_tag_t tag;
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rrename, lib9p_msg_Rrename);
+/* size = 11 ; max_iov = 1 ; max_copy = 11 */
+struct lib9p_msg_Treadlink {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Treadlink, lib9p_msg_Treadlink);
+
+/* size = 19 ; max_iov = 1 ; max_copy = 19 */
+struct lib9p_msg_Tgetattr {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_getattr_t request_mask;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tgetattr, lib9p_msg_Tgetattr);
+
+/* size = 67 ; max_iov = 1 ; max_copy = 67 */
+struct lib9p_msg_Tsetattr {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_setattr_t valid;
+ lib9p_mode_t mode;
+ lib9p_nuid_t uid;
+ lib9p_nuid_t gid;
+ uint64_t filesize;
+ uint64_t atime_sec;
+ uint64_t atime_nsec;
+ uint64_t mtime_sec;
+ uint64_t mtime_nsec;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tsetattr, lib9p_msg_Tsetattr);
+
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rsetattr {
lib9p_tag_t tag;
@@ -635,6 +916,15 @@ struct lib9p_msg_Rxattrcreate {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rxattrcreate, lib9p_msg_Rxattrcreate);
+/* size = 23 ; max_iov = 1 ; max_copy = 23 */
+struct lib9p_msg_Treaddir {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ uint64_t offset;
+ uint32_t count;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Treaddir, lib9p_msg_Treaddir);
+
/* min_size = 11 ; exp_size = 8,203 ; max_size = 4,294,967,306 (warning: >UINT32_MAX) ; max_iov = 2 ; max_copy = 11 */
struct lib9p_msg_Rreaddir {
lib9p_tag_t tag;
@@ -643,12 +933,27 @@ struct lib9p_msg_Rreaddir {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rreaddir, lib9p_msg_Rreaddir);
+/* size = 15 ; max_iov = 1 ; max_copy = 15 */
+struct lib9p_msg_Tfsync {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_b4_t datasync;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tfsync, lib9p_msg_Tfsync);
+
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rfsync {
lib9p_tag_t tag;
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rfsync, lib9p_msg_Rfsync);
+/* size = 8 ; max_iov = 1 ; max_copy = 8 */
+struct lib9p_msg_Rlock {
+ lib9p_tag_t tag;
+ lib9p_lock_status_t status;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlock, lib9p_msg_Rlock);
+
/* size = 7 ; max_iov = 1 ; max_copy = 7 */
struct lib9p_msg_Rlink {
lib9p_tag_t tag;
@@ -698,76 +1003,34 @@ struct lib9p_msg_Rswrite {
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rswrite, lib9p_msg_Rswrite);
#endif /* CONFIG_9P_ENABLE_9P2000_e */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 23 ; max_iov = 1 ; max_copy = 23 */
-struct lib9p_msg_Tread {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- uint64_t offset;
- uint32_t count;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tread, lib9p_msg_Tread);
-
-/* min_size = 23 ; exp_size = 8,215 ; max_size = 2,147,483,670 ; max_iov = 2 ; max_copy = 23 */
-struct lib9p_msg_Twrite {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- uint64_t offset;
- uint32_t count;
- [[gnu::nonstring]] char *data;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Twrite, lib9p_msg_Twrite);
-
-/* size = 11 ; max_iov = 1 ; max_copy = 11 */
-struct lib9p_msg_Tclunk {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tclunk, lib9p_msg_Tclunk);
-
-/* size = 11 ; max_iov = 1 ; max_copy = 11 */
-struct lib9p_msg_Tremove {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tremove, lib9p_msg_Tremove);
-
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 11 ; max_iov = 1 ; max_copy = 11 */
-struct lib9p_msg_Tstat {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
+/* LIB9P_VER_9P2000 : min_size = 49 ; exp_size = 157 ; max_size = 262,189 ; max_iov = 8 ; max_copy = 49 */
+/* LIB9P_VER_9P2000_e : min_size = 49 ; exp_size = 157 ; max_size = 262,189 ; max_iov = 8 ; max_copy = 49 */
+/* LIB9P_VER_9P2000_p9p: min_size = 49 ; exp_size = 157 ; max_size = 262,189 ; max_iov = 8 ; max_copy = 49 */
+/* LIB9P_VER_9P2000_u : min_size = 63 ; exp_size = 198 ; max_size = 327,738 ; max_iov = 11 ; max_copy = 63 */
+struct lib9p_stat {
+ uint16_t fstype;
+ uint32_t fsdev;
+ struct lib9p_qid qid;
+ lib9p_dm_t mode;
+ uint32_t atime;
+ uint32_t mtime;
+ uint64_t length;
+ struct lib9p_s name;
+ struct lib9p_s owner_uname;
+ struct lib9p_s owner_gname;
+ struct lib9p_s last_modifier_uname;
+#if CONFIG_9P_ENABLE_9P2000_u
+ struct lib9p_s extension;
+ lib9p_nuid_t owner_unum;
+ lib9p_nuid_t owner_gnum;
+ lib9p_nuid_t last_modifier_unum;
+#endif /* CONFIG_9P_ENABLE_9P2000_u */
};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tstat, lib9p_msg_Tstat);
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_stat, lib9p_stat);
#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_L
-/* size = 11 ; max_iov = 1 ; max_copy = 11 */
-struct lib9p_msg_Tstatfs {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tstatfs, lib9p_msg_Tstatfs);
-
-/* size = 11 ; max_iov = 1 ; max_copy = 11 */
-struct lib9p_msg_Treadlink {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Treadlink, lib9p_msg_Treadlink);
-
-/* size = 23 ; max_iov = 1 ; max_copy = 23 */
-struct lib9p_msg_Treaddir {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- uint64_t offset;
- uint32_t count;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Treaddir, lib9p_msg_Treaddir);
-
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
/* min_size = 13 ; exp_size = 40 ; max_size = 65,548 ; max_iov = 2 ; max_copy = 13 */
struct lib9p_msg_Tversion {
lib9p_tag_t tag;
@@ -784,113 +1047,8 @@ struct lib9p_msg_Rversion {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rversion, lib9p_msg_Rversion);
-/* min_size = 17 ; exp_size = 481 ; max_size = 1,048,609 ; max_iov = 32 ; max_copy = 49 */
-struct lib9p_msg_Twalk {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_fid_t newfid;
- uint16_t nwname;
- struct lib9p_s *wname;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Twalk, lib9p_msg_Twalk);
-
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_L
-/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
-struct lib9p_msg_Trename {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_fid_t dfid;
- struct lib9p_s name;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Trename, lib9p_msg_Trename);
-
-/* min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
-struct lib9p_msg_Rreadlink {
- lib9p_tag_t tag;
- struct lib9p_s target;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rreadlink, lib9p_msg_Rreadlink);
-
-/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
-struct lib9p_msg_Txattrwalk {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_fid_t newfid;
- struct lib9p_s name;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Txattrwalk, lib9p_msg_Txattrwalk);
-
-/* min_size = 25 ; exp_size = 52 ; max_size = 65,560 ; max_iov = 3 ; max_copy = 25 */
-struct lib9p_msg_Txattrcreate {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- struct lib9p_s name;
- uint64_t attr_size;
- uint32_t flags;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Txattrcreate, lib9p_msg_Txattrcreate);
-
-/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
-struct lib9p_msg_Tlink {
- lib9p_tag_t tag;
- lib9p_fid_t dfid;
- lib9p_fid_t fid;
- struct lib9p_s name;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlink, lib9p_msg_Tlink);
-
-/* min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 4 ; max_copy = 19 */
-struct lib9p_msg_Trenameat {
- lib9p_tag_t tag;
- lib9p_fid_t olddirfid;
- struct lib9p_s oldname;
- lib9p_fid_t newdirfid;
- struct lib9p_s newname;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Trenameat, lib9p_msg_Trenameat);
-
-/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 3 ; max_copy = 17 */
-struct lib9p_msg_Tunlinkat {
- lib9p_tag_t tag;
- lib9p_fid_t dirfd;
- struct lib9p_s name;
- uint32_t flags;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tunlinkat, lib9p_msg_Tunlinkat);
-
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000_e
-/* min_size = 13 ; exp_size = 477 ; max_size = 4,294,967,308 (warning: >UINT32_MAX) ; max_iov = 0 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) ; max_copy = 13 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) */
-struct lib9p_msg_Tsread {
- lib9p_tag_t tag;
- uint32_t fid;
- uint16_t nwname;
- struct lib9p_s *wname;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tsread, lib9p_msg_Tsread);
-
-/* min_size = 17 ; exp_size = 8,673 ; max_size = 8,589,934,607 (warning: >UINT32_MAX) ; max_iov = 2 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) ; max_copy = 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) */
-struct lib9p_msg_Tswrite {
- lib9p_tag_t tag;
- uint32_t fid;
- uint16_t nwname;
- struct lib9p_s *wname;
- uint32_t count;
- [[gnu::nonstring]] char *data;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tswrite, lib9p_msg_Tswrite);
-
-#endif /* CONFIG_9P_ENABLE_9P2000_e */
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 13 ; max_iov = 1 ; max_copy = 13 */
-struct lib9p_qid {
- lib9p_qt_t type;
- uint32_t vers;
- uint64_t path;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_qid, lib9p_qid);
-
/* LIB9P_VER_9P2000 : min_size = 15 ; exp_size = 69 ; max_size = 131,085 ; max_iov = 4 ; max_copy = 15 */
/* LIB9P_VER_9P2000_L : min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 5 ; max_copy = 19 */
/* LIB9P_VER_9P2000_e : min_size = 15 ; exp_size = 69 ; max_size = 131,085 ; max_iov = 4 ; max_copy = 15 */
@@ -902,11 +1060,18 @@ struct lib9p_msg_Tauth {
struct lib9p_s uname;
struct lib9p_s aname;
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
- lib9p_nuid_t n_uid;
+ lib9p_nuid_t unum;
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tauth, lib9p_msg_Tauth);
+/* size = 20 ; max_iov = 1 ; max_copy = 20 */
+struct lib9p_msg_Rauth {
+ lib9p_tag_t tag;
+ struct lib9p_qid aqid;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rauth, lib9p_msg_Rauth);
+
/* LIB9P_VER_9P2000 : min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 4 ; max_copy = 19 */
/* LIB9P_VER_9P2000_L : min_size = 23 ; exp_size = 77 ; max_size = 131,093 ; max_iov = 5 ; max_copy = 23 */
/* LIB9P_VER_9P2000_e : min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 4 ; max_copy = 19 */
@@ -919,251 +1084,45 @@ struct lib9p_msg_Tattach {
struct lib9p_s uname;
struct lib9p_s aname;
#if CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u
- lib9p_nuid_t n_uid;
+ lib9p_nuid_t unum;
#endif /* CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_u */
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tattach, lib9p_msg_Tattach);
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_L
-/* min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 5 ; max_copy = 19 */
-struct lib9p_msg_Tsymlink {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- struct lib9p_s name;
- struct lib9p_s symtgt;
- lib9p_nuid_t gid;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tsymlink, lib9p_msg_Tsymlink);
-
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 12 ; max_iov = 1 ; max_copy = 12 */
-struct lib9p_msg_Topen {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_o_t mode;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Topen, lib9p_msg_Topen);
-
-/* min_size = 18 ; exp_size = 45 ; max_size = 65,553 ; max_iov = 3 ; max_copy = 18 */
-struct lib9p_msg_Tcreate {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- struct lib9p_s name;
- lib9p_dm_t perm;
- lib9p_o_t mode;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tcreate, lib9p_msg_Tcreate);
-
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_p9p
-/* size = 12 ; max_iov = 1 ; max_copy = 12 */
-struct lib9p_msg_Topenfd {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_o_t mode;
+/* size = 20 ; max_iov = 1 ; max_copy = 20 */
+struct lib9p_msg_Rattach {
+ lib9p_tag_t tag;
+ struct lib9p_qid qid;
};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Topenfd, lib9p_msg_Topenfd);
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rattach, lib9p_msg_Rattach);
-#endif /* CONFIG_9P_ENABLE_9P2000_p9p */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown
/* LIB9P_VER_9P2000 : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
-/* LIB9P_VER_9P2000_L : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
/* LIB9P_VER_9P2000_e : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
/* LIB9P_VER_9P2000_p9p: min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
/* LIB9P_VER_9P2000_u : min_size = 13 ; exp_size = 40 ; max_size = 65,548 ; max_iov = 3 ; max_copy = 13 */
+/* LIB9P_VER_unknown : min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
struct lib9p_msg_Rerror {
lib9p_tag_t tag;
- struct lib9p_s ename;
+ struct lib9p_s errstr;
#if CONFIG_9P_ENABLE_9P2000_u
- lib9p_errno_t errno;
+ lib9p_errno_t errnum;
#endif /* CONFIG_9P_ENABLE_9P2000_u */
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rerror, lib9p_msg_Rerror);
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000_L
-/* size = 11 ; max_iov = 1 ; max_copy = 11 */
-struct lib9p_msg_Rlerror {
- lib9p_tag_t tag;
- lib9p_errno_t ecode;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlerror, lib9p_msg_Rlerror);
-
-/* size = 67 ; max_iov = 1 ; max_copy = 67 */
-struct lib9p_msg_Rstatfs {
- lib9p_tag_t tag;
- lib9p_super_magic_t type;
- uint32_t bsize;
- uint64_t blocks;
- uint64_t bfree;
- uint64_t bavail;
- uint64_t files;
- uint64_t ffree;
- uint64_t fsid;
- uint32_t namelen;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rstatfs, lib9p_msg_Rstatfs);
-
-/* size = 15 ; max_iov = 1 ; max_copy = 15 */
-struct lib9p_msg_Tlopen {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_lo_t flags;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlopen, lib9p_msg_Tlopen);
-
-/* min_size = 25 ; exp_size = 52 ; max_size = 65,560 ; max_iov = 3 ; max_copy = 25 */
-struct lib9p_msg_Tlcreate {
+#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_unknown */
+#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
+/* min_size = 17 ; exp_size = 481 ; max_size = 1,048,609 ; max_iov = 32 ; max_copy = 49 */
+struct lib9p_msg_Twalk {
lib9p_tag_t tag;
lib9p_fid_t fid;
- struct lib9p_s name;
- lib9p_lo_t flags;
- lib9p_mode_t mode;
- lib9p_nuid_t gid;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlcreate, lib9p_msg_Tlcreate);
-
-/* min_size = 29 ; exp_size = 56 ; max_size = 65,564 ; max_iov = 3 ; max_copy = 29 */
-struct lib9p_msg_Tmknod {
- lib9p_tag_t tag;
- lib9p_fid_t dfid;
- struct lib9p_s name;
- lib9p_mode_t mode;
- uint32_t major;
- uint32_t minor;
- lib9p_nuid_t gid;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tmknod, lib9p_msg_Tmknod);
-
-/* min_size = 21 ; exp_size = 48 ; max_size = 65,556 ; max_iov = 3 ; max_copy = 21 */
-struct lib9p_msg_Tmkdir {
- lib9p_tag_t tag;
- lib9p_fid_t dfid;
- struct lib9p_s name;
- lib9p_mode_t mode;
- lib9p_nuid_t gid;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tmkdir, lib9p_msg_Tmkdir);
-
-/* size = 15 ; max_iov = 1 ; max_copy = 15 */
-struct lib9p_msg_Tfsync {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_b4_t datasync;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tfsync, lib9p_msg_Tfsync);
-
-/* size = 19 ; max_iov = 1 ; max_copy = 19 */
-struct lib9p_msg_Tgetattr {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_getattr_t request_mask;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tgetattr, lib9p_msg_Tgetattr);
-
-/* size = 67 ; max_iov = 1 ; max_copy = 67 */
-struct lib9p_msg_Tsetattr {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_setattr_t valid;
- lib9p_mode_t mode;
- lib9p_nuid_t uid;
- lib9p_nuid_t gid;
- uint64_t filesize;
- uint64_t atime_sec;
- uint64_t atime_nsec;
- uint64_t mtime_sec;
- uint64_t mtime_nsec;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tsetattr, lib9p_msg_Tsetattr);
-
-/* min_size = 34 ; exp_size = 61 ; max_size = 65,569 ; max_iov = 2 ; max_copy = 34 */
-struct lib9p_msg_Tgetlock {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_lock_type_t type;
- uint64_t start;
- uint64_t length;
- uint32_t proc_id;
- struct lib9p_s client_id;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tgetlock, lib9p_msg_Tgetlock);
-
-/* min_size = 30 ; exp_size = 57 ; max_size = 65,565 ; max_iov = 2 ; max_copy = 30 */
-struct lib9p_msg_Rgetlock {
- lib9p_tag_t tag;
- lib9p_lock_type_t type;
- uint64_t start;
- uint64_t length;
- uint32_t proc_id;
- struct lib9p_s client_id;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rgetlock, lib9p_msg_Rgetlock);
-
-/* min_size = 38 ; exp_size = 65 ; max_size = 65,573 ; max_iov = 2 ; max_copy = 38 */
-struct lib9p_msg_Tlock {
- lib9p_tag_t tag;
- lib9p_fid_t fid;
- lib9p_lock_type_t type;
- lib9p_lock_flags_t flags;
- uint64_t start;
- uint64_t length;
- uint32_t proc_id;
- struct lib9p_s client_id;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlock, lib9p_msg_Tlock);
-
-/* size = 8 ; max_iov = 1 ; max_copy = 8 */
-struct lib9p_msg_Rlock {
- lib9p_tag_t tag;
- lib9p_lock_status_t status;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlock, lib9p_msg_Rlock);
-
-#endif /* CONFIG_9P_ENABLE_9P2000_L */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* LIB9P_VER_9P2000 : min_size = 49 ; exp_size = 157 ; max_size = 262,189 ; max_iov = 8 ; max_copy = 49 */
-/* LIB9P_VER_9P2000_e : min_size = 49 ; exp_size = 157 ; max_size = 262,189 ; max_iov = 8 ; max_copy = 49 */
-/* LIB9P_VER_9P2000_p9p: min_size = 49 ; exp_size = 157 ; max_size = 262,189 ; max_iov = 8 ; max_copy = 49 */
-/* LIB9P_VER_9P2000_u : min_size = 63 ; exp_size = 198 ; max_size = 327,738 ; max_iov = 11 ; max_copy = 63 */
-struct lib9p_stat {
- uint16_t kern_type;
- uint32_t kern_dev;
- struct lib9p_qid file_qid;
- lib9p_dm_t file_mode;
- uint32_t file_atime;
- uint32_t file_mtime;
- uint64_t file_size;
- struct lib9p_s file_name;
- struct lib9p_s file_owner_uid;
- struct lib9p_s file_owner_gid;
- struct lib9p_s file_last_modified_uid;
-#if CONFIG_9P_ENABLE_9P2000_u
- struct lib9p_s file_extension;
- lib9p_nuid_t file_owner_n_uid;
- lib9p_nuid_t file_owner_n_gid;
- lib9p_nuid_t file_last_modified_n_uid;
-#endif /* CONFIG_9P_ENABLE_9P2000_u */
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_stat, lib9p_stat);
-
-#endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u */
-#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
-/* size = 20 ; max_iov = 1 ; max_copy = 20 */
-struct lib9p_msg_Rauth {
- lib9p_tag_t tag;
- struct lib9p_qid aqid;
-};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rauth, lib9p_msg_Rauth);
-
-/* size = 20 ; max_iov = 1 ; max_copy = 20 */
-struct lib9p_msg_Rattach {
- lib9p_tag_t tag;
- struct lib9p_qid qid;
+ lib9p_fid_t newfid;
+ uint16_t nwname;
+ struct lib9p_s *wname;
};
-LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rattach, lib9p_msg_Rattach);
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Twalk, lib9p_msg_Twalk);
/* min_size = 9 ; exp_size = 217 ; max_size = 217 ; max_iov = 1 ; max_copy = 217 */
struct lib9p_msg_Rwalk {
@@ -1183,6 +1142,16 @@ struct lib9p_msg_Ropen {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Ropen, lib9p_msg_Ropen);
+/* min_size = 18 ; exp_size = 45 ; max_size = 65,553 ; max_iov = 3 ; max_copy = 18 */
+struct lib9p_msg_Tcreate {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ struct lib9p_s name;
+ lib9p_dm_t perm;
+ lib9p_o_t mode;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tcreate, lib9p_msg_Tcreate);
+
/* size = 24 ; max_iov = 1 ; max_copy = 24 */
struct lib9p_msg_Rcreate {
lib9p_tag_t tag;
@@ -1212,6 +1181,17 @@ struct lib9p_msg_Rlopen {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlopen, lib9p_msg_Rlopen);
+/* min_size = 25 ; exp_size = 52 ; max_size = 65,560 ; max_iov = 3 ; max_copy = 25 */
+struct lib9p_msg_Tlcreate {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ struct lib9p_s name;
+ lib9p_lo_t flags;
+ lib9p_mode_t mode;
+ lib9p_nuid_t gid;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlcreate, lib9p_msg_Tlcreate);
+
/* size = 24 ; max_iov = 1 ; max_copy = 24 */
struct lib9p_msg_Rlcreate {
lib9p_tag_t tag;
@@ -1220,6 +1200,16 @@ struct lib9p_msg_Rlcreate {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rlcreate, lib9p_msg_Rlcreate);
+/* min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 5 ; max_copy = 19 */
+struct lib9p_msg_Tsymlink {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ struct lib9p_s name;
+ struct lib9p_s symtgt;
+ lib9p_nuid_t gid;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tsymlink, lib9p_msg_Tsymlink);
+
/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rsymlink {
lib9p_tag_t tag;
@@ -1227,6 +1217,18 @@ struct lib9p_msg_Rsymlink {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rsymlink, lib9p_msg_Rsymlink);
+/* min_size = 29 ; exp_size = 56 ; max_size = 65,564 ; max_iov = 3 ; max_copy = 29 */
+struct lib9p_msg_Tmknod {
+ lib9p_tag_t tag;
+ lib9p_fid_t dfid;
+ struct lib9p_s name;
+ lib9p_mode_t mode;
+ uint32_t major;
+ uint32_t minor;
+ lib9p_nuid_t gid;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tmknod, lib9p_msg_Tmknod);
+
/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rmknod {
lib9p_tag_t tag;
@@ -1234,6 +1236,22 @@ struct lib9p_msg_Rmknod {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rmknod, lib9p_msg_Rmknod);
+/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
+struct lib9p_msg_Trename {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_fid_t dfid;
+ struct lib9p_s name;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Trename, lib9p_msg_Trename);
+
+/* min_size = 9 ; exp_size = 36 ; max_size = 65,544 ; max_iov = 2 ; max_copy = 9 */
+struct lib9p_msg_Rreadlink {
+ lib9p_tag_t tag;
+ struct lib9p_s target;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rreadlink, lib9p_msg_Rreadlink);
+
/* size = 160 ; max_iov = 1 ; max_copy = 160 */
struct lib9p_msg_Rgetattr {
lib9p_tag_t tag;
@@ -1260,6 +1278,80 @@ struct lib9p_msg_Rgetattr {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rgetattr, lib9p_msg_Rgetattr);
+/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
+struct lib9p_msg_Txattrwalk {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_fid_t newfid;
+ struct lib9p_s name;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Txattrwalk, lib9p_msg_Txattrwalk);
+
+/* min_size = 25 ; exp_size = 52 ; max_size = 65,560 ; max_iov = 3 ; max_copy = 25 */
+struct lib9p_msg_Txattrcreate {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ struct lib9p_s name;
+ uint64_t attr_size;
+ uint32_t flags;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Txattrcreate, lib9p_msg_Txattrcreate);
+
+/* min_size = 38 ; exp_size = 65 ; max_size = 65,573 ; max_iov = 2 ; max_copy = 38 */
+struct lib9p_msg_Tlock {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_lock_type_t type;
+ lib9p_lock_flags_t flags;
+ uint64_t start;
+ uint64_t length;
+ uint32_t proc_id;
+ struct lib9p_s client_id;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlock, lib9p_msg_Tlock);
+
+/* min_size = 34 ; exp_size = 61 ; max_size = 65,569 ; max_iov = 2 ; max_copy = 34 */
+struct lib9p_msg_Tgetlock {
+ lib9p_tag_t tag;
+ lib9p_fid_t fid;
+ lib9p_lock_type_t type;
+ uint64_t start;
+ uint64_t length;
+ uint32_t proc_id;
+ struct lib9p_s client_id;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tgetlock, lib9p_msg_Tgetlock);
+
+/* min_size = 30 ; exp_size = 57 ; max_size = 65,565 ; max_iov = 2 ; max_copy = 30 */
+struct lib9p_msg_Rgetlock {
+ lib9p_tag_t tag;
+ lib9p_lock_type_t type;
+ uint64_t start;
+ uint64_t length;
+ uint32_t proc_id;
+ struct lib9p_s client_id;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rgetlock, lib9p_msg_Rgetlock);
+
+/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 2 ; max_copy = 17 */
+struct lib9p_msg_Tlink {
+ lib9p_tag_t tag;
+ lib9p_fid_t dfid;
+ lib9p_fid_t fid;
+ struct lib9p_s name;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tlink, lib9p_msg_Tlink);
+
+/* min_size = 21 ; exp_size = 48 ; max_size = 65,556 ; max_iov = 3 ; max_copy = 21 */
+struct lib9p_msg_Tmkdir {
+ lib9p_tag_t tag;
+ lib9p_fid_t dfid;
+ struct lib9p_s name;
+ lib9p_mode_t mode;
+ lib9p_nuid_t gid;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tmkdir, lib9p_msg_Tmkdir);
+
/* size = 20 ; max_iov = 1 ; max_copy = 20 */
struct lib9p_msg_Rmkdir {
lib9p_tag_t tag;
@@ -1267,7 +1359,48 @@ struct lib9p_msg_Rmkdir {
};
LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Rmkdir, lib9p_msg_Rmkdir);
+/* min_size = 19 ; exp_size = 73 ; max_size = 131,089 ; max_iov = 4 ; max_copy = 19 */
+struct lib9p_msg_Trenameat {
+ lib9p_tag_t tag;
+ lib9p_fid_t olddirfid;
+ struct lib9p_s oldname;
+ lib9p_fid_t newdirfid;
+ struct lib9p_s newname;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Trenameat, lib9p_msg_Trenameat);
+
+/* min_size = 17 ; exp_size = 44 ; max_size = 65,552 ; max_iov = 3 ; max_copy = 17 */
+struct lib9p_msg_Tunlinkat {
+ lib9p_tag_t tag;
+ lib9p_fid_t dirfd;
+ struct lib9p_s name;
+ uint32_t flags;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tunlinkat, lib9p_msg_Tunlinkat);
+
#endif /* CONFIG_9P_ENABLE_9P2000_L */
+#if CONFIG_9P_ENABLE_9P2000_e
+/* min_size = 13 ; exp_size = 477 ; max_size = 4,294,967,308 (warning: >UINT32_MAX) ; max_iov = 0 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) ; max_copy = 13 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) */
+struct lib9p_msg_Tsread {
+ lib9p_tag_t tag;
+ uint32_t fid;
+ uint16_t nwname;
+ struct lib9p_s *wname;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tsread, lib9p_msg_Tsread);
+
+/* min_size = 17 ; exp_size = 8,673 ; max_size = 8,589,934,607 (warning: >UINT32_MAX) ; max_iov = 2 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) ; max_copy = 17 + (CONFIG_9P_MAX_9P2000_e_WELEM * 2) */
+struct lib9p_msg_Tswrite {
+ lib9p_tag_t tag;
+ uint32_t fid;
+ uint16_t nwname;
+ struct lib9p_s *wname;
+ uint32_t count;
+ [[gnu::nonstring]] char *data;
+};
+LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Tswrite, lib9p_msg_Tswrite);
+
+#endif /* CONFIG_9P_ENABLE_9P2000_e */
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
/* LIB9P_VER_9P2000 : min_size = 58 ; exp_size = 166 ; max_size = 262,198 ; max_iov = 8 ; max_copy = 58 */
/* LIB9P_VER_9P2000_e : min_size = 58 ; exp_size = 166 ; max_size = 262,198 ; max_iov = 8 ; max_copy = 58 */
@@ -1301,6 +1434,8 @@ LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Twstat, lib9p_msg_Twstat);
#else
#define LIB9P_TMSG_MAX_IOV 32
#endif
+#elif CONFIG_9P_ENABLE_unknown
+ #define LIB9P_TMSG_MAX_IOV 2
#endif
#if CONFIG_9P_ENABLE_9P2000_u
@@ -1321,18 +1456,22 @@ LO_IMPLEMENTATION_H(fmt_formatter, struct lib9p_msg_Twstat, lib9p_msg_Twstat);
#else
#define LIB9P_TMSG_MAX_COPY 62
#endif
+#elif CONFIG_9P_ENABLE_unknown
+ #define LIB9P_TMSG_MAX_COPY 13
#endif
#if CONFIG_9P_ENABLE_9P2000_u
#define LIB9P_RMSG_MAX_IOV 11
#elif CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p
#define LIB9P_RMSG_MAX_IOV 8
-#elif CONFIG_9P_ENABLE_9P2000_L
+#elif CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_unknown
#define LIB9P_RMSG_MAX_IOV 2
#endif
#if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_L || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_p9p || CONFIG_9P_ENABLE_9P2000_u
#define LIB9P_RMSG_MAX_COPY 217
+#elif CONFIG_9P_ENABLE_unknown
+ #define LIB9P_RMSG_MAX_COPY 13
#endif
struct lib9p_Tmsg_send_buf {
diff --git a/lib9p/include/lib9p/9p.h b/lib9p/core_include/lib9p/core.h
index 5919260..38f3934 100644
--- a/lib9p/include/lib9p/9p.h
+++ b/lib9p/core_include/lib9p/core.h
@@ -1,19 +1,19 @@
-/* lib9p/9p.h - Base 9P protocol definitions for both clients and servers
+/* lib9p/core.h - Base 9P protocol definitions for both clients and servers
*
* Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-#ifndef _LIB9P_9P_H_
-#define _LIB9P_9P_H_
+#ifndef _LIB9P_CORE_H_
+#define _LIB9P_CORE_H_
#include <stdbool.h>
#include <sys/types.h> /* for ssize_t */
#include <libmisc/assert.h>
-#include <lib9p/linux-errno.h>
-#include <lib9p/9p.generated.h>
+#define CONFIG_9P_ENABLE_unknown 1
+#include <lib9p/_core_generated.h>
#ifndef CONFIG_9P_MAX_ERR_SIZE
#error config.h must define CONFIG_9P_MAX_ERR_SIZE
@@ -46,7 +46,7 @@ struct lib9p_ctx {
uint32_t max_msg_size;
/* state */
-#ifdef CONFIG_9P_ENABLE_9P2000_u
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
lib9p_errno_t err_num;
#endif
[[gnu::nonstring]] char err_msg[CONFIG_9P_MAX_ERR_SIZE];
@@ -57,9 +57,31 @@ void lib9p_ctx_clear_error(struct lib9p_ctx *ctx);
bool lib9p_ctx_has_error(struct lib9p_ctx *ctx);
/** Write an static error into ctx, return -1. */
-int lib9p_error(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *msg);
+int lib9p_error(struct lib9p_ctx *ctx,
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+ lib9p_errno_t linux_errno,
+#endif
+ char const *msg);
/** Write a printf-style error into ctx, return -1. */
-int lib9p_errorf(struct lib9p_ctx *ctx, lib9p_errno_t linux_errno, char const *fmt, ...) [[gnu::format(printf, 3, 4)]];
+int lib9p_errorf(struct lib9p_ctx *ctx,
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+ lib9p_errno_t linux_errno,
+#endif
+ char const *fmt, ...)
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+ [[gnu::format(printf, 3, 4)]]
+#else
+ [[gnu::format(printf, 2, 3)]]
+#endif
+ ;
+
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+/* Detect things that should be just lib9p_error() */
+#define lib9p_errorf(ctx, errnum, fmt, ...) lib9p_errorf(ctx, errnum, fmt, __VA_ARGS__)
+#else
+#define lib9p_errorf(ctx, errnum, fmt, ...) lib9p_errorf(ctx, fmt, __VA_ARGS__)
+#define lib9p_error(ctx, errnum, errmsg) lib9p_error(ctx, errmsg)
+#endif
/* misc utilities *************************************************************/
@@ -86,12 +108,12 @@ lo_interface fmt_formatter lo_box_lib9p_msg_as_fmt_formatter(struct lib9p_ctx *c
*
* @return required size, or -1 on error
*
- * @errno LINUX_EOPNOTSUPP: message is an R-message
- * @errno LINUX_EOPNOTSUPP: message has unknown type
- * @errno LINUX_EBADMSG: message is wrong size for content
- * @errno LINUX_EBADMSG: message contains invalid UTF-8
- * @errno LINUX_EBADMSG: message contains a bitfield with unknown bits
- * @errno LINUX_EMSGSIZE: would-be return value overflows SSIZE_MAX
+ * @errno L_EOPNOTSUPP: message is an R-message
+ * @errno L_EOPNOTSUPP: message has unknown type
+ * @errno L_EBADMSG: message is wrong size for content
+ * @errno L_EBADMSG: message contains invalid UTF-8
+ * @errno L_EBADMSG: message contains a bitfield with unknown bits
+ * @errno L_EMSGSIZE: would-be return value overflows SSIZE_MAX
*/
ssize_t lib9p_Tmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes);
@@ -126,7 +148,7 @@ void lib9p_Tmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
* @return ret_bytes : the buffer to encode to, must be at be at least ctx->max_msg_size bytes
* @return whether there was an error (false=success, true=error)
*
- * @errno LINUX_ERANGE: reply does not fit in ctx->max_msg_size
+ * @errno L_ERANGE: reply does not fit in ctx->max_msg_size
*/
bool lib9p_Tmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body,
struct lib9p_Tmsg_send_buf *ret);
@@ -144,16 +166,7 @@ bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *bo
/* `struct lib9p_stat` helpers ************************************************/
-/** Assert that a `struct lib9p_stat` object looks valid. */
-static inline void lib9p_stat_assert(struct lib9p_stat stat) {
- assert( ((bool)(stat.file_mode & LIB9P_DM_DIR )) == ((bool)(stat.file_qid.type & LIB9P_QT_DIR )) );
- assert( ((bool)(stat.file_mode & LIB9P_DM_APPEND)) == ((bool)(stat.file_qid.type & LIB9P_QT_APPEND)) );
- assert( ((bool)(stat.file_mode & LIB9P_DM_EXCL )) == ((bool)(stat.file_qid.type & LIB9P_QT_EXCL )) );
- assert( ((bool)(stat.file_mode & LIB9P_DM_AUTH )) == ((bool)(stat.file_qid.type & LIB9P_QT_AUTH )) );
- assert( ((bool)(stat.file_mode & LIB9P_DM_TMP )) == ((bool)(stat.file_qid.type & LIB9P_QT_TMP )) );
- assert( (stat.file_size == 0) || !(stat.file_mode & LIB9P_DM_DIR) );
-}
-
+#if _LIB9P_ENABLE_stat
/**
* Validate a message's `stat` structure.
*
@@ -166,7 +179,7 @@ static inline void lib9p_stat_assert(struct lib9p_stat stat) {
* @return whether there was an error
*/
bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes,
- uint32_t *ret_net_size, ssize_t *ret_host_size);
+ uint32_t *ret_net_size, size_t *ret_host_size);
/**
* Unmarshal the 9P `net_bytes` into the C struct `ret_obj`.
@@ -198,9 +211,10 @@ void lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes,
* @return ret_bytes: the buffer to encode into
* @return the number of bytes written, or 0 if the stat object does not fit in max_net_size
*
- * @errno LINUX_ERANGE: reply does not fit in max_net_size
+ * @errno L_ERANGE: reply does not fit in max_net_size
*/
uint32_t lib9p_stat_marshal(struct lib9p_ctx *ctx, uint32_t max_net_size, struct lib9p_stat *obj,
uint8_t *ret_bytes);
+#endif
-#endif /* _LIB9P_9P_H_ */
+#endif /* _LIB9P_CORE_H_ */
diff --git a/lib9p/tables.c b/lib9p/core_tables.c
index 271b17b..bc452c7 100644
--- a/lib9p/tables.c
+++ b/lib9p/core_tables.c
@@ -1,4 +1,4 @@
-/* lib9p/tables.c - Access tables of version and message information
+/* lib9p/core_tables.c - Access tables of version and message information
*
* Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
@@ -9,7 +9,7 @@
#include <libmisc/endian.h>
#include <libmisc/log.h> /* for const_byte_str() */
-#include "tables.h"
+#include "core_tables.h"
/* bounds checks **************************************************************/
@@ -64,14 +64,14 @@ ssize_t _lib9p_validate(uint8_t xxx_low_typ_bit,
/* Inspect the first 5 bytes ourselves. */
uint32_t net_size = uint32le_decode(net_bytes);
if (net_size < 5)
- return lib9p_error(ctx, LINUX_EBADMSG, "message is impossibly short");
+ return lib9p_error(ctx, LIB9P_ERRNO_L_EBADMSG, "message is impossibly short");
uint8_t typ = net_bytes[4];
if (typ % 2 != xxx_low_typ_bit)
- return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "%s: message_type=%s", xxx_errmsg,
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EOPNOTSUPP, "%s: message_type=%s", xxx_errmsg,
lib9p_msgtype_str(ctx->version, typ));
struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2];
if (!tentry.validate)
- return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)",
+ return lib9p_errorf(ctx, LIB9P_ERRNO_L_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)",
lib9p_msgtype_str(ctx->version, typ), lib9p_version_str(ctx->version));
/* Now use the message-type-specific tentry to process the whole thing. */
@@ -96,6 +96,7 @@ void _lib9p_unmarshal(const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0
enum lib9p_msg_type typ = net_bytes[4];
*ret_typ = typ;
struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2];
+ assert(tentry.unmarshal);
tentry.unmarshal(ctx, net_bytes, ret_body);
}
@@ -124,8 +125,9 @@ bool _lib9p_marshal(const struct _lib9p_send_tentry xxx_table[LIB9P_VER_NUM][0x8
.net_copied_size = 0,
.net_copied = ret_copied,
};
-
struct _lib9p_send_tentry tentry = xxx_table[ctx->version][typ/2];
+ assert(tentry.marshal);
+
bool ret_erred = tentry.marshal(ctx, body, &ret);
if (ret_iov[ret.net_iov_cnt-1].iov_len == 0)
ret.net_iov_cnt--;
@@ -153,13 +155,14 @@ bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *bo
/* `struct lib9p_stat` helpers ************************************************/
+#if _LIB9P_ENABLE_stat
bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes,
- uint32_t *ret_net_size, ssize_t *ret_host_size) {
+ uint32_t *ret_net_size, size_t *ret_host_size) {
ssize_t host_size = _lib9p_stat_validate(ctx, net_size, net_bytes, ret_net_size);
if (host_size < 0)
return true;
if (ret_host_size)
- *ret_host_size = host_size;
+ *ret_host_size = (size_t)host_size;
return false;
}
@@ -184,3 +187,4 @@ uint32_t lib9p_stat_marshal(struct lib9p_ctx *ctx, uint32_t max_net_size, struct
return 0;
return ret.net_iov[0].iov_len;
}
+#endif
diff --git a/lib9p/tables.h b/lib9p/core_tables.h
index edb402a..17e9398 100644
--- a/lib9p/tables.h
+++ b/lib9p/core_tables.h
@@ -1,13 +1,13 @@
-/* lib9p/tables.h - Declare tables of version and message information
+/* lib9p/core_tables.h - Declare tables of version and message information
*
* Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-#ifndef _LIB9P_TABLES_H_
-#define _LIB9P_TABLES_H_
+#ifndef _LIB9P_CORE_TABLES_H_
+#define _LIB9P_CORE_TABLES_H_
-#include <lib9p/9p.h>
+#include <lib9p/core.h>
/* version ********************************************************************/
@@ -52,8 +52,10 @@ extern const struct _lib9p_send_tentry _lib9p_table_Rmsg_send[LIB9P_VER_NUM][0x8
/* stat ***********************************************************************/
+#if _LIB9P_ENABLE_stat
ssize_t _lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size);
void _lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, void *out);
bool _lib9p_stat_marshal(struct lib9p_ctx *ctx, struct lib9p_stat *val, struct _marshal_ret *ret);
+#endif
-#endif /* _LIB9P_TABLES_H_ */
+#endif /* _LIB9P_CORE_TABLES_H_ */
diff --git a/lib9p/utf8.h b/lib9p/core_utf8.h
index 5ffd674..636d4eb 100644
--- a/lib9p/utf8.h
+++ b/lib9p/core_utf8.h
@@ -1,11 +1,11 @@
-/* lib9p/utf8.h - Internal UTF-8 validation
+/* lib9p/core_utf8.h - Internal UTF-8 validation
*
* Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-#ifndef _LIB9P_UTF8_H_
-#define _LIB9P_UTF8_H_
+#ifndef _LIB9P_CORE_UTF8_H_
+#define _LIB9P_CORE_UTF8_H_
static inline bool _is_valid_utf8(uint8_t *str, size_t len, bool forbid_nul) {
uint32_t ch;
@@ -31,4 +31,4 @@ static inline bool _is_valid_utf8(uint8_t *str, size_t len, bool forbid_nul) {
#define is_valid_utf8(str, len) _is_valid_utf8(str, len, false)
#define is_valid_utf8_without_nul(str, len) _is_valid_utf8(str, len, true)
-#endif /* _LIB9P_UTF8_H_ */
+#endif /* _LIB9P_CORE_UTF8_H_ */
diff --git a/lib9p/idl/0000-uninitialized.9p b/lib9p/idl/0000-uninitialized.9p
new file mode 100644
index 0000000..9319b5e
--- /dev/null
+++ b/lib9p/idl/0000-uninitialized.9p
@@ -0,0 +1,13 @@
+# lib9p/idl/0000-uninitialized.9p - Defs for bootstrapping
+#
+# Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+version "unknown"
+
+# For the actual protocol.
+from ./2002-9P2000.9p import s, tag
+from ./2002-9P2000.9p import Tversion, Rversion, Rerror
+
+# For srv.h
+from ./2002-9P2000.9p import dm, qt, qid, fid
diff --git a/lib9p/idl/1992-9P0.9p.wip b/lib9p/idl/1992-9P0.9p.wip
index a434ba2..c9432c9 100644
--- a/lib9p/idl/1992-9P0.9p.wip
+++ b/lib9p/idl/1992-9P0.9p.wip
@@ -107,7 +107,7 @@ msg Rnop = "typ[1,val=51] tag[tag,val=0xFFFF]"
msg Tsession = "typ[1,val=52] tag[tag,val=0xFFFF]"
msg Rsession = "typ[1,val=53] tag[tag,val=0xFFFF]"
#msg Terror = "typ[1,val=54] illegal"
-msg Rerror = "typ[1,val=55] tag[tag] ename[errstr]"
+msg Rerror = "typ[1,val=55] tag[tag] errstr[errstr]"
msg Tflush = "typ[1,val=56] tag[tag] oldtag[tag]"
msg Rflush = "typ[1,val=57] tag[tag]"
msg Tattach = "typ[1,val=58] tag[tag] fid[fid] uid[name] aname[name] auth[auth_ticket] 13*(pad[1])" # Pad to allow auth_tickets up to 28 bytes.
diff --git a/lib9p/idl/1996-Styx.9p.wip b/lib9p/idl/1996-Styx.9p.wip
index 3cb3774..143be83 100644
--- a/lib9p/idl/1996-Styx.9p.wip
+++ b/lib9p/idl/1996-Styx.9p.wip
@@ -28,7 +28,7 @@ from ./1992-9P1.9p import tag, fid, qid, name, errstr, o, ch, stat
msg Tnop = "typ[1,val=0] tag[tag,val=0xFFFF]"
msg Rnop = "typ[1,val=1] tag[tag,val=0xFFFF]"
#msg Terror = "typ[1,val=2] illegal"
-msg Rerror = "typ[1,val=3] tag[tag] ename[errstr]"
+msg Rerror = "typ[1,val=3] tag[tag] errstr[errstr]"
msg Tflush = "typ[1,val=4] tag[tag] oldtag[tag]"
msg Rflush = "typ[1,val=5] tag[tag]"
msg Tclone = "typ[1,val=6] tag[tag] fid[fid] newfid[fid]"
diff --git a/lib9p/idl/2002-9P2000.9p b/lib9p/idl/2002-9P2000.9p
index 2b51612..712ffea 100644
--- a/lib9p/idl/2002-9P2000.9p
+++ b/lib9p/idl/2002-9P2000.9p
@@ -91,18 +91,26 @@ bitfield qt = 1
struct qid = "type[qt] vers[4] path[8]"
# stat - file status
-struct stat = "stat_size[2,val=end-&kern_type]"
- "kern_type[2]"
- "kern_dev[4]"
- "file_qid[qid]"
- "file_mode[dm]"
- "file_atime[4]"
- "file_mtime[4]"
- "file_size[8]"
- "file_name[s]"
- "file_owner_uid[s]"
- "file_owner_gid[s]"
- "file_last_modified_uid[s]"
+struct stat = "_stat_size[2,val=end-&fstype]"
+ # fstype and fsdev are documented simply as "for kernel
+ # use". The are ignored by Plan 9's in-kernel 9P
+ # client; mntdirfix() overwrites them with fstype='M'
+ # and fsdev=nonce. Processes may observe values other
+ # than fstype='M', as 'M' is used for actual 9P servers,
+ # while other values are used for in-kernel device
+ # servers (such as '|' for pipes, or 'I' for the IP
+ # stack).
+ "fstype[2]" # filesystem type
+ "fsdev[4]" # filesystem instance/subtype
+ "qid[qid]"
+ "mode[dm]"
+ "atime[4]"
+ "mtime[4]"
+ "length[8]" # 0 for directories
+ "name[s]"
+ "owner_uname[s]"
+ "owner_gname[s]"
+ "last_modifier_uname[s]"
# "O"pen flags (flags to pass to Topen and Tcreate)
# Unused bits *must* be 0.
@@ -137,7 +145,7 @@ msg Rauth = "size[4,val=end-&size] typ[1,val=103] tag[tag] aqid[qid]"
msg Tattach = "size[4,val=end-&size] typ[1,val=104] tag[tag] fid[fid] afid[fid] uname[s] aname[s]"
msg Rattach = "size[4,val=end-&size] typ[1,val=105] tag[tag] qid[qid]"
#msg Terror = "size[4,val=end-&size] typ[1,val=106] tag[tag] illegal"
-msg Rerror = "size[4,val=end-&size] typ[1,val=107] tag[tag] ename[s]"
+msg Rerror = "size[4,val=end-&size] typ[1,val=107] tag[tag] errstr[s]"
msg Tflush = "size[4,val=end-&size] typ[1,val=108] tag[tag] oldtag[2]"
msg Rflush = "size[4,val=end-&size] typ[1,val=109] tag[tag]"
msg Twalk = "size[4,val=end-&size] typ[1,val=110] tag[tag] fid[fid] newfid[fid] nwname[2,max=16] nwname*(wname[s])"
diff --git a/lib9p/idl/2003-9P2000.p9p.9p b/lib9p/idl/2003-9P2000.p9p.9p
index 3f6a524..1d1c307 100644
--- a/lib9p/idl/2003-9P2000.p9p.9p
+++ b/lib9p/idl/2003-9P2000.p9p.9p
@@ -27,7 +27,7 @@ from ./2002-9P2000.9p import *
# e.g. you replace syscall:`open()` with lib9pclient:`fsopen()`).
#
# "Unfortunately", programs in plan9port must deal both with 9P files
-# and native "Unix" files; and need to turn an 9P FID into a native
+# and native "Unix" files; and need to turn a 9P FID into a native
# file descriptor. To do this, the `9pserve` program and lib9pclient
# add an extension call to 9P2000: Topenfd/Ropenfd/fsopenfd().
#
diff --git a/lib9p/idl/2005-9P2000.u.9p b/lib9p/idl/2005-9P2000.u.9p
index 6c2f2dc..446385c 100644
--- a/lib9p/idl/2005-9P2000.u.9p
+++ b/lib9p/idl/2005-9P2000.u.9p
@@ -17,15 +17,15 @@ num nuid = 4
num errno = 4
"NOERROR = 0"
-struct stat += "file_extension[s]"
- "file_owner_n_uid[nuid]"
- "file_owner_n_gid[nuid]"
- "file_last_modified_n_uid[nuid]"
+struct stat += "extension[s]"
+ "owner_unum[nuid]"
+ "owner_gnum[nuid]"
+ "last_modifier_unum[nuid]"
-msg Tauth += "n_uid[nuid]"
-msg Tattach += "n_uid[nuid]"
+msg Tauth += "unum[nuid]"
+msg Tattach += "unum[nuid]"
-msg Rerror += "errno[errno]"
+msg Rerror += "errnum[errno]"
bitfield dm += "bit 23=DEVICE"
"bit 21=PIPE"
diff --git a/lib9p/idl/2010-9P2000.L.9p b/lib9p/idl/2010-9P2000.L.9p
index d81a15b..5eb7d5c 100644
--- a/lib9p/idl/2010-9P2000.L.9p
+++ b/lib9p/idl/2010-9P2000.L.9p
@@ -1,3 +1,6 @@
+# lib9p/idl/2010-9P2000.L.9p - Generated by `lib9p/idl/2010-9P2000.L.9p.gen 3rd-party/linux-errno.txt`. DO NOT EDIT!
+# 3rd-party/linux-errno.txt - Generated from lib9p/linux-errno.txt.gen and linux.git v6.14. DO NOT EDIT!
+
# lib9p/idl/2010-9P2000.L.9p - Definitions of 9P2000.L messages
#
# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
@@ -8,12 +11,149 @@
# https://github.com/chaos/diod/blob/master/src/libnpfs/protocol.h
version "9P2000.L"
+# low-level types ##############################################################
+
from ./2002-9P2000.9p import tag, fid, s, qt, qid
-from ./2002-9P2000.9p import Rerror
-from ./2002-9P2000.9p import Tversion, Rversion, Tflush, Rflush, Twalk, Rwalk, Tread, Rread, Twrite, Rwrite, Tclunk, Rclunk, Tremove, Rremove
-from ./2005-9P2000.u.9p import nuid, errno, Tauth, Rauth, Tattach, Rattach
+from ./2005-9P2000.u.9p import nuid, errno
-#num errno += # TODO
+# BUG: The definitions of errno are not defined in the 9P2000.L
+# protocol spec, and Linux kernel errno values vary by architecture.
+# Most architectures share a "generic" list, but a handful (as of
+# Linux v6.14, Alpha, MIPS, PA-RISC, PowerPC, and SPARC) have their
+# own numbers. This IDL file lists the generic numbers.
+#
+# https://github.com/chaos/diod/issues/35
+num errno += "L_EPERM = 1" # Operation not permitted
+ "L_ENOENT = 2" # No such file or directory
+ "L_ESRCH = 3" # No such process
+ "L_EINTR = 4" # Interrupted system call
+ "L_EIO = 5" # I/O error
+ "L_ENXIO = 6" # No such device or address
+ "L_E2BIG = 7" # Argument list too long
+ "L_ENOEXEC = 8" # Exec format error
+ "L_EBADF = 9" # Bad file number
+ "L_ECHILD = 10" # No child processes
+ "L_EAGAIN = 11" # Try again
+ "L_ENOMEM = 12" # Out of memory
+ "L_EACCES = 13" # Permission denied
+ "L_EFAULT = 14" # Bad address
+ "L_ENOTBLK = 15" # Block device required
+ "L_EBUSY = 16" # Device or resource busy
+ "L_EEXIST = 17" # File exists
+ "L_EXDEV = 18" # Cross-device link
+ "L_ENODEV = 19" # No such device
+ "L_ENOTDIR = 20" # Not a directory
+ "L_EISDIR = 21" # Is a directory
+ "L_EINVAL = 22" # Invalid argument
+ "L_ENFILE = 23" # File table overflow
+ "L_EMFILE = 24" # Too many open files
+ "L_ENOTTY = 25" # Not a typewriter
+ "L_ETXTBSY = 26" # Text file busy
+ "L_EFBIG = 27" # File too large
+ "L_ENOSPC = 28" # No space left on device
+ "L_ESPIPE = 29" # Illegal seek
+ "L_EROFS = 30" # Read-only file system
+ "L_EMLINK = 31" # Too many links
+ "L_EPIPE = 32" # Broken pipe
+ "L_EDOM = 33" # Math argument out of domain of func
+ "L_ERANGE = 34" # Math result not representable
+ "L_EDEADLK = 35" # Resource deadlock would occur
+ "L_ENAMETOOLONG = 36" # File name too long
+ "L_ENOLCK = 37" # No record locks available
+ "L_ENOSYS = 38" # Invalid system call number
+ "L_ENOTEMPTY = 39" # Directory not empty
+ "L_ELOOP = 40" # Too many symbolic links encountered
+ "L_ENOMSG = 42" # No message of desired type
+ "L_EIDRM = 43" # Identifier removed
+ "L_ECHRNG = 44" # Channel number out of range
+ "L_EL2NSYNC = 45" # Level 2 not synchronized
+ "L_EL3HLT = 46" # Level 3 halted
+ "L_EL3RST = 47" # Level 3 reset
+ "L_ELNRNG = 48" # Link number out of range
+ "L_EUNATCH = 49" # Protocol driver not attached
+ "L_ENOCSI = 50" # No CSI structure available
+ "L_EL2HLT = 51" # Level 2 halted
+ "L_EBADE = 52" # Invalid exchange
+ "L_EBADR = 53" # Invalid request descriptor
+ "L_EXFULL = 54" # Exchange full
+ "L_ENOANO = 55" # No anode
+ "L_EBADRQC = 56" # Invalid request code
+ "L_EBADSLT = 57" # Invalid slot
+ "L_EBFONT = 59" # Bad font file format
+ "L_ENOSTR = 60" # Device not a stream
+ "L_ENODATA = 61" # No data available
+ "L_ETIME = 62" # Timer expired
+ "L_ENOSR = 63" # Out of streams resources
+ "L_ENONET = 64" # Machine is not on the network
+ "L_ENOPKG = 65" # Package not installed
+ "L_EREMOTE = 66" # Object is remote
+ "L_ENOLINK = 67" # Link has been severed
+ "L_EADV = 68" # Advertise error
+ "L_ESRMNT = 69" # Srmount error
+ "L_ECOMM = 70" # Communication error on send
+ "L_EPROTO = 71" # Protocol error
+ "L_EMULTIHOP = 72" # Multihop attempted
+ "L_EDOTDOT = 73" # RFS specific error
+ "L_EBADMSG = 74" # Not a data message
+ "L_EOVERFLOW = 75" # Value too large for defined data type
+ "L_ENOTUNIQ = 76" # Name not unique on network
+ "L_EBADFD = 77" # File descriptor in bad state
+ "L_EREMCHG = 78" # Remote address changed
+ "L_ELIBACC = 79" # Can not access a needed shared library
+ "L_ELIBBAD = 80" # Accessing a corrupted shared library
+ "L_ELIBSCN = 81" # .lib section in a.out corrupted
+ "L_ELIBMAX = 82" # Attempting to link in too many shared libraries
+ "L_ELIBEXEC = 83" # Cannot exec a shared library directly
+ "L_EILSEQ = 84" # Illegal byte sequence
+ "L_ERESTART = 85" # Interrupted system call should be restarted
+ "L_ESTRPIPE = 86" # Streams pipe error
+ "L_EUSERS = 87" # Too many users
+ "L_ENOTSOCK = 88" # Socket operation on non-socket
+ "L_EDESTADDRREQ = 89" # Destination address required
+ "L_EMSGSIZE = 90" # Message too long
+ "L_EPROTOTYPE = 91" # Protocol wrong type for socket
+ "L_ENOPROTOOPT = 92" # Protocol not available
+ "L_EPROTONOSUPPORT = 93" # Protocol not supported
+ "L_ESOCKTNOSUPPORT = 94" # Socket type not supported
+ "L_EOPNOTSUPP = 95" # Operation not supported on transport endpoint
+ "L_EPFNOSUPPORT = 96" # Protocol family not supported
+ "L_EAFNOSUPPORT = 97" # Address family not supported by protocol
+ "L_EADDRINUSE = 98" # Address already in use
+ "L_EADDRNOTAVAIL = 99" # Cannot assign requested address
+ "L_ENETDOWN = 100" # Network is down
+ "L_ENETUNREACH = 101" # Network is unreachable
+ "L_ENETRESET = 102" # Network dropped connection because of reset
+ "L_ECONNABORTED = 103" # Software caused connection abort
+ "L_ECONNRESET = 104" # Connection reset by peer
+ "L_ENOBUFS = 105" # No buffer space available
+ "L_EISCONN = 106" # Transport endpoint is already connected
+ "L_ENOTCONN = 107" # Transport endpoint is not connected
+ "L_ESHUTDOWN = 108" # Cannot send after transport endpoint shutdown
+ "L_ETOOMANYREFS = 109" # Too many references: cannot splice
+ "L_ETIMEDOUT = 110" # Connection timed out
+ "L_ECONNREFUSED = 111" # Connection refused
+ "L_EHOSTDOWN = 112" # Host is down
+ "L_EHOSTUNREACH = 113" # No route to host
+ "L_EALREADY = 114" # Operation already in progress
+ "L_EINPROGRESS = 115" # Operation now in progress
+ "L_ESTALE = 116" # Stale file handle
+ "L_EUCLEAN = 117" # Structure needs cleaning
+ "L_ENOTNAM = 118" # Not a XENIX named type file
+ "L_ENAVAIL = 119" # No XENIX semaphores available
+ "L_EISNAM = 120" # Is a named type file
+ "L_EREMOTEIO = 121" # Remote I/O error
+ "L_EDQUOT = 122" # Quota exceeded
+ "L_ENOMEDIUM = 123" # No medium found
+ "L_EMEDIUMTYPE = 124" # Wrong medium type
+ "L_ECANCELED = 125" # Operation Canceled
+ "L_ENOKEY = 126" # Required key not available
+ "L_EKEYEXPIRED = 127" # Key has expired
+ "L_EKEYREVOKED = 128" # Key has been revoked
+ "L_EKEYREJECTED = 129" # Key was rejected by service
+ "L_EOWNERDEAD = 130" # Owner died
+ "L_ENOTRECOVERABLE = 131" # State not recoverable
+ "L_ERFKILL = 132" # Operation not possible due to RF-kill
+ "L_EHWPOISON = 133" # Memory page has hardware error
num super_magic = 4
# See <linux/magic.h> (linux.git include/uapi/linux/magic.h).
@@ -168,8 +308,23 @@ num lock_status = 1
"ERROR=2"
"GRACE=3"
+# 9P2000 Operations (.L subset) ################################################
+
+from ./2002-9P2000.9p import Tversion, Rversion
+from ./2002-9P2000.9p import Tflush, Rflush
+from ./2002-9P2000.9p import Twalk, Rwalk
+from ./2002-9P2000.9p import Tread, Rread, Twrite, Rwrite
+from ./2002-9P2000.9p import Tclunk, Rclunk
+from ./2002-9P2000.9p import Tremove, Rremove
+
+# 9P2000.u Operations (.L subset) ##############################################
+
+from ./2005-9P2000.u.9p import Tattach, Rattach, Tauth, Rauth
+
+# 9P2000.L Operations ##########################################################
+
#msg Tlerror = "size[4,val=end-&size] typ[1,val=6] tag[tag] illegal" # analogous to 106/Terror
-msg Rlerror = "size[4,val=end-&size] typ[1,val=7] tag[tag] ecode[errno]" # analogous to 107/Rerror
+msg Rlerror = "size[4,val=end-&size] typ[1,val=7] tag[tag] errnum[errno]" # analogous to 107/Rerror
msg Tstatfs = "size[4,val=end-&size] typ[1,val=8] tag[tag] fid[fid]"
msg Rstatfs = "size[4,val=end-&size] typ[1,val=9] tag[tag]" # Description | statfs | statvfs
"type[super_magic]" # Type of filesystem | f_type | -
diff --git a/lib9p/idl/2010-9P2000.L.9p.gen b/lib9p/idl/2010-9P2000.L.9p.gen
new file mode 100755
index 0000000..cb32585
--- /dev/null
+++ b/lib9p/idl/2010-9P2000.L.9p.gen
@@ -0,0 +1,282 @@
+#!/usr/bin/env python
+# lib9p/idl/2010-9P2000.L.9p.gen - Generate definitions of 9P2000.L messages
+import sys
+
+print(
+ f"# lib9p/idl/2010-9P2000.L.9p - Generated by `{' '.join(sys.argv)}`. DO NOT EDIT!"
+)
+errnos: dict[str, tuple[int, str]] = {}
+with open(sys.argv[1], "r", encoding="utf-8") as fh:
+ for line in fh:
+ if line.startswith("#"):
+ print(line)
+ continue
+ _num, _name, _desc = line.split(maxsplit=2)
+ errnos[_name] = (int(_num), _desc.strip())
+print(
+ """
+# lib9p/idl/2010-9P2000.L.9p - Definitions of 9P2000.L messages
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+# "9P2000.L" Linux extension
+# https://github.com/chaos/diod/blob/master/protocol.md
+# https://github.com/chaos/diod/blob/master/src/libnpfs/protocol.h
+version "9P2000.L"
+
+# low-level types ##############################################################
+
+from ./2002-9P2000.9p import tag, fid, s, qt, qid
+from ./2005-9P2000.u.9p import nuid, errno
+
+# BUG: The definitions of errno are not defined in the 9P2000.L
+# protocol spec, and Linux kernel errno values vary by architecture.
+# Most architectures share a "generic" list, but a handful (as of
+# Linux v6.14, Alpha, MIPS, PA-RISC, PowerPC, and SPARC) have their
+# own numbers. This IDL file lists the generic numbers.
+#
+# https://github.com/chaos/diod/issues/35
+""".strip()
+)
+
+prefix = "num errno += "
+namelen = max(len(name) for name in errnos)
+numlen = max(len(str(num)) for (num, desc) in errnos.values())
+for name, (num, desc) in errnos.items():
+ print(f'{prefix}"L_{name:<{namelen}} = {num:>{numlen}}" # {desc}')
+ prefix = " " * len(prefix)
+print()
+
+print(
+ """
+num super_magic = 4
+ # See <linux/magic.h> (linux.git include/uapi/linux/magic.h).
+ #
+ # To quote `util-linux.git:include/statfs_magic.h`:
+ # "Unfortunately, Linux kernel header file <linux/magic.h> is
+ # incomplete mess and kernel returns by statfs f_type many numbers
+ # that are nowhere specified (in API)."
+ #
+ # util-linux <statfs_magic.h> is also incomplete. As is the
+ # statfs(2) man-page.
+ #
+ # I'm working on a patchset to the kernel to get <linux/magic.h>
+ # to be complete, but in the mean-time I'm just not going to
+ # bother with putting a list here.
+ #
+ # TODO
+ "V9FS_MAGIC=0x01021997"
+
+# "L"inux "O"pen flags (flags to pass to Tlopen and Tlcreate)
+#
+# The values are not specified in in protocol.md, but are specified in
+# protocol.h (and are different than the Linux kernel's values, which
+# vary by architecture).
+bitfield lo = 4
+ "bit 0=num(MODE)" # low bit of the 2-bit RDONLY/WRONLY/RDWR/NOACCESS enum
+ "bit 1=num(MODE)" # high bit of the 2-bit RDONLY/WRONLY/RDWR/NOACCESS enum
+ #"bit 2=unused"
+ #"bit 3=unused"
+ #"bit 4=unused"
+ #"bit 5=unused"
+ "bit 6=CREATE"
+ "bit 7=EXCL"
+ "bit 8=NOCTTY"
+ "bit 9=TRUNC"
+ "bit 10=APPEND"
+ "bit 11=NONBLOCK"
+ "bit 12=DSYNC"
+ "bit 13=BSD_FASYNC"
+ "bit 14=DIRECT"
+ "bit 15=LARGEFILE"
+ "bit 16=DIRECTORY"
+ "bit 17=NOFOLLOW"
+ "bit 18=NOATIME"
+ "bit 19=CLOEXEC"
+ "bit 20=SYNC"
+
+ "num(MODE) RDONLY = 0"
+ "num(MODE) WRONLY = 1"
+ "num(MODE) RDWR = 2"
+ "num(MODE) NOACCESS = 3"
+
+ "mask FLAG = 0b111111111111111000000"
+
+# "D"irentry "T"ype
+#
+# These match the Linux kernel's values.
+num dt = 1
+ "UNKNOWN = 0"
+ "PIPE = 1"
+ "CHAR_DEV = 2"
+ "DIRECTORY = 4"
+ "BLOCK_DEV = 6" # proof it's not a bitfield
+ "REGULAR = 8"
+ "SYMLINK = 10" # proof it's not a bitfield
+ "SOCKET = 12" # proof it's not a bitfield
+ "_WHITEOUT = 14" # proof it's not a bitfield
+
+# Mode
+#
+# These match the Linux kernel's values. Why is this 32-bits wide
+# instead of just 16? Who knows?
+bitfield mode = 4
+ #...
+ "bit 15=num(FMT)" # bit of the 4-bit FMT_ enum
+ "bit 14=num(FMT)" # bit of the 4-bit FMT_ enum
+ "bit 13=num(FMT)" # bit of the 4-bit FMT_ enum
+ "bit 12=num(FMT)" # bit of the 4-bit FMT_ enum
+ #...
+ "bit 11=PERM_SETGROUP"
+ "bit 10=PERM_SETUSER"
+ "bit 9=PERM_STICKY"
+ "bit 8=PERM_OWNER_R"
+ "bit 7=PERM_OWNER_W"
+ "bit 6=PERM_OWNER_X"
+ "bit 5=PERM_GROUP_R"
+ "bit 4=PERM_GROUP_W"
+ "bit 3=PERM_GROUP_X"
+ "bit 2=PERM_OTHER_R"
+ "bit 1=PERM_OTHER_W"
+ "bit 0=PERM_OTHER_X"
+
+ "num(FMT) PIPE = dt.PIPE<<12"
+ "num(FMT) CHAR_DEV = dt.CHAR_DEV<<12"
+ "num(FMT) DIRECTORY = dt.DIRECTORY<<12"
+ "num(FMT) BLOCK_DEV = dt.BLOCK_DEV<<12"
+ "num(FMT) REGULAR = dt.REGULAR<<12"
+ "num(FMT) SYMLINK = dt.SYMLINK<<12"
+ "num(FMT) SOCKET = dt.SOCKET<<12"
+
+ "mask PERM = 07777" # PERM_*
+
+# A boolean value that is for some reason 4 bytes wide.
+num b4 = 4
+ "FALSE=0"
+ "TRUE=1"
+ # all other values are true also
+
+bitfield getattr = 8
+ "bit 0=MODE"
+ "bit 1=NLINK"
+ "bit 2=UID"
+ "bit 3=GID"
+ "bit 4=RDEV"
+ "bit 5=ATIME"
+ "bit 6=MTIME"
+ "bit 7=CTIME"
+ "bit 8=INO"
+ "bit 9=SIZE"
+ "bit 10=BLOCKS"
+
+ "bit 11=BTIME"
+ "bit 12=GEN"
+ "bit 13=DATA_VERSION"
+
+ "alias BASIC=0x000007ff" # Mask for fields up to BLOCKS
+ "alias ALL =0x00003fff" # Mask for All fields above
+
+bitfield setattr = 4
+ "bit 0=MODE"
+ "bit 1=UID"
+ "bit 2=GID"
+ "bit 3=SIZE"
+ "bit 4=ATIME"
+ "bit 5=MTIME"
+ "bit 6=CTIME"
+ "bit 7=ATIME_SET"
+ "bit 8=MTIME_SET"
+
+num lock_type = 1
+ "RDLCK=0"
+ "WRLCK=1"
+ "UNLCK=2"
+
+bitfield lock_flags = 4
+ "bit 0=BLOCK"
+ "bit 1=RECLAIM"
+
+num lock_status = 1
+ "SUCCESS=0"
+ "BLOCKED=1"
+ "ERROR=2"
+ "GRACE=3"
+
+# 9P2000 Operations (.L subset) ################################################
+
+from ./2002-9P2000.9p import Tversion, Rversion
+from ./2002-9P2000.9p import Tflush, Rflush
+from ./2002-9P2000.9p import Twalk, Rwalk
+from ./2002-9P2000.9p import Tread, Rread, Twrite, Rwrite
+from ./2002-9P2000.9p import Tclunk, Rclunk
+from ./2002-9P2000.9p import Tremove, Rremove
+
+# 9P2000.u Operations (.L subset) ##############################################
+
+from ./2005-9P2000.u.9p import Tattach, Rattach, Tauth, Rauth
+
+# 9P2000.L Operations ##########################################################
+
+#msg Tlerror = "size[4,val=end-&size] typ[1,val=6] tag[tag] illegal" # analogous to 106/Terror
+msg Rlerror = "size[4,val=end-&size] typ[1,val=7] tag[tag] errnum[errno]" # analogous to 107/Rerror
+msg Tstatfs = "size[4,val=end-&size] typ[1,val=8] tag[tag] fid[fid]"
+msg Rstatfs = "size[4,val=end-&size] typ[1,val=9] tag[tag]" # Description | statfs | statvfs
+ "type[super_magic]" # Type of filesystem | f_type | -
+ "bsize[4]" # Block size in bytes | f_bsize | f_bsize
+ # - # Fragment size in bytes | f_frsize (since Linux 2.6) | f_frsize
+ "blocks[8]" # Size of FS in f_frsize units | f_blocks | f_blocks
+ "bfree[8]" # Number of free blocks | f_bfree | f_bfree
+ "bavail[8]" # Number of free blocks for unprivileged users | f_bavail | b_avail
+ "files[8]" # Number of inodes | f_files | f_files
+ "ffree[8]" # Number of free inodes | f_ffree | f_ffree
+ # - # Number of free inodes for unprivileged users | - | f_favail
+ "fsid[8]" # Filesystem instance ID | f_fsid | f_fsid
+ # - # Mount flags | f_flags (since Linux 2.6.36) | f_flag
+ "namelen[4]" # Maximum filename length | f_namemax | f_namemax
+msg Tlopen = "size[4,val=end-&size] typ[1,val=12] tag[tag] fid[fid] flags[lo]" # analogous to 112/Topen
+msg Rlopen = "size[4,val=end-&size] typ[1,val=13] tag[tag] qid[qid] iounit[4]" # analogous to 113/Ropen
+msg Tlcreate = "size[4,val=end-&size] typ[1,val=14] tag[tag] fid[fid] name[s] flags[lo] mode[mode] gid[nuid]" # analogous to 114/Tcreate
+msg Rlcreate = "size[4,val=end-&size] typ[1,val=15] tag[tag] qid[qid] iounit[4]" # analogous to 115/Rcreate
+msg Tsymlink = "size[4,val=end-&size] typ[1,val=16] tag[tag] fid[fid] name[s] symtgt[s] gid[nuid]"
+msg Rsymlink = "size[4,val=end-&size] typ[1,val=17] tag[tag] qid[qid]"
+msg Tmknod = "size[4,val=end-&size] typ[1,val=18] tag[tag] dfid[fid] name[s] mode[mode] major[4] minor[4] gid[nuid]"
+msg Rmknod = "size[4,val=end-&size] typ[1,val=19] tag[tag] qid[qid]"
+msg Trename = "size[4,val=end-&size] typ[1,val=20] tag[tag] fid[fid] dfid[fid] name[s]"
+msg Rrename = "size[4,val=end-&size] typ[1,val=21] tag[tag]"
+msg Treadlink = "size[4,val=end-&size] typ[1,val=22] tag[tag] fid[fid]"
+msg Rreadlink = "size[4,val=end-&size] typ[1,val=23] tag[tag] target[s]"
+msg Tgetattr = "size[4,val=end-&size] typ[1,val=24] tag[tag] fid[fid] request_mask[getattr]"
+msg Rgetattr = "size[4,val=end-&size] typ[1,val=25] tag[tag] valid[getattr] qid[qid] mode[mode] uid[nuid] gid[nuid] nlink[8]"
+ "rdev[8] filesize[8] blksize[8] blocks[8]"
+ "atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8]"
+ "ctime_sec[8] ctime_nsec[8] btime_sec[8] btime_nsec[8]"
+ "gen[8] data_version[8]"
+msg Tsetattr = "size[4,val=end-&size] typ[1,val=26] tag[tag] fid[fid] valid[setattr] mode[mode] uid[nuid] gid[nuid] filesize[8] atime_sec[8] atime_nsec[8] mtime_sec[8] mtime_nsec[8]"
+msg Rsetattr = "size[4,val=end-&size] typ[1,val=27] tag[tag]"
+#...
+msg Txattrwalk = "size[4,val=end-&size] typ[1,val=30] tag[tag] fid[fid] newfid[fid] name[s]"
+msg Rxattrwalk = "size[4,val=end-&size] typ[1,val=31] tag[tag] attr_size[8]"
+msg Txattrcreate = "size[4,val=end-&size] typ[1,val=32] tag[tag] fid[fid] name[s] attr_size[8] flags[4]"
+msg Rxattrcreate = "size[4,val=end-&size] typ[1,val=33] tag[tag]"
+#...
+msg Treaddir = "size[4,val=end-&size] typ[1,val=40] tag[tag] fid[fid] offset[8] count[4]"
+msg Rreaddir = "size[4,val=end-&size] typ[1,val=41] tag[tag] count[4] count*(data[1])" # data is "qid[qid] offset[8] type[dt] name[s]"
+#...
+msg Tfsync = "size[4,val=end-&size] typ[1,val=50] tag[tag] fid[fid] datasync[b4]"
+msg Rfsync = "size[4,val=end-&size] typ[1,val=51] tag[tag]"
+msg Tlock = "size[4,val=end-&size] typ[1,val=52] tag[tag] fid[fid] type[lock_type] flags[lock_flags] start[8] length[8] proc_id[4] client_id[s]"
+msg Rlock = "size[4,val=end-&size] typ[1,val=53] tag[tag] status[lock_status]"
+msg Tgetlock = "size[4,val=end-&size] typ[1,val=54] tag[tag] fid[fid] type[lock_type] start[8] length[8] proc_id[4] client_id[s]"
+msg Rgetlock = "size[4,val=end-&size] typ[1,val=55] tag[tag] type[lock_type] start[8] length[8] proc_id[4] client_id[s]"
+# ...
+msg Tlink = "size[4,val=end-&size] typ[1,val=70] tag[tag] dfid[fid] fid[fid] name[s]"
+msg Rlink = "size[4,val=end-&size] typ[1,val=71] tag[tag]"
+msg Tmkdir = "size[4,val=end-&size] typ[1,val=72] tag[tag] dfid[fid] name[s] mode[mode] gid[nuid]"
+msg Rmkdir = "size[4,val=end-&size] typ[1,val=73] tag[tag] qid[qid]"
+msg Trenameat = "size[4,val=end-&size] typ[1,val=74] tag[tag] olddirfid[fid] oldname[s] newdirfid[fid] newname[s]"
+msg Rrenameat = "size[4,val=end-&size] typ[1,val=75] tag[tag]"
+msg Tunlinkat = "size[4,val=end-&size] typ[1,val=76] tag[tag] dirfd[fid] name[s] flags[4]"
+msg Runlinkat = "size[4,val=end-&size] typ[1,val=77] tag[tag]"
+""".strip()
+)
diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py
index 2d09217..3133cc4 100644
--- a/lib9p/idl/__init__.py
+++ b/lib9p/idl/__init__.py
@@ -647,17 +647,16 @@ def re_string(grpname: str) -> str:
re_line_version = f"version\\s+{re_string('version')}"
re_line_import = f"from\\s+(?P<file>\\S+)\\s+import\\s+(?P<syms>{re_impname}(?:\\s*,\\s*{re_impname})*)"
re_line_num = f"num\\s+(?P<name>{re_symname})\\s*=\\s*(?P<prim>{re_priname})"
+re_line_num_ = f"num\\s+(?P<name>{re_symname})\\s*\\+=\\s*{re_string('spec')}"
re_line_bitfield = f"bitfield\\s+(?P<name>{re_symname})\\s*=\\s*(?P<prim>{re_priname})"
-re_line_bitfield_ = (
- f"bitfield\\s+(?P<name>{re_symname})\\s*\\+=\\s*{re_string('member')}"
-)
+re_line_bitfield_ = f"bitfield\\s+(?P<name>{re_symname})\\s*\\+=\\s*{re_string('spec')}"
re_line_struct = (
f"struct\\s+(?P<name>{re_symname})\\s*(?P<op>\\+?=)\\s*{re_string('members')}"
)
re_line_msg = (
f"msg\\s+(?P<name>{re_msgname})\\s*(?P<op>\\+?=)\\s*{re_string('members')}"
)
-re_line_cont = f"\\s+{re_string('specs')}" # could be bitfield/struct/msg
+re_line_cont = f"\\s+{re_string('spec')}" # could be bitfield/struct/msg
def parse_file(
@@ -741,6 +740,11 @@ def parse_file(
raise ValueError(f"duplicate type name {num.typname!r}")
env[num.typname] = num
prev = num
+ elif m := re.fullmatch(re_line_num_, line):
+ num = get_type(env, m.group("name"), Number)
+ parse_numspec(env, version, num, m.group("spec"))
+
+ prev = num
elif m := re.fullmatch(re_line_bitfield, line):
prim = env[m.group("prim")]
assert isinstance(prim, Primitive)
@@ -754,7 +758,7 @@ def parse_file(
prev = bf
elif m := re.fullmatch(re_line_bitfield_, line):
bf = get_type(env, m.group("name"), Bitfield)
- parse_bitspec(env, version, bf, m.group("member"))
+ parse_bitspec(env, version, bf, m.group("spec"))
prev = bf
elif m := re.fullmatch(re_line_struct, line):
@@ -798,11 +802,11 @@ def parse_file(
elif m := re.fullmatch(re_line_cont, line):
match prev:
case Bitfield():
- parse_bitspec(env, version, prev, m.group("specs"))
+ parse_bitspec(env, version, prev, m.group("spec"))
case Number():
- parse_numspec(env, version, prev, m.group("specs"))
+ parse_numspec(env, version, prev, m.group("spec"))
case Struct(): # and Message()
- parse_members(version, env, prev, m.group("specs"))
+ parse_members(version, env, prev, m.group("spec"))
case _:
raise SyntaxError(
"continuation line must come after a bitfield, struct, or msg line"
diff --git a/lib9p/include/lib9p/linux-errno.h b/lib9p/include/lib9p/linux-errno.h
deleted file mode 100644
index e7c74f5..0000000
--- a/lib9p/include/lib9p/linux-errno.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* lib9p/linux-errno.h - Generated by `lib9p/include/lib9p/linux-errno.h.gen 3rd-party/linux-errno.txt`. DO NOT EDIT! */
-/* 3rd-party/linux-errno.txt - Generated from build-aux/linux-errno.txt.gen and linux.git v6.7. DO NOT EDIT! */
-
-#ifndef _LIB9P_LINUX_ERRNO_H_
-#define _LIB9P_LINUX_ERRNO_H_
-
-#define LINUX_EPERM 1 /* Operation not permitted */
-#define LINUX_ENOENT 2 /* No such file or directory */
-#define LINUX_ESRCH 3 /* No such process */
-#define LINUX_EINTR 4 /* Interrupted system call */
-#define LINUX_EIO 5 /* I/O error */
-#define LINUX_ENXIO 6 /* No such device or address */
-#define LINUX_E2BIG 7 /* Argument list too long */
-#define LINUX_ENOEXEC 8 /* Exec format error */
-#define LINUX_EBADF 9 /* Bad file number */
-#define LINUX_ECHILD 10 /* No child processes */
-#define LINUX_EAGAIN 11 /* Try again */
-#define LINUX_ENOMEM 12 /* Out of memory */
-#define LINUX_EACCES 13 /* Permission denied */
-#define LINUX_EFAULT 14 /* Bad address */
-#define LINUX_ENOTBLK 15 /* Block device required */
-#define LINUX_EBUSY 16 /* Device or resource busy */
-#define LINUX_EEXIST 17 /* File exists */
-#define LINUX_EXDEV 18 /* Cross-device link */
-#define LINUX_ENODEV 19 /* No such device */
-#define LINUX_ENOTDIR 20 /* Not a directory */
-#define LINUX_EISDIR 21 /* Is a directory */
-#define LINUX_EINVAL 22 /* Invalid argument */
-#define LINUX_ENFILE 23 /* File table overflow */
-#define LINUX_EMFILE 24 /* Too many open files */
-#define LINUX_ENOTTY 25 /* Not a typewriter */
-#define LINUX_ETXTBSY 26 /* Text file busy */
-#define LINUX_EFBIG 27 /* File too large */
-#define LINUX_ENOSPC 28 /* No space left on device */
-#define LINUX_ESPIPE 29 /* Illegal seek */
-#define LINUX_EROFS 30 /* Read-only file system */
-#define LINUX_EMLINK 31 /* Too many links */
-#define LINUX_EPIPE 32 /* Broken pipe */
-#define LINUX_EDOM 33 /* Math argument out of domain of func */
-#define LINUX_ERANGE 34 /* Math result not representable */
-#define LINUX_EDEADLK 35 /* Resource deadlock would occur */
-#define LINUX_ENAMETOOLONG 36 /* File name too long */
-#define LINUX_ENOLCK 37 /* No record locks available */
-#define LINUX_ENOSYS 38 /* Invalid system call number */
-#define LINUX_ENOTEMPTY 39 /* Directory not empty */
-#define LINUX_ELOOP 40 /* Too many symbolic links encountered */
-#define LINUX_ENOMSG 42 /* No message of desired type */
-#define LINUX_EIDRM 43 /* Identifier removed */
-#define LINUX_ECHRNG 44 /* Channel number out of range */
-#define LINUX_EL2NSYNC 45 /* Level 2 not synchronized */
-#define LINUX_EL3HLT 46 /* Level 3 halted */
-#define LINUX_EL3RST 47 /* Level 3 reset */
-#define LINUX_ELNRNG 48 /* Link number out of range */
-#define LINUX_EUNATCH 49 /* Protocol driver not attached */
-#define LINUX_ENOCSI 50 /* No CSI structure available */
-#define LINUX_EL2HLT 51 /* Level 2 halted */
-#define LINUX_EBADE 52 /* Invalid exchange */
-#define LINUX_EBADR 53 /* Invalid request descriptor */
-#define LINUX_EXFULL 54 /* Exchange full */
-#define LINUX_ENOANO 55 /* No anode */
-#define LINUX_EBADRQC 56 /* Invalid request code */
-#define LINUX_EBADSLT 57 /* Invalid slot */
-#define LINUX_EBFONT 59 /* Bad font file format */
-#define LINUX_ENOSTR 60 /* Device not a stream */
-#define LINUX_ENODATA 61 /* No data available */
-#define LINUX_ETIME 62 /* Timer expired */
-#define LINUX_ENOSR 63 /* Out of streams resources */
-#define LINUX_ENONET 64 /* Machine is not on the network */
-#define LINUX_ENOPKG 65 /* Package not installed */
-#define LINUX_EREMOTE 66 /* Object is remote */
-#define LINUX_ENOLINK 67 /* Link has been severed */
-#define LINUX_EADV 68 /* Advertise error */
-#define LINUX_ESRMNT 69 /* Srmount error */
-#define LINUX_ECOMM 70 /* Communication error on send */
-#define LINUX_EPROTO 71 /* Protocol error */
-#define LINUX_EMULTIHOP 72 /* Multihop attempted */
-#define LINUX_EDOTDOT 73 /* RFS specific error */
-#define LINUX_EBADMSG 74 /* Not a data message */
-#define LINUX_EOVERFLOW 75 /* Value too large for defined data type */
-#define LINUX_ENOTUNIQ 76 /* Name not unique on network */
-#define LINUX_EBADFD 77 /* File descriptor in bad state */
-#define LINUX_EREMCHG 78 /* Remote address changed */
-#define LINUX_ELIBACC 79 /* Can not access a needed shared library */
-#define LINUX_ELIBBAD 80 /* Accessing a corrupted shared library */
-#define LINUX_ELIBSCN 81 /* .lib section in a.out corrupted */
-#define LINUX_ELIBMAX 82 /* Attempting to link in too many shared libraries */
-#define LINUX_ELIBEXEC 83 /* Cannot exec a shared library directly */
-#define LINUX_EILSEQ 84 /* Illegal byte sequence */
-#define LINUX_ERESTART 85 /* Interrupted system call should be restarted */
-#define LINUX_ESTRPIPE 86 /* Streams pipe error */
-#define LINUX_EUSERS 87 /* Too many users */
-#define LINUX_ENOTSOCK 88 /* Socket operation on non-socket */
-#define LINUX_EDESTADDRREQ 89 /* Destination address required */
-#define LINUX_EMSGSIZE 90 /* Message too long */
-#define LINUX_EPROTOTYPE 91 /* Protocol wrong type for socket */
-#define LINUX_ENOPROTOOPT 92 /* Protocol not available */
-#define LINUX_EPROTONOSUPPORT 93 /* Protocol not supported */
-#define LINUX_ESOCKTNOSUPPORT 94 /* Socket type not supported */
-#define LINUX_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
-#define LINUX_EPFNOSUPPORT 96 /* Protocol family not supported */
-#define LINUX_EAFNOSUPPORT 97 /* Address family not supported by protocol */
-#define LINUX_EADDRINUSE 98 /* Address already in use */
-#define LINUX_EADDRNOTAVAIL 99 /* Cannot assign requested address */
-#define LINUX_ENETDOWN 100 /* Network is down */
-#define LINUX_ENETUNREACH 101 /* Network is unreachable */
-#define LINUX_ENETRESET 102 /* Network dropped connection because of reset */
-#define LINUX_ECONNABORTED 103 /* Software caused connection abort */
-#define LINUX_ECONNRESET 104 /* Connection reset by peer */
-#define LINUX_ENOBUFS 105 /* No buffer space available */
-#define LINUX_EISCONN 106 /* Transport endpoint is already connected */
-#define LINUX_ENOTCONN 107 /* Transport endpoint is not connected */
-#define LINUX_ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
-#define LINUX_ETOOMANYREFS 109 /* Too many references: cannot splice */
-#define LINUX_ETIMEDOUT 110 /* Connection timed out */
-#define LINUX_ECONNREFUSED 111 /* Connection refused */
-#define LINUX_EHOSTDOWN 112 /* Host is down */
-#define LINUX_EHOSTUNREACH 113 /* No route to host */
-#define LINUX_EALREADY 114 /* Operation already in progress */
-#define LINUX_EINPROGRESS 115 /* Operation now in progress */
-#define LINUX_ESTALE 116 /* Stale file handle */
-#define LINUX_EUCLEAN 117 /* Structure needs cleaning */
-#define LINUX_ENOTNAM 118 /* Not a XENIX named type file */
-#define LINUX_ENAVAIL 119 /* No XENIX semaphores available */
-#define LINUX_EISNAM 120 /* Is a named type file */
-#define LINUX_EREMOTEIO 121 /* Remote I/O error */
-#define LINUX_EDQUOT 122 /* Quota exceeded */
-#define LINUX_ENOMEDIUM 123 /* No medium found */
-#define LINUX_EMEDIUMTYPE 124 /* Wrong medium type */
-#define LINUX_ECANCELED 125 /* Operation Canceled */
-#define LINUX_ENOKEY 126 /* Required key not available */
-#define LINUX_EKEYEXPIRED 127 /* Key has expired */
-#define LINUX_EKEYREVOKED 128 /* Key has been revoked */
-#define LINUX_EKEYREJECTED 129 /* Key was rejected by service */
-#define LINUX_EOWNERDEAD 130 /* Owner died */
-#define LINUX_ENOTRECOVERABLE 131 /* State not recoverable */
-#define LINUX_ERFKILL 132 /* Operation not possible due to RF-kill */
-#define LINUX_EHWPOISON 133 /* Memory page has hardware error */
-
-#endif /* _LIB9P_LINUX_ERRNO_H_ */
diff --git a/lib9p/include/lib9p/linux-errno.h.gen b/lib9p/include/lib9p/linux-errno.h.gen
deleted file mode 100755
index 2c736a2..0000000
--- a/lib9p/include/lib9p/linux-errno.h.gen
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python
-# lib9p/linux-errno.h.gen - Generate a C header from a list of errno numbers
-#
-# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
-# SPDX-License-Identifier: AGPL-3.0-or-later
-
-import sys
-
-
-def print_errnos() -> None:
- print(
- f"/* lib9p/linux-errno.h - Generated by `{' '.join(sys.argv)}`. DO NOT EDIT! */"
- )
- errnos: dict[str, tuple[int, str]] = {}
- for txtlist in sys.argv[1:]:
- with open(txtlist, "r", encoding="utf-8") as fh:
- for line in fh:
- if line.startswith("#"):
- print(f"/* {line[1:].strip()} */")
- continue
- _num, name, desc = line.split(maxsplit=2)
- num = int(_num)
- desc = desc.strip()
- errnos[name] = (num, desc)
- print()
- print("#ifndef _LIB9P_LINUX_ERRNO_H_")
- print("#define _LIB9P_LINUX_ERRNO_H_")
- print()
- namelen = max(len(name) for name in errnos)
- numlen = max(len(str(num)) for (num, desc) in errnos.values())
- for name, [num, msg] in errnos.items():
- print(f"#define LINUX_{name:<{namelen}} {num:>{numlen}} /* {msg} */")
- print()
- print("#endif /* _LIB9P_LINUX_ERRNO_H_ */")
-
-
-if __name__ == "__main__":
- print_errnos()
diff --git a/lib9p/include/lib9p/srv.h b/lib9p/include/lib9p/srv.h
deleted file mode 100644
index 070cf5a..0000000
--- a/lib9p/include/lib9p/srv.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/* lib9p/srv.h - 9P server
- *
- * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-#ifndef _LIB9P_SRV_H_
-#define _LIB9P_SRV_H_
-
-#include <libcr/coroutine.h>
-#include <libcr_ipc/rpc.h>
-#include <libcr_ipc/chan.h>
-#include <libhw/generic/net.h>
-#include <libmisc/assert.h>
-#include <libmisc/private.h>
-#include <libobj/obj.h>
-
-#include <lib9p/9p.h>
-
-/* context ********************************************************************/
-
-CR_CHAN_DECLARE(_lib9p_srv_flushch, bool)
-
-struct lib9p_srv_ctx {
- struct lib9p_ctx basectx;
- uint32_t uid;
- struct lib9p_s uname;
-
- BEGIN_PRIVATE(LIB9P_SRV_H);
- _lib9p_srv_flushch_t _flushch;
- END_PRIVATE(LIB9P_SRV_H);
-};
-
-bool lib9p_srv_flush_requested(struct lib9p_srv_ctx *ctx);
-
-int lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx);
-
-/* interface definitions ******************************************************/
-
-lo_interface lib9p_srv_fio;
-lo_interface lib9p_srv_dio;
-
-/* FIXME: I don't like that the pointers returned by stat() and
- * pread() have to remain live after they return. Perhaps a
- * `respond()`-callback? But that just reads as gross in C.
- *
- * FIXME: It would be nice if pread() could return more than 1 iovec.
- */
-#define lib9p_srv_file_LO_IFACE \
- /* resource management **********************************************/ \
- \
- /** \
- * free() is be called when all FIDs associated with the file are \
- * clunked. \
- * \
- * free() MUST NOT error. \
- */ \
- LO_FUNC(void , free ) \
- \
- /** \
- * qid() is called frequently and returns the current QID of the file. \
- * The .path field MUST never change, the .type field may change in \
- * response to wstat() calls (but the QT_DIR bit MUST NOT change), and \
- * the .vers field may change frequently in response to any number of \
- * things (wstat(), write(), or non-9P events). \
- * \
- * qid() MUST NOT error. \
- */ \
- LO_FUNC(struct lib9p_qid , qid ) \
- \
- /* non-"opened" generic I/O *****************************************/ \
- \
- LO_FUNC(struct lib9p_stat , stat , struct lib9p_srv_ctx *) \
- LO_FUNC(void , wstat , struct lib9p_srv_ctx *, \
- struct lib9p_stat new) \
- LO_FUNC(void , remove , struct lib9p_srv_ctx *) \
- \
- /* non-"opened" directory I/O ***************************************/ \
- \
- LO_FUNC(lo_interface lib9p_srv_file, dwalk , struct lib9p_srv_ctx *, \
- struct lib9p_s childname) \
- LO_FUNC(lo_interface lib9p_srv_file, dcreate, struct lib9p_srv_ctx *, \
- struct lib9p_s childname, \
- lib9p_dm_t perm, \
- lib9p_o_t flags) \
- \
- /* open() for I/O ***************************************************/ \
- \
- LO_FUNC(lo_interface lib9p_srv_fio , fopen , struct lib9p_srv_ctx *, \
- bool rd, bool wr, \
- bool trunc) \
- LO_FUNC(lo_interface lib9p_srv_dio , dopen , struct lib9p_srv_ctx *)
-LO_INTERFACE(lib9p_srv_file);
-
-#define lib9p_srv_fio_LO_IFACE \
- LO_FUNC(struct lib9p_qid , qid ) \
- LO_FUNC(void , iofree ) \
- LO_FUNC(uint32_t , iounit ) \
- LO_FUNC(void , pread , struct lib9p_srv_ctx *, \
- uint32_t byte_count, \
- uint64_t byte_offset, \
- struct iovec *ret) \
- LO_FUNC(uint32_t , pwrite , struct lib9p_srv_ctx *, \
- void *buf, \
- uint32_t byte_count, \
- uint64_t byte_offset)
-LO_INTERFACE(lib9p_srv_fio);
-
-/* FIXME: The dio interface just feels clunky. I'm not in a rush to
- * change it because util9p_static_dir is already implemented and I
- * don't anticipate the sbc-harness needing another dio
- * implementation. But if I wanted lib9p to be used outside of
- * sbc-harness, this is one of the first things that I'd want to
- * change.
- */
-#define lib9p_srv_dio_LO_IFACE \
- LO_FUNC(struct lib9p_qid , qid ) \
- LO_FUNC(void , iofree ) \
- LO_FUNC(size_t /* <- obj cnt */ , dread , struct lib9p_srv_ctx *, \
- uint8_t *buf, \
- /* num bytes -> */ uint32_t byte_count, \
- /* starting at this object -> */ size_t obj_offset)
-LO_INTERFACE(lib9p_srv_dio);
-
-#define LIB9P_SRV_NOTDIR(TYP, NAM) \
- static lo_interface lib9p_srv_file NAM##_dwalk (TYP *, struct lib9p_srv_ctx *, struct lib9p_s) { assert_notreached("not a directory"); } \
- static lo_interface lib9p_srv_file NAM##_dcreate(TYP *, struct lib9p_srv_ctx *, struct lib9p_s, lib9p_dm_t, lib9p_o_t) { assert_notreached("not a directory"); } \
- static lo_interface lib9p_srv_dio NAM##_dopen (TYP *, struct lib9p_srv_ctx *) { assert_notreached("not a directory"); }
-
-#define LIB9P_SRV_NOTFILE(TYP, NAM) \
- static lo_interface lib9p_srv_fio NAM##_fopen (TYP *, struct lib9p_srv_ctx *, bool, bool, bool) { assert_notreached("not a file"); }
-
-/* main server entrypoints ****************************************************/
-
-CR_RPC_DECLARE(_lib9p_srv_reqch, struct _lib9p_srv_req *, bool)
-
-struct lib9p_srv {
- /* Things you provide */
- void /*TODO*/ (*auth )(struct lib9p_srv_ctx *, struct lib9p_s treename); /* optional */
- lo_interface lib9p_srv_file (*rootdir)(struct lib9p_srv_ctx *, struct lib9p_s treename);
-
- /* For internal use */
- BEGIN_PRIVATE(LIB9P_SRV_H);
- unsigned int readers;
- unsigned int writers;
- _lib9p_srv_reqch_t _reqch;
- END_PRIVATE(LIB9P_SRV_H);
-};
-
-/**
- * In an infinite loop, accept a connection and read messages from it until
- * close; dispatching requests to a pool of lib9p_srv_write_cr() coroutines
- * with the same `srv`.
- *
- * Will just close the connection if a T-message has a size[4] <7.
- *
- * @param srv: The server configuration and state; has an associated pool of
- * lib9p_srv_write_cr() coroutines.
- * @param listener: The listener object to accept connections from.
- *
- * @errno LINUX_EMSGSIZE T-message has size[4] bigger than max_msg_size
- * @errno LINUX_EDOM Tversion specified an impossibly small max_msg_size
- * @errno LINUX_EOPNOTSUPP T-message has an R-message type, or an unrecognized T-message type
- * @errno LINUX_EBADMSG T-message has wrong size[4] for its content, or has invalid UTF-8
- * @errno LINUX_ERANGE R-message does not fit into max_msg_size
- */
-[[noreturn]] void lib9p_srv_read_cr(struct lib9p_srv *srv, lo_interface net_stream_listener listener);
-
-/**
- * Service requests to the `struct lib9p_srv *srv` argument that have been
- * read by lib9p_srv_read_cr().
- *
- * @param struct lib9p_srv *srv: The server configuration and state; has an
- * associated pool of lib9p_srv_read_cr()
- * coroutines.
- */
-COROUTINE lib9p_srv_write_cr(void *_srv);
-
-#endif /* _LIB9P_SRV_H_ */
diff --git a/build-aux/linux-errno.txt.gen b/lib9p/linux-errno.txt.gen
index f94178f..687e58b 100755
--- a/build-aux/linux-errno.txt.gen
+++ b/lib9p/linux-errno.txt.gen
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
-# build-aux/linux-errno.txt.gen - Generate a listing of Linux kernel errnos
+# lib9p/linux-errno.txt.gen - Generate a listing of Linux kernel errnos
#
-# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
set -e
diff --git a/lib9p/map.h b/lib9p/map.h
deleted file mode 100644
index c5eab0f..0000000
--- a/lib9p/map.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* lib9p/map.h - A really dumb map/dict data structure
- *
- * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-/**
- * `#define` `NAME`, `KEY_T`, `VAL_T`, and `CAP`; then `#include
- * "map.h".
- */
-
-#ifndef NAME
- #error NAME must be defined
-#endif
-#ifndef KEY_T
- #error KEY_T must be defined
-#endif
-#ifndef VAL_T
- #error VAL_T must be defined
-#endif
-#ifndef CAP
- #error CAP must be defined
-#endif
-
-#ifndef MAP_KEY
-#define MAP_KV(TNAME) LM_CAT3(_,TNAME,_kv)
-#define MAP_METHOD(TNAME, MNAME) LM_CAT3(TNAME,_,MNAME)
-#define MAP_FOREACH(m, k, v) \
- for (size_t i = 0; i < LM_ARRAY_LEN((m)->items); i++) \
- if ( ({ k = (m)->items[i].key; v = &(m)->items[i].val; (m)->items[i].set; }) )
-#endif
-
-/* This implementation is just an array that we brute-force search
- * over for a slot. I don't want to use the heap, which means
- * statically-sized maps, and I'm probably going to choose a low
- * static size, so this is fine. */
-
-struct MAP_KV(NAME) {
- bool set;
- KEY_T key;
- VAL_T val;
-};
-
-struct NAME {
- size_t len;
- struct MAP_KV(NAME) items[CAP];
-};
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-
-/**
- * Load an item from the map; return a pointer to the in-map value, or
- * NULL if the item is not in the map.
- */
-static VAL_T *MAP_METHOD(NAME,load)(struct NAME *m, KEY_T k) {
- if (!m->len)
- return NULL;
- for (size_t i = 0; i < LM_ARRAY_LEN(m->items); i++)
- if (m->items[i].set && m->items[i].key == k)
- return &(m->items[i].val);
- return NULL;
-}
-
-/**
- * Store an item into the map, perhaps replacing an existing value.
- * Return a pointer to the in-map value, or NULL if the map is full.
- */
-static VAL_T *MAP_METHOD(NAME,store)(struct NAME *m, KEY_T k, VAL_T v) {
- VAL_T *old = MAP_METHOD(NAME,load)(m, k);
- if (old) {
- *old = v;
- return old;
- }
- if (m->len == LM_ARRAY_LEN(m->items))
- return NULL;
- for (size_t i = 0; i < LM_ARRAY_LEN(m->items); i++)
- if (!m->items[i].set) {
- m->len++;
- m->items[i].set = true;
- m->items[i].key = k;
- m->items[i].val = v;
- return &(m->items[i].val);
- }
- assert_notreached("should have returned from inside for() loop");
-}
-
-/**
- * Delete an item from the map. Returns true if an item was deleted,
- * false if no such item was in the map.
- */
-static bool MAP_METHOD(NAME,del)(struct NAME *m, KEY_T k) {
- if (!m->len)
- return NULL;
- for (size_t i = 0; i < LM_ARRAY_LEN(m->items); i++)
- if (m->items[i].set && m->items[i].key == k) {
- m->items[i].set = false;
- m->len--;
- return true;
- }
- return false;
-}
-
-#pragma GCC diagnostic pop
-
-#undef NAME
-#undef KEY_T
-#undef VAL_T
-#undef CAP
-
-/* Keep the linter happy. */
-#ifndef _LIB9P_MAP_H_
-#define _LIB9P_MAP_H_
-#endif /* _LIB9P_MAP_H_ */
diff --git a/lib9p/srv.c b/lib9p/srv.c
index a425dc9..08ccfc3 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -4,10 +4,11 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-#include <alloca.h>
#include <inttypes.h> /* for PRI* */
-#include <stddef.h> /* for size_t */
#include <limits.h> /* for SSIZE_MAX, not set by newlib */
+#include <stddef.h> /* for size_t */
+#include <stdlib.h> /* for malloc() */
+#include <string.h> /* for memcpy() */
#ifndef SSIZE_MAX
#define SSIZE_MAX (SIZE_MAX >> 1)
#endif
@@ -15,9 +16,10 @@
#include <libcr/coroutine.h>
#include <libcr_ipc/chan.h>
#include <libcr_ipc/mutex.h>
-#include <libcr_ipc/select.h>
+#include <libmisc/alloc.h>
#include <libmisc/assert.h>
#include <libmisc/endian.h>
+#include <libmisc/map.h>
#include <libhw/generic/net.h>
#define LOG_NAME 9P_SRV
@@ -30,16 +32,6 @@
#include "config.h"
-#ifndef CONFIG_9P_SRV_MAX_FIDS
- #error config.h must define CONFIG_9P_SRV_MAX_FIDS
-#endif
-#ifndef CONFIG_9P_SRV_MAX_REQS
- #error config.h must define CONFIG_9P_SRV_MAX_REQS
-#endif
-#ifndef CONFIG_9P_SRV_MAX_DEPTH
- /* 1=just the root dir, 2=just files in the root dir, 3=1 subdir, ... */
- #error config.h must define CONFIG_9P_SRV_MAX_DEPTH
-#endif
#ifndef CONFIG_9P_SRV_MAX_MSG_SIZE
#error config.h must define CONFIG_9P_SRV_MAX_MSG_SIZE
#endif
@@ -53,23 +45,39 @@ static_assert(CONFIG_9P_SRV_MAX_HOSTMSG_SIZE <= SSIZE_MAX);
bool lib9p_srv_flush_requested(struct lib9p_srv_ctx *ctx) {
assert(ctx);
- return _lib9p_srv_flushch_can_send(&ctx->_flushch);
+ return cr_chan_can_send(&ctx->flush_ch);
}
-int lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx) {
+void lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx) {
assert(ctx);
- assert(_lib9p_srv_flushch_can_send(&ctx->_flushch));
- lib9p_error(&ctx->basectx, LINUX_ECANCELED, "request canceled by flush");
- _lib9p_srv_flushch_send(&ctx->_flushch, true);
- return -1;
+ assert(cr_chan_can_send(&ctx->flush_ch));
+ ctx->flush_acknowledged = true;
}
+#define req_debugf(fmt, ...) \
+ debugf("cid=%zu: %s(tag=%"PRIu16"): " fmt, \
+ cr_getcid(), \
+ lib9p_msgtype_str(ctx->basectx.version, ctx->net_bytes[4]), \
+ ctx->tag \
+ __VA_OPT__(,) __VA_ARGS__)
+
/* structs ********************************************************************/
+enum srv_filetype {
+ SRV_FILETYPE_FILE,
+ SRV_FILETYPE_DIR,
+ SRV_FILETYPE_AUTH,
+};
+
+/* path *****************************************/
+
typedef typeof( ((struct lib9p_qid){}).path ) srv_path_t;
struct srv_pathinfo {
lo_interface lib9p_srv_file file;
+ enum srv_filetype type;
+ /* .parent_dir is used for (1) Twalk(".."), and (2) for checking
+ * permissions on the parent directory for remove(). */
srv_path_t parent_dir;
/* References from other srv_pathinfos (via .parent_dir) or
@@ -79,21 +87,19 @@ struct srv_pathinfo {
unsigned int io_refcount;
};
-#define NAME pathmap
-#define KEY_T srv_path_t
-#define VAL_T struct srv_pathinfo
-/* ( naive ) + ( working space for walk() ) */
-#define CAP ( (CONFIG_9P_SRV_MAX_FIDS*CONFIG_9P_SRV_MAX_DEPTH) + (CONFIG_9P_SRV_MAX_REQS*2) )
-#include "map.h"
+/* fid ******************************************/
#define FIDFLAG_OPEN_R (1<<0)
#define FIDFLAG_OPEN_W (1<<1)
#define FIDFLAG_RCLOSE (1<<2)
+#define FIDFLAG_APPEND (1<<3)
#define FIDFLAG_OPEN (FIDFLAG_OPEN_R|FIDFLAG_OPEN_W)
-struct _srv_fidinfo {
+struct srv_fidinfo {
srv_path_t path;
+ struct lib9p_srv_userid *user;
uint8_t flags;
+ enum srv_filetype type;
union {
struct {
lo_interface lib9p_srv_fio io;
@@ -102,31 +108,26 @@ struct _srv_fidinfo {
lo_interface lib9p_srv_dio io;
size_t idx;
uint64_t off;
+ struct lib9p_srv_dirent buffered_dirent;
} dir;
+ struct {
+ struct lib9p_s aname;
+ bool completed;
+ } auth;
};
};
-#define NAME fidmap
-#define KEY_T lib9p_fid_t
-#define VAL_T struct _srv_fidinfo
-#define CAP CONFIG_9P_SRV_MAX_FIDS
-#include "map.h"
-
-#define NAME reqmap
-#define KEY_T lib9p_tag_t
-#define VAL_T struct _lib9p_srv_req *
-#define CAP CONFIG_9P_SRV_MAX_REQS
-#include "map.h"
-
-/* The hierarchy of concepts is:
+/* contexts **************************************
+ *
+ * The hierarchy of contexts is:
*
* server -> connection -> session -> request
*
*/
-/* struct _srv_srv {} is defined in <lib9p/srv.h> */
+/* struct lib9p_srv {} is defined in <lib9p/srv.h> */
-struct _srv_conn {
+struct srv_conn {
/* immutable */
struct lib9p_srv *parent_srv;
lo_interface net_stream_conn fd;
@@ -135,34 +136,236 @@ struct _srv_conn {
cr_mutex_t writelock;
};
-struct _srv_sess {
+#define srv_sess _lib9p_srv_sess
+MAP_DECLARE(srv_pathmap, srv_path_t, struct srv_pathinfo);
+MAP_DECLARE(srv_fidmap, lib9p_fid_t, struct srv_fidinfo);
+MAP_DECLARE(srv_reqmap, lib9p_tag_t, struct lib9p_srv_ctx *);
+struct srv_sess {
/* immutable */
- struct _srv_conn *parent_conn;
+ struct srv_conn *parent_conn;
enum lib9p_version version;
uint32_t max_msg_size;
- uint32_t rerror_overhead;
/* mutable */
bool initialized;
bool closing;
- struct pathmap paths; /* srv_path_t => lib9p_srv_file + metadata */
- struct fidmap fids; /* lib9p_fid_t => lib9p_srv_{fio,dio} + metadata */
- struct reqmap reqs; /* lib9p_tag_t => *_lib9p_srv_req */
+ struct srv_pathmap paths; /* srv_path_t => `lib9p_srv_file` + metadata */
+ struct srv_fidmap fids; /* lib9p_fid_t => `lib9p_srv_{fio,dio}` + metadata */
+ struct srv_reqmap reqs; /* lib9p_tag_t => `struct srv_req *` */
};
-struct _lib9p_srv_req {
- /* immutable */
- struct _srv_sess *parent_sess;
- uint16_t tag;
- uint8_t *net_bytes;
- /* mutable */
- struct lib9p_srv_ctx ctx;
-};
+#define srv_req lib9p_srv_ctx /* struct lib9p_srv_ctx {} is defined in <lib9p/srv.h> */
+
+/* utilities for the above types **********************************************/
+
+static inline enum srv_filetype srv_qid_filetype(struct lib9p_qid qid) {
+ if (qid.type & LIB9P_QT_AUTH)
+ return SRV_FILETYPE_AUTH;
+ if (qid.type & LIB9P_QT_DIR)
+ return SRV_FILETYPE_DIR;
+ return SRV_FILETYPE_FILE;
+}
+
+static inline bool srv_check_perm(struct srv_req *ctx, struct lib9p_srv_stat *stat, uint8_t action) {
+ assert(ctx);
+ assert(stat);
+ assert(action);
+
+ /* TODO actually check user and group instead of just assuming "other". */
+ uint8_t mode = (uint8_t)(stat->mode & 07);
+
+ return mode & action;
+}
+
+[[gnu::unused]]
+static struct lib9p_srv_userid *srv_userid_new(struct lib9p_s name
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+ , lib9p_nuid_t num
+#endif
+ ) {
+ struct lib9p_srv_userid *ret = malloc(sizeof(struct lib9p_srv_userid) + name.len);
+ if (!ret)
+ return NULL;
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+ ret->num = num;
+#endif
+ ret->name.len = name.len;
+ ret->name.utf8 = (void *)&ret[1];
+ memcpy(ret->name.utf8, name.utf8, name.len);
+ ret->refcount = 1;
+ return ret;
+}
+#if !(CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L)
+#define srv_userid_new(name, num) srv_userid_new(name)
+#endif
+
+static struct lib9p_srv_userid *srv_userid_decref(struct lib9p_srv_userid *userid) {
+ assert(userid);
+ assert(userid->refcount);
+ userid->refcount--;
+ if (!userid->refcount)
+ free(userid);
+ return NULL;
+}
+
+static struct lib9p_srv_userid *srv_userid_incref(struct lib9p_srv_userid *userid) {
+ assert(userid);
+ userid->refcount++;
+ return userid;
+}
+
+/**
+ * Ensures that `file` is saved into the pathmap, and increments the
+ * gc_refcount by 1 (for presumptive insertion into the fidmap).
+ * parent_path's gc_refcount is also incremented as appropriate.
+ *
+ * Returns a pointer to the stored pathinfo.
+ */
+static inline struct srv_pathinfo *srv_path_save(struct srv_req *ctx,
+ lo_interface lib9p_srv_file file,
+ srv_path_t parent_path) {
+ assert(ctx);
+ assert(!LO_IS_NULL(file));
+
+ struct lib9p_qid qid = LO_CALL(file, qid);
+ struct srv_pathinfo *pathinfo = map_load(&ctx->parent_sess->paths, qid.path);
+ if (pathinfo)
+ assert(LO_EQ(pathinfo->file, file));
+ else {
+ pathinfo = map_store(&ctx->parent_sess->paths, qid.path,
+ (struct srv_pathinfo){
+ .file = file,
+ .type = srv_qid_filetype(qid),
+ .parent_dir = parent_path,
+ .gc_refcount = 0,
+ .io_refcount = 0,
+ });
+ assert(pathinfo);
+ if (parent_path != qid.path) {
+ struct srv_pathinfo *parent = map_load(&ctx->parent_sess->paths, parent_path);
+ assert(parent);
+ parent->gc_refcount++;
+ }
+ }
+ pathinfo->gc_refcount++;
+ return pathinfo;
+}
+
+/**
+ * Decrement the path's gc_refcount, and trigger garbage collection as
+ * appropriate.
+ */
+static inline void srv_path_decref(struct srv_req *ctx, srv_path_t path) {
+ assert(ctx);
+
+ for (;;) {
+ struct srv_pathinfo *pathinfo = map_load(&ctx->parent_sess->paths, path);
+ assert(pathinfo);
+ pathinfo->gc_refcount--;
+ if (pathinfo->gc_refcount)
+ break;
+ srv_path_t parent_path = pathinfo->parent_dir;
+ LO_CALL(pathinfo->file, free);
+ map_del(&ctx->parent_sess->paths, path);
+ if (parent_path == path)
+ break;
+ path = parent_path;
+ }
+}
+
+static inline void srv_fid_del(struct srv_req *ctx, lib9p_fid_t fid, struct srv_fidinfo *fidinfo, bool remove) {
+ assert(ctx);
+ assert(!ctx->user);
+ assert(fidinfo);
+
+ if (fidinfo->flags & FIDFLAG_RCLOSE)
+ remove = true;
+ ctx->user = srv_userid_incref(fidinfo->user);
+
+ struct srv_pathinfo *pathinfo = map_load(&ctx->parent_sess->paths, fidinfo->path);
+ assert(pathinfo);
+
+ if (remove)
+ LO_CALL(pathinfo->file, remove, ctx);
+
+ if (fidinfo->flags & FIDFLAG_OPEN) {
+ switch (fidinfo->type) {
+ case SRV_FILETYPE_DIR:
+ LO_CALL(fidinfo->dir.io, iofree);
+ break;
+ case SRV_FILETYPE_FILE:
+ LO_CALL(fidinfo->file.io, iofree);
+ break;
+ case SRV_FILETYPE_AUTH:
+ assert_notreached("TODO: auth not yet implemented");
+ break;
+ }
+ pathinfo->io_refcount--;
+ }
+ fidinfo->user = srv_userid_decref(fidinfo->user);
+ srv_path_decref(ctx, fidinfo->path);
+ map_del(&ctx->parent_sess->fids, fid);
+
+ ctx->user = srv_userid_decref(ctx->user);
+}
+
+/**
+ * Store fid as pointing to pathinfo. Assumes that
+ * pathinfo->gc_refcount has already been incremented; does *not*
+ * decrement it on failure.
+ */
+static inline struct srv_fidinfo *srv_fid_store(struct srv_req *ctx, lib9p_fid_t fid, struct srv_pathinfo *pathinfo, bool overwrite) {
+ assert(ctx);
+ assert(fid != LIB9P_FID_NOFID);
+ assert(pathinfo);
+
+ struct lib9p_qid qid = LO_CALL(pathinfo->file, qid);
+
+ struct srv_fidinfo *old_fidinfo = map_load(&ctx->parent_sess->fids, fid);
+ if (old_fidinfo) {
+ if (overwrite) {
+ /* This should only happen from Twalk; because
+ * directories cannot be RCLOSE and Twalk cannot walk on
+ * FIDs open for I/O, we can skip most of
+ * srv_fid_del(). */
+ assert(old_fidinfo->type == SRV_FILETYPE_DIR);
+ assert(old_fidinfo->flags == 0);
+
+ old_fidinfo->user = srv_userid_decref(old_fidinfo->user);
+ srv_path_decref(ctx, old_fidinfo->path);
+ map_del(&ctx->parent_sess->fids, fid);
+ } else {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EBADF, "FID already in use");
+ return NULL;
+ }
+ }
+ struct srv_fidinfo *fidinfo = map_store(&ctx->parent_sess->fids, fid, (struct srv_fidinfo){
+ .path = qid.path,
+ .type = srv_qid_filetype(qid),
+ .user = srv_userid_incref(ctx->user),
+ });
+ assert(fidinfo);
+ return fidinfo;
+}
/* base utilities *************************************************************/
-#define nonrespond_errorf errorf
+static void srv_msglog(struct srv_req *req, enum lib9p_msg_type typ, void *hostmsg) {
+ struct lib9p_srv *srv = req->parent_sess->parent_conn->parent_srv;
+ if (srv->msglog) {
+ srv->msglog(req, typ, hostmsg);
+ return;
+ }
+ /* 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"
+ infof("%c %v", typ % 2 ? '<' : '>', lo_box_lib9p_msg_as_fmt_formatter(&req->basectx, typ, hostmsg));
+#pragma GCC diagnostic pop
+}
-static ssize_t write_Rmsg(struct _lib9p_srv_req *req, struct lib9p_Rmsg_send_buf *resp) {
+static ssize_t srv_write_Rmsg(struct srv_req *req, struct lib9p_Rmsg_send_buf *resp) {
ssize_t r;
cr_mutex_lock(&req->parent_sess->parent_conn->writelock);
r = io_writev(req->parent_sess->parent_conn->fd, resp->iov, resp->iov_cnt);
@@ -170,59 +373,62 @@ static ssize_t write_Rmsg(struct _lib9p_srv_req *req, struct lib9p_Rmsg_send_buf
return r;
}
-static void respond_error(struct _lib9p_srv_req *req) {
-#if CONFIG_9P_ENABLE_9P2000_u
- assert(req->ctx.basectx.err_num);
+#define srv_nonrespond_errorf errorf
+
+static void srv_respond_error(struct srv_req *req) {
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+ assert(req->basectx.err_num);
#endif
- assert(req->ctx.basectx.err_msg[0]);
+ assert(req->basectx.err_msg[0]);
ssize_t r;
struct lib9p_msg_Rerror host = {
.tag = req->tag,
- .ename = lib9p_strn(req->ctx.basectx.err_msg,
- CONFIG_9P_MAX_ERR_SIZE),
+ .errstr = lib9p_strn(req->basectx.err_msg,
+ CONFIG_9P_MAX_ERR_SIZE),
#if CONFIG_9P_ENABLE_9P2000_u
- .errno = req->ctx.basectx.err_num,
+ .errnum = req->basectx.err_num,
#endif
};
- struct _srv_sess *sess = req->parent_sess;
+ struct srv_sess *sess = req->parent_sess;
+
+ /* XXX: This assumes that a version's min_msg_size is the
+ * Rerror overhead. That's true for the current
+ * implementation of core_gen, but is a sneaky assumption. */
+ uint32_t overhead = lib9p_version_min_msg_size(sess->version);
/* Truncate the error-string if necessary to avoid needing to
- * return LINUX_ERANGE. */
- if (((uint32_t)host.ename.len) + sess->rerror_overhead > sess->max_msg_size)
- host.ename.len = sess->max_msg_size - sess->rerror_overhead;
+ * return LIB9P_ERRNO_L_ERANGE. */
+ if (((uint32_t)host.errstr.len) + overhead > sess->max_msg_size)
+ host.errstr.len = sess->max_msg_size - overhead;
struct lib9p_Rmsg_send_buf net;
- lib9p_Rmsg_marshal(&req->ctx.basectx,
+ lib9p_Rmsg_marshal(&req->basectx,
LIB9P_TYP_Rerror, &host,
&net);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat"
-#pragma GCC diagnostic ignored "-Wformat-extra-args"
- infof("< %v", lo_box_lib9p_msg_Rerror_as_fmt_formatter(&host));
-#pragma GCC diagnostic pop
- r = write_Rmsg(req, &net);
+ srv_msglog(req, LIB9P_TYP_Rerror, &host);
+ r = srv_write_Rmsg(req, &net);
if (r < 0)
- nonrespond_errorf("write: %s", net_strerror(-r));
+ srv_nonrespond_errorf("write: %s", net_strerror(-r));
}
/* read coroutine *************************************************************/
-static bool read_exactly(lo_interface net_stream_conn fd, uint8_t *buf, size_t goal, size_t *done) {
+static inline bool srv_read_exactly(lo_interface net_stream_conn fd, uint8_t *buf, size_t goal, size_t *done) {
assert(buf);
assert(goal);
assert(done);
while (*done < goal) {
ssize_t r = io_read(fd, &buf[*done], goal - *done);
if (r < 0) {
- nonrespond_errorf("read: %s", net_strerror(-r));
+ srv_nonrespond_errorf("read: %s", net_strerror(-r));
return true;
} else if (r == 0) {
if (*done != 0)
- nonrespond_errorf("read: unexpected EOF");
+ srv_nonrespond_errorf("read: unexpected EOF");
return true;
}
*done += r;
@@ -230,151 +436,163 @@ static bool read_exactly(lo_interface net_stream_conn fd, uint8_t *buf, size_t g
return false;
}
-static void handle_message(struct _lib9p_srv_req *ctx);
-
-[[noreturn]] void lib9p_srv_read_cr(struct lib9p_srv *srv, lo_interface net_stream_listener listener) {
+void lib9p_srv_accept_and_read_loop(struct lib9p_srv *srv, lo_interface net_stream_listener listener) {
assert(srv);
assert(srv->rootdir);
assert(!LO_IS_NULL(listener));
srv->readers++;
- uint32_t initial_rerror_overhead = lib9p_version_min_msg_size(LIB9P_VER_unknown);
-
for (;;) {
- struct _srv_conn conn = {
- .parent_srv = srv,
- .fd = LO_CALL(listener, accept),
- .reader = cr_getcid(),
- };
- if (LO_IS_NULL(conn.fd)) {
- nonrespond_errorf("accept: error");
+ lo_interface net_stream_conn conn = LO_CALL(listener, accept);
+ if (LO_IS_NULL(conn)) {
+ srv_nonrespond_errorf("accept: error");
srv->readers--;
if (srv->readers == 0)
while (srv->writers > 0)
- _lib9p_srv_reqch_send_req(&srv->_reqch, NULL);
- cr_exit();
+ cr_rpc_send_req(&srv->_reqch, NULL);
+ return;
}
+ lib9p_srv_read(srv, conn);
+ }
+}
- struct _srv_sess sess = {
- .parent_conn = &conn,
- .version = LIB9P_VER_unknown,
- .max_msg_size = CONFIG_9P_SRV_MAX_MSG_SIZE,
- .rerror_overhead = initial_rerror_overhead,
- .initialized = false,
- };
- for (;;) {
- nextmsg:
- /* Read the message. */
- size_t done = 0;
- uint8_t buf[7];
- if (read_exactly(conn.fd, buf, 4, &done))
- goto close;
- size_t goal = uint32le_decode(buf);
- if (goal < 7) {
- nonrespond_errorf("T-message is impossibly small");
- goto close;
- }
- if (read_exactly(conn.fd, buf, 7, &done))
- goto close;
- struct _lib9p_srv_req req = {
- .parent_sess = &sess,
- .tag = uint16le_decode(&buf[5]),
- .net_bytes = buf,
- .ctx = {
- .basectx = {
- .version = sess.version,
- .max_msg_size = sess.max_msg_size,
- },
- },
- };
- if (goal > sess.max_msg_size) {
- lib9p_errorf(&req.ctx.basectx,
- LINUX_EMSGSIZE, "T-message larger than %s limit (%zu > %"PRIu32")",
- sess.initialized ? "negotiated" : "server",
- goal,
- sess.max_msg_size);
- respond_error(&req);
- goto nextmsg;
- }
- req.net_bytes = malloc(goal);
- assert(req.net_bytes);
- memcpy(req.net_bytes, buf, done);
- if (read_exactly(conn.fd, req.net_bytes, goal, &done)) {
- free(req.net_bytes);
- goto close;
- }
+void lib9p_srv_read(struct lib9p_srv *srv, lo_interface net_stream_conn _conn) {
+ assert(srv);
+ assert(srv->rootdir);
+ assert(!LO_IS_NULL(_conn));
- /* Handle the message... */
- if (req.net_bytes[4] == LIB9P_TYP_Tversion)
- /* ...in this coroutine for Tversion, */
- handle_message(&req);
- else
- /* ...but usually in another coroutine. */
- _lib9p_srv_reqch_send_req(&srv->_reqch, &req);
+ struct srv_conn conn = {
+ .parent_srv = srv,
+ .fd = _conn,
+ .reader = cr_getcid(),
+ };
+ struct srv_sess sess = {
+ .parent_conn = &conn,
+ .version = LIB9P_VER_unknown,
+ .max_msg_size = CONFIG_9P_SRV_MAX_MSG_SIZE,
+ .initialized = false,
+ };
+ for (;;) {
+ /* Read the message. */
+ size_t done = 0;
+ uint8_t buf[7];
+ if (srv_read_exactly(conn.fd, buf, 4, &done))
+ break;
+ size_t goal = uint32le_decode(buf);
+ if (goal < 7) {
+ srv_nonrespond_errorf("T-message is impossibly small");
+ break;
+ }
+ if (srv_read_exactly(conn.fd, buf, 7, &done))
+ break;
+ struct srv_req req = {
+ .basectx = {
+ .version = sess.version,
+ .max_msg_size = sess.max_msg_size,
+ },
+
+ .parent_sess = &sess,
+ .tag = uint16le_decode(&buf[5]),
+ .net_bytes = buf,
+ };
+ if (goal > sess.max_msg_size) {
+ lib9p_errorf(&req.basectx,
+ LIB9P_ERRNO_L_EMSGSIZE, "T-message larger than %s limit (%zu > %"PRIu32")",
+ sess.initialized ? "negotiated" : "server",
+ goal,
+ sess.max_msg_size);
+ srv_respond_error(&req);
+ continue;
}
- close:
- if (sess.reqs.len == 0)
- io_close(conn.fd);
- else {
- io_close_read(conn.fd);
- sess.closing = true;
- cr_pause_and_yield();
- assert(sess.reqs.len == 0);
- io_close_write(conn.fd);
+ req.net_bytes = malloc(goal);
+ assert(req.net_bytes);
+ memcpy(req.net_bytes, buf, done);
+ if (srv_read_exactly(conn.fd, req.net_bytes, goal, &done)) {
+ free(req.net_bytes);
+ break;
+ }
+
+ /* Handle the message... */
+ if (req.net_bytes[4] == LIB9P_TYP_Tversion)
+ /* ...in this coroutine for Tversion, */
+ lib9p_srv_worker(&req);
+ else
+ /* ...but usually in another coroutine. */
+ cr_rpc_send_req(&srv->_reqch, &req);
+ }
+ if (map_len(&sess.reqs) == 0)
+ io_close(conn.fd);
+ else {
+ io_close_read(conn.fd);
+ sess.closing = true;
+ cr_pause_and_yield();
+ assert(map_len(&sess.reqs) == 0);
+ io_close_write(conn.fd);
+ }
+
+ assert(map_len(&sess.reqs) == 0);
+ map_free(&sess.reqs);
+
+ struct srv_req pseudoreq = {
+ .basectx = {
+ .version = sess.version,
+ .max_msg_size = sess.max_msg_size,
+ },
+ .parent_sess = &sess,
+ };
+ MAP_FOREACH(&sess.fids, fid, fidinfo) {
+ srv_fid_del(&pseudoreq, fid, fidinfo, false);
+ if (lib9p_ctx_has_error(&pseudoreq.basectx)) {
+ srv_nonrespond_errorf("clunk: %.*s", CONFIG_9P_MAX_ERR_SIZE, pseudoreq.basectx.err_msg);
+ lib9p_ctx_clear_error(&pseudoreq.basectx);
}
}
+ map_free(&sess.fids);
+
+ assert(map_len(&sess.paths) == 0);
+ map_free(&sess.paths);
}
/* write coroutine ************************************************************/
-COROUTINE lib9p_srv_write_cr(void *_srv) {
- struct _lib9p_srv_req req;
+void lib9p_srv_worker_loop(struct lib9p_srv *srv) {
+ struct srv_req req;
_lib9p_srv_reqch_req_t rpc_handle;
- struct lib9p_srv *srv = _srv;
assert(srv);
assert(srv->rootdir);
- cr_begin();
srv->writers++;
for (;;) {
/* Receive the request from the reader coroutine. ************/
- rpc_handle = _lib9p_srv_reqch_recv_req(&srv->_reqch);
+ rpc_handle = cr_rpc_recv_req(&srv->_reqch);
if (!rpc_handle.req) {
srv->writers--;
- _lib9p_srv_reqch_send_resp(rpc_handle, 0);
- cr_exit();
+ cr_rpc_send_resp(rpc_handle, 0);
+ return;
}
/* Copy the request from the reader coroutine's
* stack to our stack. */
req = *rpc_handle.req;
/* Record that we have it. */
- reqmap_store(&req.parent_sess->reqs, req.tag, &req);
+ struct srv_req **reqpp = map_store(&req.parent_sess->reqs, req.tag, &req);
+ assert(reqpp && *reqpp == &req);
/* Notify the reader coroutine that we're done with
* its data. */
- _lib9p_srv_reqch_send_resp(rpc_handle, 0);
+ cr_rpc_send_resp(rpc_handle, 0);
/* Process the request. **************************************/
- handle_message(&req);
-
- /* Release resources. ****************************************/
- while (_lib9p_srv_flushch_can_send(&req.ctx._flushch))
- _lib9p_srv_flushch_send(&req.ctx._flushch, false);
- reqmap_del(&req.parent_sess->reqs, req.tag);
- if (req.parent_sess->closing && !req.parent_sess->reqs.len)
- cr_unpause(req.parent_sess->parent_conn->reader);
+ lib9p_srv_worker(&req);
}
-
- cr_end();
}
#define _HANDLER_PROTO(typ) \
- static void handle_T##typ(struct _lib9p_srv_req *, \
- struct lib9p_msg_T##typ *, \
- struct lib9p_msg_R##typ *)
+ static void handle_T##typ(struct srv_req *, \
+ struct lib9p_msg_T##typ *)
_HANDLER_PROTO(version);
+#if _LIB9P_ENABLE_stat
_HANDLER_PROTO(auth);
_HANDLER_PROTO(attach);
_HANDLER_PROTO(flush);
@@ -387,201 +605,120 @@ _HANDLER_PROTO(clunk);
_HANDLER_PROTO(remove);
_HANDLER_PROTO(stat);
_HANDLER_PROTO(wstat);
+#endif
+#if CONFIG_9P_ENABLE_9P2000_p9p
+_HANDLER_PROTO(openfd);
+#endif
#if CONFIG_9P_ENABLE_9P2000_e
_HANDLER_PROTO(session);
_HANDLER_PROTO(sread);
_HANDLER_PROTO(swrite);
#endif
-typedef void (*tmessage_handler)(struct _lib9p_srv_req *, void *, void *);
-
-static tmessage_handler tmessage_handlers[0x100] = {
- [LIB9P_TYP_Tversion] = (tmessage_handler)handle_Tversion,
- [LIB9P_TYP_Tauth] = (tmessage_handler)handle_Tauth,
- [LIB9P_TYP_Tattach] = (tmessage_handler)handle_Tattach,
- [LIB9P_TYP_Tflush] = (tmessage_handler)handle_Tflush,
- [LIB9P_TYP_Twalk] = (tmessage_handler)handle_Twalk,
- [LIB9P_TYP_Topen] = (tmessage_handler)handle_Topen,
- [LIB9P_TYP_Tcreate] = (tmessage_handler)handle_Tcreate,
- [LIB9P_TYP_Tread] = (tmessage_handler)handle_Tread,
- [LIB9P_TYP_Twrite] = (tmessage_handler)handle_Twrite,
- [LIB9P_TYP_Tclunk] = (tmessage_handler)handle_Tclunk,
- [LIB9P_TYP_Tremove] = (tmessage_handler)handle_Tremove,
- [LIB9P_TYP_Tstat] = (tmessage_handler)handle_Tstat,
- [LIB9P_TYP_Twstat] = (tmessage_handler)handle_Twstat,
-#if CONFIG_9P_ENABLE_9P2000_e
- [LIB9P_TYP_Tsession] = (tmessage_handler)handle_Tsession,
- [LIB9P_TYP_Tsread] = (tmessage_handler)handle_Tsread,
- [LIB9P_TYP_Tswrite] = (tmessage_handler)handle_Tswrite,
-#endif
-};
+typedef void (*tmessage_handler)(struct srv_req *, void *);
-static void handle_message(struct _lib9p_srv_req *ctx) {
+void lib9p_srv_worker(struct srv_req *ctx) {
uint8_t *host_req = NULL;
- uint8_t host_resp[CONFIG_9P_SRV_MAX_HOSTMSG_SIZE];
- /* Unmarshal it. */
- ssize_t host_size = lib9p_Tmsg_validate(&ctx->ctx.basectx, ctx->net_bytes);
- if (host_size < 0)
- goto write;
+ /* Unmarshal it. *****************************************************/
+ ssize_t host_size = lib9p_Tmsg_validate(&ctx->basectx, ctx->net_bytes);
+ if (host_size < 0) {
+ srv_respond_error(ctx);
+ goto release;
+ }
host_req = calloc(1, host_size);
assert(host_req);
enum lib9p_msg_type typ;
- lib9p_Tmsg_unmarshal(&ctx->ctx.basectx, ctx->net_bytes,
- &typ, host_req);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat"
-#pragma GCC diagnostic ignored "-Wformat-extra-args"
- infof("> %v", lo_box_lib9p_msg_as_fmt_formatter(&ctx->ctx.basectx, typ, host_req));
-#pragma GCC diagnostic pop
-
- /* Handle it. */
- tmessage_handlers[typ](ctx, (void *)host_req, (void *)host_resp);
+ lib9p_Tmsg_unmarshal(&ctx->basectx, ctx->net_bytes,
+ &typ, host_req);
+ srv_msglog(ctx, typ, host_req);
- write:
- if (lib9p_ctx_has_error(&ctx->ctx.basectx))
- respond_error(ctx);
- else {
- struct lib9p_Rmsg_send_buf net_resp;
- if (lib9p_Rmsg_marshal(&ctx->ctx.basectx,
- typ+1, host_resp,
- &net_resp))
- goto write;
+ /* Handle it. ********************************************************/
+ tmessage_handler handler;
#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat"
-#pragma GCC diagnostic ignored "-Wformat-extra-args"
- infof("< %v", lo_box_lib9p_msg_as_fmt_formatter(&ctx->ctx.basectx, typ+1, &host_resp));
+#pragma GCC diagnostic ignored "-Wswitch-enum"
+ switch (typ) {
+ case LIB9P_TYP_Tversion: handler = (tmessage_handler)handle_Tversion; break;
+#if _LIB9P_ENABLE_stat
+ case LIB9P_TYP_Tauth: handler = (tmessage_handler)handle_Tauth; break;
+ case LIB9P_TYP_Tattach: handler = (tmessage_handler)handle_Tattach; break;
+ case LIB9P_TYP_Tflush: handler = (tmessage_handler)handle_Tflush; break;
+ case LIB9P_TYP_Twalk: handler = (tmessage_handler)handle_Twalk; break;
+ case LIB9P_TYP_Topen: handler = (tmessage_handler)handle_Topen; break;
+ case LIB9P_TYP_Tcreate: handler = (tmessage_handler)handle_Tcreate; break;
+ case LIB9P_TYP_Tread: handler = (tmessage_handler)handle_Tread; break;
+ case LIB9P_TYP_Twrite: handler = (tmessage_handler)handle_Twrite; break;
+ case LIB9P_TYP_Tclunk: handler = (tmessage_handler)handle_Tclunk; break;
+ case LIB9P_TYP_Tremove: handler = (tmessage_handler)handle_Tremove; break;
+ case LIB9P_TYP_Tstat: handler = (tmessage_handler)handle_Tstat; break;
+ case LIB9P_TYP_Twstat: handler = (tmessage_handler)handle_Twstat; break;
+#endif
+#if CONFIG_9P_ENABLE_9P2000_p9p
+ case LIB9P_TYP_Topenfd: handler = (tmessage_handler)handle_Topenfd; break;
+#endif
+#if CONFIG_9P_ENABLE_9P2000_e
+ case LIB9P_TYP_Tsession: handler = (tmessage_handler)handle_Tsession; break;
+ case LIB9P_TYP_Tsread: handler = (tmessage_handler)handle_Tsread; break;
+ case LIB9P_TYP_Tswrite: handler = (tmessage_handler)handle_Tswrite; break;
+#endif
+ default:
+ assert_notreached("lib9p_Tmsg_validate() should have rejected unknown typ");
+ }
#pragma GCC diagnostic pop
- write_Rmsg(ctx, &net_resp);
+ handler(ctx, (void *)host_req);
+ assert(ctx->responded);
+
+ /* Release resources. ************************************************/
+ release:
+ map_del(&ctx->parent_sess->reqs, ctx->tag);
+ size_t nwaiters;
+ while ((nwaiters = cr_chan_num_waiters(&ctx->flush_ch))) {
+ cr_chan_send(&ctx->flush_ch, (nwaiters == 1)
+ ? _LIB9P_SRV_FLUSH_RFLUSH
+ : _LIB9P_SRV_FLUSH_SILENT);
}
+ if (ctx->parent_sess->closing && !map_len(&ctx->parent_sess->reqs))
+ cr_unpause(ctx->parent_sess->parent_conn->reader);
if (host_req)
free(host_req);
free(ctx->net_bytes);
}
-#define util_handler_common(ctx, req, resp) do { \
- assert(ctx); \
- assert(req); \
- assert(resp); \
- resp->tag = req->tag; \
- } while (0)
-
-static inline bool srv_util_check_perm(struct _lib9p_srv_req *ctx, struct lib9p_stat *stat, uint8_t action) {
- assert(ctx);
- assert(stat);
- assert(action);
-
- /* TODO actually check user and group instead of just assuming "other". */
- uint8_t mode = (uint8_t)(stat->file_mode & 07);
-
- return mode & action;
-}
-
-/**
- * Ensures that `file` is saved into the pathmap, and increments the
- * gc_refcount by 1 (for presumptive insertion into the fidmap).
- * parent_path's gc_refcount is also incremented as appropriate.
- *
- * Returns a pointer to the stored pathinfo.
- */
-static inline struct srv_pathinfo *srv_util_pathsave(struct _lib9p_srv_req *ctx,
- lo_interface lib9p_srv_file file,
- srv_path_t parent_path) {
- assert(ctx);
- assert(!LO_IS_NULL(file));
-
- struct lib9p_qid qid = LO_CALL(file, qid);
- struct srv_pathinfo *pathinfo = pathmap_load(&ctx->parent_sess->paths, qid.path);
- if (pathinfo)
- assert(LO_EQ(pathinfo->file, file));
- else {
- pathinfo = pathmap_store(&ctx->parent_sess->paths, qid.path,
- (struct srv_pathinfo){
- .file = file,
- .parent_dir = parent_path,
- .gc_refcount = 0,
- .io_refcount = 0,
- });
- assert(pathinfo);
- if (parent_path != qid.path) {
- struct srv_pathinfo *parent = pathmap_load(&ctx->parent_sess->paths, parent_path);
- assert(parent);
- parent->gc_refcount++;
- }
- }
- pathinfo->gc_refcount++;
- return pathinfo;
-}
-
-/**
- * Decrement the path's gc_refcount, and trigger garbage collection as
- * appropriate.
- */
-static inline void srv_util_pathfree(struct _lib9p_srv_req *ctx, srv_path_t path) {
- assert(ctx);
-
- struct srv_pathinfo *pathinfo = pathmap_load(&ctx->parent_sess->paths, path);
- assert(pathinfo);
- pathinfo->gc_refcount--;
- if (pathinfo->gc_refcount == 0) {
- if (pathinfo->parent_dir != path)
- srv_util_pathfree(ctx, pathinfo->parent_dir);
- LO_CALL(pathinfo->file, free);
- pathmap_del(&ctx->parent_sess->paths, path);
- }
-}
-
-static inline bool srv_util_pathisdir(struct srv_pathinfo *pathinfo) {
- assert(pathinfo);
- return LO_CALL(pathinfo->file, qid).type & LIB9P_QT_DIR;
-}
-
-/**
- * Store fid as pointing to pathinfo. Assumes that
- * pathinfo->gc_refcount has already been incremented; does *not*
- * decrement it on failure.
- */
-static inline struct _srv_fidinfo *srv_util_fidsave(struct _lib9p_srv_req *ctx, lib9p_fid_t fid, struct srv_pathinfo *pathinfo, bool overwrite) {
- assert(ctx);
- assert(fid != LIB9P_FID_NOFID);
- assert(pathinfo);
-
- struct lib9p_qid qid = LO_CALL(pathinfo->file, qid);
-
- struct _srv_fidinfo *fidinfo = fidmap_load(&ctx->parent_sess->fids, fid);
- if (fidinfo) {
- if (overwrite) {
- struct srv_pathinfo *old_pathinfo = pathmap_load(&ctx->parent_sess->paths, fidinfo->path);
- assert(old_pathinfo);
- if (srv_util_pathisdir(old_pathinfo))
- LO_CALL(fidinfo->dir.io, iofree);
- else
- LO_CALL(fidinfo->file.io, iofree);
- srv_util_pathfree(ctx, fidinfo->path);
- } else {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EBADF, "FID already in use");
- return NULL;
- }
+static inline void _srv_respond(struct srv_req *ctx, enum lib9p_msg_type resp_typ, void *host_resp) {
+ assert(!ctx->responded);
+ if (lib9p_ctx_has_error(&ctx->basectx)) {
+ error:
+ srv_respond_error(ctx);
+ } else if (ctx->flush_acknowledged) {
+ /* do nothing */
} else {
- fidinfo = fidmap_store(&ctx->parent_sess->fids, fid, (struct _srv_fidinfo){});
- if (!fidinfo) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EMFILE, "too many open files");
- return NULL;
- }
+ assert(host_resp);
+ struct lib9p_Rmsg_send_buf net_resp;
+ if (lib9p_Rmsg_marshal(&ctx->basectx,
+ resp_typ, host_resp,
+ &net_resp))
+ goto error;
+ srv_msglog(ctx, resp_typ, host_resp);
+ srv_write_Rmsg(ctx, &net_resp);
}
- *fidinfo = (struct _srv_fidinfo){
- .path = qid.path,
- };
- return fidinfo;
+ ctx->responded = true;
}
+#define srv_respond(CTX, TYP, HOST_RESP) do { \
+ struct lib9p_msg_R##TYP *_host_resp = HOST_RESP; \
+ _srv_respond(CTX, LIB9P_TYP_R##TYP, _host_resp); \
+} while (0)
+
+/* handle_T* ******************************************************************/
+#define srv_handler_common(ctx, typ, req) \
+ assert(ctx); \
+ assert(req); \
+ struct lib9p_msg_T##typ *_typecheck_req [[gnu::unused]] = req; \
+ struct lib9p_msg_R##typ resp = { .tag = ctx->tag }
-static void handle_Tversion(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tversion *req,
- struct lib9p_msg_Rversion *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Tversion(struct srv_req *ctx,
+ struct lib9p_msg_Tversion *req) {
+ srv_handler_common(ctx, version, req);
enum lib9p_version version = LIB9P_VER_unknown;
@@ -593,7 +730,14 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx,
'0' <= req->version.utf8[4] && req->version.utf8[4] <= '9' &&
'0' <= req->version.utf8[5] && req->version.utf8[5] <= '9' &&
(req->version.len == 6 || req->version.utf8[6] == '.')) {
+#if CONFIG_9P_ENABLE_9P2000
version = LIB9P_VER_9P2000;
+#endif
+#if CONFIG_9P_ENABLE_9P2000_p9p
+ struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv;
+ if (srv->type_assert_unix && !LO_IS_NULL(srv->type_assert_unix(ctx->parent_sess->parent_conn->fd)))
+ version = LIB9P_VER_9P2000_p9p;
+#endif
#if CONFIG_9P_ENABLE_9P2000_u
if (lib9p_str_eq(lib9p_str_sliceleft(req->version, 6), lib9p_str(".u")))
version = LIB9P_VER_9P2000_u;
@@ -606,292 +750,321 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx,
uint32_t min_msg_size = lib9p_version_min_msg_size(version);
if (req->max_msg_size < min_msg_size) {
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EDOM, "requested max_msg_size is less than minimum for %s (%"PRIu32" < %"PRIu32")",
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EDOM, "requested max_msg_size is less than minimum for %s (%"PRIu32" < %"PRIu32")",
lib9p_version_str(version), req->max_msg_size, min_msg_size);
- return;
+ goto tversion_return;
}
- resp->version = lib9p_str((char *)lib9p_version_str(version)); /* cast to discard "const" qualifier */
- resp->max_msg_size = (CONFIG_9P_SRV_MAX_MSG_SIZE < req->max_msg_size)
+ resp.version = lib9p_str((char *)lib9p_version_str(version)); /* cast to discard "const" qualifier */
+#if CONFIG_9P_ENABLE_9P2000_p9p
+ if (version == LIB9P_VER_9P2000_p9p)
+ resp.version = lib9p_str("9P2000");
+#endif
+ resp.max_msg_size = (CONFIG_9P_SRV_MAX_MSG_SIZE < req->max_msg_size)
? CONFIG_9P_SRV_MAX_MSG_SIZE
: req->max_msg_size;
/* Close the old session. */
- if (ctx->parent_sess->reqs.len) {
+ if (map_len(&ctx->parent_sess->reqs)) {
/* Flush all in-progress requests, and wait for them
* to finish. */
- struct cr_select_arg *list = alloca(sizeof(struct cr_select_arg) * ctx->parent_sess->reqs.len);
- while (ctx->parent_sess->reqs.len) {
- uint16_t tag [[gnu::unused]];
- struct _lib9p_srv_req **reqpp;
+ struct cr_select_arg *args = stack_alloc(map_len(&ctx->parent_sess->reqs), struct cr_select_arg);
+ while (map_len(&ctx->parent_sess->reqs)) {
size_t i = 0;
- bool flushed;
MAP_FOREACH(&ctx->parent_sess->reqs, tag, reqpp) {
- list[i] = CR_SELECT_RECV(&((*reqpp)->ctx._flushch), &flushed);
+ enum _lib9p_srv_flush_result flushed;
+ args[i++] = CR_SELECT_RECV(&((*reqpp)->flush_ch), &flushed);
}
- cr_select_v(i, list);
+ assert(i == map_len(&ctx->parent_sess->reqs));
+ cr_select_v(i, args);
}
}
- if (ctx->parent_sess->fids.len) {
- /* Close all FIDs. */
- uint32_t fid;
- struct _srv_fidinfo *fidinfo [[gnu::unused]];
- MAP_FOREACH(&ctx->parent_sess->fids, fid, fidinfo) {
- handle_Tclunk(ctx,
- &(struct lib9p_msg_Tclunk){.fid = fid},
- &(struct lib9p_msg_Rclunk){});
+ /* Close all FIDs. */
+ MAP_FOREACH(&ctx->parent_sess->fids, fid, fidinfo) {
+ srv_fid_del(ctx, fid, fidinfo, false);
+ if (lib9p_ctx_has_error(&ctx->basectx)) {
+ srv_nonrespond_errorf("clunk: %.*s", CONFIG_9P_MAX_ERR_SIZE, ctx->basectx.err_msg);
+ lib9p_ctx_clear_error(&ctx->basectx);
}
}
/* Replace the old session with the new session. */
ctx->parent_sess->version = version;
- ctx->parent_sess->max_msg_size = resp->max_msg_size;
- ctx->parent_sess->rerror_overhead = min_msg_size;
+ ctx->parent_sess->max_msg_size = resp.max_msg_size;
+
+ tversion_return:
+ srv_respond(ctx, version, &resp);
}
-static void handle_Tauth(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tauth *req,
- struct lib9p_msg_Rauth *resp) {
- util_handler_common(ctx, req, resp);
+#if _LIB9P_ENABLE_stat
+static void handle_Tauth(struct srv_req *ctx,
+ struct lib9p_msg_Tauth *req) {
+ srv_handler_common(ctx, auth, req);
- ctx->ctx.uid = req->n_uid;
- ctx->ctx.uname = req->uname;
struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv;
-
if (!srv->auth) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EOPNOTSUPP, "authentication not required");
- return;
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EOPNOTSUPP, "authentication not required");
+ goto tauth_return;
}
- srv->auth(&ctx->ctx, req->aname);
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EOPNOTSUPP, "TODO: auth not implemented");
+ ctx->user = srv_userid_new(req->uname, req->unum);
+
+ srv->auth(ctx, req->aname);
+
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EOPNOTSUPP, "TODO: auth not implemented");
+
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ ctx->user = srv_userid_decref(ctx->user);
+
+ tauth_return:
+ srv_respond(ctx, auth, &resp);
}
-static void handle_Tattach(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tattach *req,
- struct lib9p_msg_Rattach *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Tattach(struct srv_req *ctx,
+ struct lib9p_msg_Tattach *req) {
+ srv_handler_common(ctx, attach, req);
- ctx->ctx.uid = req->n_uid;
- ctx->ctx.uname = req->uname;
- struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv;
+ if (req->fid == LIB9P_FID_NOFID) {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EBADF, "cannot assign to NOFID");
+ goto tattach_return;
+ }
+ struct lib9p_srv *srv = ctx->parent_sess->parent_conn->parent_srv;
if (srv->auth) {
- /*
- struct lib9p_srv_filehandle *fh = fidmap_get(req->afid);
- if (!fh)
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EACCES, "FID provided as auth-file is not a valid FID");
- else if (fh->type != FH_AUTH)
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EACCES, "FID provided as auth-file is not an auth-file");
- else if (!lib9p_str_eq(fh->data.auth.uname, req->uname))
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EACCES, "FID provided as auth-file is for user=\"%.*s\" and cannot be used for user=\"%.*s\"",
- fh->data.auth.uname.len, fh->data.auth.uname.utf8,
+ struct srv_fidinfo *afid = map_load(&ctx->parent_sess->fids, req->afid);
+ if (!afid)
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "FID provided as auth-file is not a valid FID");
+ else if (afid->type != SRV_FILETYPE_AUTH)
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "FID provided as auth-file is not an auth-file");
+ else if (!lib9p_str_eq(afid->user->name, req->uname))
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "FID provided as auth-file is for user=\"%.*s\" and cannot be used for user=\"%.*s\"",
+ afid->user->name.len, afid->user->name.utf8,
req->uname.len, req->uname.utf8);
- else if (!lib9p_str_eq(fh->data.auth.aname, req->aname))
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EACCES, "FID provided as auth-file is for tree=\"%.*s\" and cannot be used for tree=\"%.*s\"",
- fh->data.auth.aname.len, fh->data.auth.aname.utf8,
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+ else if (afid->user->num != req->unum)
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "FID provided as auth-file is for user=%"PRIu32" and cannot be used for user=%"PRIu32,
+ afid->user->num, req->unum);
+#endif
+ else if (!lib9p_str_eq(afid->auth.aname, req->aname))
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "FID provided as auth-file is for tree=\"%.*s\" and cannot be used for tree=\"%.*s\"",
+ afid->auth.aname.len, afid->auth.aname.utf8,
req->aname.len, req->aname.utf8);
- else if (!fh->data.auth.authenticated)
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EACCES, "FID provided as auth-file has not completed authentication");
- fh->refcount--;
- if (lib9p_ctx_has_error(&ctx->ctx))
- return;
- */
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EOPNOTSUPP, "TODO: auth not (yet?) implemented");
- return;
+ else if (!afid->auth.completed)
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "FID provided as auth-file has not completed authentication");
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ goto tattach_return;
+ ctx->user = srv_userid_incref(afid->user);
} else {
if (req->afid != LIB9P_FID_NOFID) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EACCES, "FID provided as auth-file, but no auth-file is required");
- return;
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "FID provided as auth-file, but no auth-file is required");
+ goto tattach_return;
}
- }
-
- if (req->fid == LIB9P_FID_NOFID) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EBADF, "cannot assign to NOFID");
- return;
+ ctx->user = srv_userid_new(req->uname, req->unum);
}
/* 1. File object */
- lo_interface lib9p_srv_file root_file = srv->rootdir(&ctx->ctx, req->aname);
- assert(LO_IS_NULL(root_file) == lib9p_ctx_has_error(&ctx->ctx.basectx));
- if (lib9p_ctx_has_error(&ctx->ctx.basectx))
- return;
+ lo_interface lib9p_srv_file root_file = srv->rootdir(ctx, req->aname);
+ assert(LO_IS_NULL(root_file) == lib9p_ctx_has_error(&ctx->basectx));
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ goto tattach_return;
struct lib9p_qid root_qid = LO_CALL(root_file, qid);
- assert(root_qid.type & LIB9P_QT_DIR);
+ assert(srv_qid_filetype(root_qid) == SRV_FILETYPE_DIR);
/* 2. pathinfo */
- struct srv_pathinfo *root_pathinfo = srv_util_pathsave(ctx, root_file, root_qid.path);
+ struct srv_pathinfo *root_pathinfo = srv_path_save(ctx, root_file, root_qid.path);
/* 3. fidinfo */
- if (!srv_util_fidsave(ctx, req->fid, root_pathinfo, false)) {
- srv_util_pathfree(ctx, root_qid.path);
- return;
+ if (!srv_fid_store(ctx, req->fid, root_pathinfo, false)) {
+ srv_path_decref(ctx, root_qid.path);
+ goto tattach_return;
}
- resp->qid = root_qid;
- return;
+ resp.qid = root_qid;
+ tattach_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, attach, &resp);
}
-static void handle_Tflush(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tflush *req,
- struct lib9p_msg_Rflush *resp) {
- util_handler_common(ctx, req, resp);
-
- struct _lib9p_srv_req **oldreqp = reqmap_load(&ctx->parent_sess->reqs, req->oldtag);
- if (oldreqp)
- _lib9p_srv_flushch_recv(&((*oldreqp)->ctx._flushch));
+static void handle_Tflush(struct srv_req *ctx,
+ struct lib9p_msg_Tflush *req) {
+ srv_handler_common(ctx, flush, req);
+
+ struct srv_req **oldreqp = map_load(&ctx->parent_sess->reqs, req->oldtag);
+ if (oldreqp) {
+ struct srv_req *oldreq = *oldreqp;
+ enum _lib9p_srv_flush_result res = _LIB9P_SRV_FLUSH_RFLUSH;
+ switch (cr_select_l(CR_SELECT_RECV(&oldreq->flush_ch, &res),
+ CR_SELECT_SEND(&ctx->flush_ch, &res))) {
+ case 0: /* original request returned */
+ req_debugf("original request (tag=%"PRIu16") returned", req->oldtag);
+ ctx->flush_acknowledged = (res == _LIB9P_SRV_FLUSH_SILENT);
+ break;
+ case 1: /* flush itself got flushed */
+ req_debugf("flush itself flushed");
+ ctx->flush_acknowledged = true;
+ break;
+ }
+ }
+ srv_respond(ctx, flush, &resp);
}
-static void handle_Twalk(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Twalk *req,
- struct lib9p_msg_Rwalk *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Twalk(struct srv_req *ctx,
+ struct lib9p_msg_Twalk *req) {
+ srv_handler_common(ctx, walk, req);
if (req->newfid == LIB9P_FID_NOFID) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EBADF, "cannot assign to NOFID");
- return;
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EBADF, "cannot assign to NOFID");
+ goto twalk_return;
}
- struct _srv_fidinfo *fidinfo = fidmap_load(&ctx->parent_sess->fids, req->fid);
+ struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
+ goto twalk_return;
+ }
+ if (fidinfo->flags & FIDFLAG_OPEN) {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EALREADY, "cannot walk on FID open for I/O");
+ goto twalk_return;
}
+ ctx->user = srv_userid_incref(fidinfo->user);
- struct srv_pathinfo *pathinfo = pathmap_load(&ctx->parent_sess->paths, fidinfo->path);
+ struct srv_pathinfo *pathinfo = map_load(&ctx->parent_sess->paths, fidinfo->path);
assert(pathinfo);
pathinfo->gc_refcount++;
- resp->wqid = (struct lib9p_qid *)(&resp[1]);
- for (resp->nwqid = 0; resp->nwqid < req->nwname; resp->nwqid++) {
+ struct lib9p_qid _resp_qid[16];
+ resp.wqid = _resp_qid;
+ for (resp.nwqid = 0; resp.nwqid < req->nwname; resp.nwqid++) {
+ if (pathinfo->type != SRV_FILETYPE_DIR) {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_ENOTDIR, "not a directory");
+ break;
+ }
+
struct srv_pathinfo *new_pathinfo;
- if (lib9p_str_eq(req->wname[resp->nwqid], lib9p_str(".."))) {
- new_pathinfo = pathmap_load(&ctx->parent_sess->paths, pathinfo->parent_dir);
+ if (lib9p_str_eq(req->wname[resp.nwqid], lib9p_str(".."))) {
+ new_pathinfo = map_load(&ctx->parent_sess->paths, pathinfo->parent_dir);
assert(new_pathinfo);
new_pathinfo->gc_refcount++;
} else {
- if (!srv_util_pathisdir(pathinfo)) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_ENOTDIR, "not a directory");
- break;
- }
-
- lo_interface lib9p_srv_file member_file = LO_CALL(pathinfo->file, dwalk, &ctx->ctx, req->wname[resp->nwqid]);
- assert(LO_IS_NULL(member_file) == lib9p_ctx_has_error(&ctx->ctx.basectx));
- if (lib9p_ctx_has_error(&ctx->ctx.basectx))
+ lo_interface lib9p_srv_file member_file = LO_CALL(pathinfo->file, dwalk, ctx, req->wname[resp.nwqid]);
+ assert(LO_IS_NULL(member_file) == lib9p_ctx_has_error(&ctx->basectx));
+ if (lib9p_ctx_has_error(&ctx->basectx))
break;
- new_pathinfo = srv_util_pathsave(ctx, member_file, LO_CALL(pathinfo->file, qid).path);
+ new_pathinfo = srv_path_save(ctx, member_file, LO_CALL(pathinfo->file, qid).path);
+ assert(new_pathinfo);
}
- if (srv_util_pathisdir(new_pathinfo)) {
- struct lib9p_stat stat = LO_CALL(new_pathinfo->file, stat, &ctx->ctx);
- if (lib9p_ctx_has_error(&ctx->ctx.basectx))
+ if (new_pathinfo->type == SRV_FILETYPE_DIR) {
+ struct lib9p_srv_stat stat = LO_CALL(new_pathinfo->file, stat, ctx);
+ if (lib9p_ctx_has_error(&ctx->basectx))
break;
- lib9p_stat_assert(stat);
- if (!srv_util_check_perm(ctx, &stat, 0b001)) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EACCES, "you do not have execute permission on that directory");
- srv_util_pathfree(ctx, LO_CALL(new_pathinfo->file, qid).path);
+ lib9p_srv_stat_assert(stat);
+ if (!srv_check_perm(ctx, &stat, 0b001)) {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "you do not have execute permission on that directory");
+ srv_path_decref(ctx, LO_CALL(new_pathinfo->file, qid).path);
break;
}
}
- resp->wqid[resp->nwqid] = LO_CALL(new_pathinfo->file, qid);
+ resp.wqid[resp.nwqid] = LO_CALL(new_pathinfo->file, qid);
- srv_util_pathfree(ctx, LO_CALL(pathinfo->file, qid).path);
+ srv_path_decref(ctx, LO_CALL(pathinfo->file, qid).path);
pathinfo = new_pathinfo;
}
- if (resp->nwqid == req->nwname) {
- if (req->newfid == req->fid) {
- if (srv_util_pathisdir(pathinfo))
- LO_CALL(fidinfo->dir.io, iofree);
- else
- LO_CALL(fidinfo->file.io, iofree);
- fidinfo->flags = 0;
- }
- if (!srv_util_fidsave(ctx, req->newfid, pathinfo, req->newfid == req->fid))
- srv_util_pathfree(ctx, LO_CALL(pathinfo->file, qid).path);
+ if (resp.nwqid == req->nwname) {
+ if (!srv_fid_store(ctx, req->newfid, pathinfo, req->newfid == req->fid))
+ srv_path_decref(ctx, LO_CALL(pathinfo->file, qid).path);
} else {
- assert(lib9p_ctx_has_error(&ctx->ctx.basectx));
- srv_util_pathfree(ctx, LO_CALL(pathinfo->file, qid).path);
- if (resp->nwqid > 0)
- lib9p_ctx_clear_error(&ctx->ctx.basectx);
+ assert(lib9p_ctx_has_error(&ctx->basectx));
+ srv_path_decref(ctx, LO_CALL(pathinfo->file, qid).path);
+ if (resp.nwqid > 0)
+ lib9p_ctx_clear_error(&ctx->basectx);
}
+ twalk_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, walk, &resp);
}
-static void handle_Topen(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Topen *req,
- struct lib9p_msg_Ropen *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Topen(struct srv_req *ctx,
+ struct lib9p_msg_Topen *req) {
+ srv_handler_common(ctx, open, req);
/* Check that the FID is valid for this. */
- struct _srv_fidinfo *fidinfo = fidmap_load(&ctx->parent_sess->fids, req->fid);
+ struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
+ goto topen_return;
}
if (fidinfo->flags & FIDFLAG_OPEN) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EALREADY, "FID is already open");
- return;
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EALREADY, "FID is already open");
+ goto topen_return;
}
- struct srv_pathinfo *pathinfo = pathmap_load(&ctx->parent_sess->paths, fidinfo->path);
- assert(pathinfo);
- if (srv_util_pathisdir(pathinfo)) {
+ if (fidinfo->type == SRV_FILETYPE_DIR) {
if ( ((req->mode & LIB9P_O_MODE_MASK) != LIB9P_O_MODE_READ) ||
(req->mode & LIB9P_O_TRUNC) ||
(req->mode & LIB9P_O_RCLOSE) ) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EISDIR, "directories cannot be written, executed, truncated, or removed-on-close");
- return;
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EISDIR, "directories cannot be written, executed, truncated, or removed-on-close");
+ goto topen_return;
}
}
+ ctx->user = srv_userid_incref(fidinfo->user);
/* Variables. */
- lib9p_o_t reqmode = req->mode;
- uint8_t fidflags = fidinfo->flags;
+ lib9p_o_t reqmode = req->mode;
+ uint8_t fidflags = fidinfo->flags;
+ struct srv_pathinfo *pathinfo = map_load(&ctx->parent_sess->paths, fidinfo->path);
+ assert(pathinfo);
/* Check permissions. */
if (reqmode & LIB9P_O_RCLOSE) {
- struct srv_pathinfo *parent = pathmap_load(&ctx->parent_sess->paths, pathinfo->parent_dir);
+ struct srv_pathinfo *parent = map_load(&ctx->parent_sess->paths, pathinfo->parent_dir);
assert(parent);
- struct lib9p_stat parent_stat = LO_CALL(parent->file, stat, &ctx->ctx);
- if (lib9p_ctx_has_error(&ctx->ctx.basectx))
- return;
- lib9p_stat_assert(parent_stat);
- if (!srv_util_check_perm(ctx, &parent_stat, 0b010)) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EACCES, "permission denied to remove-on-close");
- return;
+ struct lib9p_srv_stat parent_stat = LO_CALL(parent->file, stat, ctx);
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ goto topen_return;
+ lib9p_srv_stat_assert(parent_stat);
+ if (!srv_check_perm(ctx, &parent_stat, 0b010)) {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "permission denied to remove-on-close");
+ goto topen_return;
}
fidflags |= FIDFLAG_RCLOSE;
}
- struct lib9p_stat stat = LO_CALL(pathinfo->file, stat, &ctx->ctx);
- if (lib9p_ctx_has_error(&ctx->ctx.basectx))
- return;
- lib9p_stat_assert(stat);
- if ((stat.file_mode & LIB9P_DM_EXCL) && pathinfo->io_refcount) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EEXIST, "exclusive file is already opened");
- return;
+ struct lib9p_srv_stat stat = LO_CALL(pathinfo->file, stat, ctx);
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ goto topen_return;
+ lib9p_srv_stat_assert(stat);
+ if ((stat.mode & LIB9P_DM_EXCL) && pathinfo->io_refcount) {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EEXIST, "exclusive file is already opened");
+ goto topen_return;
}
- if (stat.file_mode & LIB9P_DM_APPEND)
+ if (stat.mode & LIB9P_DM_APPEND) {
+ fidflags |= FIDFLAG_APPEND;
reqmode = reqmode & ~LIB9P_O_TRUNC;
+ }
uint8_t perm_bits = 0;
bool rd = false, wr = false;
switch (reqmode & LIB9P_O_MODE_MASK) {
@@ -912,33 +1085,42 @@ static void handle_Topen(struct _lib9p_srv_req *ctx,
rd = true;
break;
}
- if (!srv_util_check_perm(ctx, &stat, perm_bits)) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EACCES, "permission denied");
- return;
+ if (!srv_check_perm(ctx, &stat, perm_bits)) {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "permission denied");
+ goto topen_return;
}
/* Actually make the call. */
uint32_t iounit;
struct lib9p_qid qid;
- if (srv_util_pathisdir(pathinfo)) {
- fidinfo->dir.io = LO_CALL(pathinfo->file, dopen, &ctx->ctx);
- assert(LO_IS_NULL(fidinfo->dir.io) == lib9p_ctx_has_error(&ctx->ctx.basectx));
- if (lib9p_ctx_has_error(&ctx->ctx.basectx))
- return;
+ switch (pathinfo->type) {
+ case SRV_FILETYPE_DIR:
+ fidinfo->dir.io = LO_CALL(pathinfo->file, dopen, ctx);
+ assert(LO_IS_NULL(fidinfo->dir.io) == lib9p_ctx_has_error(&ctx->basectx));
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ goto topen_return;
fidinfo->dir.idx = 0;
fidinfo->dir.off = 0;
qid = LO_CALL(fidinfo->dir.io, qid);
iounit = 0;
- } else {
- fidinfo->file.io = LO_CALL(pathinfo->file, fopen, &ctx->ctx,
+ break;
+ case SRV_FILETYPE_FILE:
+ fidinfo->file.io = LO_CALL(pathinfo->file, fopen, ctx,
rd, wr,
reqmode & LIB9P_O_TRUNC);
- assert(LO_IS_NULL(fidinfo->file.io) == lib9p_ctx_has_error(&ctx->ctx.basectx));
- if (lib9p_ctx_has_error(&ctx->ctx.basectx))
- return;
+ assert(LO_IS_NULL(fidinfo->file.io) == lib9p_ctx_has_error(&ctx->basectx));
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ goto topen_return;
qid = LO_CALL(fidinfo->file.io, qid);
iounit = LO_CALL(fidinfo->file.io, iounit);
+ break;
+ case SRV_FILETYPE_AUTH:
+ assert_notreached("TODO: auth not yet implemented");
+ break;
+ default:
+ assert_notreached("invalid srv_filetype");
+ break;
}
/* Success. */
@@ -948,222 +1130,326 @@ static void handle_Topen(struct _lib9p_srv_req *ctx,
fidflags |= FIDFLAG_OPEN_W;
pathinfo->io_refcount++;
fidinfo->flags = fidflags;
- resp->qid = qid;
- resp->iounit = iounit;
+ resp.qid = qid;
+ resp.iounit = iounit;
+ topen_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, open, &resp);
}
-static void handle_Tcreate(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tcreate *req,
- struct lib9p_msg_Rcreate *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Tcreate(struct srv_req *ctx,
+ struct lib9p_msg_Tcreate *req) {
+ srv_handler_common(ctx, create, req);
+
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EOPNOTSUPP, "create not (yet?) implemented");
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EOPNOTSUPP, "create not (yet?) implemented");
+ srv_respond(ctx, create, &resp);
}
-static void handle_Tread(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tread *req,
- struct lib9p_msg_Rread *resp) {
- util_handler_common(ctx, req, resp);
+static inline struct lib9p_stat srv_stat_to_net_stat(struct lib9p_srv_stat in) {
+ return (struct lib9p_stat){
+ .qid = in.qid,
+ .mode = in.mode,
+ .atime = in.atime_sec,
+ .mtime = in.mtime_sec,
+ .length = in.size,
+ .name = in.name,
+ .owner_uname = in.owner_uid.name,
+ .owner_gname = in.owner_gid.name,
+ .last_modifier_uname = in.last_modifier_uid.name,
+#if CONFIG_9P_ENABLE_9P2000_u
+ .owner_unum = in.owner_uid.num,
+ .owner_gnum = in.owner_gid.num,
+ .last_modifier_unum = in.last_modifier_uid.num,
+ .extension = in.extension,
+#endif
+ };
+}
+
+static void handle_Tread(struct srv_req *ctx,
+ struct lib9p_msg_Tread *req) {
+ srv_handler_common(ctx, read, req);
+ char *heap = NULL;
/* TODO: serialize simultaneous reads to the same FID */
/* Check that the FID is valid for this. */
- struct _srv_fidinfo *fidinfo = fidmap_load(&ctx->parent_sess->fids, req->fid);
+ struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
+ goto tread_return;
}
if (!(fidinfo->flags & FIDFLAG_OPEN_R)) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EINVAL, "FID not open for reading");
- return;
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EINVAL, "FID not open for reading");
+ goto tread_return;
}
- /* Variables. */
- struct srv_pathinfo *pathinfo = pathmap_load(&ctx->parent_sess->paths, fidinfo->path);
- assert(pathinfo);
-
/* Do it. */
- if (srv_util_pathisdir(pathinfo)) {
- /* Translate byte-offset to object-index. */
- size_t idx;
- if (req->offset == 0)
- idx = 0;
- else if (req->offset == fidinfo->dir.off)
- idx = fidinfo->dir.idx;
- else {
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EINVAL, "invalid offset (must be 0 or %"PRIu64"): %"PRIu64,
+ ctx->user = srv_userid_incref(fidinfo->user);
+ switch (fidinfo->type) {
+ case SRV_FILETYPE_DIR:
+#if _LIB9P_ENABLE_stat
+ /* Seek. */
+ if (req->offset == 0) {
+ fidinfo->dir.idx = 0;
+ fidinfo->dir.off = 0;
+ fidinfo->dir.buffered_dirent = (struct lib9p_srv_dirent){};
+ } else if (req->offset != fidinfo->dir.off) {
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EINVAL, "invalid offset (must be 0 or %"PRIu64"): %"PRIu64,
fidinfo->dir.off, req->offset);
- return;
+ goto tread_return;
}
- /* Do it. */
- resp->data = (char *)(&resp[1]);
- size_t num = LO_CALL(fidinfo->dir.io, dread, &ctx->ctx, (uint8_t *)resp->data, req->count, idx);
- /* Translate object-count back to byte-count. */
- uint32_t len = 0;
- for (size_t i = 0; i < num; i++) {
- uint32_t i_len;
- lib9p_stat_validate(&ctx->ctx.basectx, req->count, &((uint8_t *)resp->data)[len], &i_len, NULL);
- len += i_len;
+ /* Read. */
+ resp.data = heap = malloc(req->count); /* TODO: cap req->count */
+ resp.count = 0;
+ struct srv_pathinfo *dir_pathinfo = NULL;
+ for (;;) {
+ lo_interface lib9p_srv_file member_file = {};
+ struct lib9p_srv_dirent member_dirent;
+ if (fidinfo->dir.buffered_dirent.name.len) {
+ member_dirent = fidinfo->dir.buffered_dirent;
+ } else {
+ member_dirent = LO_CALL(fidinfo->dir.io, dread, ctx, fidinfo->dir.idx);
+ if (lib9p_ctx_has_error(&ctx->basectx)) {
+ if (!resp.count)
+ goto tread_return;
+ lib9p_ctx_clear_error(&ctx->basectx);
+ break;
+ }
+ }
+ if (!member_dirent.name.len)
+ break;
+ struct lib9p_srv_stat member_stat;
+ struct srv_pathinfo *member_pathinfo = map_load(&ctx->parent_sess->paths, member_dirent.qid.path);
+ if (member_pathinfo) {
+ member_stat = LO_CALL(member_pathinfo->file, stat, ctx);
+ } else {
+ if (!dir_pathinfo)
+ dir_pathinfo = map_load(&ctx->parent_sess->paths, fidinfo->path);
+ assert(dir_pathinfo);
+ member_file = LO_CALL(dir_pathinfo->file, dwalk, ctx, member_dirent.name);
+ assert(LO_IS_NULL(member_file) == lib9p_ctx_has_error(&ctx->basectx));
+ if (!lib9p_ctx_has_error(&ctx->basectx))
+ member_stat = LO_CALL(member_file, stat, ctx);
+ }
+ if (lib9p_ctx_has_error(&ctx->basectx)) {
+ if (!LO_IS_NULL(member_file))
+ LO_CALL(member_file, free);
+ if (!resp.count)
+ goto tread_return;
+ lib9p_ctx_clear_error(&ctx->basectx);
+ break;
+ }
+ lib9p_srv_stat_assert(member_stat);
+ struct lib9p_stat member_netstat = srv_stat_to_net_stat(member_stat);
+ uint32_t nbytes = lib9p_stat_marshal(&ctx->basectx, req->count-resp.count, &member_netstat,
+ (uint8_t *)&resp.data[resp.count]);
+ if (!LO_IS_NULL(member_file))
+ LO_CALL(member_file, free);
+ if (!nbytes) {
+ if (!resp.count) {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_ERANGE, "stat object does not fit into negotiated max message size");
+ goto tread_return;
+ }
+ fidinfo->dir.buffered_dirent = member_dirent;
+ break;
+ }
+ resp.count += nbytes;
+ fidinfo->dir.idx++;
+ fidinfo->dir.off += nbytes;
+ fidinfo->dir.buffered_dirent = (struct lib9p_srv_dirent){};
}
- resp->count = len;
- /* Remember. */
- fidinfo->dir.idx = idx+num;
- fidinfo->dir.off = req->offset + len;
- } else {
+#else
+ assert_notreached("Tread for directory on protocol version without that");
+#endif
+ break;
+ case SRV_FILETYPE_FILE:
struct iovec iov;
- LO_CALL(fidinfo->file.io, pread, &ctx->ctx, req->count, req->offset, &iov);
- if (!lib9p_ctx_has_error(&ctx->ctx.basectx)) {
- resp->count = iov.iov_len;
- resp->data = iov.iov_base;
- if (resp->count > req->count)
- resp->count = req->count;
+ LO_CALL(fidinfo->file.io, pread, ctx, req->count, req->offset, &iov);
+ if (!lib9p_ctx_has_error(&ctx->basectx) && !ctx->flush_acknowledged) {
+ resp.count = iov.iov_len;
+ resp.data = iov.iov_base;
+ if (resp.count > req->count)
+ resp.count = req->count;
}
+ break;
+ case SRV_FILETYPE_AUTH:
+ assert_notreached("TODO: auth not yet implemented");
+ break;
}
+ tread_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, read, &resp);
+ if (heap)
+ free(heap);
}
-static void handle_Twrite(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Twrite *req,
- struct lib9p_msg_Rwrite *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Twrite(struct srv_req *ctx,
+ struct lib9p_msg_Twrite *req) {
+ srv_handler_common(ctx, write, req);
/* TODO: serialize simultaneous writes to the same FID */
/* Check that the FID is valid for this. */
- struct _srv_fidinfo *fidinfo = fidmap_load(&ctx->parent_sess->fids, req->fid);
+ struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
+ goto twrite_return;
}
if (!(fidinfo->flags & FIDFLAG_OPEN_W)) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EINVAL, "FID not open for writing");
- return;
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EINVAL, "FID not open for writing");
+ goto twrite_return;
}
-
- /* Variables. */
- struct srv_pathinfo *pathinfo = pathmap_load(&ctx->parent_sess->paths, fidinfo->path);
- assert(pathinfo);
+ if (fidinfo->flags & FIDFLAG_APPEND)
+ req->offset = 0;
/* Do it. */
- resp->count = LO_CALL(fidinfo->file.io, pwrite, &ctx->ctx, req->data, req->count, req->offset);
+ ctx->user = srv_userid_incref(fidinfo->user);
+ resp.count = LO_CALL(fidinfo->file.io, pwrite, ctx, req->data, req->count, req->offset);
+ twrite_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, write, &resp);
}
-static void clunkremove(struct _lib9p_srv_req *ctx, lib9p_fid_t fid, bool remove) {
- struct _srv_fidinfo *fidinfo = fidmap_load(&ctx->parent_sess->fids, fid);
+static void handle_Tclunk(struct srv_req *ctx,
+ struct lib9p_msg_Tclunk *req) {
+ srv_handler_common(ctx, clunk, req);
+
+ struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EBADF, "bad file number %"PRIu32, fid);
- return;
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
+ goto tclunk_return;
}
- if (fidinfo->flags & FIDFLAG_RCLOSE)
- remove = true;
- struct srv_pathinfo *pathinfo = pathmap_load(&ctx->parent_sess->paths, fidinfo->path);
- assert(pathinfo);
- if (remove) {
- if (pathinfo->parent_dir == fidinfo->path) {
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EBUSY, "cannot remove root");
- goto clunk;
- }
- struct srv_pathinfo *parent = pathmap_load(&ctx->parent_sess->paths, pathinfo->parent_dir);
- assert(parent);
- struct lib9p_stat parent_stat = LO_CALL(parent->file, stat, &ctx->ctx);
- if (!srv_util_check_perm(ctx, &parent_stat, 0b010)) {
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EACCES, "you do not have write permission on the parent directory");
- goto clunk;
- }
- LO_CALL(pathinfo->file, remove, &ctx->ctx);
- }
+ srv_fid_del(ctx, req->fid, fidinfo, false);
- clunk:
- if (fidinfo->flags & FIDFLAG_OPEN) {
- if (srv_util_pathisdir(pathinfo))
- LO_CALL(fidinfo->dir.io, iofree);
- else
- LO_CALL(fidinfo->file.io, iofree);
- pathinfo->io_refcount--;
- }
- srv_util_pathfree(ctx, LO_CALL(pathinfo->file, qid).path);
- fidmap_del(&ctx->parent_sess->fids, fid);
+ tclunk_return:
+ srv_respond(ctx, clunk, &resp);
}
-static void handle_Tclunk(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tclunk *req,
- struct lib9p_msg_Rclunk *resp) {
- util_handler_common(ctx, req, resp);
-
- clunkremove(ctx, req->fid, false);
-}
+static void handle_Tremove(struct srv_req *ctx,
+ struct lib9p_msg_Tremove *req) {
+ srv_handler_common(ctx, remove, req);
+ struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
+ if (!fidinfo) {
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
+ goto tremove_return;
+ }
-static void handle_Tremove(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tremove *req,
- struct lib9p_msg_Rremove *resp) {
- util_handler_common(ctx, req, resp);
+ bool remove = true;
+ struct srv_pathinfo *pathinfo = map_load(&ctx->parent_sess->paths, fidinfo->path);
+ assert(pathinfo);
+ if (pathinfo->parent_dir == fidinfo->path) {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EBUSY, "cannot remove root");
+ remove = false;
+ goto tremove_main;
+ }
+ struct srv_pathinfo *parent = map_load(&ctx->parent_sess->paths, pathinfo->parent_dir);
+ assert(parent);
+ struct lib9p_srv_stat parent_stat = LO_CALL(parent->file, stat, ctx);
+ if (!lib9p_ctx_has_error(&ctx->basectx) && !srv_check_perm(ctx, &parent_stat, 0b010)) {
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EACCES, "you do not have write permission on the parent directory");
+ remove = false;
+ goto tremove_main;
+ }
- clunkremove(ctx, req->fid, true);
+ tremove_main:
+ srv_fid_del(ctx, req->fid, fidinfo, remove);
+ tremove_return:
+ srv_respond(ctx, remove, &resp);
}
-static void handle_Tstat(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tstat *req,
- struct lib9p_msg_Rstat *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Tstat(struct srv_req *ctx,
+ struct lib9p_msg_Tstat *req) {
+ srv_handler_common(ctx, stat, req);
- struct _srv_fidinfo *fidinfo = fidmap_load(&ctx->parent_sess->fids, req->fid);
+ struct srv_fidinfo *fidinfo = map_load(&ctx->parent_sess->fids, req->fid);
if (!fidinfo) {
- lib9p_errorf(&ctx->ctx.basectx,
- LINUX_EBADF, "bad file number %"PRIu32, req->fid);
- return;
+ lib9p_errorf(&ctx->basectx,
+ LIB9P_ERRNO_L_EBADF, "bad file number %"PRIu32, req->fid);
+ goto tstat_return;
}
- struct srv_pathinfo *pathinfo = pathmap_load(&ctx->parent_sess->paths, fidinfo->path);
+ struct srv_pathinfo *pathinfo = map_load(&ctx->parent_sess->paths, fidinfo->path);
assert(pathinfo);
- resp->stat = LO_CALL(pathinfo->file, stat, &ctx->ctx);
- if (!lib9p_ctx_has_error(&ctx->ctx.basectx))
- lib9p_stat_assert(resp->stat);
+ ctx->user = srv_userid_incref(fidinfo->user);
+ struct lib9p_srv_stat stat = LO_CALL(pathinfo->file, stat, ctx);
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ goto tstat_return;
+ lib9p_srv_stat_assert(stat);
+ resp.stat = srv_stat_to_net_stat(stat);
+ tstat_return:
+ if (ctx->user)
+ ctx->user = srv_userid_decref(ctx->user);
+ srv_respond(ctx, stat, &resp);
}
-static void handle_Twstat(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Twstat *req,
- struct lib9p_msg_Rwstat *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Twstat(struct srv_req *ctx,
+ struct lib9p_msg_Twstat *req) {
+ srv_handler_common(ctx, wstat, req);
+
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EOPNOTSUPP, "wstat not (yet?) implemented");
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EOPNOTSUPP, "wstat not (yet?) implemented");
+ srv_respond(ctx, wstat, &resp);
}
+#endif
+
+#if CONFIG_9P_ENABLE_9P2000_p9p
+static void handle_Topenfd(struct srv_req *ctx,
+ struct lib9p_msg_Topenfd *req) {
+ srv_handler_common(ctx, openfd, req);
+
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EOPNOTSUPP, "openfd not (yet?) implemented");
+
+ srv_respond(ctx, openfd, &resp);
+}
+#endif
#if CONFIG_9P_ENABLE_9P2000_e
-static void handle_Tsession(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tsession *req,
- struct lib9p_msg_Rsession *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Tsession(struct srv_req *ctx,
+ struct lib9p_msg_Tsession *req) {
+ srv_handler_common(ctx, session, req);
+
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EOPNOTSUPP, "session not (yet?) implemented");
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EOPNOTSUPP, "session not (yet?) implemented");
+ srv_respond(ctx, session, &resp);
}
-static void handle_Tsread(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tsread *req,
- struct lib9p_msg_Rsread *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Tsread(struct srv_req *ctx,
+ struct lib9p_msg_Tsread *req) {
+ srv_handler_common(ctx, sread, req);
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EOPNOTSUPP, "sread not (yet?) implemented");
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EOPNOTSUPP, "sread not (yet?) implemented");
+
+ srv_respond(ctx, sread, &resp);
}
-static void handle_Tswrite(struct _lib9p_srv_req *ctx,
- struct lib9p_msg_Tswrite *req,
- struct lib9p_msg_Rswrite *resp) {
- util_handler_common(ctx, req, resp);
+static void handle_Tswrite(struct srv_req *ctx,
+ struct lib9p_msg_Tswrite *req) {
+ srv_handler_common(ctx, swrite, req);
+
+ lib9p_error(&ctx->basectx,
+ LIB9P_ERRNO_L_EOPNOTSUPP, "swrite not (yet?) implemented");
- lib9p_error(&ctx->ctx.basectx,
- LINUX_EOPNOTSUPP, "swrite not (yet?) implemented");
+ srv_respond(ctx, swrite, &resp);
}
#endif
diff --git a/lib9p/srv_include/lib9p/srv.h b/lib9p/srv_include/lib9p/srv.h
new file mode 100644
index 0000000..c72aff5
--- /dev/null
+++ b/lib9p/srv_include/lib9p/srv.h
@@ -0,0 +1,305 @@
+/* lib9p/srv.h - 9P server
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _LIB9P_SRV_H_
+#define _LIB9P_SRV_H_
+
+#include <libcr/coroutine.h>
+#include <libcr_ipc/chan.h>
+#include <libcr_ipc/rpc.h>
+#include <libhw/generic/net.h>
+#include <libmisc/assert.h>
+#include <libmisc/private.h>
+#include <libobj/obj.h>
+
+#include <lib9p/core.h>
+
+/* context ********************************************************************/
+
+struct lib9p_srv_userid {
+ struct lib9p_s name;
+#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L
+ lib9p_nuid_t num;
+#endif
+
+ BEGIN_PRIVATE(LIB9P_SRV_H);
+ unsigned int refcount;
+ END_PRIVATE(LIB9P_SRV_H);
+};
+
+enum _lib9p_srv_flush_result {
+ _LIB9P_SRV_FLUSH_RFLUSH,
+ _LIB9P_SRV_FLUSH_SILENT,
+};
+
+CR_CHAN_DECLARE(_lib9p_srv_flush_ch, enum _lib9p_srv_flush_result);
+
+struct lib9p_srv_ctx {
+ struct lib9p_ctx basectx;
+ struct lib9p_srv_userid *user;
+
+ BEGIN_PRIVATE(LIB9P_SRV_H);
+ struct _lib9p_srv_sess *parent_sess;
+ lib9p_tag_t tag;
+ uint8_t *net_bytes;
+ _lib9p_srv_flush_ch_t flush_ch;
+ bool flush_acknowledged;
+ bool responded;
+ END_PRIVATE(LIB9P_SRV_H);
+};
+
+/**
+ * Return whether there is an outstanding Tflush or Tversion
+ * cancellation of this request. After becoming true, this may go
+ * back to false if the Tflush itself is flushed.
+ */
+bool lib9p_srv_flush_requested(struct lib9p_srv_ctx *ctx);
+
+/**
+ * Acknowledge that the handler is responding to an outstanding flush;
+ * a non-Rerror R-message will be elided in favor of Rflush/Rversion.
+ * lib9p_srv_flush_requested() must be true; so do not cr_yield()
+ * between checking lib9p_srv_flush_requested() and calling
+ * lib9p_srv_acknowledge_flush(). These are separate calls to
+ * facilitate cases where a flush merely truncates a call, instead of
+ * totally canceling it.
+ */
+void lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx);
+
+/* version-independent stat ***************************************************/
+
+struct lib9p_srv_stat {
+ struct lib9p_qid qid;
+ lib9p_dm_t mode;
+ uint32_t atime_sec; /* BUG: u32 seconds means a 2106 problem */
+#if CONFIG_9P_ENABLE_9P2000_L
+ uint32_t atime_nsec;
+#endif
+ uint32_t mtime_sec; /* BUG: u32 seconds means a 2106 problem */
+#if CONFIG_9P_ENABLE_9P2000_L
+ uint32_t mtime_nsec;
+ uint32_t ctime_sec; /* BUG: u32 seconds means a 2106 problem */
+ uint32_t ctime_nsec;
+ uint32_t btime_sec; /* BUG: u32 seconds means a 2106 problem */
+ uint32_t btime_nsec;
+#endif
+ uint64_t size;
+ struct lib9p_s name;
+ struct lib9p_srv_userid owner_uid;
+ struct lib9p_srv_userid owner_gid;
+ struct lib9p_srv_userid last_modifier_uid;
+#if CONFIG_9P_ENABLE_9P2000_u
+ struct lib9p_s extension;
+#endif
+};
+
+static inline void lib9p_srv_stat_assert(struct lib9p_srv_stat stat) {
+ assert( ((bool)(stat.mode & LIB9P_DM_DIR )) == ((bool)(stat.qid.type & LIB9P_QT_DIR )) );
+ assert( ((bool)(stat.mode & LIB9P_DM_APPEND)) == ((bool)(stat.qid.type & LIB9P_QT_APPEND)) );
+ assert( ((bool)(stat.mode & LIB9P_DM_EXCL )) == ((bool)(stat.qid.type & LIB9P_QT_EXCL )) );
+ assert( ((bool)(stat.mode & LIB9P_DM_AUTH )) == ((bool)(stat.qid.type & LIB9P_QT_AUTH )) );
+ assert( ((bool)(stat.mode & LIB9P_DM_TMP )) == ((bool)(stat.qid.type & LIB9P_QT_TMP )) );
+ assert( (stat.size == 0) || !(stat.mode & LIB9P_DM_DIR) );
+}
+
+/* interface definitions ******************************************************/
+
+struct lib9p_srv_dirent {
+ struct lib9p_qid qid;
+ struct lib9p_s name;
+};
+
+lo_interface lib9p_srv_fio;
+lo_interface lib9p_srv_dio;
+
+/* FIXME: I don't like that the pointer returned by pread() has to
+ * remain live after it returns. Perhaps a `respond()`-callback? But
+ * that just reads as gross in C.
+ *
+ * FIXME: It would be nice if pread() could return more than 1 iovec.
+ */
+#define lib9p_srv_file_LO_IFACE \
+ /* resource management **********************************************/ \
+ \
+ /** \
+ * free() is be called when all FIDs associated with the file are \
+ * clunked. \
+ * \
+ * free() MUST NOT error. \
+ */ \
+ LO_FUNC(void , free ) \
+ \
+ /** \
+ * qid() is called frequently and returns the current QID of the file. \
+ * The .path field MUST never change, the .type field may change in \
+ * response to wstat() calls (but the QT_DIR bit MUST NOT change), and \
+ * the .vers field may change frequently in response to any number of \
+ * things (wstat(), write(), or non-9P events). \
+ * \
+ * qid() MUST NOT error. \
+ */ \
+ LO_FUNC(struct lib9p_qid , qid ) \
+ \
+ /* non-"opened" generic I/O *****************************************/ \
+ \
+ /** Strings returned from stat() must remain valid until free(). */ \
+ LO_FUNC(struct lib9p_srv_stat , stat , struct lib9p_srv_ctx *) \
+ LO_FUNC(void , wstat , struct lib9p_srv_ctx *, \
+ struct lib9p_srv_stat) \
+ LO_FUNC(void , remove , struct lib9p_srv_ctx *) \
+ \
+ /* non-"opened" directory I/O ***************************************/ \
+ \
+ LO_FUNC(lo_interface lib9p_srv_file, dwalk , struct lib9p_srv_ctx *, \
+ struct lib9p_s childname) \
+ LO_FUNC(lo_interface lib9p_srv_file, dcreate, struct lib9p_srv_ctx *, \
+ struct lib9p_s childname, \
+ struct lib9p_srv_userid *user, \
+ struct lib9p_srv_userid *group, \
+ lib9p_dm_t perm) \
+ \
+ /* open() for I/O ***************************************************/ \
+ \
+ LO_FUNC(lo_interface lib9p_srv_fio , fopen , struct lib9p_srv_ctx *, \
+ bool rd, bool wr, \
+ bool trunc) \
+ LO_FUNC(lo_interface lib9p_srv_dio , dopen , struct lib9p_srv_ctx *)
+LO_INTERFACE(lib9p_srv_file);
+
+#define lib9p_srv_fio_LO_IFACE \
+ LO_FUNC(struct lib9p_qid , qid ) \
+ LO_FUNC(void , iofree ) \
+ LO_FUNC(uint32_t , iounit ) \
+ LO_FUNC(void , pread , struct lib9p_srv_ctx *, \
+ uint32_t byte_count, \
+ uint64_t byte_offset, \
+ struct iovec *ret) \
+ /** \
+ * If the file was append-only when fopen()ed, then byte_offset will \
+ * always be 0. \
+ */ \
+ LO_FUNC(uint32_t , pwrite , struct lib9p_srv_ctx *, \
+ void *buf, \
+ uint32_t byte_count, \
+ uint64_t byte_offset)
+LO_INTERFACE(lib9p_srv_fio);
+
+#define lib9p_srv_dio_LO_IFACE \
+ LO_FUNC(struct lib9p_qid , qid ) \
+ LO_FUNC(void , iofree ) \
+ /** \
+ * Return the idx-th dirent. idx will always be either 0 or \
+ * prev_idx+1. A dirrent with an empty name signals EOF. The string
+ * must remain valid until the next dread() call or iofree(). \
+ */ \
+ LO_FUNC(struct lib9p_srv_dirent , dread , struct lib9p_srv_ctx *, \
+ size_t idx)
+LO_INTERFACE(lib9p_srv_dio);
+
+#define LIB9P_SRV_NOTDIR(TYP, NAM) \
+ static lo_interface lib9p_srv_file NAM##_dwalk (TYP *, struct lib9p_srv_ctx *, struct lib9p_s) { assert_notreached("not a directory"); } \
+ static lo_interface lib9p_srv_file NAM##_dcreate(TYP *, struct lib9p_srv_ctx *, struct lib9p_s, \
+ struct lib9p_srv_userid *, struct lib9p_srv_userid *, lib9p_dm_t) { assert_notreached("not a directory"); } \
+ static lo_interface lib9p_srv_dio NAM##_dopen (TYP *, struct lib9p_srv_ctx *) { assert_notreached("not a directory"); }
+
+#define LIB9P_SRV_NOTFILE(TYP, NAM) \
+ static lo_interface lib9p_srv_fio NAM##_fopen (TYP *, struct lib9p_srv_ctx *, bool, bool, bool) { assert_notreached("not a file"); }
+
+/* main server entrypoints ****************************************************/
+
+CR_RPC_DECLARE(_lib9p_srv_reqch, struct lib9p_srv_ctx *, bool);
+
+#if CONFIG_9P_ENABLE_9P2000_p9p
+#define net_stream_conn_unix_LO_IFACE \
+ LO_NEST(net_stream_conn) \
+ /** Returns 0 on success, -errno on error. */ \
+ LO_FUNC(int, send_unix_fd, int fd)
+LO_INTERFACE(net_stream_conn_unix);
+#endif
+
+struct lib9p_srv {
+ /* Things you provide */
+ void /*TODO*/ (*auth )(struct lib9p_srv_ctx *, struct lib9p_s treename); /* optional */
+ lo_interface lib9p_srv_file (*rootdir)(struct lib9p_srv_ctx *, struct lib9p_s treename);
+ void (*msglog )(struct lib9p_srv_ctx *, enum lib9p_msg_type, void *hostmsg); /* optional */
+#if CONFIG_9P_ENABLE_9P2000_p9p
+ lo_interface net_stream_conn_unix (*type_assert_unix)(lo_interface net_stream_conn); /* optional */
+#endif
+
+ /* For internal use */
+ BEGIN_PRIVATE(LIB9P_SRV_H);
+ unsigned int readers;
+ unsigned int writers;
+ _lib9p_srv_reqch_t _reqch;
+ END_PRIVATE(LIB9P_SRV_H);
+};
+
+/**
+ * In a loop loop, accept a connection call lib9p_srv_read() on it.
+ * If LO_CALL(listener, accept) fails, then the function returns.
+ *
+ * When the last lib9p_srv_accept_and_read_loop() instance for a given
+ * `srv` returns, it will signal all lib9p_srv_worker_loop() calls to
+ * return.
+ *
+ * @param srv: The server configuration and state; has an associated
+ * pool of lib9p_srv_worker_loop() coroutines.
+ *
+ * @param listener: The listener object to accept connections from.
+ */
+void lib9p_srv_accept_and_read_loop(struct lib9p_srv *srv, lo_interface net_stream_listener listener);
+
+/**
+ * You should probably not call this directly; you should probably use
+ * lib9p_srv_accept_and_read_loop().
+ *
+ * Given an already-established stream connection (i.e. a TCP
+ * connection), service that connection; return once the connection is
+ * closed. Requests are dispatched to a pool of
+ * lib9p_srv_worker_loop() coroutines with the same `srv`.
+ *
+ * Will just close the connection if a T-message has a size[4] <7.
+ *
+ * @param srv: The server configuration and state; has an associated
+ * pool of lib9p_srv_worker_loop() coroutines.
+ *
+ * @param conn: The listener object to accept connections from.
+ *
+ * Errors that this function itself may send to clients:
+ *
+ * @errno L_EMSGSIZE T-message has size[4] bigger than max_msg_size
+ * @errno L_EDOM Tversion specified an impossibly small max_msg_size
+ * @errno L_EOPNOTSUPP T-message has an R-message type, or an unrecognized T-message type
+ * @errno L_EBADMSG T-message has wrong size[4] for its content, or has invalid UTF-8
+ */
+void lib9p_srv_read(struct lib9p_srv *srv, lo_interface net_stream_conn conn);
+
+/**
+ * In a loop, call lib9p_srv_worker() to service requests to the
+ * `struct lib9p_srv *srv` argument that have been read by
+ * lib9p_srv_accept_and_read_loop() / lib9p_srv_read(). A "NULL"
+ * request causes the function to return.
+ *
+ * @param srv: The server configuration and state; has an associated
+ * pool of lib9p_srv_accept_and_read_loop() coroutines.
+ */
+void lib9p_srv_worker_loop(struct lib9p_srv *srv);
+
+/**
+ * You should probably not call this directly; you should probably use
+ * lib9p_srv_worker_loop().
+ *
+ * Handle and send a response to a single request.
+ *
+ * @param req: The request to handle.
+ *
+ * Errors that this function itself may send to clients:
+ *
+ * @errno L_ERANGE R-message does not fit into max_msg_size
+ */
+void lib9p_srv_worker(struct lib9p_srv_ctx *req);
+
+#endif /* _LIB9P_SRV_H_ */
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 }
diff --git a/lib9p_util/CMakeLists.txt b/lib9p_util/CMakeLists.txt
index 2e5790e..feeada7 100644
--- a/lib9p_util/CMakeLists.txt
+++ b/lib9p_util/CMakeLists.txt
@@ -9,5 +9,5 @@ target_sources(lib9p_util INTERFACE
static.c
)
target_link_libraries(lib9p_util INTERFACE
- lib9p
+ lib9p_srv
)
diff --git a/lib9p_util/static.c b/lib9p_util/static.c
index 7f1e6b7..1726319 100644
--- a/lib9p_util/static.c
+++ b/lib9p_util/static.c
@@ -33,40 +33,35 @@ static struct lib9p_qid util9p_static_dir_qid(struct util9p_static_dir *self) {
};
}
-static struct lib9p_stat util9p_static_dir_stat(struct util9p_static_dir *self, struct lib9p_srv_ctx *ctx) {
+static struct lib9p_srv_stat util9p_static_dir_stat(struct util9p_static_dir *self, struct lib9p_srv_ctx *ctx) {
assert(self);
assert(ctx);
- return (struct lib9p_stat){
- .kern_type = 0,
- .kern_dev = 0,
- .file_qid = util9p_static_dir_qid(self),
- .file_mode = LIB9P_DM_DIR | (self->perm & 0555),
- .file_atime = self->atime,
- .file_mtime = self->mtime,
- .file_size = 0,
- .file_name = lib9p_str(self->name),
- .file_owner_uid = lib9p_str(self->u_name),
- .file_owner_gid = lib9p_str(self->g_name),
- .file_last_modified_uid = lib9p_str(self->m_name),
- .file_extension = lib9p_str(NULL),
- .file_owner_n_uid = self->u_num,
- .file_owner_n_gid = self->g_num,
- .file_last_modified_n_uid = self->m_num,
+ return (struct lib9p_srv_stat){
+ .qid = util9p_static_dir_qid(self),
+ .mode = LIB9P_DM_DIR | (self->perm & 0555),
+ .atime_sec = self->atime,
+ .mtime_sec = self->mtime,
+ .size = 0,
+ .name = lib9p_str(self->name),
+ .owner_uid = { .name = lib9p_str(self->u_name), .num = self->u_num },
+ .owner_gid = { .name = lib9p_str(self->g_name), .num = self->g_num },
+ .last_modifier_uid = { .name = lib9p_str(self->m_name), .num = self->m_num },
+ .extension = lib9p_str(NULL),
};
}
static void util9p_static_dir_wstat(struct util9p_static_dir *self, struct lib9p_srv_ctx *ctx,
- struct lib9p_stat) {
+ struct lib9p_srv_stat) {
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
}
static void util9p_static_dir_remove(struct util9p_static_dir *self, struct lib9p_srv_ctx *ctx) {
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
}
static lo_interface lib9p_srv_file util9p_static_dir_dwalk(struct util9p_static_dir *self, struct lib9p_srv_ctx *ctx,
@@ -76,25 +71,27 @@ static lo_interface lib9p_srv_file util9p_static_dir_dwalk(struct util9p_static_
for (size_t i = 0; !LO_IS_NULL(self->members[i]); i++) {
lo_interface lib9p_srv_file file = self->members[i];
- struct lib9p_stat stat = LO_CALL(file, stat, ctx);
+ struct lib9p_srv_stat stat = LO_CALL(file, stat, ctx);
if (lib9p_ctx_has_error(&ctx->basectx))
break;
- lib9p_stat_assert(stat);
- if (lib9p_str_eq(stat.file_name, childname))
+ lib9p_srv_stat_assert(stat);
+ if (lib9p_str_eq(stat.name, childname))
return file;
}
lib9p_error(&ctx->basectx,
- LINUX_ENOENT, "no such file or directory");
+ LIB9P_ERRNO_L_ENOENT, "no such file or directory");
return LO_NULL(lib9p_srv_file);
}
static lo_interface lib9p_srv_file util9p_static_dir_dcreate(struct util9p_static_dir *self, struct lib9p_srv_ctx *ctx,
struct lib9p_s LM_UNUSED(childname),
- lib9p_dm_t LM_UNUSED(perm), lib9p_o_t LM_UNUSED(flags)) {
+ struct lib9p_srv_userid *LM_UNUSED(user),
+ struct lib9p_srv_userid *LM_UNUSED(group),
+ lib9p_dm_t LM_UNUSED(perm)) {
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
return LO_NULL(lib9p_srv_file);
}
@@ -108,33 +105,23 @@ static lo_interface lib9p_srv_dio util9p_static_dir_dopen(struct util9p_static_d
static void util9p_static_dir_iofree(struct util9p_static_dir *self) {
assert(self);
}
-static size_t util9p_static_dir_dread(struct util9p_static_dir *self, struct lib9p_srv_ctx *ctx,
- uint8_t *buf,
- uint32_t byte_count,
- size_t _obj_offset) {
+static struct lib9p_srv_dirent util9p_static_dir_dread(struct util9p_static_dir *self, struct lib9p_srv_ctx *ctx, size_t idx) {
assert(self);
assert(ctx);
- uint32_t byte_offset = 0;
- size_t obj_offset = _obj_offset;
- while (!LO_IS_NULL(self->members[obj_offset])) {
- lo_interface lib9p_srv_file file = self->members[obj_offset];
- struct lib9p_stat stat = LO_CALL(file, stat, ctx);
- if (lib9p_ctx_has_error(&ctx->basectx))
- break;
- lib9p_stat_assert(stat);
- uint32_t nbytes = lib9p_stat_marshal(&ctx->basectx, byte_count-byte_offset, &stat,
- &buf[byte_offset]);
- if (!nbytes) {
- if (obj_offset == _obj_offset)
- lib9p_error(&ctx->basectx,
- LINUX_ERANGE, "stat object does not fit into negotiated max message size");
- break;
- }
- byte_offset += nbytes;
- obj_offset++;
- }
- return obj_offset - _obj_offset;
+ lo_interface lib9p_srv_file file = self->members[idx];
+ if (LO_IS_NULL(file))
+ return (struct lib9p_srv_dirent){};
+
+ struct lib9p_srv_stat stat = LO_CALL(file, stat, ctx);
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ return (struct lib9p_srv_dirent){};
+ lib9p_srv_stat_assert(stat);
+
+ return (struct lib9p_srv_dirent){
+ .qid = stat.qid,
+ .name = stat.name,
+ };
}
/* file ***********************************************************************/
@@ -164,40 +151,35 @@ static inline size_t util9p_static_file_size(struct util9p_static_file *file) {
}
-static struct lib9p_stat util9p_static_file_stat(struct util9p_static_file *self, struct lib9p_srv_ctx *ctx) {
+static struct lib9p_srv_stat util9p_static_file_stat(struct util9p_static_file *self, struct lib9p_srv_ctx *ctx) {
assert(self);
assert(ctx);
- return (struct lib9p_stat){
- .kern_type = 0,
- .kern_dev = 0,
- .file_qid = util9p_static_file_qid(self),
- .file_mode = self->perm & 0444,
- .file_atime = self->atime,
- .file_mtime = self->mtime,
- .file_size = (uint64_t)util9p_static_file_size(self),
- .file_name = lib9p_str(self->name),
- .file_owner_uid = lib9p_str(self->u_name),
- .file_owner_gid = lib9p_str(self->g_name),
- .file_last_modified_uid = lib9p_str(self->m_name),
- .file_extension = lib9p_str(NULL),
- .file_owner_n_uid = self->u_num,
- .file_owner_n_gid = self->g_num,
- .file_last_modified_n_uid = self->m_num,
+ return (struct lib9p_srv_stat){
+ .qid = util9p_static_file_qid(self),
+ .mode = self->perm & 0444,
+ .atime_sec = self->atime,
+ .mtime_sec = self->mtime,
+ .size = (uint64_t)util9p_static_file_size(self),
+ .name = lib9p_str(self->name),
+ .owner_uid = { .name = lib9p_str(self->u_name), .num = self->u_num },
+ .owner_gid = { .name = lib9p_str(self->g_name), .num = self->g_num },
+ .last_modifier_uid = { .name = lib9p_str(self->m_name), .num = self->m_num },
+ .extension = lib9p_str(NULL),
};
}
static void util9p_static_file_wstat(struct util9p_static_file *self, struct lib9p_srv_ctx *ctx,
- struct lib9p_stat) {
+ struct lib9p_srv_stat) {
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
}
static void util9p_static_file_remove(struct util9p_static_file *self, struct lib9p_srv_ctx *ctx) {
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
}
LIB9P_SRV_NOTDIR(struct util9p_static_file, util9p_static_file);
@@ -229,7 +211,7 @@ static void util9p_static_file_pread(struct util9p_static_file *self, struct lib
if (byte_offset > (uint64_t)data_size) {
lib9p_error(&ctx->basectx,
- LINUX_EINVAL, "offset is past end-of-file length");
+ LIB9P_ERRNO_L_EINVAL, "offset is past end-of-file length");
return;
}
@@ -247,6 +229,6 @@ static uint32_t util9p_static_file_pwrite(struct util9p_static_file *self, struc
assert(self);
assert(ctx);
- lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem");
+ lib9p_error(&ctx->basectx, LIB9P_ERRNO_L_EROFS, "read-only part of filesystem");
return 0;
}
diff --git a/libcr/CMakeLists.txt b/libcr/CMakeLists.txt
index 80a4ece..2e66020 100644
--- a/libcr/CMakeLists.txt
+++ b/libcr/CMakeLists.txt
@@ -30,7 +30,7 @@ function(add_libcr_matrix_test n defs)
if ("CONFIG_COROUTINE_VALGRIND=1" IN_LIST defs)
add_test(
NAME "libcr/test_matrix${n}"
- COMMAND valgrind --error-exitcode=2 "./test_matrix${n}"
+ COMMAND "${CMAKE_SOURCE_DIR}/build-aux/valgrind" "./test_matrix${n}"
)
else()
add_test(
diff --git a/libcr/tests/test_matrix.c b/libcr/tests/test_matrix.c
index 1f23455..eaa4bdc 100644
--- a/libcr/tests/test_matrix.c
+++ b/libcr/tests/test_matrix.c
@@ -1,6 +1,6 @@
/* libcr/tests/test_matrix.c - Tests for libcr
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@@ -8,14 +8,14 @@
int a = 1;
-COROUTINE cr_init(void *) {
+COROUTINE init_cr(void *) {
cr_begin();
a = 2;
cr_end();
}
int main() {
- coroutine_add("init", cr_init, NULL);
+ coroutine_add("init", init_cr, NULL);
coroutine_main();
if (a != 2)
return 1;
diff --git a/libcr_ipc/CMakeLists.txt b/libcr_ipc/CMakeLists.txt
index 8545798..60d3f2d 100644
--- a/libcr_ipc/CMakeLists.txt
+++ b/libcr_ipc/CMakeLists.txt
@@ -7,18 +7,22 @@ add_library(libcr_ipc INTERFACE)
target_include_directories(libcr_ipc PUBLIC INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
target_sources(libcr_ipc INTERFACE
chan.c
- select.c
+ mutex.c
+ rpc.c
+ rwmutex.c
+ sema.c
)
target_link_libraries(libcr_ipc INTERFACE
libcr
+ libmisc
)
set(ipc_tests
chan
- #select
- #mutex
- #owned_mutex
+ mutex
rpc
+ rwmutex
+ select
sema
)
foreach(test IN LISTS ipc_tests)
diff --git a/libcr_ipc/chan.c b/libcr_ipc/chan.c
index 7dd1132..b7ecfc8 100644
--- a/libcr_ipc/chan.c
+++ b/libcr_ipc/chan.c
@@ -4,37 +4,131 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
+#include <string.h> /* for memcpy() */
+
+#include <libcr/coroutine.h> /* for cid_t, cr_* */
+#include <libmisc/assert.h>
+#include <libmisc/rand.h>
+
+#define IMPLEMENTATION_FOR_LIBCR_IPC_CHAN_H YES
#include <libcr_ipc/chan.h>
-void _cr_chan_dequeue(void *_ch, size_t) {
- struct _cr_chan *ch = _ch;
- _cr_ipc_dll_pop_from_front(&ch->waiters);
-}
+struct _cr_select_waiter {
+ cid_t cid;
+ struct _cr_select_arg_list_node *arg_vec;
+ size_t arg_cnt;
-void _cr_chan_xfer(enum _cr_chan_waiter_typ self_typ, struct _cr_chan *ch, void *val_ptr, size_t val_size) {
- assert(ch);
- assert(val_ptr);
+ size_t ret;
+};
- if (ch->waiters.front && ch->waiter_typ != self_typ) { /* non-blocking fast-path */
- /* Copy. */
- struct _cr_chan_waiter *front = _cr_ipc_dll_node_cast(struct _cr_chan_waiter, ch->waiters.front);
- if (self_typ == _CR_CHAN_SENDER)
- memcpy(front->val_ptr, val_ptr, val_size);
+enum cr_select_class {
+ CR_SELECT_CLASS_DEFAULT,
+ CR_SELECT_CLASS_BLOCKING,
+ CR_SELECT_CLASS_NONBLOCK,
+};
+
+static inline enum cr_select_class cr_select_getclass(struct _cr_select_arg *arg) {
+ switch (arg->op) {
+ case _CR_SELECT_OP_RECV:
+ if (arg->ch->waiters.front && arg->ch->waiters.front->val.op == _CR_SELECT_OP_SEND)
+ return CR_SELECT_CLASS_NONBLOCK;
+ else
+ return CR_SELECT_CLASS_BLOCKING;
+ case _CR_SELECT_OP_SEND:
+ if (arg->ch->waiters.front && arg->ch->waiters.front->val.op == _CR_SELECT_OP_RECV)
+ return CR_SELECT_CLASS_NONBLOCK;
else
- memcpy(val_ptr, front->val_ptr, val_size);
- cr_unpause(front->cid);
- front->dequeue(front->dequeue_arg1,
- front->dequeue_arg2);
+ return CR_SELECT_CLASS_BLOCKING;
+ case _CR_SELECT_OP_DEFAULT:
+ return CR_SELECT_CLASS_DEFAULT;
+ default:
+ assert_notreached("invalid arg->op");
+ }
+}
+
+size_t cr_select_v(size_t arg_cnt, struct _cr_select_arg_list_node arg_vec[]) {
+ size_t cnt_blocking = 0;
+ size_t cnt_nonblock = 0;
+ size_t cnt_default = 0;
+
+ assert(arg_cnt);
+ assert(arg_vec);
+ cr_assert_in_coroutine();
+
+ for (size_t i = 0; i < arg_cnt; i++) {
+ switch (cr_select_getclass(&arg_vec[i].val)) {
+ case CR_SELECT_CLASS_BLOCKING:
+ cnt_blocking++;
+ break;
+ case CR_SELECT_CLASS_NONBLOCK:
+ cnt_nonblock++;
+ break;
+ case CR_SELECT_CLASS_DEFAULT:
+ cnt_default++;
+ break;
+ }
+ }
+
+ if (cnt_nonblock) {
+ size_t choice_among_nonblock = rand_uint63n(cnt_nonblock);
+ size_t choice_among_all = arg_cnt;
+ for (size_t i = 0, seen = 0; i < choice_among_all; i++) {
+ if (cr_select_getclass(&arg_vec[i].val) == CR_SELECT_CLASS_NONBLOCK) {
+ if (seen == choice_among_nonblock)
+ choice_among_all = i;
+ seen++;
+ }
+ }
+ assert(choice_among_all < arg_cnt);
+
+ struct _cr_select_arg *this = &arg_vec[choice_among_all].val;
+ assert(this->ch->waiters.front);
+ struct _cr_select_arg *other = &this->ch->waiters.front->val;
+ assert(this->val_siz == other->val_siz);
+ assert(this->ch == other->ch);
+ switch (this->op) {
+ case _CR_SELECT_OP_SEND:
+ assert(other->op == _CR_SELECT_OP_RECV);
+ memcpy(other->val_ptr, this->val_ptr, this->val_siz);
+ break;
+ case _CR_SELECT_OP_RECV:
+ assert(other->op == _CR_SELECT_OP_SEND);
+ memcpy(this->val_ptr, other->val_ptr, this->val_siz);
+ break;
+ case _CR_SELECT_OP_DEFAULT:
+ assert_notreached("_CR_SELECT_OP_DEFAULT is not CR_SELECT_CLASS_NONBLOCK");
+ }
+ struct _cr_select_waiter *waiter = other->waiter;
+ for (size_t i = 0; i < waiter->arg_cnt; i++) {
+ waiter->arg_vec[i].val.ch->nwaiters--;
+ dlist_remove(&waiter->arg_vec[i].val.ch->waiters, &waiter->arg_vec[i]);
+ if (&waiter->arg_vec[i].val == other)
+ waiter->ret = i;
+ }
+ cr_unpause(waiter->cid);
cr_yield();
- } else { /* blocking slow-path */
- struct _cr_chan_waiter self = {
- .cid = cr_getcid(),
- .val_ptr = val_ptr,
- .dequeue = _cr_chan_dequeue,
- .dequeue_arg1 = ch,
- };
- _cr_ipc_dll_push_to_rear(&ch->waiters, &self);
- ch->waiter_typ = self_typ;
- cr_pause_and_yield();
+ return choice_among_all;
+ }
+
+ if (cnt_default) {
+ for (size_t i = 0; i < arg_cnt; i++)
+ if (cr_select_getclass(&arg_vec[i].val) == CR_SELECT_CLASS_DEFAULT)
+ return i;
+ assert_notreached("should have returned from inside for() loop");
+ }
+
+ assert(cnt_blocking && cnt_blocking == arg_cnt);
+
+ struct _cr_select_waiter waiter = {
+ .cid = cr_getcid(),
+ .arg_vec = arg_vec,
+ .arg_cnt = arg_cnt,
+ };
+ for (size_t i = 0; i < arg_cnt; i++) {
+ arg_vec[i].val.waiter = &waiter;
+ arg_vec[i].val.ch->nwaiters++;
+ dlist_push_to_rear(&arg_vec[i].val.ch->waiters, &arg_vec[i]);
}
+ cr_pause_and_yield();
+ return waiter.ret;
}
diff --git a/libcr_ipc/include/libcr_ipc/_linkedlist.h b/libcr_ipc/include/libcr_ipc/_linkedlist.h
deleted file mode 100644
index 543e058..0000000
--- a/libcr_ipc/include/libcr_ipc/_linkedlist.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* libcr_ipc/_linkedlist.h - Common low-level linked lists for use in libcr_ipc
- *
- * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-#ifndef _LIBCR_IPC__LINKEDLIST_H_
-#define _LIBCR_IPC__LINKEDLIST_H_
-
-#include <libmisc/assert.h>
-
-/* singly linked list *********************************************************/
-
-typedef struct __cr_ipc_sll_node {
- struct __cr_ipc_sll_node *rear;
-} _cr_ipc_sll_node;
-
-typedef struct {
- _cr_ipc_sll_node *front, *rear;
-} _cr_ipc_sll_root;
-
-#define _cr_ipc_sll_node_cast(node_typ, node_ptr) \
- ({ \
- static_assert(_Generic(node_ptr, _cr_ipc_sll_node *: 1, default: 0), \
- "typeof("#node_ptr") != _cr_ipc_sll_node *"); \
- assert(node_ptr); \
- static_assert(offsetof(node_typ, _cr_ipc_sll_node) == 0); \
- ((node_typ*)(node_ptr)); \
- })
-
-static inline void _cr_ipc_sll_push_to_rear(_cr_ipc_sll_root *root, _cr_ipc_sll_node *node) {
- assert(root);
- node->rear = NULL;
- if (root->rear)
- root->rear->rear = node;
- else
- root->front = node;
- root->rear = node;
-}
-
-static inline void _cr_ipc_sll_pop_from_front(_cr_ipc_sll_root *root) {
- assert(root);
- assert(root->front);
- root->front = root->front->rear;
- if (!root->front)
- root->rear = NULL;
-}
-
-/* doubly linked list *********************************************************/
-
-typedef struct __cr_ipc_dll_node {
- struct __cr_ipc_dll_node *front, *rear;
-} _cr_ipc_dll_node;
-
-typedef struct {
- _cr_ipc_dll_node *front, *rear;
-} _cr_ipc_dll_root;
-
-#define _cr_ipc_dll_node_cast(node_typ, node_ptr) \
- ({ \
- static_assert(_Generic(node_ptr, _cr_ipc_dll_node *: 1, default: 0), \
- "typeof("#node_ptr") != _cr_ipc_dll_node *"); \
- assert(node_ptr); \
- static_assert(offsetof(node_typ, _cr_ipc_dll_node) == 0); \
- ((node_typ*)(node_ptr)); \
- })
-
-static inline void _cr_ipc_dll_push_to_rear(_cr_ipc_dll_root *root, _cr_ipc_dll_node *node) {
- assert(root);
- assert(node);
- node->front = root->rear;
- node->rear = NULL;
- if (root->rear)
- root->rear->rear = node;
- else
- root->front = node;
- root->rear = node;
-}
-
-static inline void _cr_ipc_dll_remove(_cr_ipc_dll_root *root, _cr_ipc_dll_node *node) {
- assert(root);
- assert(node);
- if (node->front)
- node->front->rear = node->rear;
- else
- root->front = node->rear;
- if (node->rear)
- node->rear->front = node->front;
- else
- root->rear = node->front;
-}
-
-static inline void _cr_ipc_dll_pop_from_front(_cr_ipc_dll_root *root) {
- assert(root);
- assert(root->front);
- _cr_ipc_dll_remove(root, root->front);
-}
-
-#endif /* _LIBCR_IPC__LINKEDLIST_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/chan.h b/libcr_ipc/include/libcr_ipc/chan.h
index dafc92d..c57979a 100644
--- a/libcr_ipc/include/libcr_ipc/chan.h
+++ b/libcr_ipc/include/libcr_ipc/chan.h
@@ -9,17 +9,14 @@
#include <stdbool.h> /* for bool */
#include <stddef.h> /* for size_t */
-#include <string.h> /* for memcpy */
-#include <libcr/coroutine.h> /* for cid_t, cr_* */
+#include <libmisc/linkedlist.h> /* for DLIST_DECLARE() */
+#include <libmisc/private.h>
-#include <libcr_ipc/_linkedlist.h>
+/* base channels **************************************************************/
/**
- * CR_CHAN_DECLARE(NAME, VAL_T) declares the following type and
- * methods:
- *
- * type:
+ * CR_CHAN_DECLARE(NAME, VAL_T) declares the following type:
*
* / **
* * A NAME##_t is a fair unbuffered channel that transports
@@ -32,97 +29,163 @@
* * something from an interrupt handler.
* * /
* typedef ... NAME##_t;
+ */
+#define CR_CHAN_DECLARE(NAME, VAL_T) \
+ typedef struct { \
+ struct _cr_chan core; \
+ VAL_T val_typ[0]; \
+ } NAME##_t
+
+/**
+ * cr_chan_send(ch, val) sends `val` over `ch`.
*
- * methods:
+ * @runs_in coroutine
+ * @cr_pauses maybe
+ * @cr_yields always
*
- * / **
- * * NAME##_send(ch, val) sends `val` over `ch`.
- * *
- * * @runs_in coroutine
- * * @cr_pauses maybe
- * * @cr_yields always
- * * /
- * void NAME##_send(NAME##_t *ch, VAL_T val);
+ * void cr_chan_send(NAME##_t *ch, VAL_T val);
+ */
+#define cr_chan_send(CH, VAL) do { \
+ typeof((CH)->val_typ[0]) _val_lvalue = VAL; \
+ (void)cr_select_l(CR_SELECT_SEND(CH, &_val_lvalue)); \
+} while (0)
+
+/**
+ * cr_chan_recv(ch) reads and returns a value from ch.
*
- * / **
- * * NAME##_recv(ch) reads and returns a value from ch.
- * *
- * * @runs_in coroutine
- * * @cr_pauses maybe
- * * @cr_yields always
- * * /
- * VAL_T NAME##_recv(NAME##_t *ch);
+ * @runs_in coroutine
+ * @cr_pauses maybe
+ * @cr_yields always
*
- * / **
- * * NAME##_can_send(ch) returns whether NAME##_send(ch, val)
- * * would run without pausing.
- * *
- * * @runs_in coroutine
- * * @cr_pauses never
- * * @cr_yields never
- * * /
- * bool NAME##_can_send(NAME##_t *ch);
+ * VAL_T cr_chan_recv(NAME##_T ch);
+ */
+#define cr_chan_recv(CH) ({ \
+ typeof((CH)->val_typ[0]) _val_lvalue; \
+ (void)cr_select_l(CR_SELECT_RECV(CH, &_val_lvalue)); \
+ _val_lvalue; \
+})
+
+/**
+ * cr_chan_can_send(ch) returns whether cr_chan_send(ch, val) would
+ * run without pausing.
*
- * / **
- * * NAME##_can_recv(ch) returns whether NAME##_recv(ch) would
- * * return without pausing.
- * *
- * * @runs_in coroutine
- * * @cr_pauses never
- * * @cr_yields never
- * * /
- * NAME##_can_recv(NAME##_t *ch);
+ * @runs_in coroutine
+ * @cr_pauses never
+ * @cr_yields never
+ *
+ * bool cr_chan_can_send(NAME##_t *ch);
*/
-#define CR_CHAN_DECLARE(NAME, VAL_T) \
- typedef struct { \
- struct _cr_chan core; \
- VAL_T vals[0]; \
- } NAME##_t; \
- \
- static inline void NAME##_send(NAME##_t *ch, VAL_T val) { \
- cr_assert_in_coroutine(); \
- _cr_chan_xfer(_CR_CHAN_SENDER, &ch->core, &val, sizeof(val)); \
- } \
- \
- static inline VAL_T NAME##_recv(NAME##_t *ch) { \
- cr_assert_in_coroutine(); \
- VAL_T val; \
- _cr_chan_xfer(_CR_CHAN_RECVER, &ch->core, &val, sizeof(val)); \
- return val; \
- } \
- \
- static inline bool NAME##_can_send(NAME##_t *ch) { \
- cr_assert_in_coroutine(); \
- return ch->core.waiters.front && \
- ch->core.waiter_typ == _CR_CHAN_RECVER; \
- } \
- \
- static inline bool NAME##_can_recv(NAME##_t *ch) { \
- cr_assert_in_coroutine(); \
- return ch->core.waiters.front && \
- ch->core.waiter_typ == _CR_CHAN_SENDER; \
- }
-
-enum _cr_chan_waiter_typ {
- _CR_CHAN_SENDER,
- _CR_CHAN_RECVER,
+#define cr_chan_can_send(CH) ({ \
+ cr_assert_in_coroutine(); \
+ (bool)((CH)->core.waiters.front && \
+ (CH)->core.waiters.front->val.op == _CR_SELECT_OP_RECV); \
+})
+
+/**
+ * cr_chan_can_recv(ch) returns whether cr_chan_recv(ch) would return
+ * without pausing.
+ *
+ * @runs_in coroutine
+ * @cr_pauses never
+ * @cr_yields never
+ *
+ * bool cr_chan_can_recv(NAME##_t *ch);
+ */
+#define cr_chan_can_recv(CH) ({ \
+ cr_assert_in_coroutine(); \
+ (bool)((CH)->core.waiters.front && \
+ (CH)->core.waiters.front->val.op == _CR_SELECT_OP_SEND); \
+})
+
+/**
+ * cr_chan_num_waiters(ch) returns the number of coroutines currently
+ * blocked on the channel.
+ *
+ * @runs_in coroutine
+ * @cr_pauses never
+ * @cr_yields never
+ *
+ * size_t cr_chan_num_waiters(NAME##_t *ch);
+ */
+#define cr_chan_num_waiters(CH) ({ \
+ cr_assert_in_coroutine(); \
+ ((CH)->core.nwaiters); \
+})
+
+DLIST_DECLARE(_cr_select_arg_list);
+struct _cr_chan {
+ struct _cr_select_arg_list waiters;
+ size_t nwaiters;
};
-struct _cr_chan_waiter {
- _cr_ipc_dll_node;
- cid_t cid;
+/* cr_select arguments ********************************************************/
+
+/**
+ * Do not populate cr_select_arg yourself; use the
+ * CR_SELECT_{RECV,SEND,DEFAULT} macros.
+ */
+struct _cr_select_waiter;
+struct _cr_select_arg {
+ enum {
+ _CR_SELECT_OP_RECV,
+ _CR_SELECT_OP_SEND,
+ _CR_SELECT_OP_DEFAULT,
+ } op;
+ struct _cr_chan *ch;
void *val_ptr;
- void (*dequeue)(void *, size_t);
- void *dequeue_arg1;
- size_t dequeue_arg2;
+ size_t val_siz;
+ BEGIN_PRIVATE(LIBCR_IPC_CHAN_H);
+ struct _cr_select_waiter *waiter;
+ END_PRIVATE(LIBCR_IPC_CHAN_H);
};
+DLIST_DECLARE_NODE(_cr_select_arg_list, struct _cr_select_arg);
+#define cr_select_arg _cr_select_arg_list_node
-struct _cr_chan {
- enum _cr_chan_waiter_typ waiter_typ;
- _cr_ipc_dll_root waiters;
-};
+#define CR_SELECT_RECV(CH, VALP) ((struct cr_select_arg){ .val = { \
+ .op = _CR_SELECT_OP_RECV, \
+ .ch = &((CH)->core), \
+ /* The _valp temporary variable is to get the compiler to check that \
+ * the types are compatible. */ \
+ .val_ptr = ({ typeof((CH)->val_typ[0]) *_valp = VALP; _valp; }), \
+ .val_siz = sizeof((CH)->val_typ[0]), \
+}})
+
+/* BUG: It's bogus that CR_SELECT_SEND takes VALP instead of VAL, but
+ * since we need an address, taking VAL would introduce uncomfortable
+ * questions about where VAL sits on the stack. */
+#define CR_SELECT_SEND(CH, VALP) ((struct cr_select_arg){ .val = { \
+ .op = _CR_SELECT_OP_SEND, \
+ .ch = &((CH)->core), \
+ /* The _valp temporary variable is to get the compiler to check that \
+ * the types are compatible. */ \
+ .val_ptr = ({ typeof((CH)->val_typ[0]) *_valp = VALP; _valp; }), \
+ .val_siz = sizeof((CH)->val_typ[0]), \
+}})
+
+#define CR_SELECT_DEFAULT ((struct cr_select_arg){ .val = { \
+ .op = _CR_SELECT_OP_DEFAULT, \
+}})
+
+/* cr_select_v(arg_cnt, arg_vec) **********************************************/
-void _cr_chan_dequeue(void *_ch, size_t);
-void _cr_chan_xfer(enum _cr_chan_waiter_typ self_typ, struct _cr_chan *ch, void *val_ptr, size_t val_size);
+/**
+ * @runs_in coroutine
+ * @cr_pauses maybe
+ * @cr_yields always
+ */
+size_t cr_select_v(size_t arg_cnt, struct cr_select_arg arg_vec[]);
+
+/* cr_select_l(arg1, arg2, arg3, ...) ******************************************/
+
+/**
+ * @runs_in coroutine
+ * @cr_pauses maybe
+ * @cr_yields always
+ */
+#define cr_select_l(...) ({ \
+ struct cr_select_arg _cr_select_args[] = { __VA_ARGS__ }; \
+ cr_select_v(sizeof(_cr_select_args)/sizeof(_cr_select_args[0]), \
+ _cr_select_args); \
+})
#endif /* _LIBCR_IPC_CHAN_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/mutex.h b/libcr_ipc/include/libcr_ipc/mutex.h
index cba8c19..e5f43c8 100644
--- a/libcr_ipc/include/libcr_ipc/mutex.h
+++ b/libcr_ipc/include/libcr_ipc/mutex.h
@@ -1,6 +1,6 @@
/* libcr_ipc/mutex.h - Simple mutexes for libcr
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@@ -9,14 +9,10 @@
#include <stdbool.h> /* for bool */
-#include <libcr/coroutine.h> /* for cid_t, cr_* */
+#include <libmisc/linkedlist.h> /* for SLIST_DECLARE() */
+#include <libmisc/private.h>
-#include <libcr_ipc/_linkedlist.h>
-
-struct _cr_mutex_waiter {
- _cr_ipc_sll_node;
- cid_t cid;
-};
+SLIST_DECLARE(_cr_mutex_waiter_list);
/**
* A cr_mutex_t is a fair mutex.
@@ -27,8 +23,10 @@ struct _cr_mutex_waiter {
* first place, then it has no business unlocking one.
*/
typedef struct {
- bool locked;
- _cr_ipc_sll_root waiters;
+ BEGIN_PRIVATE(LIBCR_IPC_MUTEX_H);
+ bool locked;
+ struct _cr_mutex_waiter_list waiters;
+ END_PRIVATE(LIBCR_IPC_MUTEX_H);
} cr_mutex_t;
/**
@@ -38,21 +36,7 @@ typedef struct {
* @cr_pauses maybe
* @cr_yields maybe
*/
-static inline void cr_mutex_lock(cr_mutex_t *mu) {
- assert(mu);
- cr_assert_in_coroutine();
-
- if (!mu->locked) /* non-blocking fast-path */
- mu->locked = true;
- else { /* blocking slow-path */
- struct _cr_mutex_waiter self = {
- .cid = cr_getcid(),
- };
- _cr_ipc_sll_push_to_rear(&mu->waiters, &self);
- cr_pause_and_yield();
- }
- assert(mu->locked);
-}
+void cr_mutex_lock(cr_mutex_t *mu);
/**
* Unlock the mutex. Unblocks a coroutine that is blocked on
@@ -62,16 +46,6 @@ static inline void cr_mutex_lock(cr_mutex_t *mu) {
* @cr_pauses never
* @cr_yields never
*/
-static inline void cr_mutex_unlock(cr_mutex_t *mu) {
- assert(mu);
- cr_assert_in_coroutine();
-
- assert(mu->locked);
- if (mu->waiters.front) {
- cr_unpause(_cr_ipc_sll_node_cast(struct _cr_mutex_waiter, mu->waiters.front)->cid);
- _cr_ipc_sll_pop_from_front(&mu->waiters);
- } else
- mu->locked = false;
-}
+void cr_mutex_unlock(cr_mutex_t *mu);
#endif /* _LIBCR_IPC_MUTEX_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/owned_mutex.h b/libcr_ipc/include/libcr_ipc/owned_mutex.h
deleted file mode 100644
index c66240f..0000000
--- a/libcr_ipc/include/libcr_ipc/owned_mutex.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* libcr_ipc/owned_mutex.h - Owned mutexes for libcr
- *
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-#ifndef _LIBCR_IPC_OWNED_MUTEX_H_
-#define _LIBCR_IPC_OWNED_MUTEX_H_
-
-#include <stdbool.h> /* for bool */
-
-#include <libcr/coroutine.h> /* for cid_t, cr_unpause(), cr_pause_and_yield() */
-
-#include <libcr_ipc/_linkedlist.h>
-
-struct _cr_owned_mutex_waiter {
- _cr_ipc_sll_node;
- cid_t cid;
-};
-
-/**
- * A cr_owned_mutex_t is a fair mutex that tracks not just whether it
- * is locked, but which coroutine has it locked.
- *
- * None of the methods have `_from_intrhandler` variants because (1)
- * an interrupt handler can't block, so it shouldn't ever lock a mutex
- * because that can block; and (2) if it can't lock a mutex in the
- * first place, then it has no business unlocking one.
- */
-typedef struct {
- cid_t owner;
- _cr_ipc_sll_root waiters;
-} cr_owned_mutex_t;
-
-/**
- * Lock the mutex. Blocks if it is already locked.
- *
- * @runs_in coroutine
- * @cr_pauses maybe
- * @cr_yields maybe
- */
-static inline void cr_owned_mutex_lock(cr_owned_mutex_t *mu) {
- assert(mu);
-
- if (!mu->owner) /* non-blocking fast-path */
- mu->owner = cr_getcid();
- else { /* blocking slow-path */
- struct _cr_owned_mutex_waiter self = {
- .cid = cr_getcid(),
- };
- _cr_ipc_sll_push_to_rear(&mu->waiters, &self);
- cr_pause_and_yield();
- }
- assert(mu->owner == cr_getcid());
-}
-
-/**
- * Unlock the mutex. Unblocks a coroutine that is blocked on
- * cr_owned_mutex_lock(). Must be the called from the same coroutine
- * that called cr_owned_mutex_lock().
- *
- * @runs_in coroutine
- * @cr_pauses never
- * @cr_yields never
- */
-static inline void cr_owned_mutex_unlock(cr_owned_mutex_t *mu) {
- assert(mu);
-
- assert(mu->owner == cr_getcid());
- if (mu->waiters.front) {
- cid_t waiter = _cr_ipc_sll_node_cast(struct _cr_owned_mutex_waiter, mu->waiters.front)->cid;
- cr_unpause(waiter);
- mu->owner = waiter;
- _cr_ipc_sll_pop_from_front(&mu->waiters);
- } else
- mu->owner = 0;
-}
-
-#endif /* _LIBCR_IPC_OWNED_MUTEX_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/rpc.h b/libcr_ipc/include/libcr_ipc/rpc.h
index 0600399..bfa0a04 100644
--- a/libcr_ipc/include/libcr_ipc/rpc.h
+++ b/libcr_ipc/include/libcr_ipc/rpc.h
@@ -8,17 +8,11 @@
#define _LIBCR_IPC_RPC_H_
#include <stdbool.h> /* for bool */
-#include <string.h> /* for memcpy() */
-#include <libcr/coroutine.h> /* for cid_t, cr_* */
-
-#include <libcr_ipc/_linkedlist.h>
+#include <libmisc/linkedlist.h> /* for SLIST_DECLARE() */
/**
- * CR_RPC_DECLARE(NAME, REQ_T, RESP_T) declares the following types
- * and methods:
- *
- * type:
+ * CR_RPC_DECLARE(NAME, REQ_T, RESP_T) declares the following types:
*
* / **
* * A NAME##_t is a fair rpc-channel on which the requester submits a
@@ -40,191 +34,112 @@
* * the response RESP_T to the correct requester. `REQ_T req` is the
* * only public member.
* typedef struct { REQ_T req; ... } NAME##_req_t;
+ */
+#define CR_RPC_DECLARE(NAME, REQ_T, RESP_T) \
+ typedef struct { \
+ REQ_T req; \
+ \
+ RESP_T *_resp; /* where to write resp to */ \
+ cid_t _requester; \
+ } NAME##_req_t; \
+ \
+ typedef struct { \
+ struct _cr_rpc core; \
+ NAME##_req_t handle_typ[0]; \
+ } NAME##_t
+
+/* Methods for NAME##_t *******************************************************/
+
+/**
+ * cr_rpc_send_req(ch, req) submits the `req` request over `ch` and
+ * returns the response.
*
- * methods:
+ * @runs_in coroutine
+ * @cr_pauses always
+ * @cr_yields always
*
- * / **
- * * NAME##_send_req(ch, req) submits the `req` request over `ch` and
- * * returns the response.
- * *
- * * @runs_in coroutine
- * * @cr_pauses always
- * * @cr_yields always
- * * /
- * RESP_T NAME##_send_req(NAME##_t *ch, REQ_T req);
+ * RESP_T cr_rpc_send_req(NAME##_t *ch, REQ_T req);
+ */
+#define cr_rpc_send_req(CH, REQ) ({ \
+ cr_assert_in_coroutine(); \
+ typeof((CH)->handle_typ[0].req) _req_lvalue = REQ; \
+ typeof(*(CH)->handle_typ[0]._resp) _resp_lvalue; \
+ _cr_rpc_send_req(&(CH)->core, \
+ &_req_lvalue, sizeof(_req_lvalue), \
+ &_resp_lvalue); \
+ _resp_lvalue; \
+})
+
+/**
+ * cr_rpc_recv_req(ch) reads a request from ch, and returns a
+ * NAME##_req_t handle wrapping that request.
*
- * / **
- * * NAME##_recv_req(ch) reads a request from ch, and returns a
- * * NAME##_req_t handle wrapping that request.
- * *
- * * @runs_in coroutine
- * * @cr_pauses maybe
- * * @cr_yields maybe
- * * /
- * NAME##_req_t NAME##_recv_req(NAME##_t *ch);
+ * @runs_in coroutine
+ * @cr_pauses maybe
+ * @cr_yields maybe
*
- * / **
- * * NAME##_can_recv_req(ch) returns whether NAME##_recv_req(ch)
- * * would return without pausing.
- * *
- * * @runs_in coroutine
- * * @cr_pauses never
- * * @cr_yields never
- * * /
- * bool NAME##_can_recv_req(NAME##_t *ch);
+ * NAME##_req_t cr_rcp_recv_req(NAME##_t *ch);
+ */
+#define cr_rpc_recv_req(CH) ({ \
+ cr_assert_in_coroutine(); \
+ typeof((CH)->handle_typ[0]) ret; \
+ _cr_rpc_recv_req(&(CH)->core, \
+ &ret.req, sizeof(ret.req), \
+ (void **)&ret._resp, \
+ &ret._requester); \
+ ret; \
+})
+
+/**
+ * cr_rpc_can_recv_req(ch) returns whether NAME##_recv_req(ch)
+ * would return without pausing.
*
- * type:
+ * @runs_in coroutine
+ * @cr_pauses never
+ * @cr_yields never
*
- * / **
- * * A NAME##_req_t is a handle that wraps a REQ_T, and is a channel
- * * that a response may be written to.
- * * /
- * typedef ... NAME##_req_t;
+ * bool cr_rpc_can_recv_req(NAME##_t *ch);
+ */
+#define cr_rpc_can_recv_req(CH) ({ \
+ cr_assert_in_coroutine(); \
+ (bool)((CH)->core.waiters.front && \
+ (CH)->core.waiter_typ == _CR_RPC_REQUESTER); \
+})
+
+/* Methods for NAME##_req_t ***************************************************/
+
+/**
+ * cr_rpc_send_resp(req, resp) sends the given response to the given
+ * request.
*
- * methods:
+ * @runs_in coroutine
+ * @cr_pauses never
+ * @cr_yields always
*
- * / **
- * * cr_rpc_send_resp(req, resp) sends the given response to the given
- * * request.
- * *
- * * @runs_in coroutine
- * * @cr_pauses never
- * * @cr_yields always
- * * /
- * void NAME##_send_resp(NAME##_req_t req, RESP_T resp);
+ * void cr_rpc_send_resp(NAME##_req_t req, RESP_T resp);
*/
-#define CR_RPC_DECLARE(NAME, REQ_T, RESP_T) \
- typedef struct { \
- REQ_T req; \
- \
- RESP_T *_resp; /* where to write resp to */ \
- cid_t _requester; \
- } NAME##_req_t; \
- \
- typedef struct { \
- struct _cr_rpc core; \
- NAME##_req_t handle[0]; \
- } NAME##_t; \
- \
- static inline RESP_T NAME##_send_req(NAME##_t *ch, REQ_T req) { \
- cr_assert_in_coroutine(); \
- RESP_T resp; \
- _cr_rpc_send_req(&ch->core, \
- &req, sizeof(req), \
- &resp); \
- return resp; \
- } \
- \
- static inline NAME##_req_t NAME##_recv_req(NAME##_t *ch) { \
- cr_assert_in_coroutine(); \
- NAME##_req_t ret; \
- _cr_rpc_recv_req(&ch->core, \
- &ret.req, sizeof(ret.req), \
- (void **)&ret._resp, \
- &ret._requester); \
- return ret; \
- } \
- \
- static inline bool NAME##_can_recv_req(NAME##_t *ch) { \
- cr_assert_in_coroutine(); \
- return ch->core.waiters.front && \
- ch->core.waiter_typ == _CR_RPC_REQUESTER; \
- } \
- \
- static inline void NAME##_send_resp(NAME##_req_t req, RESP_T resp) { \
- cr_assert_in_coroutine(); \
- *(req._resp) = resp; \
- cr_unpause(req._requester); \
- cr_yield(); \
- }
+#define cr_rpc_send_resp(REQ, RESP) { \
+ cr_assert_in_coroutine(); \
+ *((REQ)._resp) = RESP; \
+ cr_unpause(REQ._requester); \
+ cr_yield(); \
+} while (0)
+
+/* Background details *********************************************************/
enum _cr_rpc_waiter_typ {
_CR_RPC_REQUESTER,
_CR_RPC_RESPONDER,
};
-struct _cr_rpc_requester {
- _cr_ipc_sll_node;
- cid_t cid;
- void *req_ptr; /* where to read req from */
- void *resp_ptr; /* where to write resp to */
-};
-
-struct _cr_rpc_responder {
- _cr_ipc_sll_node;
- /* before enqueued | after dequeued */
- /* -------------------+-------------------- */
- cid_t cid; /* responder cid | requester cid */
- void *ptr; /* where to write req | where to write resp */
-};
+SLIST_DECLARE(_cr_rpc_waiter_list);
struct _cr_rpc {
enum _cr_rpc_waiter_typ waiter_typ;
- _cr_ipc_sll_root waiters;
+ struct _cr_rpc_waiter_list waiters;
};
-static inline void _cr_rpc_send_req(struct _cr_rpc *ch,
- void *req_ptr, size_t req_size,
- void *resp_ptr)
-{
- assert(ch);
- assert(req_ptr);
- assert(resp_ptr);
-
- if (ch->waiters.front && ch->waiter_typ != _CR_RPC_REQUESTER) { /* fast-path (still blocks) */
- struct _cr_rpc_responder *responder =
- _cr_ipc_sll_node_cast(struct _cr_rpc_responder, ch->waiters.front);
- _cr_ipc_sll_pop_from_front(&ch->waiters);
- /* Copy the req to the responder's stack. */
- memcpy(responder->ptr, req_ptr, req_size);
- /* Notify the responder that we have done so. */
- cr_unpause(responder->cid);
- responder->cid = cr_getcid();
- responder->ptr = resp_ptr;
- /* Wait for the responder to set `*resp_ptr`. */
- cr_pause_and_yield();
- } else { /* blocking slow-path */
- struct _cr_rpc_requester self = {
- .cid = cr_getcid(),
- .req_ptr = req_ptr,
- .resp_ptr = resp_ptr,
- };
- _cr_ipc_sll_push_to_rear(&ch->waiters, &self);
- /* Wait for a responder to both copy our req and sed
- * `*resp_ptr`. */
- cr_pause_and_yield();
- }
-}
-
-static inline void _cr_rpc_recv_req(struct _cr_rpc *ch,
- void *req_ptr, size_t req_size,
- void **ret_resp_ptr,
- cid_t *ret_requester)
-{
- assert(ch);
- assert(req_ptr);
- assert(ret_resp_ptr);
- assert(ret_requester);
-
- if (ch->waiters.front && ch->waiter_typ != _CR_RPC_RESPONDER) { /* non-blocking fast-path */
- struct _cr_rpc_requester *requester =
- _cr_ipc_sll_node_cast(struct _cr_rpc_requester, ch->waiters.front);
- _cr_ipc_sll_pop_from_front(&ch->waiters);
-
- memcpy(req_ptr, requester->req_ptr, req_size);
- *ret_requester = requester->cid;
- *ret_resp_ptr = requester->resp_ptr;
- } else { /* blocking slow-path */
- struct _cr_rpc_responder self = {
- .cid = cr_getcid(),
- .ptr = req_ptr,
- };
- _cr_ipc_sll_push_to_rear(&ch->waiters, &self);
- ch->waiter_typ = _CR_RPC_RESPONDER;
- cr_pause_and_yield();
- *ret_requester = self.cid;
- *ret_resp_ptr = self.ptr;
- }
-}
+void _cr_rpc_send_req(struct _cr_rpc *ch, void *req_ptr, size_t req_size, void *resp_ptr);
+void _cr_rpc_recv_req(struct _cr_rpc *ch, void *req_ptr, size_t req_size, void **ret_resp_ptr, cid_t *ret_requester);
#endif /* _LIBCR_IPC_RPC_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/rwmutex.h b/libcr_ipc/include/libcr_ipc/rwmutex.h
new file mode 100644
index 0000000..8ccae63
--- /dev/null
+++ b/libcr_ipc/include/libcr_ipc/rwmutex.h
@@ -0,0 +1,78 @@
+/* libcr_ipc/rwmutex.h - Simple read/write mutexes for libcr
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _LIBCR_IPC_RWMUTEX_H_
+#define _LIBCR_IPC_RWMUTEX_H_
+
+#include <stdbool.h>
+
+#include <libmisc/linkedlist.h> /* for SLIST_DECLARE() */
+#include <libmisc/private.h>
+
+SLIST_DECLARE(_cr_rwmutex_waiter_list);
+
+/**
+ * A cr_rwmutex_t is a fair read/write mutex.
+ *
+ * A waiting writer blocks any new readers; this ensures that the
+ * writer is able to eventually get the lock.
+ *
+ * None of the methods have `_from_intrhandler` variants because (1)
+ * an interrupt handler can't block, so it shouldn't ever lock a mutex
+ * because that can block; and (2) if it can't lock a mutex in the
+ * first place, then it has no business unlocking one.
+ */
+typedef struct {
+ BEGIN_PRIVATE(LIBCR_IPC_RWMUTEX_H);
+ unsigned nreaders;
+ bool locked;
+ bool unpausing;
+ struct _cr_rwmutex_waiter_list waiters;
+ END_PRIVATE(LIBCR_IPC_RWMUTEX_H);
+} cr_rwmutex_t;
+
+/**
+ * Lock the mutex for writing. Blocks if it is already locked.
+ *
+ * @runs_in coroutine
+ * @cr_pauses maybe
+ * @cr_yields maybe
+ */
+void cr_rwmutex_lock(cr_rwmutex_t *mu);
+
+/**
+ * Undo a single cr_rwmutex_lock() call. Unblocks either a single
+ * coroutine that is blocked on cr_rwmutex_lock() or arbitrarily many
+ * coroutines that are blocked on cr_rwmutex_rlock().
+ *
+ * @runs_in coroutine
+ * @cr_pauses never
+ * @cr_yields never
+ */
+void cr_rwmutex_unlock(cr_rwmutex_t *mu);
+
+/**
+ * Lock the mutex for reading. Blocks if it is already locked for
+ * writing.
+ *
+ * @runs_in coroutine
+ * @cr_pauses maybe
+ * @cr_yields maybe
+ */
+void cr_rwmutex_rlock(cr_rwmutex_t *mu);
+
+/**
+ * Undo a single cr_rwmutext_rock() call. If the reader count is
+ * reduced to zero, unblocks a single coroutine that is blocked on
+ * cr_rwmutex_lock().
+ *
+ * @runs_in coroutine
+ * @cr_pauses never
+ * @cr_yields never
+ */
+void cr_rwmutex_runlock(cr_rwmutex_t *mu);
+
+#endif /* _LIBCR_IPC_RWMUTEX_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/select.h b/libcr_ipc/include/libcr_ipc/select.h
deleted file mode 100644
index 0e35351..0000000
--- a/libcr_ipc/include/libcr_ipc/select.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* libcr_ipc/select.h - Select between channels
- *
- * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-#include <alloca.h> /* for alloca() */
-#include <stddef.h> /* for size_t */
-
-#include <libmisc/assert.h>
-#include <libmisc/rand.h>
-
-#include <libcr_ipc/chan.h>
-
-#ifndef _LIBCR_IPC_SELECT_H_
-#define _LIBCR_IPC_SELECT_H_
-
-/* arguments ******************************************************************/
-
-/**
- * Do not populate cr_select_arg yourself; use the
- * CR_SELECT_{RECV,SEND,DEFAULT} macros.
- */
-struct cr_select_arg {
- enum {
- _CR_SELECT_OP_RECV,
- _CR_SELECT_OP_SEND,
- _CR_SELECT_OP_DEFAULT,
- } op;
- struct _cr_chan *ch;
- void *val_ptr;
- size_t val_siz;
-};
-
-#define CR_SELECT_RECV(CH, VALP) ({ \
- /* The _valp indirection is to get the \
- * compiler to check that the types are \
- * compatible. */ \
- typeof((CH)->vals[0]) *_valp = VALP; \
- ((struct cr_select_arg){ \
- .op = _CR_SELECT_OP_RECV, \
- .ch = &((CH)->core), \
- .val_ptr = _valp, \
- .val_siz = sizeof((CH)->vals[0]), \
- }); \
- })
-#define CR_SELECT_SEND(CH, VAL) ({ \
- typeof((CH)->vals[0]) val_lvalue = VAL; \
- ((struct cr_select_arg){ \
- .op = _CR_SELECT_OP_SEND, \
- .ch = &((CH)->core), \
- .val_ptr = &val_lvalue;, \
- .val_siz = sizeof((CH)->vals[0]), \
- }); \
- })
-#define CR_SELECT_DEFAULT \
- ((struct cr_select_arg){ \
- .op = _CR_SELECT_OP_DEFAULT, \
- })
-
-/* cr_select_v(arg_cnt, arg_vec) **********************************************/
-
-enum _cr_select_class {
- _CR_SELECT_CLASS_DEFAULT,
- _CR_SELECT_CLASS_BLOCKING,
- _CR_SELECT_CLASS_NONBLOCK,
-};
-
-struct _cr_select_waiters {
- size_t cnt;
- struct cr_select_arg *args;
- struct _cr_chan_waiter *nodes;
-};
-
-void _cr_select_dequeue(void *_waiters, size_t idx);
-size_t cr_select_v(size_t arg_cnt, struct cr_select_arg arg_vec[]);
-
-/* cr_select_l(arg1, arg2, arg3, ...) ******************************************/
-
-#define cr_select_l(...) ({ \
- struct cr_select_arg _cr_select_args[] = { __VA_ARGS__ }; \
- cr_select_v(sizeof(_cr_select_args)/sizeof(_cr_select_args[0])); \
-})
-
-#endif /* _LIBCR_IPC_SELECT_H_ */
diff --git a/libcr_ipc/include/libcr_ipc/sema.h b/libcr_ipc/include/libcr_ipc/sema.h
index fcabf28..8b5ac5b 100644
--- a/libcr_ipc/include/libcr_ipc/sema.h
+++ b/libcr_ipc/include/libcr_ipc/sema.h
@@ -9,14 +9,10 @@
#include <stdbool.h>
-#include <libcr/coroutine.h> /* for cid_t, cr_* */
+#include <libmisc/linkedlist.h> /* for SLIST_DECLARE() */
+#include <libmisc/private.h>
-#include <libcr_ipc/_linkedlist.h>
-
-struct _cr_sema_waiter {
- _cr_ipc_sll_node;
- cid_t cid;
-};
+SLIST_DECLARE(_cr_sema_waiter_list);
/**
* A cr_sema_t is a fair unbounded[1] counting semaphore.
@@ -24,9 +20,11 @@ struct _cr_sema_waiter {
* [1]: Well, UINT_MAX
*/
typedef struct {
- unsigned int cnt;
- bool unpausing;
- _cr_ipc_sll_root waiters;
+ BEGIN_PRIVATE(LIBCR_IPC_SEMA_H);
+ unsigned int cnt;
+ bool unpausing;
+ struct _cr_sema_waiter_list waiters;
+ END_PRIVATE(LIBCR_IPC_SEMA_H);
} cr_sema_t;
/**
@@ -36,36 +34,14 @@ typedef struct {
* @cr_pauses never
* @cr_yields never
*/
-static inline void cr_sema_signal(cr_sema_t *sema) {
- assert(sema);
- cr_assert_in_coroutine();
-
- bool saved = cr_save_and_disable_interrupts();
- sema->cnt++;
- if (sema->waiters.front && !sema->unpausing) {
- cr_unpause(
- _cr_ipc_sll_node_cast(struct _cr_sema_waiter, sema->waiters.front)->cid);
- sema->unpausing = true;
- }
- cr_restore_interrupts(saved);
-}
+void cr_sema_signal(cr_sema_t *sema);
/**
* Like cr_sema_signal(), but for use from an interrupt handler.
*
* @runs_in intrhandler
*/
-static inline void cr_sema_signal_from_intrhandler(cr_sema_t *sema) {
- assert(sema);
- cr_assert_in_intrhandler();
-
- sema->cnt++;
- if (sema->waiters.front && !sema->unpausing) {
- cr_unpause_from_intrhandler(
- _cr_ipc_sll_node_cast(struct _cr_sema_waiter, sema->waiters.front)->cid);
- sema->unpausing = true;
- }
-}
+void cr_sema_signal_from_intrhandler(cr_sema_t *sema);
/**
* Wait until the semaphore is >0, then decrement it.
@@ -74,27 +50,6 @@ static inline void cr_sema_signal_from_intrhandler(cr_sema_t *sema) {
* @cr_pauses maybe
* @cr_yields maybe
*/
-static inline void cr_sema_wait(cr_sema_t *sema) {
- assert(sema);
- cr_assert_in_coroutine();
-
- bool saved = cr_save_and_disable_interrupts();
-
- struct _cr_sema_waiter self = {
- .cid = cr_getcid(),
- };
- _cr_ipc_sll_push_to_rear(&sema->waiters, &self);
- if (sema->waiters.front != &self._cr_ipc_sll_node || !sema->cnt)
- cr_pause_and_yield();
- assert(sema->waiters.front == &self._cr_ipc_sll_node && sema->cnt);
- _cr_ipc_sll_pop_from_front(&sema->waiters);
- sema->cnt--;
- if (sema->cnt && sema->waiters.front)
- cr_unpause(
- _cr_ipc_sll_node_cast(struct _cr_sema_waiter, sema->waiters.front)->cid);
- else
- sema->unpausing = false;
- cr_restore_interrupts(saved);
-}
+void cr_sema_wait(cr_sema_t *sema);
#endif /* _LIBCR_IPC_SEMA_H_ */
diff --git a/libcr_ipc/mutex.c b/libcr_ipc/mutex.c
new file mode 100644
index 0000000..1b4e626
--- /dev/null
+++ b/libcr_ipc/mutex.c
@@ -0,0 +1,44 @@
+/* libcr_ipc/mutex.c - Simple mutexes for libcr
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libcr/coroutine.h> /* for cid_t, cr_* */
+#include <libmisc/assert.h>
+
+#define IMPLEMENTATION_FOR_LIBCR_IPC_MUTEX_H YES
+#include <libcr_ipc/mutex.h>
+
+struct cr_mutex_waiter {
+ cid_t cid;
+};
+SLIST_DECLARE_NODE(_cr_mutex_waiter_list, struct cr_mutex_waiter);
+
+void cr_mutex_lock(cr_mutex_t *mu) {
+ assert(mu);
+ cr_assert_in_coroutine();
+
+ if (!mu->locked) /* non-blocking fast-path */
+ mu->locked = true;
+ else { /* blocking slow-path */
+ struct _cr_mutex_waiter_list_node self = { .val = {
+ .cid = cr_getcid(),
+ }};
+ slist_push_to_rear(&mu->waiters, &self);
+ cr_pause_and_yield();
+ }
+ assert(mu->locked);
+}
+
+void cr_mutex_unlock(cr_mutex_t *mu) {
+ assert(mu);
+ cr_assert_in_coroutine();
+
+ assert(mu->locked);
+ if (mu->waiters.front) {
+ cr_unpause(mu->waiters.front->val.cid);
+ slist_pop_from_front(&mu->waiters);
+ } else
+ mu->locked = false;
+}
diff --git a/libcr_ipc/rpc.c b/libcr_ipc/rpc.c
new file mode 100644
index 0000000..fcf51ba
--- /dev/null
+++ b/libcr_ipc/rpc.c
@@ -0,0 +1,84 @@
+/* libcr_ipc/rpc.c - Simple request/response system for libcr
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <string.h> /* for memcpy() */
+
+#include <libcr/coroutine.h> /* for cid_t, cr_* */
+#include <libmisc/assert.h>
+
+#include <libcr_ipc/rpc.h>
+
+struct cr_rpc_requester {
+ cid_t cid;
+ void *req_ptr; /* where to read req from */
+ void *resp_ptr; /* where to write resp to */
+};
+struct cr_rpc_responder {
+ /* before enqueued | after dequeued */
+ /* -------------------+-------------------- */
+ cid_t cid; /* responder cid | requester cid */
+ void *ptr; /* where to write req | where to write resp */
+};
+union cr_rpc_waiter {
+ struct cr_rpc_requester requester;
+ struct cr_rpc_responder responder;
+};
+SLIST_DECLARE_NODE(_cr_rpc_waiter_list, union cr_rpc_waiter);
+
+void _cr_rpc_send_req(struct _cr_rpc *ch, void *req_ptr, size_t req_size, void *resp_ptr) {
+ assert(ch);
+ assert(req_ptr);
+ assert(resp_ptr);
+
+ if (ch->waiters.front && ch->waiter_typ != _CR_RPC_REQUESTER) { /* fast-path (still blocks) */
+ struct cr_rpc_responder *responder = &ch->waiters.front->val.responder;
+ slist_pop_from_front(&ch->waiters);
+ /* Copy the req to the responder's stack. */
+ memcpy(responder->ptr, req_ptr, req_size);
+ /* Notify the responder that we have done so. */
+ cr_unpause(responder->cid);
+ responder->cid = cr_getcid();
+ responder->ptr = resp_ptr;
+ /* Wait for the responder to set `*resp_ptr`. */
+ cr_pause_and_yield();
+ } else { /* blocking slow-path */
+ struct _cr_rpc_waiter_list_node self = { .val = { .requester = {
+ .cid = cr_getcid(),
+ .req_ptr = req_ptr,
+ .resp_ptr = resp_ptr,
+ }}};
+ slist_push_to_rear(&ch->waiters, &self);
+ /* Wait for a responder to both copy our req and sed
+ * `*resp_ptr`. */
+ cr_pause_and_yield();
+ }
+}
+
+void _cr_rpc_recv_req(struct _cr_rpc *ch, void *req_ptr, size_t req_size, void **ret_resp_ptr, cid_t *ret_requester) {
+ assert(ch);
+ assert(req_ptr);
+ assert(ret_resp_ptr);
+ assert(ret_requester);
+
+ if (ch->waiters.front && ch->waiter_typ != _CR_RPC_RESPONDER) { /* non-blocking fast-path */
+ struct cr_rpc_requester *requester = &ch->waiters.front->val.requester;
+ slist_pop_from_front(&ch->waiters);
+
+ memcpy(req_ptr, requester->req_ptr, req_size);
+ *ret_requester = requester->cid;
+ *ret_resp_ptr = requester->resp_ptr;
+ } else { /* blocking slow-path */
+ struct _cr_rpc_waiter_list_node self = { .val = { .responder = {
+ .cid = cr_getcid(),
+ .ptr = req_ptr,
+ }}};
+ slist_push_to_rear(&ch->waiters, &self);
+ ch->waiter_typ = _CR_RPC_RESPONDER;
+ cr_pause_and_yield();
+ *ret_requester = self.val.responder.cid;
+ *ret_resp_ptr = self.val.responder.ptr;
+ }
+}
diff --git a/libcr_ipc/rwmutex.c b/libcr_ipc/rwmutex.c
new file mode 100644
index 0000000..191b7fe
--- /dev/null
+++ b/libcr_ipc/rwmutex.c
@@ -0,0 +1,98 @@
+/* libcr_ipc/rwmutex.c - Simple read/write mutexes for libcr
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libcr/coroutine.h> /* for cid_t, cr_* */
+#include <libmisc/assert.h>
+
+#define IMPLEMENTATION_FOR_LIBCR_IPC_RWMUTEX_H YES
+#include <libcr_ipc/rwmutex.h>
+
+struct cr_rwmutex_waiter {
+ bool is_reader;
+ cid_t cid;
+};
+SLIST_DECLARE_NODE(_cr_rwmutex_waiter_list, struct cr_rwmutex_waiter);
+
+void cr_rwmutex_lock(cr_rwmutex_t *mu) {
+ assert(mu);
+ cr_assert_in_coroutine();
+
+ struct _cr_rwmutex_waiter_list_node self = { .val = {
+ .is_reader = false,
+ .cid = cr_getcid(),
+ }};
+ slist_push_to_rear(&mu->waiters, &self);
+ if (mu->waiters.front != &self || mu->locked)
+ cr_pause_and_yield();
+ assert(mu->waiters.front == &self);
+
+ /* We now hold the lock (and are mu->waiters.front). */
+ slist_pop_from_front(&mu->waiters);
+ assert(mu->nreaders == 0);
+ mu->locked = true;
+ mu->unpausing = false;
+}
+
+void cr_rwmutex_rlock(cr_rwmutex_t *mu) {
+ assert(mu);
+ cr_assert_in_coroutine();
+
+ struct _cr_rwmutex_waiter_list_node self = { .val = {
+ .is_reader = true,
+ .cid = cr_getcid(),
+ }};
+ slist_push_to_rear(&mu->waiters, &self);
+ if (mu->waiters.front != &self || (mu->locked && mu->nreaders == 0))
+ cr_pause_and_yield();
+ assert(mu->waiters.front == &self);
+
+ /* We now hold the lock (and are mu->waiters.front). */
+ slist_pop_from_front(&mu->waiters);
+ mu->nreaders++;
+ mu->locked = true;
+ struct _cr_rwmutex_waiter_list_node *waiter = mu->waiters.front;
+ if (waiter && waiter->val.is_reader) {
+ assert(mu->unpausing);
+ cr_unpause(waiter->val.cid);
+ } else {
+ mu->unpausing = false;
+ }
+}
+
+void cr_rwmutex_unlock(cr_rwmutex_t *mu) {
+ assert(mu);
+ cr_assert_in_coroutine();
+
+ assert(mu->locked);
+ assert(mu->nreaders == 0);
+ assert(!mu->unpausing);
+ if (mu->waiters.front) {
+ struct _cr_rwmutex_waiter_list_node *waiter = mu->waiters.front;
+ mu->unpausing = true;
+ cr_unpause(waiter->val.cid);
+ } else {
+ mu->locked = false;
+ }
+}
+
+void cr_rwmutex_runlock(cr_rwmutex_t *mu) {
+ assert(mu);
+ cr_assert_in_coroutine();
+
+ assert(mu->locked);
+ assert(mu->nreaders > 0);
+ mu->nreaders--;
+ if (mu->nreaders == 0 && !mu->unpausing) {
+ if (mu->waiters.front) {
+ struct _cr_rwmutex_waiter_list_node *waiter = mu->waiters.front;
+ assert(!waiter->val.is_reader);
+ mu->unpausing = true;
+ cr_unpause(waiter->val.cid);
+ } else {
+ mu->locked = false;
+ }
+ }
+}
diff --git a/libcr_ipc/select.c b/libcr_ipc/select.c
deleted file mode 100644
index 4bd9067..0000000
--- a/libcr_ipc/select.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* libcr_ipc/select.c - Select between channels
- *
- * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-#include <libcr_ipc/select.h>
-
-static inline enum _cr_select_class _cr_select_getclass(struct cr_select_arg arg) {
- switch (arg.op) {
- case _CR_SELECT_OP_RECV:
- if (arg.ch->waiters.front && arg.ch->waiter_typ == _CR_CHAN_SENDER)
- return _CR_SELECT_CLASS_NONBLOCK;
- else
- return _CR_SELECT_CLASS_BLOCKING;
- case _CR_SELECT_OP_SEND:
- if (arg.ch->waiters.front && arg.ch->waiter_typ == _CR_CHAN_RECVER)
- return _CR_SELECT_CLASS_NONBLOCK;
- else
- return _CR_SELECT_CLASS_BLOCKING;
- case _CR_SELECT_OP_DEFAULT:
- return _CR_SELECT_CLASS_DEFAULT;
- default:
- assert_notreached("invalid arg.op");
- }
-}
-
-void _cr_select_dequeue(void *_waiters, size_t idx) {
- struct _cr_select_waiters *waiters = _waiters;
- for (size_t i = 0; i < waiters->cnt; i++)
- _cr_ipc_dll_remove(&(waiters->args[i].ch->waiters),
- &(waiters->nodes[i]));
- waiters->cnt = idx;
-}
-
-size_t cr_select_v(size_t arg_cnt, struct cr_select_arg arg_vec[]) {
- size_t cnt_blocking = 0;
- size_t cnt_nonblock = 0;
- size_t cnt_default = 0;
-
- assert(arg_cnt);
- assert(arg_vec);
- cr_assert_in_coroutine();
-
- for (size_t i = 0; i < arg_cnt; i++) {
- switch (_cr_select_getclass(arg_vec[i])) {
- case _CR_SELECT_CLASS_BLOCKING:
- cnt_blocking++;
- break;
- case _CR_SELECT_CLASS_NONBLOCK:
- cnt_nonblock++;
- break;
- case _CR_SELECT_CLASS_DEFAULT:
- cnt_default++;
- break;
- }
- }
-
- if (cnt_nonblock) {
- size_t choice = rand_uint63n(cnt_nonblock);
- for (size_t i = 0, seen = 0; i < arg_cnt; i++) {
- if (_cr_select_getclass(arg_vec[i]) == _CR_SELECT_CLASS_NONBLOCK) {
- if (seen == choice) {
- _cr_chan_xfer(arg_vec[i].op == _CR_SELECT_OP_RECV
- ? _CR_CHAN_RECVER
- : _CR_CHAN_SENDER,
- arg_vec[i].ch,
- arg_vec[i].val_ptr,
- arg_vec[i].val_siz);
- return i;
- }
- seen++;
- }
- }
- assert_notreached("should have returned from inside for() loop");
- }
-
- if (cnt_default) {
- for (size_t i = 0; i < arg_cnt; i++)
- if (_cr_select_getclass(arg_vec[i]) == _CR_SELECT_CLASS_DEFAULT)
- return i;
- assert_notreached("should have returned from inside for() loop");
- }
-
- struct _cr_select_waiters waiters = {
- .cnt = arg_cnt,
- .args = arg_vec,
- .nodes = alloca(sizeof(struct _cr_chan_waiter) * arg_cnt),
- };
- for (size_t i = 0; i < arg_cnt; i++) {
- waiters.nodes[i] = (struct _cr_chan_waiter){
- .cid = cr_getcid(),
- .val_ptr = arg_vec[i].val_ptr,
- .dequeue = _cr_select_dequeue,
- .dequeue_arg1 = &waiters,
- .dequeue_arg2 = i,
- };
- _cr_ipc_dll_push_to_rear(&arg_vec[i].ch->waiters, &waiters.nodes[i]);
- }
- cr_pause_and_yield();
- return waiters.cnt;
-}
diff --git a/libcr_ipc/sema.c b/libcr_ipc/sema.c
new file mode 100644
index 0000000..f2ac9b6
--- /dev/null
+++ b/libcr_ipc/sema.c
@@ -0,0 +1,62 @@
+/* libcr_ipc/sema.c - Simple semaphores for libcr
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libcr/coroutine.h> /* for cid_t, cr_* */
+#include <libmisc/assert.h>
+
+#define IMPLEMENTATION_FOR_LIBCR_IPC_SEMA_H YES
+#include <libcr_ipc/sema.h>
+
+struct cr_sema_waiter {
+ cid_t cid;
+};
+SLIST_DECLARE_NODE(_cr_sema_waiter_list, struct cr_sema_waiter);
+
+void cr_sema_signal(cr_sema_t *sema) {
+ assert(sema);
+ cr_assert_in_coroutine();
+
+ bool saved = cr_save_and_disable_interrupts();
+ sema->cnt++;
+ if (sema->waiters.front && !sema->unpausing) {
+ cr_unpause(sema->waiters.front->val.cid);
+ sema->unpausing = true;
+ }
+ cr_restore_interrupts(saved);
+}
+
+void cr_sema_signal_from_intrhandler(cr_sema_t *sema) {
+ assert(sema);
+ cr_assert_in_intrhandler();
+
+ sema->cnt++;
+ if (sema->waiters.front && !sema->unpausing) {
+ cr_unpause_from_intrhandler(sema->waiters.front->val.cid);
+ sema->unpausing = true;
+ }
+}
+
+void cr_sema_wait(cr_sema_t *sema) {
+ assert(sema);
+ cr_assert_in_coroutine();
+
+ bool saved = cr_save_and_disable_interrupts();
+
+ struct _cr_sema_waiter_list_node self = { .val = {
+ .cid = cr_getcid(),
+ }};
+ slist_push_to_rear(&sema->waiters, &self);
+ if (sema->waiters.front != &self || !sema->cnt)
+ cr_pause_and_yield();
+ assert(sema->waiters.front == &self && sema->cnt);
+ slist_pop_from_front(&sema->waiters);
+ sema->cnt--;
+ if (sema->cnt && sema->waiters.front)
+ cr_unpause(sema->waiters.front->val.cid);
+ else
+ sema->unpausing = false;
+ cr_restore_interrupts(saved);
+}
diff --git a/libcr_ipc/tests/config.h b/libcr_ipc/tests/config.h
index b00508c..a648589 100644
--- a/libcr_ipc/tests/config.h
+++ b/libcr_ipc/tests/config.h
@@ -7,9 +7,9 @@
#ifndef _CONFIG_H_
#define _CONFIG_H_
-#define CONFIG_COROUTINE_STACK_SIZE_DEFAULT (4*1024)
+#define CONFIG_COROUTINE_STACK_SIZE_DEFAULT (8*1024)
#define CONFIG_COROUTINE_NAME_LEN 16
-#define CONFIG_COROUTINE_NUM 8
+#define CONFIG_COROUTINE_NUM 16
#define CONFIG_COROUTINE_MEASURE_STACK 1
#define CONFIG_COROUTINE_PROTECT_STACK 1
diff --git a/libcr_ipc/tests/test_chan.c b/libcr_ipc/tests/test_chan.c
index 9d6eecf..4788dd4 100644
--- a/libcr_ipc/tests/test_chan.c
+++ b/libcr_ipc/tests/test_chan.c
@@ -1,6 +1,6 @@
/* libcr_ipc/tests/test_chan.c - Tests for <libcr_ipc/chan.h>
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@@ -9,32 +9,32 @@
#include "test.h"
-CR_CHAN_DECLARE(intchan, int)
+CR_CHAN_DECLARE(intchan, int);
-COROUTINE cr_producer(void *_ch) {
+COROUTINE producer_cr(void *_ch) {
intchan_t *ch = _ch;
cr_begin();
- intchan_send(ch, 1);
+ cr_chan_send(ch, 1);
- while (!intchan_can_send(ch))
+ while (!cr_chan_can_send(ch))
cr_yield();
- intchan_send(ch, 2);
+ cr_chan_send(ch, 2);
cr_end();
}
-COROUTINE cr_consumer(void *_ch) {
+COROUTINE consumer_cr(void *_ch) {
int x;
intchan_t *ch = _ch;
cr_begin();
- x = intchan_recv(ch);
+ x = cr_chan_recv(ch);
test_assert(x == 1);
- x = intchan_recv(ch);
+ x = cr_chan_recv(ch);
test_assert(x == 2);
cr_end();
@@ -42,8 +42,8 @@ COROUTINE cr_consumer(void *_ch) {
int main() {
intchan_t ch = {0};
- coroutine_add("producer", cr_producer, &ch);
- coroutine_add("consumer", cr_consumer, &ch);
+ coroutine_add("producer", producer_cr, &ch);
+ coroutine_add("consumer", consumer_cr, &ch);
coroutine_main();
return 0;
}
diff --git a/libcr_ipc/tests/test_mutex.c b/libcr_ipc/tests/test_mutex.c
new file mode 100644
index 0000000..d08315d
--- /dev/null
+++ b/libcr_ipc/tests/test_mutex.c
@@ -0,0 +1,37 @@
+/* libcr_ipc/tests/test_mutex.c - Tests for <libcr_ipc/mutex.h>
+ *
+ * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libcr/coroutine.h>
+#include <libcr_ipc/mutex.h>
+
+#include "test.h"
+
+int counter = 0;
+
+COROUTINE worker_cr(void *_mu) {
+ cr_mutex_t *mu = _mu;
+ cr_begin();
+
+ for (int i = 0; i < 100; i++) {
+ cr_mutex_lock(mu);
+ int a = counter;
+ cr_yield();
+ counter = a + 1;
+ cr_mutex_unlock(mu);
+ cr_yield();
+ }
+
+ cr_end();
+}
+
+int main() {
+ cr_mutex_t mu = {};
+ coroutine_add("a", worker_cr, &mu);
+ coroutine_add("b", worker_cr, &mu);
+ coroutine_main();
+ test_assert(counter == 200);
+ return 0;
+}
diff --git a/libcr_ipc/tests/test_rpc.c b/libcr_ipc/tests/test_rpc.c
index 4aff5ca..1461450 100644
--- a/libcr_ipc/tests/test_rpc.c
+++ b/libcr_ipc/tests/test_rpc.c
@@ -9,51 +9,51 @@
#include "test.h"
-CR_RPC_DECLARE(intrpc, int, int)
+CR_RPC_DECLARE(intrpc, int, int);
/* Test that the RPC is fair, have worker1 start waiting first, and
* ensure that it gets the first request. */
-COROUTINE cr_caller(void *_ch) {
+COROUTINE caller_cr(void *_ch) {
intrpc_t *ch = _ch;
cr_begin();
- int resp = intrpc_send_req(ch, 1);
+ int resp = cr_rpc_send_req(ch, 1);
test_assert(resp == 2);
- resp = intrpc_send_req(ch, 3);
+ resp = cr_rpc_send_req(ch, 3);
test_assert(resp == 4);
cr_exit();
}
-COROUTINE cr_worker1(void *_ch) {
+COROUTINE worker1_cr(void *_ch) {
intrpc_t *ch = _ch;
cr_begin();
- intrpc_req_t req = intrpc_recv_req(ch);
+ intrpc_req_t req = cr_rpc_recv_req(ch);
test_assert(req.req == 1);
- intrpc_send_resp(req, 2);
+ cr_rpc_send_resp(req, 2);
cr_exit();
}
-COROUTINE cr_worker2(void *_ch) {
+COROUTINE worker2_cr(void *_ch) {
intrpc_t *ch = _ch;
cr_begin();
- intrpc_req_t req = intrpc_recv_req(ch);
+ intrpc_req_t req = cr_rpc_recv_req(ch);
test_assert(req.req == 3);
- intrpc_send_resp(req, 4);
+ cr_rpc_send_resp(req, 4);
cr_exit();
}
int main() {
intrpc_t ch = {0};
- coroutine_add("worker1", cr_worker1, &ch);
- coroutine_add("caller", cr_caller, &ch);
- coroutine_add("worker2", cr_worker2, &ch);
+ coroutine_add("worker1", worker1_cr, &ch);
+ coroutine_add("caller", caller_cr, &ch);
+ coroutine_add("worker2", worker2_cr, &ch);
coroutine_main();
return 0;
}
diff --git a/libcr_ipc/tests/test_rwmutex.c b/libcr_ipc/tests/test_rwmutex.c
new file mode 100644
index 0000000..77e8c7c
--- /dev/null
+++ b/libcr_ipc/tests/test_rwmutex.c
@@ -0,0 +1,88 @@
+/* libcr_ipc/tests/test_rwmutex.c - Tests for <libcr_ipc/rwmutex.h>
+ *
+ * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <string.h>
+
+#include <libcr/coroutine.h>
+#include <libcr_ipc/rwmutex.h>
+
+#include "test.h"
+
+cr_rwmutex_t mu = {};
+char out[10] = {0};
+size_t len = 0;
+
+COROUTINE cr1_reader(void *_mu) {
+ cr_rwmutex_t *mu = _mu;
+ cr_begin();
+
+ cr_rwmutex_rlock(mu);
+ out[len++] = 'r';
+ cr_yield();
+ cr_rwmutex_runlock(mu);
+
+ cr_end();
+}
+
+COROUTINE cr1_writer(void *_mu) {
+ cr_rwmutex_t *mu = _mu;
+ cr_begin();
+
+ cr_rwmutex_lock(mu);
+ out[len++] = 'w';
+ cr_yield();
+ cr_rwmutex_unlock(mu);
+
+ cr_end();
+}
+
+COROUTINE cr2_waiter(void *_ch) {
+ char ch = *(char *)_ch;
+ cr_begin();
+
+ cr_rwmutex_rlock(&mu);
+ out[len++] = ch;
+ cr_rwmutex_runlock(&mu);
+
+ cr_end();
+}
+
+COROUTINE cr2_init(void *) {
+ cr_begin();
+
+ char ch;
+ cr_rwmutex_lock(&mu);
+ ch = 'a'; coroutine_add("wait-a", cr2_waiter, &ch);
+ ch = 'b'; coroutine_add("wait-b", cr2_waiter, &ch);
+ cr_yield();
+ ch = 'c'; coroutine_add("wait-c", cr2_waiter, &ch);
+ cr_rwmutex_unlock(&mu);
+
+ cr_end();
+}
+
+int main() {
+ printf("== test 1 =========================================\n");
+ coroutine_add("r1", cr1_reader, &mu);
+ coroutine_add("r2", cr1_reader, &mu);
+ coroutine_add("w", cr1_writer, &mu);
+ coroutine_add("r3", cr1_reader, &mu);
+ coroutine_add("r4", cr1_reader, &mu);
+ coroutine_main();
+ test_assert(len == 5);
+ test_assert(strcmp(out, "rrwrr") == 0);
+
+ printf("== test 2 =========================================\n");
+ mu = (cr_rwmutex_t){};
+ len = 0;
+ memset(out, 0, sizeof(out));
+ coroutine_add("init", cr2_init, NULL);
+ coroutine_main();
+ test_assert(len == 3);
+ test_assert(strcmp(out, "abc") == 0);
+
+ return 0;
+}
diff --git a/libcr_ipc/tests/test_select.c b/libcr_ipc/tests/test_select.c
new file mode 100644
index 0000000..9b5d117
--- /dev/null
+++ b/libcr_ipc/tests/test_select.c
@@ -0,0 +1,89 @@
+/* libcr_ipc/tests/test_select.c - Tests for <libcr_ipc/select.h>
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libcr/coroutine.h>
+#include <libcr_ipc/chan.h>
+
+#include "test.h"
+
+CR_CHAN_DECLARE(intchan, int);
+
+intchan_t ch[10] = {0};
+intchan_t fch = {0};
+
+COROUTINE consumer_cr(void *) {
+ cr_begin();
+
+ struct cr_select_arg args[11];
+
+ bool chdone[10] = {0};
+ int arg2ch[10];
+ for (;;) {
+ int ret_ch;
+ int i_arg = 0;
+ for (int i_ch = 0; i_ch < 10; i_ch++) {
+ if (!chdone[i_ch]) {
+ args[i_arg] = CR_SELECT_RECV(&ch[i_ch], &ret_ch);
+ arg2ch[i_arg] = i_ch;
+ i_arg++;
+ }
+ }
+ if (!i_arg)
+ break;
+ args[i_arg] = CR_SELECT_DEFAULT; /* check that default doesn't trigger */
+ test_assert(i_arg <= 10);
+ int ret_arg = cr_select_v(i_arg+1, args);
+ test_assert(ret_arg < i_arg);
+ test_assert(arg2ch[ret_arg] == ret_ch);
+ chdone[ret_ch] = true;
+ }
+ int ret_ch, ret_arg;
+ args[0] = CR_SELECT_RECV(&ch[0], &ret_ch);
+ args[1] = CR_SELECT_DEFAULT;
+ ret_arg = cr_select_v(2, args);
+ test_assert(ret_arg == 1);
+
+ int send = 567;
+ args[0] = CR_SELECT_SEND(&fch, &send);
+ args[1] = CR_SELECT_DEFAULT;
+ ret_arg = cr_select_v(2, args);
+ test_assert(ret_arg == 0);
+
+ send = 890;
+ ret_arg = cr_select_l(CR_SELECT_SEND(&fch, &send),
+ CR_SELECT_DEFAULT);
+ test_assert(ret_arg == 1);
+
+ cr_end();
+}
+
+COROUTINE producer_cr(void *_n) {
+ int n = *(int *)_n;
+ cr_begin();
+
+ cr_chan_send(&ch[n], n);
+
+ cr_end();
+}
+
+COROUTINE final_cr(void *) {
+ cr_begin();
+
+ int ret = cr_chan_recv(&fch);
+ printf("ret=%d\n", ret);
+ test_assert(ret == 567);
+
+ cr_end();
+}
+
+int main() {
+ for (int i = 0; i < 10; i++)
+ coroutine_add("producer", producer_cr, &i);
+ coroutine_add("consumer", consumer_cr, NULL);
+ coroutine_add("final", final_cr, NULL);
+ coroutine_main();
+ return 0;
+}
diff --git a/libcr_ipc/tests/test_sema.c b/libcr_ipc/tests/test_sema.c
index 3208237..435c01a 100644
--- a/libcr_ipc/tests/test_sema.c
+++ b/libcr_ipc/tests/test_sema.c
@@ -5,13 +5,15 @@
*/
#include <libcr/coroutine.h>
+
+#define IMPLEMENTATION_FOR_LIBCR_IPC_SEMA_H YES /* so we can access .cnt */
#include <libcr_ipc/sema.h>
#include "test.h"
int counter = 0;
-COROUTINE cr_first(void *_sema) {
+COROUTINE first_cr(void *_sema) {
cr_sema_t *sema = _sema;
cr_begin();
@@ -22,7 +24,7 @@ COROUTINE cr_first(void *_sema) {
cr_exit();
}
-COROUTINE cr_second(void *_sema) {
+COROUTINE second_cr(void *_sema) {
cr_sema_t *sema = _sema;
cr_begin();
@@ -33,7 +35,7 @@ COROUTINE cr_second(void *_sema) {
cr_exit();
}
-COROUTINE cr_producer(void *_sema) {
+COROUTINE producer_cr(void *_sema) {
cr_sema_t *sema = _sema;
cr_begin();
@@ -43,7 +45,7 @@ COROUTINE cr_producer(void *_sema) {
cr_end();
}
-COROUTINE cr_consumer(void *_sema) {
+COROUTINE consumer_cr(void *_sema) {
cr_sema_t *sema = _sema;
cr_begin();
@@ -54,19 +56,19 @@ COROUTINE cr_consumer(void *_sema) {
}
int main() {
- cr_sema_t sema = {0};
+ cr_sema_t sema = {};
printf("== test 1 =========================================\n");
- coroutine_add("first", cr_first, &sema);
- coroutine_add("second", cr_second, &sema);
+ coroutine_add("first", first_cr, &sema);
+ coroutine_add("second", second_cr, &sema);
coroutine_main();
test_assert(sema.cnt == 0);
printf("== test 2 =========================================\n");
- coroutine_add("consumer", cr_consumer, &sema);
- coroutine_add("producer", cr_producer, &sema);
+ coroutine_add("consumer", consumer_cr, &sema);
+ coroutine_add("producer", producer_cr, &sema);
coroutine_main();
- coroutine_add("consumer", cr_consumer, &sema);
+ coroutine_add("consumer", consumer_cr, &sema);
coroutine_main();
test_assert(sema.cnt == 0);
diff --git a/libfmt/libmisc.c b/libfmt/libmisc.c
index 97a2c80..803b281 100644
--- a/libfmt/libmisc.c
+++ b/libfmt/libmisc.c
@@ -5,7 +5,7 @@
*/
#include <stdarg.h> /* for va_list, va_start(), va_end() */
-#include <stdio.h> /* for vprintf(), putchar() */
+#include <stdio.h> /* for vprintf(), putchar(), fflush() */
#if LIB_PICO_STDIO
#include <pico/stdio.h> /* for stdio_putchar_raw() */
#endif
@@ -37,6 +37,7 @@ int __lm_printf(const char *format, ...) {
int ret = vprintf(format, va);
#else
int ret = fmt_vfctprintf(libfmt_libc_fct, NULL, format, va);
+ fflush(stdout);
#endif
va_end(va);
return ret;
@@ -55,6 +56,7 @@ int __lm_light_printf(const char *format, ...) {
stdio_flush();
#else
int ret = fmt_vfctprintf(libfmt_libc_fct, NULL, format, va);
+ fflush(stdout);
#endif
va_end(va);
return ret;
diff --git a/libhw_cr/host_net.c b/libhw_cr/host_net.c
index 6ed6e46..ba634a6 100644
--- a/libhw_cr/host_net.c
+++ b/libhw_cr/host_net.c
@@ -19,6 +19,7 @@
#include <signal.h> /* for siginfo_t, struct sigaction, enum sigval, sigaction(), SA_SIGINFO */
#include <libcr/coroutine.h>
+#include <libmisc/alloc.h>
#include <libmisc/assert.h>
#include <libmisc/macro.h>
#include <libobj/obj.h>
@@ -283,7 +284,7 @@ static void *hostnet_pthread_writev(void *_args) {
struct hostnet_pthread_writev_args *args = _args;
size_t count = 0;
- struct iovec *iov = alloca(sizeof(struct iovec)*args->iovcnt);
+ struct iovec *iov = stack_alloc(args->iovcnt, struct iovec);
for (int i = 0; i < args->iovcnt; i++) {
iov[i] = args->iov[i];
count += args->iov[i].iov_len;
diff --git a/libhw_cr/host_util.c b/libhw_cr/host_util.c
index 958ed9c..7b3200c 100644
--- a/libhw_cr/host_util.c
+++ b/libhw_cr/host_util.c
@@ -1,6 +1,6 @@
/* libhw_cr/host_util.c - Utilities for GNU/Linux hosts
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
diff --git a/libhw_cr/host_util.h b/libhw_cr/host_util.h
index 8c53fab..02c04dc 100644
--- a/libhw_cr/host_util.h
+++ b/libhw_cr/host_util.h
@@ -1,6 +1,6 @@
/* libhw_cr/host_util.h - Utilities for GNU/Linux hosts
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
diff --git a/libhw_cr/rp2040_hwspi.c b/libhw_cr/rp2040_hwspi.c
index 646d8ba..29a7bac 100644
--- a/libhw_cr/rp2040_hwspi.c
+++ b/libhw_cr/rp2040_hwspi.c
@@ -4,7 +4,6 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-#include <alloca.h>
#include <inttypes.h> /* for PRIu{n} */
#include <hardware/clocks.h> /* for clock_get_hz() and clk_peri */
@@ -12,6 +11,7 @@
#include <hardware/spi.h>
#include <libcr/coroutine.h>
+#include <libmisc/alloc.h>
#include <libmisc/assert.h>
#define LOG_NAME RP2040_SPI
@@ -130,7 +130,7 @@ void _rp2040_hwspi_init(struct rp2040_hwspi *self,
self->dma_tx_data = dma3;
self->dma_rx_data = dma4;
self->dead_until_ns = 0;
- self->sema = (cr_sema_t){0};
+ self->sema = (cr_sema_t){};
/* Initialize the interrupt handler. */
/* We do this on (just) the rx channel, because the way the
@@ -198,8 +198,8 @@ static void rp2040_hwspi_readwritev(struct rp2040_hwspi *self, const struct dupl
* happens, so the IRQ machinery doesn't need to be engaged
* at all.
*/
- struct dma_alias1 *tx_data_blocks = alloca(sizeof(struct dma_alias1)*(pruned_iovcnt+1));
- struct dma_alias0 *rx_data_blocks = alloca(sizeof(struct dma_alias0)*(pruned_iovcnt+1));
+ struct dma_alias1 *tx_data_blocks = stack_alloc(pruned_iovcnt+1, struct dma_alias1);
+ struct dma_alias0 *rx_data_blocks = stack_alloc(pruned_iovcnt+1, struct dma_alias0);
static_assert(!DMA_IS_TRIGGER(typeof(tx_data_blocks[0]), ctrl));
static_assert(DMA_IS_TRIGGER(typeof(rx_data_blocks[0]), ctrl));
diff --git a/libhw_cr/rp2040_include/libhw/rp2040_hwspi.h b/libhw_cr/rp2040_include/libhw/rp2040_hwspi.h
index 4951136..8d4effa 100644
--- a/libhw_cr/rp2040_include/libhw/rp2040_hwspi.h
+++ b/libhw_cr/rp2040_include/libhw/rp2040_hwspi.h
@@ -99,7 +99,7 @@ LO_IMPLEMENTATION_H(spi, struct rp2040_hwspi, rp2040_hwspi);
min_delay_ns, bogus_data, \
pin_miso, pin_mosi, pin_clk, pin_cs, \
dma1, dma2, dma3, dma4); \
- } while(0)
+ } while (0)
void _rp2040_hwspi_init(struct rp2040_hwspi *self,
enum rp2040_hwspi_instance inst_num,
enum spi_mode mode,
diff --git a/libhw_cr/rp2040_include/libhw/w5500.h b/libhw_cr/rp2040_include/libhw/w5500.h
index 8db6a58..8dda1a1 100644
--- a/libhw_cr/rp2040_include/libhw/w5500.h
+++ b/libhw_cr/rp2040_include/libhw/w5500.h
@@ -17,7 +17,7 @@
#include <libhw/generic/net.h>
#include <libhw/generic/spi.h>
-CR_CHAN_DECLARE(_w5500_sockintr_ch, uint8_t)
+CR_CHAN_DECLARE(_w5500_sockintr_ch, uint8_t);
struct _w5500_socket {
BEGIN_PRIVATE(LIBHW_W5500_H);
diff --git a/libhw_cr/w5500.c b/libhw_cr/w5500.c
index fa427d9..c04e344 100644
--- a/libhw_cr/w5500.c
+++ b/libhw_cr/w5500.c
@@ -217,7 +217,7 @@ static COROUTINE w5500_irq_cr(void *_chip) {
}
if (send_bits) {
debugf("w5500_irq_cr(): signal sock[%"PRIu8"]->write_ch", socknum);
- _w5500_sockintr_ch_send(&socket->write_ch, send_bits);
+ cr_chan_send(&socket->write_ch, send_bits);
}
break;
}
@@ -666,7 +666,7 @@ static ssize_t w5500_tcp_writev(struct _w5500_socket *socket, const struct iovec
w5500_socket_cmd(socket, CMD_SEND);
cr_mutex_unlock(&chip->mu);
- switch (_w5500_sockintr_ch_recv(&socket->write_ch)) {
+ switch (cr_chan_recv(&socket->write_ch)) {
case SOCKINTR_SEND_OK:
debugf(" => sent %zu", freesize);
done += freesize;
@@ -853,7 +853,7 @@ static ssize_t w5500_udp_sendto(struct _w5500_socket *socket, void *buf, size_t
w5500_socket_cmd(socket, CMD_SEND);
cr_mutex_unlock(&chip->mu);
- switch (_w5500_sockintr_ch_recv(&socket->write_ch)) {
+ switch (cr_chan_recv(&socket->write_ch)) {
case SOCKINTR_SEND_OK:
debugf(" => sent");
return count;
diff --git a/libhw_cr/w5500_ll.h b/libhw_cr/w5500_ll.h
index 2506cd2..8b98f9d 100644
--- a/libhw_cr/w5500_ll.h
+++ b/libhw_cr/w5500_ll.h
@@ -10,10 +10,10 @@
#ifndef _LIBHW_CR_W5500_LL_H_
#define _LIBHW_CR_W5500_LL_H_
-#include <alloca.h> /* for alloca() */
#include <stdint.h> /* for uint{n}_t */
#include <string.h> /* for memcmp() */
+#include <libmisc/alloc.h> /* for stack_alloc() */
#include <libmisc/assert.h> /* for assert(), static_assert() */
#include <libmisc/endian.h> /* for uint16be_t */
@@ -94,7 +94,7 @@ w5500ll_writev(
(block & CTL_MASK_BLOCK) | CTL_W | CTL_OM_VDM,
};
int inner_cnt = 1+io_slice_cnt(iov, iovcnt, skip, max);
- struct duplex_iovec *inner = alloca(sizeof(struct duplex_iovec)*inner_cnt);
+ struct duplex_iovec *inner = stack_alloc(inner_cnt, struct duplex_iovec);
inner[0] = (struct duplex_iovec){
.iov_read_to = IOVEC_DISCARD,
.iov_write_from = header,
@@ -131,7 +131,7 @@ w5500ll_readv(
(block & CTL_MASK_BLOCK) | CTL_R | CTL_OM_VDM,
};
int inner_cnt = 1+io_slice_cnt(iov, iovcnt, 0, max);
- struct duplex_iovec *inner = alloca(sizeof(struct duplex_iovec)*inner_cnt);
+ struct duplex_iovec *inner = stack_alloc(inner_cnt, struct duplex_iovec);
inner[0] = (struct duplex_iovec){
.iov_read_to = IOVEC_DISCARD,
.iov_write_from = header,
diff --git a/libmisc/CMakeLists.txt b/libmisc/CMakeLists.txt
index 4599ead..fdbe949 100644
--- a/libmisc/CMakeLists.txt
+++ b/libmisc/CMakeLists.txt
@@ -8,7 +8,9 @@ target_include_directories(libmisc PUBLIC INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/
target_sources(libmisc INTERFACE
assert.c
intercept.c
+ linkedlist.c
log.c
+ map.c
)
target_compile_options(libmisc INTERFACE "$<$<COMPILE_LANGUAGE:C>:-fplan9-extensions>")
@@ -18,5 +20,6 @@ add_lib_test(libmisc test_endian)
add_lib_test(libmisc test_hash)
add_lib_test(libmisc test_log)
add_lib_test(libmisc test_macro)
+add_lib_test(libmisc test_map)
add_lib_test(libmisc test_private)
add_lib_test(libmisc test_rand)
diff --git a/libmisc/include/libmisc/alloc.h b/libmisc/include/libmisc/alloc.h
new file mode 100644
index 0000000..afddbce
--- /dev/null
+++ b/libmisc/include/libmisc/alloc.h
@@ -0,0 +1,26 @@
+/* libmisc/alloc.h - Type-safe wrappers around alloca and malloc
+ *
+ * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _LIBMISC_ALLOC_H_
+#define _LIBMISC_ALLOC_H_
+
+#include <alloca.h> /* for alloca() */
+#include <stdlib.h> /* for calloc(), free() */
+#include <string.h> /* for memset() */
+
+#define stack_alloc(N, TYP) ({ \
+ size_t _size; \
+ TYP *_ret = NULL; \
+ if (!__builtin_mul_overflow(N, sizeof(TYP), &_size)) { \
+ _ret = alloca(_size); \
+ memset(_ret, 0, _size); \
+ } \
+ _ret; \
+})
+
+#define heap_alloc(N, TYP) ((TYP *)calloc(N, sizeof(TYP)))
+
+#endif /* _LIBMISC_ALLOC_H_ */
diff --git a/libmisc/include/libmisc/assert.h b/libmisc/include/libmisc/assert.h
index 8cf0735..ccdb288 100644
--- a/libmisc/include/libmisc/assert.h
+++ b/libmisc/include/libmisc/assert.h
@@ -1,6 +1,6 @@
/* libmisc/assert.h - More assertions
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@@ -10,15 +10,20 @@
#ifdef NDEBUG
# define __assert_msg(expr, expr_str, msg) ((void)0)
#else
-# define __assert_msg(expr, expr_str, msg) do { if (!(expr)) __assert_msg_fail(expr_str, __FILE__, __LINE__, __func__, msg); } while (0)
+# define __assert_msg(expr, expr_str, msg) \
+ do { \
+ if (!(expr)) \
+ __assert_msg_fail(expr_str, __FILE__, __LINE__, __func__, msg); \
+ } while (0)
[[noreturn]] void __assert_msg_fail(const char *expr,
const char *file, unsigned int line, const char *func,
const char *msg);
#endif
-#define assert_msg(expr, msg) __assert_msg(expr, #expr, msg) /* libmisc */
-#define assert(expr) __assert_msg(expr, #expr, 0) /* C89, POSIX-2001 */
-#define assert_notreached(msg) do { __assert_msg(0, "notreached", msg); __builtin_unreachable(); } while (0) /* libmisc */
-#define static_assert _Static_assert /* C11 */
+#define assert_msg(expr, msg) __assert_msg(expr, #expr, msg) /* libmisc */
+#define assert(expr) __assert_msg(expr, #expr, 0) /* C89, POSIX-2001 */
+#define assert_notreached(msg) do { __assert_msg(0, "notreached", msg); __builtin_unreachable(); } while (0) /* libmisc */
+#define static_assert _Static_assert /* C11 */
+#define static_assert_as_expr(...) (sizeof(struct {static_assert(__VA_ARGS__);})) /* libmisc */
#endif /* _LIBMISC_ASSERT_H_ */
diff --git a/libmisc/include/libmisc/linkedlist.h b/libmisc/include/libmisc/linkedlist.h
new file mode 100644
index 0000000..b6ff688
--- /dev/null
+++ b/libmisc/include/libmisc/linkedlist.h
@@ -0,0 +1,108 @@
+/* libmisc/linkedlist.h - Singly- and doubly- linked lists
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _LIBMISC_LINKEDLIST_H_
+#define _LIBMISC_LINKEDLIST_H_
+
+/* low-level (intrusive) singly linked list ***********************************/
+
+struct _slist_node {
+ struct _slist_node *rear;
+};
+
+struct _slist_root {
+ struct _slist_node *front, *rear;
+};
+
+void _slist_push_to_rear(struct _slist_root *root, struct _slist_node *node);
+void _slist_pop_from_front(struct _slist_root *root);
+
+/* low-level (intrusive) doubly linked list ***********************************/
+
+struct _dlist_node {
+ struct _dlist_node *front, *rear;
+};
+
+struct _dlist_root {
+ struct _dlist_node *front, *rear;
+};
+
+void _dlist_push_to_rear(struct _dlist_root *root, struct _dlist_node *node);
+void _dlist_remove(struct _dlist_root *root, struct _dlist_node *node);
+void _dlist_pop_from_front(struct _dlist_root *root);
+
+/* singly linked list (non-intrusive) *****************************************/
+
+#define SLIST_DECLARE(NAME) \
+ struct NAME##_node; \
+ struct NAME { \
+ struct NAME##_node *front, *rear; \
+ struct NAME *_slist_root_typ[0]; \
+ }
+
+#define SLIST_DECLARE_NODE(NAME, VAL_T) \
+ struct NAME##_node { \
+ struct NAME##_node *rear; \
+ VAL_T val; \
+ }
+
+#define slist_push_to_rear(ROOT, NODE) { \
+ /* These temporary variables are to get the compiler to check \
+ * the types. */ \
+ typeof(*(ROOT)->_slist_root_typ[0]) *_rootp = ROOT; \
+ typeof(*_rootp->front) *_nodep = NODE; \
+ _slist_push_to_rear((struct _slist_root *)_rootp, \
+ (struct _slist_node *)_nodep); \
+} while (0)
+
+#define slist_pop_from_front(ROOT) { \
+ /* This temporary variables are to get the compiler to check \
+ * the type. */ \
+ typeof(*(ROOT)->_slist_root_typ[0]) *_rootp = ROOT; \
+ _slist_pop_from_front((struct _slist_root *)_rootp); \
+} while (0)
+
+/* doubly linked list (non-intrusive) *****************************************/
+
+#define DLIST_DECLARE(NAME) \
+ struct NAME##_node; \
+ struct NAME { \
+ struct NAME##_node *front, *rear; \
+ struct NAME *_dlist_root_typ[0]; \
+ }
+
+#define DLIST_DECLARE_NODE(NAME, VAL_T) \
+ struct NAME##_node { \
+ struct NAME##_node *front, *rear; \
+ VAL_T val; \
+ }
+
+#define dlist_push_to_rear(ROOT, NODE) { \
+ /* These temporary variables are to get the compiler to check \
+ * the types. */ \
+ typeof(*(ROOT)->_dlist_root_typ[0]) *_rootp = ROOT; \
+ typeof(*_rootp->front) *_nodep = NODE; \
+ _dlist_push_to_rear((struct _dlist_root *)_rootp, \
+ (struct _dlist_node *)_nodep); \
+} while (0)
+
+#define dlist_remove(ROOT, NODE) { \
+ /* These temporary variables are to get the compiler to check \
+ * the types. */ \
+ typeof(*(ROOT)->_dlist_root_typ[0]) *_rootp = ROOT; \
+ typeof(*_rootp->front) *_nodep = NODE; \
+ _dlist_remove((struct _dlist_root *)_rootp, \
+ (struct _dlist_node *)_nodep); \
+} while (0)
+
+#define dlist_pop_from_front(ROOT) { \
+ /* This temporary variables are to get the compiler to check \
+ * the type. */ \
+ typeof(*(ROOT)->_dlist_root_typ[0]) *_rootp = ROOT; \
+ _dlist_pop_from_front((struct _dlist_root *)_rootp); \
+} while (0)
+
+#endif /* _LIBMISC_LINKEDLIST_H_ */
diff --git a/libmisc/include/libmisc/macro.h b/libmisc/include/libmisc/macro.h
index b3e235c..a95ac82 100644
--- a/libmisc/include/libmisc/macro.h
+++ b/libmisc/include/libmisc/macro.h
@@ -7,6 +7,8 @@
#ifndef _LIBMISC_MACRO_H_
#define _LIBMISC_MACRO_H_
+#include <libmisc/assert.h>
+
/* for function definitions */
#define LM_UNUSED(argname)
@@ -14,9 +16,22 @@
#define LM_NEVER_INLINE [[gnu::noinline]]
#define LM_FLATTEN [[gnu::flatten]]
+/* types */
+
+/* If it's a pointer instead of an array, then typeof(&ptr[0]) == typeof(ptr) */
+#define _LM_IS_ARRAY(ary) (!__builtin_types_compatible_p(typeof(&(ary)[0]), typeof(ary)))
+#define LM_ARRAY_LEN(ary) ( (sizeof(ary)/sizeof((ary)[0])) + static_assert_as_expr(_LM_IS_ARRAY(ary)) )
+
+#define LM_CAST_FIELD_TO_STRUCT(STRUCT_TYP, FIELD_NAME, PTR_TO_FIELD) ({ \
+ /* The _fptr assignment is to get the compiler to do type checking. */ \
+ typeof(((STRUCT_TYP *)NULL)->FIELD_NAME) *_fptr = (PTR_TO_FIELD); \
+ _fptr \
+ ? ((STRUCT_TYP*)( ((void*)_fptr) - offsetof(STRUCT_TYP, FIELD_NAME))) \
+ : NULL; \
+})
+
/* numeric */
-#define LM_ARRAY_LEN(ary) (sizeof(ary)/sizeof((ary)[0]))
#define LM_CEILDIV(n, d) ( ((n)+(d)-1) / (d) ) /** Return ceil(n/d) */
#define LM_ROUND_UP(n, d) ( LM_CEILDIV(n, d) * (d) ) /** Return `n` rounded up to the nearest multiple of `d` */
#define LM_ROUND_DOWN(n, d) ( ((n)/(d)) * (d) ) /** Return `n` rounded down to the nearest multiple of `d` */
diff --git a/libmisc/include/libmisc/map.h b/libmisc/include/libmisc/map.h
new file mode 100644
index 0000000..6622595
--- /dev/null
+++ b/libmisc/include/libmisc/map.h
@@ -0,0 +1,146 @@
+/* libmisc/map.h - A map/dict data structure
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _LIBMISC_MAP_H_
+#define _LIBMISC_MAP_H_
+
+#include <stdbool.h>
+#include <stddef.h> /* for size_t */
+#include <stdint.h> /* for uint8_t */
+
+#include <libmisc/linkedlist.h>
+
+/* Type ***********************************************************************/
+
+DLIST_DECLARE(_map_kv_list);
+
+struct _map {
+ size_t len;
+ size_t nbuckets;
+ struct _map_kv_list *buckets;
+
+ unsigned int iterating;
+
+ size_t sizeof_kv;
+ size_t offsetof_k, sizeof_k;
+ size_t offsetof_v, sizeof_v;
+};
+
+/**
+ * MAP_DECLARE(MAPNAME, KEY_T, VAL_T) declares `struct MAPNAME`.
+ */
+#define MAP_DECLARE(MAPNAME, KEY_T, VAL_T) \
+ struct _##MAPNAME##_kv { \
+ uint8_t flags; \
+ KEY_T key; \
+ VAL_T val; \
+ }; \
+ DLIST_DECLARE_NODE(_##MAPNAME##_kv_list, struct _##MAPNAME##_kv); \
+ struct MAPNAME { \
+ struct _map core; \
+ struct _##MAPNAME##_kv_list_node kv_typ[0]; \
+ }
+
+#define _map_init(M) do { \
+ if (!(M)->core.sizeof_kv) { \
+ (M)->core.sizeof_kv = sizeof((M)->kv_typ[0]); \
+ (M)->core.sizeof_k = sizeof((M)->kv_typ[0].val.key); \
+ (M)->core.sizeof_v = sizeof((M)->kv_typ[0].val.val); \
+ (M)->core.offsetof_k = offsetof(typeof((M)->kv_typ[0]), val.key); \
+ (M)->core.offsetof_v = offsetof(typeof((M)->kv_typ[0]), val.val); \
+ } \
+} while (0)
+
+/* Methods ********************************************************************/
+
+/**
+ * map_len(map) returns the number of entries currently in `map`.
+ */
+#define map_len(M) ((M)->core.len)
+
+/**
+ * map_load(map, key) returns a pointer to the value in `map`
+ * associated with `key`, or else NULL.
+ */
+#define map_load(M, K) ({ \
+ _map_init(M); \
+ typeof((M)->kv_typ[0].val.key) _k = K; \
+ (typeof((M)->kv_typ[0].val.val)*)_map_load(&(M)->core, &_k); \
+})
+void *_map_load(struct _map *m, void *kp);
+
+/**
+ * map_del(map, key) ensures that `key` is not present in `map`.
+ * Returns whether `key` was in `map` before the call.
+ */
+#define map_del(M, K) ({ \
+ _map_init(M); \
+ typeof((M)->kv_typ[0].val.key) _k = K; \
+ _map_del(&(M)->core, &_k); \
+})
+bool _map_del(struct _map *m, void *kp);
+
+/**
+ * map_store(map, key, val) sets a value in the map. Returns a
+ * pointer to the map's copy of `val`.
+ */
+#define map_store(M, K, ...) ({ \
+ _map_init(M); \
+ typeof((M)->kv_typ[0].val.key) _k = K; \
+ typeof((M)->kv_typ[0].val.val) _v = __VA_ARGS__; \
+ (typeof((M)->kv_typ[0].val.val)*)_map_store(&(M)->core, &_k, &_v); \
+})
+void *_map_store(struct _map *m, void *kp, void *vp);
+
+/**
+ * map_free(map) frees the memory associated with the map.
+ */
+#define map_free(M) _map_free(&(M)->core);
+void _map_free(struct _map *m);
+
+/* Iteration ******************************************************************/
+
+struct _map_iter {
+ struct _map *m;
+ void *keyp;
+ void **valpp;
+
+ size_t i;
+ struct _map_kv_list_node *kv;
+};
+
+/**
+ * MAP_FOREACH iterates over a map:
+ *
+ * MAP_FOREACH(MAP_EACH(MAP, key, valp)) {
+ * ...
+ * }
+ *
+ * It is safe to mutate the map with map_store() and, map_del() while
+ * iterating, but entries added by map_store() may or may not be
+ * visited by the iteration.
+ */
+#define MAP_FOREACH(M, KNAME, VNAME) _MAP_FOREACH(__COUNTER__, M, KNAME, VNAME)
+#define _MAP_FOREACH(CNT, M, KNAME, VNAME) \
+ for (bool _once_##CNT = true; _once_##CNT;) \
+ for (typeof((M)->kv_typ[0].val.key) KNAME; _once_##CNT;) \
+ for (typeof((M)->kv_typ[0].val.val) *VNAME; _once_##CNT;) \
+ for ( \
+ struct _map_iter _iter_##CNT = ({ \
+ _map_init(M); \
+ _map_iter_before(&(M)->core, &KNAME, (void**)&VNAME); \
+ }); \
+ _once_##CNT; \
+ ({ \
+ _once_##CNT = false; \
+ _map_iter_after(&_iter_##CNT); \
+ })) \
+ while (_map_iter_next(&_iter_##CNT))
+struct _map_iter _map_iter_before(struct _map *m, void *keyp, void **valpp);
+bool _map_iter_next(struct _map_iter *iter);
+void _map_iter_after(struct _map_iter *iter);
+
+#endif /* _LIBMISC_MAP_H_ */
diff --git a/libmisc/include/libmisc/rand.h b/libmisc/include/libmisc/rand.h
index bb1ec0b..7ef238b 100644
--- a/libmisc/include/libmisc/rand.h
+++ b/libmisc/include/libmisc/rand.h
@@ -1,6 +1,6 @@
/* libmisc/rand.h - Non-crytpographic random-number utilities
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
diff --git a/libmisc/linkedlist.c b/libmisc/linkedlist.c
new file mode 100644
index 0000000..71a0aa9
--- /dev/null
+++ b/libmisc/linkedlist.c
@@ -0,0 +1,64 @@
+/* libmisc/linkedlist.c - Singly- and doubly- linked lists
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <stddef.h> /* for NULL */
+
+#include <libmisc/assert.h>
+
+#include <libmisc/linkedlist.h>
+
+/* singly linked list *********************************************************/
+
+void _slist_push_to_rear(struct _slist_root *root, struct _slist_node *node) {
+ assert(root);
+ node->rear = NULL;
+ if (root->rear)
+ root->rear->rear = node;
+ else
+ root->front = node;
+ root->rear = node;
+}
+
+void _slist_pop_from_front(struct _slist_root *root) {
+ assert(root);
+ assert(root->front);
+ root->front = root->front->rear;
+ if (!root->front)
+ root->rear = NULL;
+}
+
+/* doubly linked list *********************************************************/
+
+void _dlist_push_to_rear(struct _dlist_root *root, struct _dlist_node *node) {
+ assert(root);
+ assert(node);
+ node->front = root->rear;
+ node->rear = NULL;
+ if (root->rear)
+ root->rear->rear = node;
+ else
+ root->front = node;
+ root->rear = node;
+}
+
+void _dlist_remove(struct _dlist_root *root, struct _dlist_node *node) {
+ assert(root);
+ assert(node);
+ if (node->front)
+ node->front->rear = node->rear;
+ else
+ root->front = node->rear;
+ if (node->rear)
+ node->rear->front = node->front;
+ else
+ root->rear = node->front;
+}
+
+void _dlist_pop_from_front(struct _dlist_root *root) {
+ assert(root);
+ assert(root->front);
+ _dlist_remove(root, root->front);
+}
diff --git a/libmisc/map.c b/libmisc/map.c
new file mode 100644
index 0000000..cc34c16
--- /dev/null
+++ b/libmisc/map.c
@@ -0,0 +1,230 @@
+/* libmisc/map.c - A map/dict data structure
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libmisc/hash.h>
+#include <libmisc/alloc.h>
+#include <libmisc/assert.h>
+#include <libmisc/map.h>
+
+#define FLAG_ITER (UINT8_C(1)<<0)
+#define FLAG_DEL (UINT8_C(1)<<1)
+
+/* Internal utilities *********************************************************/
+
+struct _map_kv {
+ uint8_t flags;
+ /* opaque key; */
+ /* opaque val; */
+};
+DLIST_DECLARE_NODE(_map_kv_list, struct _map_kv);
+
+static inline void *_map_kv_keyp(struct _map *m, struct _map_kv_list_node *kv) {
+ assert(m);
+ assert(kv);
+ return ((void*)kv)+m->offsetof_k;
+}
+static inline void *_map_kv_valp(struct _map *m, struct _map_kv_list_node *kv) {
+ assert(m);
+ assert(kv);
+ return ((void*)kv)+m->offsetof_v;
+}
+
+static inline void _map_lookup(struct _map *m, void *keyp,
+ hash_t *ret_hash,
+ struct _map_kv_list **ret_bucket,
+ struct _map_kv_list_node **ret_kv) {
+ assert(m);
+ assert(keyp);
+ assert(ret_hash);
+ assert(ret_bucket);
+ assert(ret_kv);
+ *ret_hash = hash(keyp, m->sizeof_k);
+ if (m->nbuckets == 0) {
+ *ret_bucket = NULL;
+ *ret_kv = NULL;
+ return;
+ }
+ *ret_bucket = &m->buckets[*ret_hash % m->nbuckets];
+ for (struct _map_kv_list_node *kv = (*ret_bucket)->front; kv; kv = kv->rear) {
+ if (!(kv->val.flags & FLAG_DEL) &&
+ memcmp(_map_kv_keyp(m, kv), keyp, m->sizeof_k) == 0) {
+ *ret_kv = kv;
+ return;
+ }
+ }
+ *ret_kv = NULL;
+}
+
+static inline void _map_resize(struct _map *m, size_t new_nbuckets) {
+ assert(m);
+ assert(new_nbuckets);
+ struct _map_kv_list *new_buckets = heap_alloc(new_nbuckets, struct _map_kv_list);
+ for (size_t i = 0; i < m->nbuckets; i++) {
+ while (m->buckets[i].front) {
+ struct _map_kv_list_node *kv = m->buckets[i].front;
+ dlist_pop_from_front(&m->buckets[i]);
+ hash_t h = hash(_map_kv_keyp(m, kv), m->sizeof_k);
+ dlist_push_to_rear(&new_buckets[h % new_nbuckets], kv);
+ }
+ }
+ m->nbuckets = new_nbuckets;
+ free(m->buckets);
+ m->buckets = new_buckets;
+}
+
+static bool _map_autoresize(struct _map *m) {
+ assert(m);
+ if (m->len > (m->nbuckets * 8/10)) {
+ size_t nbuckets = 1;
+ while (m->len > (nbuckets * 8/10))
+ nbuckets <<= 1;
+ _map_resize(m, nbuckets);
+ return true;
+ }
+ return false;
+}
+
+/* Methods ********************************************************************/
+
+void *_map_load(struct _map *m, void *keyp) {
+ assert(m);
+ assert(keyp);
+
+ hash_t h;
+ struct _map_kv_list *bucket;
+ struct _map_kv_list_node *kv;
+ _map_lookup(m, keyp, &h, &bucket, &kv);
+
+ if (!kv)
+ return NULL;
+ return _map_kv_valp(m, kv);
+}
+
+bool _map_del(struct _map *m, void *keyp) {
+ assert(m);
+ assert(keyp);
+
+ hash_t h;
+ struct _map_kv_list *bucket;
+ struct _map_kv_list_node *kv;
+ _map_lookup(m, keyp, &h, &bucket, &kv);
+
+ if (!kv)
+ return false;
+ if (kv->val.flags & FLAG_ITER) {
+ kv->val.flags |= FLAG_DEL;
+ } else {
+ dlist_remove(bucket, kv);
+ free(kv);
+ }
+ m->len--;
+ return true;
+}
+
+void *_map_store(struct _map *m, void *keyp, void *valp) {
+ assert(m);
+ assert(keyp);
+ assert(valp);
+
+ hash_t h;
+ struct _map_kv_list *bucket;
+ struct _map_kv_list_node *old;
+ _map_lookup(m, keyp, &h, &bucket, &old);
+
+ if (old) {
+ dlist_remove(bucket, old);
+ free(old);
+ m->len--;
+ }
+ m->len++;
+ if (!m->iterating && _map_autoresize(m)) {
+ h = hash(keyp, m->sizeof_k);
+ bucket = &m->buckets[h % m->nbuckets];
+ }
+ struct _map_kv_list_node *kv = calloc(1, m->sizeof_kv);
+ memcpy(_map_kv_keyp(m, kv), keyp, m->sizeof_k);
+ memcpy(_map_kv_valp(m, kv), valp, m->sizeof_v);
+ dlist_push_to_rear(bucket, kv);
+ return _map_kv_valp(m, kv);
+}
+
+void _map_free(struct _map *m) {
+ assert(m);
+
+ for (size_t i = 0; i < m->nbuckets; i++) {
+ while (m->buckets[i].front) {
+ struct _map_kv_list_node *kv = m->buckets[i].front;
+ dlist_pop_from_front(&m->buckets[i]);
+ free(kv);
+ }
+ }
+ free(m->buckets);
+ m->len = 0;
+ m->nbuckets = 0;
+ m->buckets = NULL;
+}
+
+/* Iteration ******************************************************************/
+
+struct _map_iter _map_iter_before(struct _map *m, void *keyp, void **valpp) {
+ assert(m);
+ assert(keyp);
+ assert(valpp);
+
+ struct _map_iter state = {
+ .m = m,
+ .keyp = keyp,
+ .valpp = valpp,
+ };
+ m->iterating++;
+ return state;
+}
+
+void _map_iter_after(struct _map_iter *state) {
+ assert(state);
+ assert(state->m);
+
+ state->m->iterating--;
+ if (!state->m->iterating)
+ _map_autoresize(state->m);
+}
+
+bool _map_iter_next(struct _map_iter *state) {
+ assert(state);
+ assert(state->m);
+ assert(state->valpp);
+
+ if (!state->kv) {
+ if (!state->m->len)
+ return false;
+ while (!state->m->buckets[state->i].front)
+ state->i++;
+ state->kv = state->m->buckets[state->i].front;
+ } else {
+ struct _map_kv_list_node *old_kv = state->kv;
+ state->kv = old_kv->rear;
+
+ old_kv->val.flags &= ~FLAG_ITER;
+ if (old_kv->val.flags & FLAG_DEL) {
+ dlist_remove(&state->m->buckets[state->i], old_kv);
+ free(old_kv);
+ }
+
+ while (!state->kv) {
+ state->i++;
+ if (state->i == state->m->nbuckets)
+ return false;
+ state->kv = state->m->buckets[state->i].front;
+ }
+ }
+ state->kv->val.flags |= FLAG_ITER;
+ memcpy(state->keyp, _map_kv_keyp(state->m, state->kv), state->m->sizeof_k);
+ *(state->valpp) = _map_kv_valp(state->m, state->kv);
+ return true;
+}
diff --git a/libmisc/tests/test_map.c b/libmisc/tests/test_map.c
new file mode 100644
index 0000000..855dace
--- /dev/null
+++ b/libmisc/tests/test_map.c
@@ -0,0 +1,60 @@
+/* libmisc/tests/test_map.c - Tests for <libmisc/map.h>
+ *
+ * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libmisc/map.h>
+
+#include "test.h"
+
+MAP_DECLARE(intmap, int, int);
+
+int main() {
+ struct intmap m = {};
+ test_assert(map_len(&m) == 0);
+
+ int *v = map_store(&m, 3, 8);
+ test_assert(v && *v == 8);
+ test_assert(map_len(&m) == 1);
+
+ v = map_load(&m, 3);
+ test_assert(v);
+ test_assert(*v == 8);
+
+ v = NULL;
+
+ test_assert(map_del(&m, 3));
+ test_assert(map_len(&m) == 0);
+ test_assert(!map_del(&m, 3));
+
+ map_store(&m, 1, 11);
+ map_store(&m, 2, 12);
+ map_store(&m, 3, 13);
+ test_assert(map_len(&m) == 3);
+ bool seen_1 = false, seen_2 = false, seen_3 = false;
+ MAP_FOREACH(&m, ik, iv) {
+ switch (ik) {
+ case 1: seen_1 = true; break;
+ case 2: seen_2 = true; break;
+ case 3: seen_3 = true; break;
+ }
+ switch (ik) {
+ case 1: case 2: case 3:
+ map_store(&m, ik+20, (*iv)+20);
+ test_assert(map_del(&m, ik));
+ test_assert(!map_del(&m, ik));
+ test_assert(map_load(&m, ik) == NULL);
+ break;
+ }
+ }
+ test_assert(map_len(&m) == 3);
+ test_assert(seen_1); v = map_load(&m, 21); test_assert(v && *v == 31); v = map_load(&m, 1); test_assert(!v);
+ test_assert(seen_2); v = map_load(&m, 22); test_assert(v && *v == 32); v = map_load(&m, 2); test_assert(!v);
+ test_assert(seen_3); v = map_load(&m, 23); test_assert(v && *v == 33); v = map_load(&m, 3); test_assert(!v);
+
+ map_free(&m);
+ test_assert(map_len(&m) == 0);
+
+ return 0;
+}
diff --git a/libmisc/tests/test_private.c b/libmisc/tests/test_private.c
index 9b39932..024dddb 100644
--- a/libmisc/tests/test_private.c
+++ b/libmisc/tests/test_private.c
@@ -1,6 +1,6 @@
/* libmisc/tests/test_private.c - Tests for <libmisc/private.h>
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
diff --git a/libusb/CMakeLists.txt b/libusb/CMakeLists.txt
index 9be44ac..b11e798 100644
--- a/libusb/CMakeLists.txt
+++ b/libusb/CMakeLists.txt
@@ -1,6 +1,6 @@
# libusb/CMakeLists.txt - Build script for libusb support library
#
-# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
add_library(libusb INTERFACE)
diff --git a/libusb/include/libusb/tusb_helpers.h b/libusb/include/libusb/tusb_helpers.h
index 1b4e48e..0c35f62 100644
--- a/libusb/include/libusb/tusb_helpers.h
+++ b/libusb/include/libusb/tusb_helpers.h
@@ -1,7 +1,7 @@
/* Generated by `libusb/include/libusb/tusb_helpers.h.gen `. DO NOT EDIT! */
/* libusb/tusb_helpers.h - Preprocessor macros that I think should be included in TinyUSB
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
*
* SPDX-License-Identifier: MIT
*
diff --git a/libusb/include/libusb/tusb_helpers.h.gen b/libusb/include/libusb/tusb_helpers.h.gen
index 5a5d1ac..1de1d09 100755
--- a/libusb/include/libusb/tusb_helpers.h.gen
+++ b/libusb/include/libusb/tusb_helpers.h.gen
@@ -7,7 +7,7 @@ echo "/* Generated by \`$0 $*\`. DO NOT EDIT! */"
cat <<'EOT'
/* libusb/tusb_helpers.h - Preprocessor macros that I think should be included in TinyUSB
*
- * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
*
* SPDX-License-Identifier: MIT
*
@@ -70,12 +70,19 @@ fi
if [[ ! -f 3rd-party/MS-LCID.txt || 3rd-party/MS-LCID.txt -ot 3rd-party/MS-LCID.pdf ]]; then
pdftotext -layout 3rd-party/MS-LCID.pdf
fi
-<3rd-party/MS-LCID.txt \
- grep -E '^\s*0x[0-9A-F]{4}\s+[a-z]' | sed 's/,.*//' | grep -v reserved | # find the lines we're interested in
- sed -E 's/^\s*0x(..)(..)\s+(\S.*)/\2 \1 \3/p' | tr '[:lower:]-' '[:upper:]_' | # format them as 'PRIhex SUBhex UPPER_STR'
- sort |
- sed -E 's/(..) (..) (.*)/#define LANGID_\3 0x\2\1/' | # format them as '#define LANGID_UPPER_STR 0xSUBPRI'
- column --table --output-separator=' '
+{
+ {
+ # find the lines we're interested in
+ grep -E '^\s*0x[0-9A-F]{4}\s+[a-z]' | sed 's/,.*//' | grep -v reserved
+ } | {
+ # format them as 'PRIhex SUBhex UPPER_STR'
+ sed -E 's/^\s*0x(..)(..)\s+(\S.*)/\2 \1 \3/p' | tr '[:lower:]-' '[:upper:]_'
+ } | sort | {
+ # format them as '#define LANGID_UPPER_STR 0xSUBPRI'
+ sed -E 's/(..) (..) (.*)/#define LANGID_\3 0x\2\1/' |
+ column --table --output-separator=' '
+ }
+} <3rd-party/MS-LCID.txt
cat <<'EOT'
/** USB 2.0 ยง9.6.6 "Endpoint", field bEndpointAddress, bit 7 */
diff --git a/notes.md b/notes.md
index 8f2f44c..84c2e72 100644
--- a/notes.md
+++ b/notes.md
@@ -187,3 +187,7 @@ OpenBMC
- Sipeed NanoKVM
- https://github.com/stefanklug/picoKVM (~$20 Arduino, ~$5 HDMI
capture), non-IP
+
+----
+
+https://hackaday.com/2022/08/26/bit-banged-ethernet-on-the-raspberry-pi-pico/