From f132dab76a07473d41e14f5f4fb1857a3229ec6a Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Thu, 17 Oct 2024 14:31:03 -0600 Subject: libmisc --- CMakeLists.txt | 2 +- cmd/sbc_harness/CMakeLists.txt | 2 +- cmd/sbc_harness/hw/rp2040_hwspi.c | 8 +- cmd/sbc_harness/hw/rp2040_hwspi.h | 2 +- cmd/sbc_harness/hw/spi.h | 7 +- cmd/sbc_harness/hw/w5500.c | 40 +- cmd/sbc_harness/hw/w5500.h | 18 +- cmd/sbc_harness/main.c | 4 +- cmd/srv9p/CMakeLists.txt | 2 +- cmd/srv9p/gnet.c | 33 +- cmd/srv9p/gnet.h | 8 +- cmd/srv9p/main.c | 30 +- cmd/srv9p/static9p.c | 156 ++--- cmd/srv9p/static9p.h | 10 +- lib9o/CMakeLists.txt | 8 - lib9o/include/lib9o/lib9o.h | 27 - lib9p/9p.c | 28 +- lib9p/9p.generated.c | 1206 ++++++++++++++++++++++++++++-------- lib9p/CMakeLists.txt | 2 +- lib9p/idl.gen | 56 +- lib9p/include/lib9p/9p.generated.h | 2 - lib9p/include/lib9p/9p.h | 2 + lib9p/include/lib9p/srv.h | 38 +- lib9p/internal.h | 13 +- lib9p/srv.c | 64 +- libmisc/CMakeLists.txt | 8 + libmisc/include/libmisc/net.h | 64 ++ libmisc/include/libmisc/vcall.h | 27 + libnet/CMakeLists.txt | 7 - libnet/include/libnet/libnet.h | 70 --- 30 files changed, 1305 insertions(+), 639 deletions(-) delete mode 100644 lib9o/CMakeLists.txt delete mode 100644 lib9o/include/lib9o/lib9o.h create mode 100644 libmisc/CMakeLists.txt create mode 100644 libmisc/include/libmisc/net.h create mode 100644 libmisc/include/libmisc/vcall.h delete mode 100644 libnet/CMakeLists.txt delete mode 100644 libnet/include/libnet/libnet.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 83341d5..2c9bead 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ add_compile_options(-Wall -Wextra -Werror) add_subdirectory(libcr) add_subdirectory(libcr_ipc) add_subdirectory(libusb) -add_subdirectory(libnet) +add_subdirectory(libmisc) add_subdirectory(lib9p) add_subdirectory(cmd/${_UBUILD_CMD}) diff --git a/cmd/sbc_harness/CMakeLists.txt b/cmd/sbc_harness/CMakeLists.txt index 04f231d..c42fecb 100644 --- a/cmd/sbc_harness/CMakeLists.txt +++ b/cmd/sbc_harness/CMakeLists.txt @@ -18,8 +18,8 @@ target_link_libraries(sbc_harness hardware_spi hardware_gpio + libmisc libusb - libnet ) pico_enable_stdio_usb(sbc_harness 0) diff --git a/cmd/sbc_harness/hw/rp2040_hwspi.c b/cmd/sbc_harness/hw/rp2040_hwspi.c index e6e4566..dd9a577 100644 --- a/cmd/sbc_harness/hw/rp2040_hwspi.c +++ b/cmd/sbc_harness/hw/rp2040_hwspi.c @@ -10,9 +10,11 @@ #include /* pico-sdk:hardware_spi */ #include /* pico-sdk:hardware_gpio5 */ +#include + #include "hw/rp2040_hwspi.h" -static void rp2040_hwspi_readwritev(struct spi *_self, const struct bidi_iovec *iov, int iovcnt); +static void rp2040_hwspi_readwritev(implements_spi *, const struct bidi_iovec *iov, int iovcnt); struct spi_vtable rp2040_hwspi_vtable = { .readwritev = rp2040_hwspi_readwritev, @@ -96,8 +98,8 @@ void _rp2040_hwspi_init(struct rp2040_hwspi *self, self->pin_cs = pin_cs; } -static void rp2040_hwspi_readwritev(struct spi *_self, const struct bidi_iovec *iov, int iovcnt) { - struct rp2040_hwspi *self = (struct rp2040_hwspi *)_self; +static void rp2040_hwspi_readwritev(implements_spi *_self, const struct bidi_iovec *iov, int iovcnt) { + struct rp2040_hwspi *self = VCALL_SELF(struct rp2040_hwspi, implements_spi, _self); assert(self); spi_inst_t *inst = self->inst; diff --git a/cmd/sbc_harness/hw/rp2040_hwspi.h b/cmd/sbc_harness/hw/rp2040_hwspi.h index 8793fd6..8bf783f 100644 --- a/cmd/sbc_harness/hw/rp2040_hwspi.h +++ b/cmd/sbc_harness/hw/rp2040_hwspi.h @@ -18,7 +18,7 @@ enum rp2040_hwspi_instance { }; struct rp2040_hwspi { - struct spi_vtable *vtable; + implements_spi; void /*spi_inst_t*/ *inst; uint pin_cs; diff --git a/cmd/sbc_harness/hw/spi.h b/cmd/sbc_harness/hw/spi.h index 86b831e..653e80f 100644 --- a/cmd/sbc_harness/hw/spi.h +++ b/cmd/sbc_harness/hw/spi.h @@ -40,11 +40,8 @@ struct spi_vtable { void (*readwritev)(struct spi *, const struct bidi_iovec *iov, int iovcnt); }; -struct spi { +typedef struct spi { struct spi_vtable *vtable; - - /* This is where your implementation data goes. */ - char data[0]; -}; +} implements_spi; #endif /* _HW_SPI_H_ */ diff --git a/cmd/sbc_harness/hw/w5500.c b/cmd/sbc_harness/hw/w5500.c index e32c589..8e3dab0 100644 --- a/cmd/sbc_harness/hw/w5500.c +++ b/cmd/sbc_harness/hw/w5500.c @@ -1,4 +1,4 @@ -/* hw/w5500.c - libnet implementation for the WIZnet W5500 chip +/* hw/w5500.c - libmisc/net.h implementation for the WIZnet W5500 chip * * Copyright (C) 2024 Luke T. Shumaker * SPDX-Licence-Identifier: AGPL-3.0-or-later @@ -42,6 +42,8 @@ #include /* pico-sdk:hardware_gpio5 */ #include +#include + #include "hw/w5500.h" #include "config.h" @@ -110,7 +112,7 @@ void w5500_spiframe_write(struct spi *spidev, uint16_t addr, uint8_t block, void {.iov_read_dst = NULL, .iov_write_src = header, .iov_len = sizeof(header)}, {.iov_read_dst = NULL, .iov_write_src = data, .iov_len = data_len}, }; - spidev->vtable->readwritev(spidev, iov, 2); + VCALL(spidev, readwritev, iov, 2); } void w5500_spiframe_read(struct spi *spidev, uint16_t addr, uint8_t block, void *data, size_t data_len) { @@ -128,7 +130,7 @@ void w5500_spiframe_read(struct spi *spidev, uint16_t addr, uint8_t block, void {.iov_read_dst = NULL, .iov_write_src = header, .iov_len = sizeof(header)}, {.iov_read_dst = data, .iov_write_src = NULL, .iov_len = data_len}, }; - spidev->vtable->readwritev(spidev, iov, 2); + VCALL(spidev, readwritev, iov, 2); } /* Offsets and sizes for use with that protocol. *****************************/ @@ -357,16 +359,16 @@ static_assert(sizeof(struct w5500_block_sock_reg) == 0x30); /* init() *********************************************************************/ -static struct libnet_conn *w5500_accept(struct libnet_listener *_listener); -static ssize_t w5500_read(struct libnet_conn *conn, void *buf, size_t count); -static ssize_t w5500_write(struct libnet_conn *conn, void *buf, size_t count); -static int w5500_close(struct libnet_conn *conn, bool rd, bool wr); +static implements_net_conn *w5500_accept(implements_net_listener *_listener); +static ssize_t w5500_read(implements_net_conn *conn, void *buf, size_t count); +static ssize_t w5500_write(implements_net_conn *conn, void *buf, size_t count); +static int w5500_close(implements_net_conn *conn, bool rd, bool wr); -static struct libnet_listener_vtable w5500_listener_vtable = { +static struct net_listener_vtable w5500_listener_vtable = { .accept = w5500_accept, }; -static struct libnet_conn_vtable w5500_conn_vtable = { +static struct net_conn_vtable w5500_conn_vtable = { .read = w5500_read, .write = w5500_write, .close = w5500_close, @@ -381,7 +383,7 @@ uint16_t w5500_get_local_port(struct w5500 *self) { void _w5500_init(struct w5500 *chip, struct spi* spi, uint pin_intr, uint pin_reset, - struct eth_addr addr) { + struct net_eth_addr addr) { chip->spidev = spi; chip->pin_reset = pin_reset; for (uint8_t i = 0; i < 8; i++) { @@ -418,12 +420,12 @@ void w5500_netcfg(struct w5500 *chip, struct w5500_netcfg cfg) { /* listen() *******************************************************************/ -struct libnet_listener *w5500_listen(struct w5500 *chip, uint8_t socknum, uint16_t port) { +implements_net_listener *w5500_listen(struct w5500 *chip, uint8_t socknum, uint16_t port) { assert(chip); assert(socknum < 8); assert(port); - w5500_close((struct libnet_conn *)&chip->_listeners[socknum].active_conn, true, true); + w5500_close(&chip->_listeners[socknum].active_conn, true, true); REGWRITE_SOCK(chip->spidev, socknum, mode, MODE_TCP); REGWRITE_SOCK(chip->spidev, socknum, local_port, ((uint8_t[2]){port>>8, port})); REGWRITE_SOCK(chip->spidev, socknum, command, CMD_OPEN); @@ -432,13 +434,13 @@ struct libnet_listener *w5500_listen(struct w5500 *chip, uint8_t socknum, uint16 while (REGREAD_SOCK(chip->spidev, socknum, state, uint8_t) != STATE_TCP_INIT) cr_yield(); - return (struct libnet_listener *)&chip->_listeners[socknum]; + return &chip->_listeners[socknum]; } /* accept() *******************************************************************/ #define ASSERT_LISTENER() \ - struct _w5500_listener *self = (struct _w5500_listener *)_self; \ + struct _w5500_listener *self = VCALL_SELF(struct _w5500_listener, implements_net_listener, _self); \ assert(self); \ \ struct w5500 *chip = self->chip; \ @@ -446,7 +448,7 @@ struct libnet_listener *w5500_listen(struct w5500 *chip, uint8_t socknum, uint16 assert(chip); \ assert(socknum < 8) -static struct libnet_conn *w5500_accept(struct libnet_listener *_self) { +static implements_net_conn *w5500_accept(implements_net_listener *_self) { ASSERT_LISTENER(); REGWRITE_SOCK(chip->spidev, socknum, command, CMD_LISTEN); @@ -460,7 +462,7 @@ static struct libnet_conn *w5500_accept(struct libnet_listener *_self) { cr_yield(); break; default: - return (struct libnet_conn *)&self->active_conn; + return &self->active_conn; } } } @@ -468,7 +470,7 @@ static struct libnet_conn *w5500_accept(struct libnet_listener *_self) { /* write() ********************************************************************/ #define ASSERT_CONN() \ - struct _w5500_conn *self = (struct _w5500_conn *)_self; \ + struct _w5500_conn *self = VCALL_SELF(struct _w5500_conn, implements_net_conn, _self); \ assert(self); \ \ struct w5500 *chip = self->parent_listener->chip; \ @@ -476,7 +478,7 @@ static struct libnet_conn *w5500_accept(struct libnet_listener *_self) { assert(chip); \ assert(socknum < 8) -static ssize_t w5500_write(struct libnet_conn *_self, void *buf, size_t count) { +static ssize_t w5500_write(implements_net_conn *_self, void *buf, size_t count) { ASSERT_CONN(); assert(buf); assert(count); @@ -484,7 +486,7 @@ static ssize_t w5500_write(struct libnet_conn *_self, void *buf, size_t count) { // TODO } -static int w5500_close(struct libnet_conn *_self, bool rd, bool wr) { +static int w5500_close(implements_net_conn *_self, bool rd, bool wr) { ASSERT_CONN(); REGWRITE_SOCK(chip->spidev, socknum, command, CMD_CLOSE); diff --git a/cmd/sbc_harness/hw/w5500.h b/cmd/sbc_harness/hw/w5500.h index bb629c5..4ec6edd 100644 --- a/cmd/sbc_harness/hw/w5500.h +++ b/cmd/sbc_harness/hw/w5500.h @@ -1,4 +1,4 @@ -/* hw/w5500.h - libnet implementation for the WIZnet W5500 chip +/* hw/w5500.h - libmisc/net.h implementation for the WIZnet W5500 chip * * Copyright (C) 2024 Luke T. Shumaker * SPDX-Licence-Identifier: AGPL-3.0-or-later @@ -7,20 +7,20 @@ #ifndef _HW_W5500_H_ #define _HW_W5500_H_ -#include +#include #include "hw/spi.h" struct _w5500_listener; struct _w5500_conn { - struct libnet_conn_vtable *vtable; + implements_net_conn; struct _w5500_listener *parent_listener; }; struct _w5500_listener { - struct libnet_listener_vtable *vtable; + implements_net_listener; struct w5500 *chip; uint8_t socknum; @@ -56,7 +56,7 @@ struct w5500 { } while (0) void _w5500_init(struct w5500 *self, struct spi* spi, uint pin_intr, uint pin_reset, - struct eth_addr addr); + struct net_eth_addr addr); /** * TODO. @@ -64,9 +64,9 @@ void _w5500_init(struct w5500 *self, void w5500_reset(struct w5500 *self); struct w5500_netcfg { - struct ip4_addr gateway_addr; - struct ip4_addr subnet_mask; - struct ip4_addr addr; + struct net_ip4_addr gateway_addr; + struct net_ip4_addr subnet_mask; + struct net_ip4_addr addr; }; /** @@ -74,6 +74,6 @@ struct w5500_netcfg { */ void w5500_netcfg(struct w5500 *self, struct w5500_netcfg cfg); -struct libnet_listener *w5500_listen(struct w5500 *self, uint8_t socknum, uint16_t port); +implements_net_listener *w5500_listen(struct w5500 *self, uint8_t socknum, uint16_t port); #endif /* _HW_W5500_H_ */ diff --git a/cmd/sbc_harness/main.c b/cmd/sbc_harness/main.c index 9564665..c6df8f5 100644 --- a/cmd/sbc_harness/main.c +++ b/cmd/sbc_harness/main.c @@ -44,10 +44,10 @@ int main() { 19, /* PIN_MOSI */ 18, /* PIN_CLK */ 17); /* PIN_CS */ - w5500_init(&dev_w5500, "W5500", (struct spi *)&dev_spi, + w5500_init(&dev_w5500, "W5500", &dev_spi, 21, /* PIN_INTR */ 20, /* PIN_RESET */ - ((struct eth_addr){{0xDE,0xAD,0xBE,0xEF,0x01,0x02}})); + ((struct net_eth_addr){{0xDE,0xAD,0xBE,0xEF,0x01,0x02}})); usb_common_earlyinit(); usb_keyboard_init(); diff --git a/cmd/srv9p/CMakeLists.txt b/cmd/srv9p/CMakeLists.txt index 61bd5c2..52e5171 100644 --- a/cmd/srv9p/CMakeLists.txt +++ b/cmd/srv9p/CMakeLists.txt @@ -18,7 +18,7 @@ target_include_directories(srv9p PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/config) target_link_libraries(srv9p libcr libcr_ipc - libnet + libmisc lib9p ) diff --git a/cmd/srv9p/gnet.c b/cmd/srv9p/gnet.c index 92e74c7..d7e8717 100644 --- a/cmd/srv9p/gnet.c +++ b/cmd/srv9p/gnet.c @@ -1,4 +1,4 @@ -/* srv9p/gnet.c - libnet implementation for libcr + GNU libc +/* srv9p/gnet.c - libmisc/net.h implementation for libcr + GNU libc * * Copyright (C) 2024 Luke T. Shumaker * SPDX-Licence-Identifier: AGPL-3.0-or-later @@ -20,6 +20,7 @@ #include /* for siginfo_t, struct sigaction, enum sigval, sigaction(), SIGRTMIN, SIGRTMAX, SA_SIGINFO */ #include +#include #include "gnet.h" @@ -71,16 +72,16 @@ static inline bool RUN_PTHREAD(void *(*fn)(void *), void *args) { /* init() ( AKA socket(3) + listen(3) )****************************************/ -static struct libnet_conn *gnet_accept(struct libnet_listener *_listener); -static ssize_t gnet_read(struct libnet_conn *conn, void *buf, size_t count); -static ssize_t gnet_write(struct libnet_conn *conn, void *buf, size_t count); -static int gnet_close(struct libnet_conn *conn, bool rd, bool wr); +static implements_net_conn *gnet_accept(implements_net_listener *_listener); +static ssize_t gnet_read(implements_net_conn *conn, void *buf, size_t count); +static ssize_t gnet_write(implements_net_conn *conn, void *buf, size_t count); +static int gnet_close(implements_net_conn *conn, bool rd, bool wr); -static struct libnet_listener_vtable gnet_listener_vtable = { +static struct net_listener_vtable gnet_listener_vtable = { .accept = gnet_accept, }; -static struct libnet_conn_vtable gnet_conn_vtable = { +static struct net_conn_vtable gnet_conn_vtable = { .read = gnet_read, .write = gnet_write, .close = gnet_close, @@ -131,8 +132,8 @@ static void *_pthread_accept(void *_args) { return NULL; }; -static struct libnet_conn *gnet_accept(struct libnet_listener *_listener) { - struct gnet_listener *listener = (struct gnet_listener *)_listener; +static implements_net_conn *gnet_accept(implements_net_listener *_listener) { + struct gnet_listener *listener = VCALL_SELF(struct gnet_listener, implements_net_listener, _listener); assert(listener); int ret_connfd; @@ -147,7 +148,7 @@ static struct libnet_conn *gnet_accept(struct libnet_listener *_listener) { listener->active_conn.vtable = &gnet_conn_vtable; listener->active_conn.fd = ret_connfd; - return (struct libnet_conn *)&listener->active_conn; + return &listener->active_conn; } /* read() *********************************************************************/ @@ -172,8 +173,8 @@ static void *_pthread_read(void *_args) { return NULL; }; -static ssize_t gnet_read(struct libnet_conn *_conn, void *buf, size_t count) { - struct _gnet_conn *conn = (struct _gnet_conn *)_conn; +static ssize_t gnet_read(implements_net_conn *_conn, void *buf, size_t count) { + struct _gnet_conn *conn = VCALL_SELF(struct _gnet_conn, implements_net_conn, _conn); assert(conn); ssize_t ret; @@ -222,8 +223,8 @@ static void *_pthread_write(void *_args) { return NULL; }; -static ssize_t gnet_write(struct libnet_conn *_conn, void *buf, size_t count) { - struct _gnet_conn *conn = (struct _gnet_conn *)_conn; +static ssize_t gnet_write(implements_net_conn *_conn, void *buf, size_t count) { + struct _gnet_conn *conn = VCALL_SELF(struct _gnet_conn, implements_net_conn, _conn); assert(conn); ssize_t ret; @@ -244,8 +245,8 @@ static ssize_t gnet_write(struct libnet_conn *_conn, void *buf, size_t count) { /* close() ********************************************************************/ -static int gnet_close(struct libnet_conn *_conn, bool rd, bool wr) { - struct _gnet_conn *conn = (struct _gnet_conn *)_conn; +static int gnet_close(implements_net_conn *_conn, bool rd, bool wr) { + struct _gnet_conn *conn = VCALL_SELF(struct _gnet_conn, implements_net_conn, _conn); assert(conn); int how; diff --git a/cmd/srv9p/gnet.h b/cmd/srv9p/gnet.h index d43874f..01f2d40 100644 --- a/cmd/srv9p/gnet.h +++ b/cmd/srv9p/gnet.h @@ -1,4 +1,4 @@ -/* srv9p/gnet.h - libnet implementation for libcr + GNU libc +/* srv9p/gnet.h - libmisc/net.h implementation for libcr + GNU libc * * Copyright (C) 2024 Luke T. Shumaker * SPDX-Licence-Identifier: AGPL-3.0-or-later @@ -9,16 +9,16 @@ #include /* for uint16_6 */ -#include +#include struct _gnet_conn { - struct libnet_conn_vtable *vtable; + implements_net_conn; int fd; }; struct gnet_listener { - struct libnet_listener_vtable *vtable; + implements_net_listener; int fd; struct _gnet_conn active_conn; diff --git a/cmd/srv9p/main.c b/cmd/srv9p/main.c index ae0e34e..d83fac4 100644 --- a/cmd/srv9p/main.c +++ b/cmd/srv9p/main.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include "static9p.h" @@ -29,8 +29,8 @@ /* file tree ******************************************************************/ -#define FILE_METADATA(NAME) { \ - .header = { .vtable = &static_file_vtable }, \ +#define FILE_COMMON(NAME) { \ + .vtable = &static_file_vtable, \ \ .u_name = "root", .u_num = 0, /* owner user */ \ .g_name = "root", .g_num = 0, /* owner group */ \ @@ -43,8 +43,8 @@ .mtime = 1728337904, \ } -#define DIR_METADATA(NAME) { \ - .header = { .vtable = &static_dir_vtable }, \ +#define DIR_COMMON(NAME) { \ + .vtable = &static_dir_vtable, \ \ .u_name = "root", .u_num = 0, /* owner user */ \ .g_name = "root", .g_num = 0, /* owner group */ \ @@ -59,28 +59,28 @@ #define STATIC_FILE(STRNAME, SYMNAME) \ &((static struct static_file){ \ - .metadata = FILE_METADATA(STRNAME), \ - .data_start = _binary_static_##SYMNAME##_start, \ - .data_end = _binary_static_##SYMNAME##_end, \ - }).metadata.header + ._static_common = FILE_COMMON(STRNAME), \ + .data_start = _binary_static_##SYMNAME##_start, \ + .data_end = _binary_static_##SYMNAME##_end, \ + }) static struct static_dir root = { - .metadata = DIR_METADATA(""), + ._static_common = DIR_COMMON(""), .members = { &((static struct static_dir){ - .metadata = DIR_METADATA("Documentation"), + ._static_common = DIR_COMMON("Documentation"), .members = { STATIC_FILE("x", Documentation_x), NULL }, - }).metadata.header, + }), STATIC_FILE("README.md", README_md), NULL, }, }; -static struct lib9p_srv_file *get_root(struct lib9p_srv_ctx *UNUSED(ctx), char *UNUSED(treename)) { - return &root.metadata.header; +static implements_lib9p_srv_file *get_root(struct lib9p_srv_ctx *UNUSED(ctx), char *UNUSED(treename)) { + return &root; } /* main ***********************************************************************/ @@ -94,7 +94,7 @@ static COROUTINE read_cr(void *_srv) { struct gnet_listener listener; gnet_listener_init(&listener, 9000); - lib9p_srv_read_cr(srv, (struct libnet_listener *)&listener); + lib9p_srv_read_cr(srv, &listener); cr_end(); } diff --git a/cmd/srv9p/static9p.c b/cmd/srv9p/static9p.c index f508ff1..47c07be 100644 --- a/cmd/srv9p/static9p.c +++ b/cmd/srv9p/static9p.c @@ -6,61 +6,63 @@ #include +#include + #include "static9p.h" #define UNUSED(name) /* name __attribute__((unused)) */ #define p9_str(cstr) ((struct lib9p_s){ .len = strlen(cstr), .utf8 = cstr }) #define p9_nulstr ((struct lib9p_s){ .len = 0, .utf8 = NULL }) -/* common metadata ************************************************************/ +/* common *********************************************************************/ -static struct lib9p_srv_file *static_metadata_clone(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_file) { +static implements_lib9p_srv_file *static_common_clone(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { + _static_common *self = VCALL_SELF(_static_common, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_metadata *file = (struct static_metadata *)_file; - assert(file); - return &file->header; + return self; } -static void static_metadata_free(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_file) { +static void static_common_free(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { + _static_common *self = VCALL_SELF(_static_common, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_metadata *file = (struct static_metadata *)_file; - assert(file); /* do nothing */ } -static uint32_t static_metadata_io(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_file, lib9p_o_t UNUSED(flags)) { +static uint32_t static_common_io(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, lib9p_o_t UNUSED(flags)) { + _static_common *self = VCALL_SELF(_static_common, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_metadata *file = (struct static_metadata *)_file; - assert(file); return 0; } -static void static_metadata_wstat(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_file, +static void static_common_wstat(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, struct lib9p_stat UNUSED(new)) { + _static_common *self = VCALL_SELF(_static_common, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_metadata *file = (struct static_metadata *)_file; - assert(file); lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem"); } -static void static_metadata_remove(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_file) { +static void static_common_remove(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { + _static_common *self = VCALL_SELF(_static_common, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_metadata *file = (struct static_metadata *)_file; - assert(file); lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem"); } /* dir ************************************************************************/ -static struct lib9p_stat static_dir_stat(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_file) { +static struct lib9p_stat static_dir_stat(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { + struct static_dir *self = VCALL_SELF(struct static_dir, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_dir *file = (struct static_dir *)_file; - assert(file); return (struct lib9p_stat){ .kern_type = 0, @@ -68,32 +70,32 @@ static struct lib9p_stat static_dir_stat(struct lib9p_srv_ctx *ctx, struct lib9p .file_qid = { .type = LIB9P_QT_DIR, .vers = 1, - .path = file->metadata.pathnum, + .path = self->pathnum, }, - .file_mode = LIB9P_DM_DIR | (file->metadata.perm & 0555), - .file_atime = file->metadata.atime, - .file_mtime = file->metadata.mtime, + .file_mode = LIB9P_DM_DIR | (self->perm & 0555), + .file_atime = self->atime, + .file_mtime = self->mtime, .file_size = 0, - .file_name = p9_str(file->metadata.name), - .file_owner_uid = p9_str(file->metadata.u_name), - .file_owner_gid = p9_str(file->metadata.g_name), - .file_last_modified_uid = p9_str(file->metadata.m_name), + .file_name = p9_str(self->name), + .file_owner_uid = p9_str(self->u_name), + .file_owner_gid = p9_str(self->g_name), + .file_last_modified_uid = p9_str(self->m_name), .file_extension = p9_nulstr, - .file_owner_n_uid = file->metadata.u_num, - .file_owner_n_gid = file->metadata.g_num, - .file_last_modified_n_uid = file->metadata.m_num, + .file_owner_n_uid = self->u_num, + .file_owner_n_gid = self->g_num, + .file_last_modified_n_uid = self->m_num, }; } -static struct lib9p_srv_file *static_dir_dopen(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_dir, +static implements_lib9p_srv_file *static_dir_dopen(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, char *childname) { + struct static_dir *self = VCALL_SELF(struct static_dir, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_dir *dir = (struct static_dir *)_dir; - assert(dir); - for (size_t i = 0; dir->members[i]; i++) { - struct lib9p_srv_file *filep = dir->members[i]; - struct lib9p_stat stat = filep->vtable->stat(ctx, filep); + for (size_t i = 0; self->members[i]; i++) { + implements_lib9p_srv_file *filep = self->members[i]; + struct lib9p_stat stat = VCALL(filep, stat, ctx); if (lib9p_ctx_has_error(&ctx->basectx)) break; lib9p_assert_stat(stat); @@ -105,30 +107,30 @@ static struct lib9p_srv_file *static_dir_dopen(struct lib9p_srv_ctx *ctx, struct return NULL; } -static struct lib9p_srv_file *static_dir_dcreate(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_dir, +static implements_lib9p_srv_file *static_dir_dcreate(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, char *UNUSED(childname), lib9p_dm_t UNUSED(perm), lib9p_o_t UNUSED(flags)) { + struct static_dir *self = VCALL_SELF(struct static_dir, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_dir *dir = (struct static_dir *)_dir; - assert(dir); lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem"); return NULL; } -static size_t static_dir_dread(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_dir, +static size_t static_dir_dread(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, uint8_t *buf, uint32_t byte_count, size_t _obj_offset) { + struct static_dir *self = VCALL_SELF(struct static_dir, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_dir *dir = (struct static_dir *)_dir; - assert(dir); uint32_t byte_offset = 0; size_t obj_offset = _obj_offset; - while (dir->members[obj_offset]) { - struct lib9p_srv_file *filep = dir->members[obj_offset]; - struct lib9p_stat stat = filep->vtable->stat(ctx, filep); + while (self->members[obj_offset]) { + implements_lib9p_srv_file *filep = self->members[obj_offset]; + struct lib9p_stat stat = VCALL(filep, stat, ctx); if (lib9p_ctx_has_error(&ctx->basectx)) break; lib9p_assert_stat(stat); @@ -147,13 +149,13 @@ static size_t static_dir_dread(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file } struct lib9p_srv_file_vtable static_dir_vtable = { - .clone = static_metadata_clone, - .free = static_metadata_free, + .clone = static_common_clone, + .free = static_common_free, - .io = static_metadata_io, + .io = static_common_io, .stat = static_dir_stat, - .wstat = static_metadata_wstat, - .remove = static_metadata_remove, + .wstat = static_common_wstat, + .remove = static_common_remove, .dopen = static_dir_dopen, .dcreate = static_dir_dcreate, @@ -166,16 +168,18 @@ struct lib9p_srv_file_vtable static_dir_vtable = { static inline size_t static_file_size(struct static_file *file) { assert(file); +#if __x86_64__ assert(file->data_start); +#endif if (!file->data_end) return file->data_size; return (size_t)((uintptr_t)file->data_end - (uintptr_t)file->data_start); } -static struct lib9p_stat static_file_stat(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_file) { +static struct lib9p_stat static_file_stat(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { + struct static_file *self = VCALL_SELF(struct static_file, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_file *file = (struct static_file *)_file; - assert(file); return (struct lib9p_stat){ .kern_type = 0, @@ -183,32 +187,32 @@ static struct lib9p_stat static_file_stat(struct lib9p_srv_ctx *ctx, struct lib9 .file_qid = { .type = LIB9P_QT_FILE, .vers = 1, - .path = file->metadata.pathnum, + .path = self->pathnum, }, - .file_mode = file->metadata.perm & 0444, - .file_atime = file->metadata.atime, - .file_mtime = file->metadata.mtime, - .file_size = (uint64_t)static_file_size(file), - .file_name = p9_str(file->metadata.name), - .file_owner_uid = p9_str(file->metadata.u_name), - .file_owner_gid = p9_str(file->metadata.g_name), - .file_last_modified_uid = p9_str(file->metadata.m_name), + .file_mode = self->perm & 0444, + .file_atime = self->atime, + .file_mtime = self->mtime, + .file_size = (uint64_t)static_file_size(self), + .file_name = p9_str(self->name), + .file_owner_uid = p9_str(self->u_name), + .file_owner_gid = p9_str(self->g_name), + .file_last_modified_uid = p9_str(self->m_name), .file_extension = p9_nulstr, - .file_owner_n_uid = file->metadata.u_num, - .file_owner_n_gid = file->metadata.g_num, - .file_last_modified_n_uid = file->metadata.m_num, + .file_owner_n_uid = self->u_num, + .file_owner_n_gid = self->g_num, + .file_last_modified_n_uid = self->m_num, }; } -static uint32_t static_file_pread(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file *_file, +static uint32_t static_file_pread(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, void *buf, uint32_t byte_count, uint64_t byte_offset) { + struct static_file *self = VCALL_SELF(struct static_file, implements_lib9p_srv_file, _self); + assert(self); assert(ctx); - struct static_file *file = (struct static_file *)_file; - assert(file); - size_t data_size = static_file_size(file); + size_t data_size = static_file_size(self); if (byte_offset > (uint64_t)data_size) { lib9p_error(&ctx->basectx, @@ -220,18 +224,18 @@ static uint32_t static_file_pread(struct lib9p_srv_ctx *ctx, struct lib9p_srv_fi size_t end_off = beg_off + (size_t)byte_count; if (end_off > data_size) end_off = data_size; - memcpy(buf, &file->data_start[beg_off], end_off-beg_off); + memcpy(buf, &self->data_start[beg_off], end_off-beg_off); return (uint32_t)(end_off-beg_off); } struct lib9p_srv_file_vtable static_file_vtable = { - .clone = static_metadata_clone, - .free = static_metadata_free, + .clone = static_common_clone, + .free = static_common_free, - .io = static_metadata_io, + .io = static_common_io, .stat = static_file_stat, - .wstat = static_metadata_wstat, - .remove = static_metadata_remove, + .wstat = static_common_wstat, + .remove = static_common_remove, .pread = static_file_pread, .pwrite = NULL, diff --git a/cmd/srv9p/static9p.h b/cmd/srv9p/static9p.h index 92f5909..98b85a2 100644 --- a/cmd/srv9p/static9p.h +++ b/cmd/srv9p/static9p.h @@ -9,8 +9,8 @@ #include -struct static_metadata { - struct lib9p_srv_file header; +typedef struct { + implements_lib9p_srv_file; char *u_name; uint32_t u_num; @@ -23,10 +23,10 @@ struct static_metadata { char *name; lib9p_dm_t perm; uint32_t atime, mtime; -}; +} _static_common; struct static_dir { - struct static_metadata metadata; + _static_common; /* NULL-terminated */ struct lib9p_srv_file *members[]; @@ -34,7 +34,7 @@ struct static_dir { struct static_file { - struct static_metadata metadata; + _static_common; char *data_start; /* must not be NULL */ char *data_end; /* may be NULL, in which case data_size is used */ diff --git a/lib9o/CMakeLists.txt b/lib9o/CMakeLists.txt deleted file mode 100644 index 815ea57..0000000 --- a/lib9o/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# lib9o/CMakeLists.txt - A simple Go-ish object system built on GCC -fplan9-extensions -# -# Copyright (C) 2024 Luke T. Shumaker -# SPDX-Licence-Identifier: AGPL-3.0-or-later - -add_library(lib9o INTERFACE) -target_include_directories(lib9o SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) -target_compile_options(lib9o PUBLIC "-fplan9-extension") diff --git a/lib9o/include/lib9o/lib9o.h b/lib9o/include/lib9o/lib9o.h deleted file mode 100644 index f5eb511..0000000 --- a/lib9o/include/lib9o/lib9o.h +++ /dev/null @@ -1,27 +0,0 @@ -/* lib9o/lib9o.h - A simple Go-ish object system built on GCC -fplan9-extensions - * - * Copyright (C) 2024 Luke T. Shumaker - * SPDX-Licence-Identifier: AGPL-3.0-or-later - */ - -#ifndef _LIB9O_H_ -#define _LIB9O_H_ - -#include /* for assert() and static_assert() */ -#include /* for offsetof() */ - -#define MCALL(o, m, ...) \ - ({ \ - assert(o); \ - (o)->vtable->m(o __VA_OPT__(,) __VA_ARGS__); \ - }) - -#define MSELF(obj_typ, iface_typ, iface_ptr) \ - ({ \ - static_assert(_Generic(iface_ptr, iface_typ *: 1, default: 0), \ - "typeof("#iface_ptr") != "#iface_typ); \ - assert(iface_ptr); \ - ((obj_typ*)(((void*)iface_ptr)-offsetof(obj_typ,iface_typ))); \ - }) - -#endif /* _LIB9O_H_ */ diff --git a/lib9p/9p.c b/lib9p/9p.c index a008ccc..86d0ab8 100644 --- a/lib9p/9p.c +++ b/lib9p/9p.c @@ -49,6 +49,12 @@ int lib9p_errorf(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *fmt, . return -1; } + +const char *lib9p_msg_type_str(struct lib9p_ctx *ctx, enum lib9p_msg_type typ) { + assert(0 <= typ && typ <= 0xFF); + return _lib9p_versions[ctx->version].msgs[typ].name; +} + ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { /* Inspect the first 5 bytes ourselves. */ struct _validate_ctx subctx = { @@ -62,13 +68,13 @@ ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { if (subctx.net_size < 5) return lib9p_error(ctx, LINUX_EBADMSG, "message is impossibly short"); uint8_t typ = net_bytes[4]; - struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ]; - if (!vtable.validate) + struct _table_msg table = _lib9p_versions[ctx->version].msgs[typ]; + if (!table.validate) return lib9p_errorf(ctx, LINUX_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)", - lib9p_msg_type_str(typ), lib9p_version_str(ctx->version)); + lib9p_msg_type_str(ctx, typ), lib9p_version_str(ctx->version)); - /* Now use the message-type-specific vtable to process the whole thing. */ - if (vtable.validate(&subctx)) + /* Now use the message-type-specific table to process the whole thing. */ + if (table.validate(&subctx)) return -1; assert(subctx.net_offset <= subctx.net_size); if (subctx.net_offset < subctx.net_size) @@ -77,7 +83,7 @@ ssize_t lib9p_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { /* Return. */ ssize_t ret; - if (__builtin_add_overflow(vtable.basesize, subctx.host_extra, &ret)) + if (__builtin_add_overflow(table.basesize, subctx.host_extra, &ret)) return lib9p_error(ctx, LINUX_EMSGSIZE, "unmarshalled payload overflows SSIZE_MAX"); return ret; } @@ -92,9 +98,9 @@ void lib9p_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, }; *ret_typ = net_bytes[4]; - struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[*ret_typ]; - subctx.extra = ret_body + vtable.basesize; - vtable.unmarshal(&subctx, ret_body); + struct _table_msg table = _lib9p_versions[ctx->version].msgs[*ret_typ]; + subctx.extra = ret_body + table.basesize; + table.unmarshal(&subctx, ret_body); } bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, @@ -105,8 +111,8 @@ bool lib9p_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, .net_offset = 0, }; - struct _vtable_msg vtable = _lib9p_vtables[ctx->version].msgs[typ]; - return vtable.marshal(&subctx, body); + struct _table_msg table = _lib9p_versions[ctx->version].msgs[typ]; + return table.marshal(&subctx, body); } bool lib9p_validate_stat(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, diff --git a/lib9p/9p.generated.c b/lib9p/9p.generated.c index 50ed53f..6136433 100644 --- a/lib9p/9p.generated.c +++ b/lib9p/9p.generated.c @@ -30,270 +30,6 @@ const char *lib9p_version_str(enum lib9p_version ver) { return version_strs[ver]; } -static const char *msg_type_strs[0x100] = { - [0x00] = "0x00", - [0x01] = "0x01", - [0x02] = "0x02", - [0x03] = "0x03", - [0x04] = "0x04", - [0x05] = "0x05", - [0x06] = "0x06", - [0x07] = "0x07", - [0x08] = "0x08", - [0x09] = "0x09", - [0x0A] = "0x0A", - [0x0B] = "0x0B", - [0x0C] = "0x0C", - [0x0D] = "0x0D", - [0x0E] = "0x0E", - [0x0F] = "0x0F", - [0x10] = "0x10", - [0x11] = "0x11", - [0x12] = "0x12", - [0x13] = "0x13", - [0x14] = "0x14", - [0x15] = "0x15", - [0x16] = "0x16", - [0x17] = "0x17", - [0x18] = "0x18", - [0x19] = "0x19", - [0x1A] = "0x1A", - [0x1B] = "0x1B", - [0x1C] = "0x1C", - [0x1D] = "0x1D", - [0x1E] = "0x1E", - [0x1F] = "0x1F", - [0x20] = "0x20", - [0x21] = "0x21", - [0x22] = "0x22", - [0x23] = "0x23", - [0x24] = "0x24", - [0x25] = "0x25", - [0x26] = "0x26", - [0x27] = "0x27", - [0x28] = "0x28", - [0x29] = "0x29", - [0x2A] = "0x2A", - [0x2B] = "0x2B", - [0x2C] = "0x2C", - [0x2D] = "0x2D", - [0x2E] = "0x2E", - [0x2F] = "0x2F", - [0x30] = "0x30", - [0x31] = "0x31", - [0x32] = "0x32", - [0x33] = "0x33", - [0x34] = "0x34", - [0x35] = "0x35", - [0x36] = "0x36", - [0x37] = "0x37", - [0x38] = "0x38", - [0x39] = "0x39", - [0x3A] = "0x3A", - [0x3B] = "0x3B", - [0x3C] = "0x3C", - [0x3D] = "0x3D", - [0x3E] = "0x3E", - [0x3F] = "0x3F", - [0x40] = "0x40", - [0x41] = "0x41", - [0x42] = "0x42", - [0x43] = "0x43", - [0x44] = "0x44", - [0x45] = "0x45", - [0x46] = "0x46", - [0x47] = "0x47", - [0x48] = "0x48", - [0x49] = "0x49", - [0x4A] = "0x4A", - [0x4B] = "0x4B", - [0x4C] = "0x4C", - [0x4D] = "0x4D", - [0x4E] = "0x4E", - [0x4F] = "0x4F", - [0x50] = "0x50", - [0x51] = "0x51", - [0x52] = "0x52", - [0x53] = "0x53", - [0x54] = "0x54", - [0x55] = "0x55", - [0x56] = "0x56", - [0x57] = "0x57", - [0x58] = "0x58", - [0x59] = "0x59", - [0x5A] = "0x5A", - [0x5B] = "0x5B", - [0x5C] = "0x5C", - [0x5D] = "0x5D", - [0x5E] = "0x5E", - [0x5F] = "0x5F", - [0x60] = "0x60", - [0x61] = "0x61", - [0x62] = "0x62", - [0x63] = "0x63", - [0x64] = "Tversion", - [0x65] = "Rversion", - [0x66] = "Tauth", - [0x67] = "Rauth", - [0x68] = "Tattach", - [0x69] = "Rattach", - [0x6A] = "0x6A", - [0x6B] = "Rerror", - [0x6C] = "Tflush", - [0x6D] = "Rflush", - [0x6E] = "Twalk", - [0x6F] = "Rwalk", - [0x70] = "Topen", - [0x71] = "Ropen", - [0x72] = "Tcreate", - [0x73] = "Rcreate", - [0x74] = "Tread", - [0x75] = "Rread", - [0x76] = "Twrite", - [0x77] = "Rwrite", - [0x78] = "Tclunk", - [0x79] = "Rclunk", - [0x7A] = "Tremove", - [0x7B] = "Rremove", - [0x7C] = "Tstat", - [0x7D] = "Rstat", - [0x7E] = "Twstat", - [0x7F] = "Rwstat", - [0x80] = "0x80", - [0x81] = "0x81", - [0x82] = "0x82", - [0x83] = "0x83", - [0x84] = "0x84", - [0x85] = "0x85", - [0x86] = "0x86", - [0x87] = "0x87", - [0x88] = "0x88", - [0x89] = "0x89", - [0x8A] = "0x8A", - [0x8B] = "0x8B", - [0x8C] = "0x8C", - [0x8D] = "0x8D", - [0x8E] = "0x8E", - [0x8F] = "0x8F", - [0x90] = "0x90", - [0x91] = "0x91", - [0x92] = "0x92", - [0x93] = "0x93", - [0x94] = "0x94", - [0x95] = "0x95", - [0x96] = "Tsession", - [0x97] = "Rsession", - [0x98] = "Tsread", - [0x99] = "Rsread", - [0x9A] = "Tswrite", - [0x9B] = "Rswrite", - [0x9C] = "0x9C", - [0x9D] = "0x9D", - [0x9E] = "0x9E", - [0x9F] = "0x9F", - [0xA0] = "0xA0", - [0xA1] = "0xA1", - [0xA2] = "0xA2", - [0xA3] = "0xA3", - [0xA4] = "0xA4", - [0xA5] = "0xA5", - [0xA6] = "0xA6", - [0xA7] = "0xA7", - [0xA8] = "0xA8", - [0xA9] = "0xA9", - [0xAA] = "0xAA", - [0xAB] = "0xAB", - [0xAC] = "0xAC", - [0xAD] = "0xAD", - [0xAE] = "0xAE", - [0xAF] = "0xAF", - [0xB0] = "0xB0", - [0xB1] = "0xB1", - [0xB2] = "0xB2", - [0xB3] = "0xB3", - [0xB4] = "0xB4", - [0xB5] = "0xB5", - [0xB6] = "0xB6", - [0xB7] = "0xB7", - [0xB8] = "0xB8", - [0xB9] = "0xB9", - [0xBA] = "0xBA", - [0xBB] = "0xBB", - [0xBC] = "0xBC", - [0xBD] = "0xBD", - [0xBE] = "0xBE", - [0xBF] = "0xBF", - [0xC0] = "0xC0", - [0xC1] = "0xC1", - [0xC2] = "0xC2", - [0xC3] = "0xC3", - [0xC4] = "0xC4", - [0xC5] = "0xC5", - [0xC6] = "0xC6", - [0xC7] = "0xC7", - [0xC8] = "0xC8", - [0xC9] = "0xC9", - [0xCA] = "0xCA", - [0xCB] = "0xCB", - [0xCC] = "0xCC", - [0xCD] = "0xCD", - [0xCE] = "0xCE", - [0xCF] = "0xCF", - [0xD0] = "0xD0", - [0xD1] = "0xD1", - [0xD2] = "0xD2", - [0xD3] = "0xD3", - [0xD4] = "0xD4", - [0xD5] = "0xD5", - [0xD6] = "0xD6", - [0xD7] = "0xD7", - [0xD8] = "0xD8", - [0xD9] = "0xD9", - [0xDA] = "0xDA", - [0xDB] = "0xDB", - [0xDC] = "0xDC", - [0xDD] = "0xDD", - [0xDE] = "0xDE", - [0xDF] = "0xDF", - [0xE0] = "0xE0", - [0xE1] = "0xE1", - [0xE2] = "0xE2", - [0xE3] = "0xE3", - [0xE4] = "0xE4", - [0xE5] = "0xE5", - [0xE6] = "0xE6", - [0xE7] = "0xE7", - [0xE8] = "0xE8", - [0xE9] = "0xE9", - [0xEA] = "0xEA", - [0xEB] = "0xEB", - [0xEC] = "0xEC", - [0xED] = "0xED", - [0xEE] = "0xEE", - [0xEF] = "0xEF", - [0xF0] = "0xF0", - [0xF1] = "0xF1", - [0xF2] = "0xF2", - [0xF3] = "0xF3", - [0xF4] = "0xF4", - [0xF5] = "0xF5", - [0xF6] = "0xF6", - [0xF7] = "0xF7", - [0xF8] = "0xF8", - [0xF9] = "0xF9", - [0xFA] = "0xFA", - [0xFB] = "0xFB", - [0xFC] = "0xFC", - [0xFD] = "0xFD", - [0xFE] = "0xFE", - [0xFF] = "0xFF", -}; - -const char *lib9p_msg_type_str(enum lib9p_msg_type typ) { - assert(0 <= typ && typ <= 0xFF); - return msg_type_strs[typ]; -} - /* validate_* *****************************************************************/ static ALWAYS_INLINE bool _validate_size_net(struct _validate_ctx *ctx, uint32_t n) { @@ -2042,29 +1778,387 @@ static FLATTEN bool marshal_Rswrite(struct _marshal_ctx *ctx, struct lib9p_msg_R } #endif /* defined(CONFIG_9P_ENABLE_9P2000_e) */ -/* vtables / exports **********************************************************/ +/* tables / exports ***********************************************************/ #define _MSG(typ) [LIB9P_TYP_##typ] = { \ + .name = #typ, \ .basesize = sizeof(struct lib9p_msg_##typ), \ .validate = validate_##typ, \ .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \ .marshal = (_marshal_fn_t)marshal_##typ, \ } +#define _NONMSG(num) [num] = { \ + .name = #num, \ + } -struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = { +struct _table_version _lib9p_versions[LIB9P_VER_NUM] = { [LIB9P_VER_unknown] = { .msgs = { + _NONMSG(0x00), + _NONMSG(0x01), + _NONMSG(0x02), + _NONMSG(0x03), + _NONMSG(0x04), + _NONMSG(0x05), + _NONMSG(0x06), + _NONMSG(0x07), + _NONMSG(0x08), + _NONMSG(0x09), + _NONMSG(0x0A), + _NONMSG(0x0B), + _NONMSG(0x0C), + _NONMSG(0x0D), + _NONMSG(0x0E), + _NONMSG(0x0F), + _NONMSG(0x10), + _NONMSG(0x11), + _NONMSG(0x12), + _NONMSG(0x13), + _NONMSG(0x14), + _NONMSG(0x15), + _NONMSG(0x16), + _NONMSG(0x17), + _NONMSG(0x18), + _NONMSG(0x19), + _NONMSG(0x1A), + _NONMSG(0x1B), + _NONMSG(0x1C), + _NONMSG(0x1D), + _NONMSG(0x1E), + _NONMSG(0x1F), + _NONMSG(0x20), + _NONMSG(0x21), + _NONMSG(0x22), + _NONMSG(0x23), + _NONMSG(0x24), + _NONMSG(0x25), + _NONMSG(0x26), + _NONMSG(0x27), + _NONMSG(0x28), + _NONMSG(0x29), + _NONMSG(0x2A), + _NONMSG(0x2B), + _NONMSG(0x2C), + _NONMSG(0x2D), + _NONMSG(0x2E), + _NONMSG(0x2F), + _NONMSG(0x30), + _NONMSG(0x31), + _NONMSG(0x32), + _NONMSG(0x33), + _NONMSG(0x34), + _NONMSG(0x35), + _NONMSG(0x36), + _NONMSG(0x37), + _NONMSG(0x38), + _NONMSG(0x39), + _NONMSG(0x3A), + _NONMSG(0x3B), + _NONMSG(0x3C), + _NONMSG(0x3D), + _NONMSG(0x3E), + _NONMSG(0x3F), + _NONMSG(0x40), + _NONMSG(0x41), + _NONMSG(0x42), + _NONMSG(0x43), + _NONMSG(0x44), + _NONMSG(0x45), + _NONMSG(0x46), + _NONMSG(0x47), + _NONMSG(0x48), + _NONMSG(0x49), + _NONMSG(0x4A), + _NONMSG(0x4B), + _NONMSG(0x4C), + _NONMSG(0x4D), + _NONMSG(0x4E), + _NONMSG(0x4F), + _NONMSG(0x50), + _NONMSG(0x51), + _NONMSG(0x52), + _NONMSG(0x53), + _NONMSG(0x54), + _NONMSG(0x55), + _NONMSG(0x56), + _NONMSG(0x57), + _NONMSG(0x58), + _NONMSG(0x59), + _NONMSG(0x5A), + _NONMSG(0x5B), + _NONMSG(0x5C), + _NONMSG(0x5D), + _NONMSG(0x5E), + _NONMSG(0x5F), + _NONMSG(0x60), + _NONMSG(0x61), + _NONMSG(0x62), + _NONMSG(0x63), _MSG(Tversion), _MSG(Rversion), + _NONMSG(0x66), + _NONMSG(0x67), + _NONMSG(0x68), + _NONMSG(0x69), + _NONMSG(0x6A), _MSG(Rerror), + _NONMSG(0x6C), + _NONMSG(0x6D), + _NONMSG(0x6E), + _NONMSG(0x6F), + _NONMSG(0x70), + _NONMSG(0x71), + _NONMSG(0x72), + _NONMSG(0x73), + _NONMSG(0x74), + _NONMSG(0x75), + _NONMSG(0x76), + _NONMSG(0x77), + _NONMSG(0x78), + _NONMSG(0x79), + _NONMSG(0x7A), + _NONMSG(0x7B), + _NONMSG(0x7C), + _NONMSG(0x7D), + _NONMSG(0x7E), + _NONMSG(0x7F), + _NONMSG(0x80), + _NONMSG(0x81), + _NONMSG(0x82), + _NONMSG(0x83), + _NONMSG(0x84), + _NONMSG(0x85), + _NONMSG(0x86), + _NONMSG(0x87), + _NONMSG(0x88), + _NONMSG(0x89), + _NONMSG(0x8A), + _NONMSG(0x8B), + _NONMSG(0x8C), + _NONMSG(0x8D), + _NONMSG(0x8E), + _NONMSG(0x8F), + _NONMSG(0x90), + _NONMSG(0x91), + _NONMSG(0x92), + _NONMSG(0x93), + _NONMSG(0x94), + _NONMSG(0x95), + _NONMSG(0x96), + _NONMSG(0x97), + _NONMSG(0x98), + _NONMSG(0x99), + _NONMSG(0x9A), + _NONMSG(0x9B), + _NONMSG(0x9C), + _NONMSG(0x9D), + _NONMSG(0x9E), + _NONMSG(0x9F), + _NONMSG(0xA0), + _NONMSG(0xA1), + _NONMSG(0xA2), + _NONMSG(0xA3), + _NONMSG(0xA4), + _NONMSG(0xA5), + _NONMSG(0xA6), + _NONMSG(0xA7), + _NONMSG(0xA8), + _NONMSG(0xA9), + _NONMSG(0xAA), + _NONMSG(0xAB), + _NONMSG(0xAC), + _NONMSG(0xAD), + _NONMSG(0xAE), + _NONMSG(0xAF), + _NONMSG(0xB0), + _NONMSG(0xB1), + _NONMSG(0xB2), + _NONMSG(0xB3), + _NONMSG(0xB4), + _NONMSG(0xB5), + _NONMSG(0xB6), + _NONMSG(0xB7), + _NONMSG(0xB8), + _NONMSG(0xB9), + _NONMSG(0xBA), + _NONMSG(0xBB), + _NONMSG(0xBC), + _NONMSG(0xBD), + _NONMSG(0xBE), + _NONMSG(0xBF), + _NONMSG(0xC0), + _NONMSG(0xC1), + _NONMSG(0xC2), + _NONMSG(0xC3), + _NONMSG(0xC4), + _NONMSG(0xC5), + _NONMSG(0xC6), + _NONMSG(0xC7), + _NONMSG(0xC8), + _NONMSG(0xC9), + _NONMSG(0xCA), + _NONMSG(0xCB), + _NONMSG(0xCC), + _NONMSG(0xCD), + _NONMSG(0xCE), + _NONMSG(0xCF), + _NONMSG(0xD0), + _NONMSG(0xD1), + _NONMSG(0xD2), + _NONMSG(0xD3), + _NONMSG(0xD4), + _NONMSG(0xD5), + _NONMSG(0xD6), + _NONMSG(0xD7), + _NONMSG(0xD8), + _NONMSG(0xD9), + _NONMSG(0xDA), + _NONMSG(0xDB), + _NONMSG(0xDC), + _NONMSG(0xDD), + _NONMSG(0xDE), + _NONMSG(0xDF), + _NONMSG(0xE0), + _NONMSG(0xE1), + _NONMSG(0xE2), + _NONMSG(0xE3), + _NONMSG(0xE4), + _NONMSG(0xE5), + _NONMSG(0xE6), + _NONMSG(0xE7), + _NONMSG(0xE8), + _NONMSG(0xE9), + _NONMSG(0xEA), + _NONMSG(0xEB), + _NONMSG(0xEC), + _NONMSG(0xED), + _NONMSG(0xEE), + _NONMSG(0xEF), + _NONMSG(0xF0), + _NONMSG(0xF1), + _NONMSG(0xF2), + _NONMSG(0xF3), + _NONMSG(0xF4), + _NONMSG(0xF5), + _NONMSG(0xF6), + _NONMSG(0xF7), + _NONMSG(0xF8), + _NONMSG(0xF9), + _NONMSG(0xFA), + _NONMSG(0xFB), + _NONMSG(0xFC), + _NONMSG(0xFD), + _NONMSG(0xFE), + _NONMSG(0xFF), }}, #if defined(CONFIG_9P_ENABLE_9P2000) [LIB9P_VER_9P2000] = { .msgs = { + _NONMSG(0x00), + _NONMSG(0x01), + _NONMSG(0x02), + _NONMSG(0x03), + _NONMSG(0x04), + _NONMSG(0x05), + _NONMSG(0x06), + _NONMSG(0x07), + _NONMSG(0x08), + _NONMSG(0x09), + _NONMSG(0x0A), + _NONMSG(0x0B), + _NONMSG(0x0C), + _NONMSG(0x0D), + _NONMSG(0x0E), + _NONMSG(0x0F), + _NONMSG(0x10), + _NONMSG(0x11), + _NONMSG(0x12), + _NONMSG(0x13), + _NONMSG(0x14), + _NONMSG(0x15), + _NONMSG(0x16), + _NONMSG(0x17), + _NONMSG(0x18), + _NONMSG(0x19), + _NONMSG(0x1A), + _NONMSG(0x1B), + _NONMSG(0x1C), + _NONMSG(0x1D), + _NONMSG(0x1E), + _NONMSG(0x1F), + _NONMSG(0x20), + _NONMSG(0x21), + _NONMSG(0x22), + _NONMSG(0x23), + _NONMSG(0x24), + _NONMSG(0x25), + _NONMSG(0x26), + _NONMSG(0x27), + _NONMSG(0x28), + _NONMSG(0x29), + _NONMSG(0x2A), + _NONMSG(0x2B), + _NONMSG(0x2C), + _NONMSG(0x2D), + _NONMSG(0x2E), + _NONMSG(0x2F), + _NONMSG(0x30), + _NONMSG(0x31), + _NONMSG(0x32), + _NONMSG(0x33), + _NONMSG(0x34), + _NONMSG(0x35), + _NONMSG(0x36), + _NONMSG(0x37), + _NONMSG(0x38), + _NONMSG(0x39), + _NONMSG(0x3A), + _NONMSG(0x3B), + _NONMSG(0x3C), + _NONMSG(0x3D), + _NONMSG(0x3E), + _NONMSG(0x3F), + _NONMSG(0x40), + _NONMSG(0x41), + _NONMSG(0x42), + _NONMSG(0x43), + _NONMSG(0x44), + _NONMSG(0x45), + _NONMSG(0x46), + _NONMSG(0x47), + _NONMSG(0x48), + _NONMSG(0x49), + _NONMSG(0x4A), + _NONMSG(0x4B), + _NONMSG(0x4C), + _NONMSG(0x4D), + _NONMSG(0x4E), + _NONMSG(0x4F), + _NONMSG(0x50), + _NONMSG(0x51), + _NONMSG(0x52), + _NONMSG(0x53), + _NONMSG(0x54), + _NONMSG(0x55), + _NONMSG(0x56), + _NONMSG(0x57), + _NONMSG(0x58), + _NONMSG(0x59), + _NONMSG(0x5A), + _NONMSG(0x5B), + _NONMSG(0x5C), + _NONMSG(0x5D), + _NONMSG(0x5E), + _NONMSG(0x5F), + _NONMSG(0x60), + _NONMSG(0x61), + _NONMSG(0x62), + _NONMSG(0x63), _MSG(Tversion), _MSG(Rversion), _MSG(Tauth), _MSG(Rauth), _MSG(Tattach), _MSG(Rattach), + _NONMSG(0x6A), _MSG(Rerror), _MSG(Tflush), _MSG(Rflush), @@ -2086,16 +2180,245 @@ struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = { _MSG(Rstat), _MSG(Twstat), _MSG(Rwstat), + _NONMSG(0x80), + _NONMSG(0x81), + _NONMSG(0x82), + _NONMSG(0x83), + _NONMSG(0x84), + _NONMSG(0x85), + _NONMSG(0x86), + _NONMSG(0x87), + _NONMSG(0x88), + _NONMSG(0x89), + _NONMSG(0x8A), + _NONMSG(0x8B), + _NONMSG(0x8C), + _NONMSG(0x8D), + _NONMSG(0x8E), + _NONMSG(0x8F), + _NONMSG(0x90), + _NONMSG(0x91), + _NONMSG(0x92), + _NONMSG(0x93), + _NONMSG(0x94), + _NONMSG(0x95), + _NONMSG(0x96), + _NONMSG(0x97), + _NONMSG(0x98), + _NONMSG(0x99), + _NONMSG(0x9A), + _NONMSG(0x9B), + _NONMSG(0x9C), + _NONMSG(0x9D), + _NONMSG(0x9E), + _NONMSG(0x9F), + _NONMSG(0xA0), + _NONMSG(0xA1), + _NONMSG(0xA2), + _NONMSG(0xA3), + _NONMSG(0xA4), + _NONMSG(0xA5), + _NONMSG(0xA6), + _NONMSG(0xA7), + _NONMSG(0xA8), + _NONMSG(0xA9), + _NONMSG(0xAA), + _NONMSG(0xAB), + _NONMSG(0xAC), + _NONMSG(0xAD), + _NONMSG(0xAE), + _NONMSG(0xAF), + _NONMSG(0xB0), + _NONMSG(0xB1), + _NONMSG(0xB2), + _NONMSG(0xB3), + _NONMSG(0xB4), + _NONMSG(0xB5), + _NONMSG(0xB6), + _NONMSG(0xB7), + _NONMSG(0xB8), + _NONMSG(0xB9), + _NONMSG(0xBA), + _NONMSG(0xBB), + _NONMSG(0xBC), + _NONMSG(0xBD), + _NONMSG(0xBE), + _NONMSG(0xBF), + _NONMSG(0xC0), + _NONMSG(0xC1), + _NONMSG(0xC2), + _NONMSG(0xC3), + _NONMSG(0xC4), + _NONMSG(0xC5), + _NONMSG(0xC6), + _NONMSG(0xC7), + _NONMSG(0xC8), + _NONMSG(0xC9), + _NONMSG(0xCA), + _NONMSG(0xCB), + _NONMSG(0xCC), + _NONMSG(0xCD), + _NONMSG(0xCE), + _NONMSG(0xCF), + _NONMSG(0xD0), + _NONMSG(0xD1), + _NONMSG(0xD2), + _NONMSG(0xD3), + _NONMSG(0xD4), + _NONMSG(0xD5), + _NONMSG(0xD6), + _NONMSG(0xD7), + _NONMSG(0xD8), + _NONMSG(0xD9), + _NONMSG(0xDA), + _NONMSG(0xDB), + _NONMSG(0xDC), + _NONMSG(0xDD), + _NONMSG(0xDE), + _NONMSG(0xDF), + _NONMSG(0xE0), + _NONMSG(0xE1), + _NONMSG(0xE2), + _NONMSG(0xE3), + _NONMSG(0xE4), + _NONMSG(0xE5), + _NONMSG(0xE6), + _NONMSG(0xE7), + _NONMSG(0xE8), + _NONMSG(0xE9), + _NONMSG(0xEA), + _NONMSG(0xEB), + _NONMSG(0xEC), + _NONMSG(0xED), + _NONMSG(0xEE), + _NONMSG(0xEF), + _NONMSG(0xF0), + _NONMSG(0xF1), + _NONMSG(0xF2), + _NONMSG(0xF3), + _NONMSG(0xF4), + _NONMSG(0xF5), + _NONMSG(0xF6), + _NONMSG(0xF7), + _NONMSG(0xF8), + _NONMSG(0xF9), + _NONMSG(0xFA), + _NONMSG(0xFB), + _NONMSG(0xFC), + _NONMSG(0xFD), + _NONMSG(0xFE), + _NONMSG(0xFF), }}, #endif /* defined(CONFIG_9P_ENABLE_9P2000) */ #if defined(CONFIG_9P_ENABLE_9P2000_e) [LIB9P_VER_9P2000_e] = { .msgs = { + _NONMSG(0x00), + _NONMSG(0x01), + _NONMSG(0x02), + _NONMSG(0x03), + _NONMSG(0x04), + _NONMSG(0x05), + _NONMSG(0x06), + _NONMSG(0x07), + _NONMSG(0x08), + _NONMSG(0x09), + _NONMSG(0x0A), + _NONMSG(0x0B), + _NONMSG(0x0C), + _NONMSG(0x0D), + _NONMSG(0x0E), + _NONMSG(0x0F), + _NONMSG(0x10), + _NONMSG(0x11), + _NONMSG(0x12), + _NONMSG(0x13), + _NONMSG(0x14), + _NONMSG(0x15), + _NONMSG(0x16), + _NONMSG(0x17), + _NONMSG(0x18), + _NONMSG(0x19), + _NONMSG(0x1A), + _NONMSG(0x1B), + _NONMSG(0x1C), + _NONMSG(0x1D), + _NONMSG(0x1E), + _NONMSG(0x1F), + _NONMSG(0x20), + _NONMSG(0x21), + _NONMSG(0x22), + _NONMSG(0x23), + _NONMSG(0x24), + _NONMSG(0x25), + _NONMSG(0x26), + _NONMSG(0x27), + _NONMSG(0x28), + _NONMSG(0x29), + _NONMSG(0x2A), + _NONMSG(0x2B), + _NONMSG(0x2C), + _NONMSG(0x2D), + _NONMSG(0x2E), + _NONMSG(0x2F), + _NONMSG(0x30), + _NONMSG(0x31), + _NONMSG(0x32), + _NONMSG(0x33), + _NONMSG(0x34), + _NONMSG(0x35), + _NONMSG(0x36), + _NONMSG(0x37), + _NONMSG(0x38), + _NONMSG(0x39), + _NONMSG(0x3A), + _NONMSG(0x3B), + _NONMSG(0x3C), + _NONMSG(0x3D), + _NONMSG(0x3E), + _NONMSG(0x3F), + _NONMSG(0x40), + _NONMSG(0x41), + _NONMSG(0x42), + _NONMSG(0x43), + _NONMSG(0x44), + _NONMSG(0x45), + _NONMSG(0x46), + _NONMSG(0x47), + _NONMSG(0x48), + _NONMSG(0x49), + _NONMSG(0x4A), + _NONMSG(0x4B), + _NONMSG(0x4C), + _NONMSG(0x4D), + _NONMSG(0x4E), + _NONMSG(0x4F), + _NONMSG(0x50), + _NONMSG(0x51), + _NONMSG(0x52), + _NONMSG(0x53), + _NONMSG(0x54), + _NONMSG(0x55), + _NONMSG(0x56), + _NONMSG(0x57), + _NONMSG(0x58), + _NONMSG(0x59), + _NONMSG(0x5A), + _NONMSG(0x5B), + _NONMSG(0x5C), + _NONMSG(0x5D), + _NONMSG(0x5E), + _NONMSG(0x5F), + _NONMSG(0x60), + _NONMSG(0x61), + _NONMSG(0x62), + _NONMSG(0x63), _MSG(Tversion), _MSG(Rversion), _MSG(Tauth), _MSG(Rauth), _MSG(Tattach), _MSG(Rattach), + _NONMSG(0x6A), _MSG(Rerror), _MSG(Tflush), _MSG(Rflush), @@ -2117,22 +2440,245 @@ struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = { _MSG(Rstat), _MSG(Twstat), _MSG(Rwstat), + _NONMSG(0x80), + _NONMSG(0x81), + _NONMSG(0x82), + _NONMSG(0x83), + _NONMSG(0x84), + _NONMSG(0x85), + _NONMSG(0x86), + _NONMSG(0x87), + _NONMSG(0x88), + _NONMSG(0x89), + _NONMSG(0x8A), + _NONMSG(0x8B), + _NONMSG(0x8C), + _NONMSG(0x8D), + _NONMSG(0x8E), + _NONMSG(0x8F), + _NONMSG(0x90), + _NONMSG(0x91), + _NONMSG(0x92), + _NONMSG(0x93), + _NONMSG(0x94), + _NONMSG(0x95), _MSG(Tsession), _MSG(Rsession), _MSG(Tsread), _MSG(Rsread), _MSG(Tswrite), _MSG(Rswrite), + _NONMSG(0x9C), + _NONMSG(0x9D), + _NONMSG(0x9E), + _NONMSG(0x9F), + _NONMSG(0xA0), + _NONMSG(0xA1), + _NONMSG(0xA2), + _NONMSG(0xA3), + _NONMSG(0xA4), + _NONMSG(0xA5), + _NONMSG(0xA6), + _NONMSG(0xA7), + _NONMSG(0xA8), + _NONMSG(0xA9), + _NONMSG(0xAA), + _NONMSG(0xAB), + _NONMSG(0xAC), + _NONMSG(0xAD), + _NONMSG(0xAE), + _NONMSG(0xAF), + _NONMSG(0xB0), + _NONMSG(0xB1), + _NONMSG(0xB2), + _NONMSG(0xB3), + _NONMSG(0xB4), + _NONMSG(0xB5), + _NONMSG(0xB6), + _NONMSG(0xB7), + _NONMSG(0xB8), + _NONMSG(0xB9), + _NONMSG(0xBA), + _NONMSG(0xBB), + _NONMSG(0xBC), + _NONMSG(0xBD), + _NONMSG(0xBE), + _NONMSG(0xBF), + _NONMSG(0xC0), + _NONMSG(0xC1), + _NONMSG(0xC2), + _NONMSG(0xC3), + _NONMSG(0xC4), + _NONMSG(0xC5), + _NONMSG(0xC6), + _NONMSG(0xC7), + _NONMSG(0xC8), + _NONMSG(0xC9), + _NONMSG(0xCA), + _NONMSG(0xCB), + _NONMSG(0xCC), + _NONMSG(0xCD), + _NONMSG(0xCE), + _NONMSG(0xCF), + _NONMSG(0xD0), + _NONMSG(0xD1), + _NONMSG(0xD2), + _NONMSG(0xD3), + _NONMSG(0xD4), + _NONMSG(0xD5), + _NONMSG(0xD6), + _NONMSG(0xD7), + _NONMSG(0xD8), + _NONMSG(0xD9), + _NONMSG(0xDA), + _NONMSG(0xDB), + _NONMSG(0xDC), + _NONMSG(0xDD), + _NONMSG(0xDE), + _NONMSG(0xDF), + _NONMSG(0xE0), + _NONMSG(0xE1), + _NONMSG(0xE2), + _NONMSG(0xE3), + _NONMSG(0xE4), + _NONMSG(0xE5), + _NONMSG(0xE6), + _NONMSG(0xE7), + _NONMSG(0xE8), + _NONMSG(0xE9), + _NONMSG(0xEA), + _NONMSG(0xEB), + _NONMSG(0xEC), + _NONMSG(0xED), + _NONMSG(0xEE), + _NONMSG(0xEF), + _NONMSG(0xF0), + _NONMSG(0xF1), + _NONMSG(0xF2), + _NONMSG(0xF3), + _NONMSG(0xF4), + _NONMSG(0xF5), + _NONMSG(0xF6), + _NONMSG(0xF7), + _NONMSG(0xF8), + _NONMSG(0xF9), + _NONMSG(0xFA), + _NONMSG(0xFB), + _NONMSG(0xFC), + _NONMSG(0xFD), + _NONMSG(0xFE), + _NONMSG(0xFF), }}, #endif /* defined(CONFIG_9P_ENABLE_9P2000_e) */ #if defined(CONFIG_9P_ENABLE_9P2000_u) [LIB9P_VER_9P2000_u] = { .msgs = { + _NONMSG(0x00), + _NONMSG(0x01), + _NONMSG(0x02), + _NONMSG(0x03), + _NONMSG(0x04), + _NONMSG(0x05), + _NONMSG(0x06), + _NONMSG(0x07), + _NONMSG(0x08), + _NONMSG(0x09), + _NONMSG(0x0A), + _NONMSG(0x0B), + _NONMSG(0x0C), + _NONMSG(0x0D), + _NONMSG(0x0E), + _NONMSG(0x0F), + _NONMSG(0x10), + _NONMSG(0x11), + _NONMSG(0x12), + _NONMSG(0x13), + _NONMSG(0x14), + _NONMSG(0x15), + _NONMSG(0x16), + _NONMSG(0x17), + _NONMSG(0x18), + _NONMSG(0x19), + _NONMSG(0x1A), + _NONMSG(0x1B), + _NONMSG(0x1C), + _NONMSG(0x1D), + _NONMSG(0x1E), + _NONMSG(0x1F), + _NONMSG(0x20), + _NONMSG(0x21), + _NONMSG(0x22), + _NONMSG(0x23), + _NONMSG(0x24), + _NONMSG(0x25), + _NONMSG(0x26), + _NONMSG(0x27), + _NONMSG(0x28), + _NONMSG(0x29), + _NONMSG(0x2A), + _NONMSG(0x2B), + _NONMSG(0x2C), + _NONMSG(0x2D), + _NONMSG(0x2E), + _NONMSG(0x2F), + _NONMSG(0x30), + _NONMSG(0x31), + _NONMSG(0x32), + _NONMSG(0x33), + _NONMSG(0x34), + _NONMSG(0x35), + _NONMSG(0x36), + _NONMSG(0x37), + _NONMSG(0x38), + _NONMSG(0x39), + _NONMSG(0x3A), + _NONMSG(0x3B), + _NONMSG(0x3C), + _NONMSG(0x3D), + _NONMSG(0x3E), + _NONMSG(0x3F), + _NONMSG(0x40), + _NONMSG(0x41), + _NONMSG(0x42), + _NONMSG(0x43), + _NONMSG(0x44), + _NONMSG(0x45), + _NONMSG(0x46), + _NONMSG(0x47), + _NONMSG(0x48), + _NONMSG(0x49), + _NONMSG(0x4A), + _NONMSG(0x4B), + _NONMSG(0x4C), + _NONMSG(0x4D), + _NONMSG(0x4E), + _NONMSG(0x4F), + _NONMSG(0x50), + _NONMSG(0x51), + _NONMSG(0x52), + _NONMSG(0x53), + _NONMSG(0x54), + _NONMSG(0x55), + _NONMSG(0x56), + _NONMSG(0x57), + _NONMSG(0x58), + _NONMSG(0x59), + _NONMSG(0x5A), + _NONMSG(0x5B), + _NONMSG(0x5C), + _NONMSG(0x5D), + _NONMSG(0x5E), + _NONMSG(0x5F), + _NONMSG(0x60), + _NONMSG(0x61), + _NONMSG(0x62), + _NONMSG(0x63), _MSG(Tversion), _MSG(Rversion), _MSG(Tauth), _MSG(Rauth), _MSG(Tattach), _MSG(Rattach), + _NONMSG(0x6A), _MSG(Rerror), _MSG(Tflush), _MSG(Rflush), @@ -2154,6 +2700,134 @@ struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM] = { _MSG(Rstat), _MSG(Twstat), _MSG(Rwstat), + _NONMSG(0x80), + _NONMSG(0x81), + _NONMSG(0x82), + _NONMSG(0x83), + _NONMSG(0x84), + _NONMSG(0x85), + _NONMSG(0x86), + _NONMSG(0x87), + _NONMSG(0x88), + _NONMSG(0x89), + _NONMSG(0x8A), + _NONMSG(0x8B), + _NONMSG(0x8C), + _NONMSG(0x8D), + _NONMSG(0x8E), + _NONMSG(0x8F), + _NONMSG(0x90), + _NONMSG(0x91), + _NONMSG(0x92), + _NONMSG(0x93), + _NONMSG(0x94), + _NONMSG(0x95), + _NONMSG(0x96), + _NONMSG(0x97), + _NONMSG(0x98), + _NONMSG(0x99), + _NONMSG(0x9A), + _NONMSG(0x9B), + _NONMSG(0x9C), + _NONMSG(0x9D), + _NONMSG(0x9E), + _NONMSG(0x9F), + _NONMSG(0xA0), + _NONMSG(0xA1), + _NONMSG(0xA2), + _NONMSG(0xA3), + _NONMSG(0xA4), + _NONMSG(0xA5), + _NONMSG(0xA6), + _NONMSG(0xA7), + _NONMSG(0xA8), + _NONMSG(0xA9), + _NONMSG(0xAA), + _NONMSG(0xAB), + _NONMSG(0xAC), + _NONMSG(0xAD), + _NONMSG(0xAE), + _NONMSG(0xAF), + _NONMSG(0xB0), + _NONMSG(0xB1), + _NONMSG(0xB2), + _NONMSG(0xB3), + _NONMSG(0xB4), + _NONMSG(0xB5), + _NONMSG(0xB6), + _NONMSG(0xB7), + _NONMSG(0xB8), + _NONMSG(0xB9), + _NONMSG(0xBA), + _NONMSG(0xBB), + _NONMSG(0xBC), + _NONMSG(0xBD), + _NONMSG(0xBE), + _NONMSG(0xBF), + _NONMSG(0xC0), + _NONMSG(0xC1), + _NONMSG(0xC2), + _NONMSG(0xC3), + _NONMSG(0xC4), + _NONMSG(0xC5), + _NONMSG(0xC6), + _NONMSG(0xC7), + _NONMSG(0xC8), + _NONMSG(0xC9), + _NONMSG(0xCA), + _NONMSG(0xCB), + _NONMSG(0xCC), + _NONMSG(0xCD), + _NONMSG(0xCE), + _NONMSG(0xCF), + _NONMSG(0xD0), + _NONMSG(0xD1), + _NONMSG(0xD2), + _NONMSG(0xD3), + _NONMSG(0xD4), + _NONMSG(0xD5), + _NONMSG(0xD6), + _NONMSG(0xD7), + _NONMSG(0xD8), + _NONMSG(0xD9), + _NONMSG(0xDA), + _NONMSG(0xDB), + _NONMSG(0xDC), + _NONMSG(0xDD), + _NONMSG(0xDE), + _NONMSG(0xDF), + _NONMSG(0xE0), + _NONMSG(0xE1), + _NONMSG(0xE2), + _NONMSG(0xE3), + _NONMSG(0xE4), + _NONMSG(0xE5), + _NONMSG(0xE6), + _NONMSG(0xE7), + _NONMSG(0xE8), + _NONMSG(0xE9), + _NONMSG(0xEA), + _NONMSG(0xEB), + _NONMSG(0xEC), + _NONMSG(0xED), + _NONMSG(0xEE), + _NONMSG(0xEF), + _NONMSG(0xF0), + _NONMSG(0xF1), + _NONMSG(0xF2), + _NONMSG(0xF3), + _NONMSG(0xF4), + _NONMSG(0xF5), + _NONMSG(0xF6), + _NONMSG(0xF7), + _NONMSG(0xF8), + _NONMSG(0xF9), + _NONMSG(0xFA), + _NONMSG(0xFB), + _NONMSG(0xFC), + _NONMSG(0xFD), + _NONMSG(0xFE), + _NONMSG(0xFF), }}, #endif /* defined(CONFIG_9P_ENABLE_9P2000_u) */ }; diff --git a/lib9p/CMakeLists.txt b/lib9p/CMakeLists.txt index 784397b..829ac8e 100644 --- a/lib9p/CMakeLists.txt +++ b/lib9p/CMakeLists.txt @@ -12,5 +12,5 @@ target_sources(lib9p INTERFACE ) target_link_libraries(lib9p INTERFACE libcr_ipc - libnet + libmisc ) diff --git a/lib9p/idl.gen b/lib9p/idl.gen index e911ed7..a353a86 100755 --- a/lib9p/idl.gen +++ b/lib9p/idl.gen @@ -636,8 +636,6 @@ enum {idprefix}version {{ ret += f"\t{idprefix.upper()}TYP_{msg.name.ljust(namewidth)} = {msg.msgid},\n" ret += ifdef_pop(0) ret += "};\n" - ret += "\n" - ret += f"const char *{idprefix}msg_type_str(enum {idprefix}msg_type);\n" for msg in [msg for msg in typs if isinstance(msg, Message)]: ret += "\n" @@ -717,20 +715,6 @@ const char *{idprefix}version_str(enum {idprefix}version ver) {{ assert(0 <= ver && ver < {c_ver_enum('NUM')}); return version_strs[ver]; }} - -static const char *msg_type_strs[0x100] = {{ -""" - id2name: dict[int, str] = {} - for msg in [msg for msg in typs if isinstance(msg, Message)]: - id2name[msg.msgid] = msg.name - for n in range(0, 0x100): - ret += '\t[0x{:02X}] = "{}",\n'.format(n, id2name.get(n, "0x{:02X}".format(n))) - ret += "};\n" - ret += f""" -const char *{idprefix}msg_type_str(enum {idprefix}msg_type typ) {{ - assert(0 <= typ && typ <= 0xFF); - return msg_type_strs[typ]; -}} """ # validate_* ############################################################### @@ -1093,33 +1077,45 @@ static ALWAYS_INLINE bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) { ret += "}\n" ret += ifdef_pop(0) - # vtables / exports ######################################################## + # tables / exports ######################################################### ret += f""" -/* vtables / exports **********************************************************/ +/* tables / exports ***********************************************************/ #define _MSG(typ) [{idprefix.upper()}TYP_##typ] = {{ \\ + .name = #typ, \\ .basesize = sizeof(struct {idprefix}msg_##typ), \\ .validate = validate_##typ, \\ .unmarshal = (_unmarshal_fn_t)unmarshal_##typ, \\ .marshal = (_marshal_fn_t)marshal_##typ, \\ }} +#define _NONMSG(num) [num] = {{ \\ + .name = #num, \\ + }} -struct _vtable_version _{idprefix}vtables[{c_ver_enum('NUM')}] = {{ +struct _table_version _{idprefix}versions[{c_ver_enum('NUM')}] = {{ """ - - ret += f"\t[{c_ver_enum('unknown')}] = {{ .msgs = {{\n" + id2typ: dict[int, Message] = {} for msg in [msg for msg in typs if isinstance(msg, Message)]: - if msg.name in ["Tversion", "Rversion", "Rerror"]: # SPECIAL - ret += f"\t\t_MSG({msg.name}),\n" - ret += "\t}},\n" + id2typ[msg.msgid] = msg - for ver in sorted(versions): - ret += ifdef_push(1, c_ver_ifdef({ver})) + for ver in ["unknown", *sorted(versions)]: + if ver != "unknown": + ret += ifdef_push(1, c_ver_ifdef({ver})) ret += f"\t[{c_ver_enum(ver)}] = {{ .msgs = {{\n" - for msg in [msg for msg in typs if isinstance(msg, Message)]: - if ver not in msg.in_versions: - continue - ret += f"\t\t_MSG({msg.name}),\n" + + for n in range(0, 0x100): + xmsg: Message | None = id2typ.get(n, None) + if xmsg: + if ver == "unknown": # SPECIAL + if xmsg.name not in ["Tversion", "Rversion", "Rerror"]: + xmsg = None + else: + if ver not in xmsg.in_versions: + xmsg = None + if xmsg: + ret += f"\t\t_MSG({xmsg.name}),\n" + else: + ret += "\t\t_NONMSG(0x{:02X}),\n".format(n) ret += "\t}},\n" ret += ifdef_pop(0) ret += "};\n" diff --git a/lib9p/include/lib9p/9p.generated.h b/lib9p/include/lib9p/9p.generated.h index 584960c..ca7ca07 100644 --- a/lib9p/include/lib9p/9p.generated.h +++ b/lib9p/include/lib9p/9p.generated.h @@ -184,8 +184,6 @@ enum lib9p_msg_type { /* uint8_t */ #endif /* defined(CONFIG_9P_ENABLE_9P2000_e) */ }; -const char *lib9p_msg_type_str(enum lib9p_msg_type); - #if defined(CONFIG_9P_ENABLE_9P2000) || defined(CONFIG_9P_ENABLE_9P2000_e) || defined(CONFIG_9P_ENABLE_9P2000_u) struct lib9p_msg_Tversion { lib9p_tag_t tag; diff --git a/lib9p/include/lib9p/9p.h b/lib9p/include/lib9p/9p.h index e7ddb15..a99cd5d 100644 --- a/lib9p/include/lib9p/9p.h +++ b/lib9p/include/lib9p/9p.h @@ -56,6 +56,8 @@ static bool lib9p_ctx_has_error(struct lib9p_ctx *ctx) { return ctx->err_msg[0]; } +const char *lib9p_msg_type_str(struct lib9p_ctx *, enum lib9p_msg_type); + /** Assert that a `struct lib9p_stat` object looks valid. */ static inline void lib9p_assert_stat(struct lib9p_stat stat) { assert( ((bool)(stat.file_mode & LIB9P_DM_DIR )) == ((bool)(stat.file_qid.type & LIB9P_QT_DIR )) ); diff --git a/lib9p/include/lib9p/srv.h b/lib9p/include/lib9p/srv.h index 91663e7..797695c 100644 --- a/lib9p/include/lib9p/srv.h +++ b/lib9p/include/lib9p/srv.h @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -38,50 +39,48 @@ static inline int lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx) { return -1; } -/* vtables you must implement *************************************************/ +/* interface definitions ******************************************************/ struct lib9p_srv_file; struct lib9p_srv_file_vtable { /* all - resource management */ - struct lib9p_srv_file *(*clone )(struct lib9p_srv_ctx *, struct lib9p_srv_file *); - void (*free )(struct lib9p_srv_ctx *, struct lib9p_srv_file *); + struct lib9p_srv_file *(*clone )(struct lib9p_srv_file *, struct lib9p_srv_ctx *); + void (*free )(struct lib9p_srv_file *, struct lib9p_srv_ctx *); /* all - syscalls */ - uint32_t (*io )(struct lib9p_srv_ctx *, struct lib9p_srv_file *, + uint32_t (*io )(struct lib9p_srv_file *, struct lib9p_srv_ctx *, lib9p_o_t flags); - struct lib9p_stat (*stat )(struct lib9p_srv_ctx *, struct lib9p_srv_file *); - void (*wstat )(struct lib9p_srv_ctx *, struct lib9p_srv_file *, + struct lib9p_stat (*stat )(struct lib9p_srv_file *, struct lib9p_srv_ctx *); + void (*wstat )(struct lib9p_srv_file *, struct lib9p_srv_ctx *, struct lib9p_stat new); - void (*remove )(struct lib9p_srv_ctx *, struct lib9p_srv_file *); + void (*remove )(struct lib9p_srv_file *, struct lib9p_srv_ctx *); /* directories - base */ - struct lib9p_srv_file *(*dopen )(struct lib9p_srv_ctx *, struct lib9p_srv_file *, + struct lib9p_srv_file *(*dopen )(struct lib9p_srv_file *, struct lib9p_srv_ctx *, char *childname); - struct lib9p_srv_file *(*dcreate)(struct lib9p_srv_ctx *, struct lib9p_srv_file *, + struct lib9p_srv_file *(*dcreate)(struct lib9p_srv_file *, struct lib9p_srv_ctx *, char *childname, lib9p_dm_t perm, lib9p_o_t flags); /* directories - once opened */ - size_t /* <- obj cnt */(*dread )(struct lib9p_srv_ctx *, struct lib9p_srv_file *, + size_t /* <- obj cnt */(*dread )(struct lib9p_srv_file *, struct lib9p_srv_ctx *, uint8_t *buf, uint32_t byte_count, /* <- num bytes */ size_t obj_offset); /* <- starting at this object */ /* non-directories - once opened */ - uint32_t (*pread )(struct lib9p_srv_ctx *, struct lib9p_srv_file *, + uint32_t (*pread )(struct lib9p_srv_file *, struct lib9p_srv_ctx *, void *buf, uint32_t byte_count, uint64_t byte_offset); - uint32_t (*pwrite )(struct lib9p_srv_ctx *, struct lib9p_srv_file *, + uint32_t (*pwrite )(struct lib9p_srv_file *, struct lib9p_srv_ctx *, void *buf, uint32_t byte_count, uint64_t byte_offset); }; -/* objects you'll deal with ***************************************************/ - -struct lib9p_srv_file { +typedef struct lib9p_srv_file { struct lib9p_srv_file_vtable *vtable; /* Managed by srv.c, but should be cloned by ->vtable->clone(). */ @@ -90,11 +89,8 @@ struct lib9p_srv_file { /* Managed by srv.c, but should be initialized to 0 by ->vtable->clone(). */ /* ref type 1: an entry in fidmap * ref type 2: ->_parent_dir of another file */ - struct lib9p_srv_file *_refcount; - - /* This is where your implementation data goes. */ - char data[0]; -}; + unsigned int _refcount; +} implements_lib9p_srv_file; /* main server entrypoints ****************************************************/ @@ -119,7 +115,7 @@ struct lib9p_srv { * @errno LINUX_ERANGE R-message does not fit into max_msg_size */ -__attribute__ ((noreturn)) void lib9p_srv_read_cr(struct lib9p_srv *srv, struct libnet_listener *listener); +__attribute__ ((noreturn)) void lib9p_srv_read_cr(struct lib9p_srv *srv, implements_net_listener *listener); COROUTINE lib9p_srv_write_cr(void *_srv); #endif /* _LIB9P_SRV_H_ */ diff --git a/lib9p/internal.h b/lib9p/internal.h index 013024e..d78823d 100644 --- a/lib9p/internal.h +++ b/lib9p/internal.h @@ -45,7 +45,7 @@ static_assert(CONFIG_9P_MAX_HOSTMSG_SIZE <= SSIZE_MAX); #define CAT2(a, b) a##b #define CAT3(a, b, c) a##b##c -/* vtables ********************************************************************/ +/* specialized contexts *******************************************************/ struct _validate_ctx { struct lib9p_ctx *ctx; @@ -77,18 +77,21 @@ struct _marshal_ctx { }; typedef bool (*_marshal_fn_t)(struct _marshal_ctx *ctx, void *host_val); -struct _vtable_msg { +/* tables *********************************************************************/ + +struct _table_msg { + char *name; size_t basesize; _validate_fn_t validate; _unmarshal_fn_t unmarshal; _marshal_fn_t marshal; }; -struct _vtable_version { - struct _vtable_msg msgs[0xFF]; +struct _table_version { + struct _table_msg msgs[0x100]; }; -extern struct _vtable_version _lib9p_vtables[LIB9P_VER_NUM]; +extern struct _table_version _lib9p_versions[LIB9P_VER_NUM]; bool _lib9p_validate_stat(struct _validate_ctx *ctx); void _lib9p_unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9p_stat *out); diff --git a/lib9p/srv.c b/lib9p/srv.c index 90791f3..cc4a048 100644 --- a/lib9p/srv.c +++ b/lib9p/srv.c @@ -14,15 +14,13 @@ #include #include #include -#include +#include #include #include "internal.h" /* structs ********************************************************************/ -#define MCALL(o, m, ...) (o)->vtable->m(o __VA_OPT__(,) __VA_ARGS__) - #define FIDFLAG_OPEN_R (1<<0) #define FIDFLAG_OPEN_W (1<<1) #define FIDFLAG_RCLOSE (1<<2) @@ -59,7 +57,7 @@ struct _srv_fidinfo { struct _srv_conn { /* immutable */ struct lib9p_srv *parent_srv; - struct libnet_conn *fd; + implements_net_conn *fd; cid_t reader; /* the lib9p_srv_read_cr() coroutine */ /* mutable */ cr_mutex_t writelock; @@ -151,7 +149,7 @@ static void respond_error(struct _lib9p_srv_req *req) { &host, req->net_bytes); cr_mutex_lock(&sess->parent_conn->writelock); - r = MCALL(sess->parent_conn->fd, write, + r = VCALL(sess->parent_conn->fd, write, req->net_bytes, decode_u32le(req->net_bytes)); cr_mutex_unlock(&sess->parent_conn->writelock); if (r < 0) @@ -160,12 +158,12 @@ static void respond_error(struct _lib9p_srv_req *req) { /* read coroutine *************************************************************/ -static bool read_at_least(struct libnet_conn *fd, uint8_t *buf, size_t goal, size_t *done) { +static bool read_at_least(implements_net_conn *fd, uint8_t *buf, size_t goal, size_t *done) { assert(buf); assert(goal); assert(done); while (*done < goal) { - ssize_t r = MCALL(fd, read, &buf[*done], CONFIG_9P_MAX_MSG_SIZE - *done); + ssize_t r = VCALL(fd, read, &buf[*done], CONFIG_9P_MAX_MSG_SIZE - *done); if (r < 0) { nonrespond_errorf("read: %s", strerror(-r)); return true; @@ -181,7 +179,7 @@ static bool read_at_least(struct libnet_conn *fd, uint8_t *buf, size_t goal, siz static void handle_message(struct _lib9p_srv_req *ctx); -__attribute__ ((noreturn)) void lib9p_srv_read_cr(struct lib9p_srv *srv, struct libnet_listener *listener) { +__attribute__ ((noreturn)) void lib9p_srv_read_cr(struct lib9p_srv *srv, implements_net_listener *listener) { uint8_t buf[CONFIG_9P_MAX_MSG_SIZE]; assert(srv); @@ -193,7 +191,7 @@ __attribute__ ((noreturn)) void lib9p_srv_read_cr(struct lib9p_srv *srv, struct for (;;) { struct _srv_conn conn = { .parent_srv = srv, - .fd = MCALL(listener, accept), + .fd = VCALL(listener, accept), .reader = cr_getcid(), }; if (!conn.fd) { @@ -253,12 +251,12 @@ __attribute__ ((noreturn)) void lib9p_srv_read_cr(struct lib9p_srv *srv, struct _lib9p_srv_reqch_send_req(&srv->_reqch, &req); } close: - MCALL(conn.fd, close, true, sess.reqs.len == 0); + VCALL(conn.fd, close, true, sess.reqs.len == 0); if (sess.reqs.len) { sess.closing = true; cr_pause_and_yield(); assert(sess.reqs.len == 0); - MCALL(conn.fd, close, true, true); + VCALL(conn.fd, close, true, true); } } } @@ -358,7 +356,7 @@ static void handle_message(struct _lib9p_srv_req *ctx) { if (typ % 2 != 0) { lib9p_errorf(&ctx->ctx.basectx, LINUX_EOPNOTSUPP, "expected a T-message but got an R-message: message_type=%s", - lib9p_msg_type_str(typ)); + lib9p_msg_type_str(&ctx->ctx.basectx, typ)); goto write; } ssize_t host_size = lib9p_validate(&ctx->ctx.basectx, ctx->net_bytes); @@ -385,17 +383,17 @@ static void handle_message(struct _lib9p_srv_req *ctx) { goto write; cr_mutex_lock(&ctx->parent_sess->parent_conn->writelock); - MCALL(ctx->parent_sess->parent_conn->fd, write, + VCALL(ctx->parent_sess->parent_conn->fd, write, ctx->net_bytes, decode_u32le(ctx->net_bytes)); cr_mutex_unlock(&ctx->parent_sess->parent_conn->writelock); } } #define util_handler_common(ctx, req, resp) do { \ - assert(ctx); \ - assert(req); \ - assert(resp); \ - resp->tag = req->tag; \ + assert(ctx); \ + assert(req); \ + assert(resp); \ + resp->tag = req->tag; \ } while (0) static inline bool util_check_perm(struct lib9p_srv_ctx *ctx, struct lib9p_stat *stat, uint8_t action) { @@ -415,7 +413,7 @@ static inline bool util_release(struct lib9p_srv_ctx *ctx, struct lib9p_srv_file if (file->_refcount == 0) { if (file->_parent_dir != file) util_release(ctx, file->_parent_dir); - file->vtable->free(ctx, file); + VCALL(file, free, ctx); } return lib9p_ctx_has_error(&ctx->basectx); } @@ -437,11 +435,11 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx, (req->version.utf8[6] == '\0' || req->version.utf8[6] == '.')) { version = LIB9P_VER_9P2000; #ifdef CONFIG_9P_ENABLE_9P2000_u - if (strcmp((char *)&req->version.utf8[6], ".u") == 0) + if (strcmp(&req->version.utf8[6], ".u") == 0) version = LIB9P_VER_9P2000_u; #endif #ifdef CONFIG_9P_ENABLE_9P2000_e - if (strcmp((char *)&req->version.utf8[6], ".e") == 0) + if (strcmp(&req->version.utf8[6], ".e") == 0) version = LIB9P_VER_9P2000_e; #endif } @@ -458,7 +456,7 @@ static void handle_Tversion(struct _lib9p_srv_req *ctx, #pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" resp->version.utf8 = lib9p_version_str(version); #pragma GCC diagnostic pop - resp->version.len = strlen((char *)resp->version.utf8); + resp->version.len = strlen(resp->version.utf8); resp->max_msg_size = (CONFIG_9P_MAX_MSG_SIZE < req->max_msg_size) ? CONFIG_9P_MAX_MSG_SIZE : req->max_msg_size; @@ -583,7 +581,7 @@ static void handle_Tattach(struct _lib9p_srv_req *ctx, return; } - struct lib9p_stat stat = rootdir->vtable->stat(&ctx->ctx, rootdir); + struct lib9p_stat stat = VCALL(rootdir, stat, &ctx->ctx); if (lib9p_ctx_has_error(&ctx->ctx.basectx)) { handle_Tclunk(ctx, &(struct lib9p_msg_Tclunk){.fid = req->fid}, @@ -627,7 +625,7 @@ static void handle_Twalk(struct _lib9p_srv_req *ctx, struct lib9p_srv_file *dir = fidinfo->file; if (req->newfid != req->fid) { - dir = dir->vtable->clone(&ctx->ctx, dir); + dir = VCALL(dir, clone, &ctx->ctx); assert((dir == NULL) == lib9p_ctx_has_error(&ctx->ctx.basectx)); if (lib9p_ctx_has_error(&ctx->ctx.basectx)) return; @@ -647,7 +645,7 @@ static void handle_Twalk(struct _lib9p_srv_req *ctx, break; } - member = dir->vtable->dopen(&ctx->ctx, dir, req->wname[resp->nwqid].utf8); + member = VCALL(dir, dopen, &ctx->ctx, req->wname[resp->nwqid].utf8); assert((member == NULL) == lib9p_ctx_has_error(&ctx->ctx.basectx)); if (lib9p_ctx_has_error(&ctx->ctx.basectx)) break; @@ -656,7 +654,7 @@ static void handle_Twalk(struct _lib9p_srv_req *ctx, } member->_refcount++; /* presumptively take ref-A */ - struct lib9p_stat stat = member->vtable->stat(&ctx->ctx, member); + struct lib9p_stat stat = VCALL(member, stat, &ctx->ctx); if (lib9p_ctx_has_error(&ctx->ctx.basectx)) { util_release(&ctx->ctx, member); /* presumption of taking ref-A failed */ break; @@ -733,7 +731,7 @@ static void handle_Topen(struct _lib9p_srv_req *ctx, /* Check permissions. */ if (reqmode & LIB9P_O_RCLOSE) { - struct lib9p_stat parent_stat = file->_parent_dir->vtable->stat(&ctx->ctx, file->_parent_dir); + struct lib9p_stat parent_stat = VCALL(file->_parent_dir, stat, &ctx->ctx); if (lib9p_ctx_has_error(&ctx->ctx.basectx)) return; lib9p_assert_stat(parent_stat); @@ -744,7 +742,7 @@ static void handle_Topen(struct _lib9p_srv_req *ctx, } fidflags = fidflags | FIDFLAG_RCLOSE; } - struct lib9p_stat stat = file->vtable->stat(&ctx->ctx, file); + struct lib9p_stat stat = VCALL(file, stat, &ctx->ctx); if (lib9p_ctx_has_error(&ctx->ctx.basectx)) return; lib9p_assert_stat(stat); @@ -775,7 +773,7 @@ static void handle_Topen(struct _lib9p_srv_req *ctx, } /* Actually make the call. */ - uint32_t iounit = file->vtable->io(&ctx->ctx, file, reqmode); + uint32_t iounit = VCALL(file, io, &ctx->ctx, reqmode); if (lib9p_ctx_has_error(&ctx->ctx.basectx)) return; @@ -831,7 +829,7 @@ static void handle_Tread(struct _lib9p_srv_req *ctx, return; } /* Do it. */ - size_t num = file->vtable->dread(&ctx->ctx, file, (uint8_t *)resp->data.dat, req->count, idx); + size_t num = VCALL(file, dread, &ctx->ctx, (uint8_t *)resp->data.dat, req->count, idx); /* Translate object-count back to byte-count. */ uint32_t len = 0; for (size_t i = 0; i < num; i++) { @@ -844,7 +842,7 @@ static void handle_Tread(struct _lib9p_srv_req *ctx, fidinfo->dir_idx = idx+num; fidinfo->dir_off = req->offset + len; } else - resp->data.len = file->vtable->pread(&ctx->ctx, file, resp->data.dat, req->count, req->offset); + resp->data.len = VCALL(file, pread, &ctx->ctx, resp->data.dat, req->count, req->offset); } static void handle_Twrite(struct _lib9p_srv_req *ctx, @@ -869,7 +867,7 @@ static void handle_Twrite(struct _lib9p_srv_req *ctx, struct lib9p_srv_file *file = fidinfo->file; /* Do it. */ - resp->count = file->vtable->pwrite(&ctx->ctx, file, req->data.dat, req->data.len, req->offset); + resp->count = VCALL(file, pwrite, &ctx->ctx, req->data.dat, req->data.len, req->offset); } static void handle_Tclunk(struct _lib9p_srv_req *ctx, @@ -890,7 +888,7 @@ static void handle_Tclunk(struct _lib9p_srv_req *ctx, return; } - fidinfo->file->vtable->free(&ctx->ctx, fidinfo->file); + VCALL(fidinfo->file, free, &ctx->ctx); fidmap_del(&ctx->parent_sess->fids, req->fid); } @@ -915,7 +913,7 @@ static void handle_Tstat(struct _lib9p_srv_req *ctx, return; } - resp->stat = fidinfo->file->vtable->stat(&ctx->ctx, fidinfo->file); + resp->stat = VCALL(fidinfo->file, stat, &ctx->ctx); if (!lib9p_ctx_has_error(&ctx->ctx.basectx)) lib9p_assert_stat(resp->stat); } diff --git a/libmisc/CMakeLists.txt b/libmisc/CMakeLists.txt new file mode 100644 index 0000000..f42f36f --- /dev/null +++ b/libmisc/CMakeLists.txt @@ -0,0 +1,8 @@ +# libmisc/CMakeLists.txt - A simple Go-ish object system built on GCC -fplan9-extensions +# +# Copyright (C) 2024 Luke T. Shumaker +# SPDX-Licence-Identifier: AGPL-3.0-or-later + +add_library(libmisc INTERFACE) +target_include_directories(libmisc SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_compile_options(libmisc INTERFACE "$<$:-fplan9-extensions>") diff --git a/libmisc/include/libmisc/net.h b/libmisc/include/libmisc/net.h new file mode 100644 index 0000000..bb5999b --- /dev/null +++ b/libmisc/include/libmisc/net.h @@ -0,0 +1,64 @@ +/* libmisc/net.h - Base definitions for network interfaces + * + * Copyright (C) 2024 Luke T. Shumaker + * SPDX-Licence-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIBMISC_NET_H_ +#define _LIBMISC_NET_H_ + +#include /* for bool */ +#include /* for size_t */ +#include /* for ssize_t */ + +struct net_ip4_addr { + unsigned char octets[4]; +}; + +struct net_eth_addr { + unsigned char octets[6]; +}; + +struct net_conn; +struct net_listener; + +struct net_listener_vtable { + /** + * It is invalid to accept() a new connection if an existing + * connection is still open. + */ + struct net_conn *(*accept)(struct net_listener *self); +}; + +struct net_conn_vtable { + /** + * Return bytes-read on success, 0 on EOF, -errno on error; a + * short read is *not* an error. + */ + ssize_t (*read)(struct net_conn *self, void *buf, size_t count); + + /** + * Return `count` on success, -errno on error; a short write *is* an + * error. + * + * Writes are *not* guaranteed to be atomic (as this would be + * expensive to implement), so if you have concurrent writers then you + * should arrange for a mutex to protect the connection. + */ + ssize_t (*write)(struct net_conn *self, void *buf, size_t count); + + /** + * Return 0 on success, -errno on error. + */ + int (*close)(struct net_conn *self, bool rd, bool wr); +}; + +typedef struct net_listener { + struct net_listener_vtable *vtable; +} implements_net_listener; + +typedef struct net_conn { + struct net_conn_vtable *vtable; +} implements_net_conn; + +#endif /* _LIBMISC_NET_H_ */ diff --git a/libmisc/include/libmisc/vcall.h b/libmisc/include/libmisc/vcall.h new file mode 100644 index 0000000..c3562ee --- /dev/null +++ b/libmisc/include/libmisc/vcall.h @@ -0,0 +1,27 @@ +/* libmisc/vcall.h - A simple Go-ish object system built on GCC -fplan9-extensions + * + * Copyright (C) 2024 Luke T. Shumaker + * SPDX-Licence-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIBMISC_VCALL_H_ +#define _LIBMISC_VCALL_H_ + +#include /* for assert() and static_assert() */ +#include /* for offsetof() */ + +#define VCALL(o, m, ...) \ + ({ \ + assert(o); \ + (o)->vtable->m(o __VA_OPT__(,) __VA_ARGS__); \ + }) + +#define VCALL_SELF(obj_typ, iface_typ, iface_ptr) \ + ({ \ + static_assert(_Generic(iface_ptr, iface_typ *: 1, default: 0), \ + "typeof("#iface_ptr") != "#iface_typ); \ + assert(iface_ptr); \ + ((obj_typ*)(((void*)iface_ptr)-offsetof(obj_typ,iface_typ))); \ + }) + +#endif /* _LIBMISC_VCALL_H_ */ diff --git a/libnet/CMakeLists.txt b/libnet/CMakeLists.txt deleted file mode 100644 index 32047f0..0000000 --- a/libnet/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# libnet/CMakeLists.txt - Build script for libnet support library -# -# Copyright (C) 2024 Luke T. Shumaker -# SPDX-Licence-Identifier: AGPL-3.0-or-later - -add_library(libnet INTERFACE) -target_include_directories(libnet SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) diff --git a/libnet/include/libnet/libnet.h b/libnet/include/libnet/libnet.h deleted file mode 100644 index 022e922..0000000 --- a/libnet/include/libnet/libnet.h +++ /dev/null @@ -1,70 +0,0 @@ -/* libnet/libnet.h - Base definitions for network interfaces - * - * Copyright (C) 2024 Luke T. Shumaker - * SPDX-Licence-Identifier: AGPL-3.0-or-later - */ - -#ifndef _NETIO_H_ -#define _NETIO_H_ - -#include /* for bool */ -#include /* for size_t */ -#include /* for ssize_t */ - -struct ip4_addr { - unsigned char bytes[4]; -}; - -struct eth_addr { - unsigned char bytes[6]; -}; - -struct libnet_conn; -struct libnet_listener; - -struct libnet_listener_vtable { - /** - * It is invalid to accept() a new connection if an existing - * connection is still open. - */ - struct libnet_conn *(*accept)(struct libnet_listener *self); -}; - -struct libnet_conn_vtable { - /** - * Return bytes-read on success, 0 on EOF, -errno on error; a - * short read is *not* an error. - */ - ssize_t (*read)(struct libnet_conn *self, void *buf, size_t count); - - /** - * Return `count` on success, -errno on error; a short write *is* an - * error. - * - * Writes are *not* guaranteed to be atomic (as this would be - * expensive to implement), so if you have concurrent writers then you - * should arrange for a mutex to protect the connection. - */ - ssize_t (*write)(struct libnet_conn *self, void *buf, size_t count); - - /** - * Return 0 on success, -errno on error. - */ - int (*close)(struct libnet_conn *self, bool rd, bool wr); -}; - -struct libnet_listener { - struct libnet_listener_vtable *vtable; - - /* This is where your implementation data goes. */ - char data[0]; -}; - -struct libnet_conn { - struct libnet_conn_vtable *vtable; - - /* This is where your implementation data goes. */ - char data[0]; -}; - -#endif /* _NETIO_H_ */ -- cgit v1.2.3-2-g168b