diff options
Diffstat (limited to 'lib9p/tests/test_server')
-rw-r--r-- | lib9p/tests/test_server/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_slowread.c | 101 | ||||
-rw-r--r-- | lib9p/tests/test_server/fs_slowread.h | 22 | ||||
-rw-r--r-- | lib9p/tests/test_server/main.c | 63 |
4 files changed, 171 insertions, 16 deletions
diff --git a/lib9p/tests/test_server/CMakeLists.txt b/lib9p/tests/test_server/CMakeLists.txt index 19c8edb..eb16165 100644 --- a/lib9p/tests/test_server/CMakeLists.txt +++ b/lib9p/tests/test_server/CMakeLists.txt @@ -10,6 +10,7 @@ if (PICO_PLATFORM STREQUAL "host") add_library(test_server_objs OBJECT main.c fs_shutdown.c + fs_slowread.c ) target_include_directories(test_server_objs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/config) target_include_directories(test_server_objs PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/lib9p/tests/test_server/fs_slowread.c b/lib9p/tests/test_server/fs_slowread.c new file mode 100644 index 0000000..520edd2 --- /dev/null +++ b/lib9p/tests/test_server/fs_slowread.c @@ -0,0 +1,101 @@ +/* lib9p/tests/test_server/fs_slowread.c - slowread API endpoint + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include "fs_slowread.h" + +LO_IMPLEMENTATION_C(lib9p_srv_file, struct slowread_file, slowread_file, static); + +LO_IMPLEMENTATION_H(lib9p_srv_fio, struct slowread_file, slowread_file); +LO_IMPLEMENTATION_C(lib9p_srv_fio, struct slowread_file, slowread_file, static); + +/* srv_file *******************************************************************/ + +static void slowread_file_free(struct slowread_file *self) { + assert(self); +} +static struct lib9p_qid slowread_file_qid(struct slowread_file *self) { + assert(self); + return (struct lib9p_qid){ + .type = LIB9P_QT_FILE, + .vers = 1, + .path = self->pathnum, + }; +} + +static struct lib9p_stat slowread_file_stat(struct slowread_file *self, struct lib9p_srv_ctx *ctx) { + assert(self); + assert(ctx); + return (struct lib9p_stat){ + .kern_type = 0, + .kern_dev = 0, + .file_qid = slowread_file_qid(self), + .file_mode = 0444, + .file_atime = UTIL9P_ATIME, + .file_mtime = UTIL9P_MTIME, + .file_size = 6, + .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, + }; +} +static void slowread_file_wstat(struct slowread_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 slowread_file_remove(struct slowread_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 slowread_file, slowread_file) + +static lo_interface lib9p_srv_fio slowread_file_fopen(struct slowread_file *self, struct lib9p_srv_ctx *ctx, bool, bool, bool) { + assert(self); + assert(ctx); + return lo_box_slowread_file_as_lib9p_srv_fio(self); +} + +/* srv_fio ********************************************************************/ + +static void slowread_file_iofree(struct slowread_file *self) { + assert(self); +} + +static uint32_t slowread_file_iounit(struct slowread_file *self) { + assert(self); + return 0; +} + +static uint32_t slowread_file_pwrite(struct slowread_file *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 slowread_file_pread(struct slowread_file *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); + + while (!lib9p_srv_flush_requested(ctx)) + cr_yield(); + if (self->flushable) + lib9p_srv_acknowledge_flush(ctx); + else + *ret = (struct iovec){ + .iov_base = "Sloth\n", + .iov_len = 6 < byte_count ? 6 : byte_count, + }; +} diff --git a/lib9p/tests/test_server/fs_slowread.h b/lib9p/tests/test_server/fs_slowread.h new file mode 100644 index 0000000..ef4b65f --- /dev/null +++ b/lib9p/tests/test_server/fs_slowread.h @@ -0,0 +1,22 @@ +/* lib9p/tests/test_server/fs_slowread.h - slowread 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_SLOWREAD_H_ +#define _LIB9P_TESTS_TEST_SERVER_FS_SLOWREAD_H_ + +#include <util9p/static.h> +#include <libhw/host_net.h> + +struct slowread_file { + char *name; + uint64_t pathnum; + + bool flushable; +}; +LO_IMPLEMENTATION_H(lib9p_srv_file, struct slowread_file, slowread_file); +#define lo_box_slowread_file_as_lib9p_srv_file(obj) util9p_box(slowread_file, obj) + +#endif /* _LIB9P_TESTS_TEST_SERVER_FS_SLOWREAD_H_ */ diff --git a/lib9p/tests/test_server/main.c b/lib9p/tests/test_server/main.c index 8d22a04..2743629 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> @@ -18,6 +20,7 @@ #include "static.h" #include "fs_shutdown.h" +#include "fs_slowread.h" /* configuration **************************************************************/ @@ -37,6 +40,7 @@ struct { uint16_t port; struct hostnet_tcp_listener listeners[CONFIG_SRV9P_NUM_CONNS]; struct lib9p_srv srv; + FILE *logstream; } globals = { .srv = (struct lib9p_srv){ .rootdir = get_root, @@ -45,32 +49,33 @@ struct { /* 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(STRNAME, SYMNAME, ...) \ +#define API_FILE(N, STRNAME, SYMNAME, ...) \ lo_box_##SYMNAME##_file_as_lib9p_srv_file(&((struct SYMNAME##_file){ \ .name = STRNAME, \ - .pathnum = PATH_COUNTER \ + .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), - API_FILE("shutdown", shutdown, + STATIC_FILE(4, "README.md", README_md), + API_FILE(5, "shutdown", shutdown, .listeners = globals.listeners, .nlisteners = LM_ARRAY_LEN(globals.listeners)), + API_FILE(6, "slowread", slowread, + .flushable = false), + API_FILE(7, "slowread-flushable", slowread, + .flushable = true), ); static lo_interface lib9p_srv_file get_root(struct lib9p_srv_ctx *LM_UNUSED(ctx), struct lib9p_s LM_UNUSED(treename)) { @@ -109,15 +114,41 @@ static COROUTINE init_cr(void *) { 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; } |