commit: 35ca9b62694daf321371979e83dcd2e9215772a6 Author: Michał Górny <mgorny <AT> gentoo <DOT> org> AuthorDate: Sat Nov 22 15:18:18 2025 +0000 Commit: Michał Górny <mgorny <AT> gentoo <DOT> org> CommitDate: Sat Nov 22 15:18:18 2025 +0000 URL: https://gitweb.gentoo.org/proj/steve.git/commit/?id=35ca9b62
Switch to low-level loop API Signed-off-by: Michał Górny <mgorny <AT> gentoo.org> steve.cxx | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/steve.cxx b/steve.cxx index a837a4a..50067d6 100644 --- a/steve.cxx +++ b/steve.cxx @@ -2,9 +2,10 @@ * (c) 2025 Michał Górny * SPDX-License-Identifier: GPL-2.0-or-later * - * Inspired by CUSE example and nixos-jobserver (draft): + * Inspired by CUSE example, nixos-jobserver (draft) and guildmaster: * https://github.com/libfuse/libfuse/blob/f58d4c5b0d56116d8870753f6b9d1620ee082709/example/cuse.c * https://github.com/RaitoBezarius/nixpkgs/blob/e97220ecf1e8887b949e4e16547bf0334826d076/pkgs/by-name/ni/nixos-jobserver/nixos-jobserver.cpp#L213 + * https://codeberg.org/amonakov/guildmaster/ */ #define FUSE_USE_VERSION 31 @@ -15,6 +16,9 @@ #include <cerrno> #include <csignal> #include <deque> +#include <functional> +#include <memory> +#include <string> #include <unordered_map> #include <sys/poll.h> @@ -32,7 +36,6 @@ static const char *usage = " --jobs=JOBS|-j JOBS jobs to use (default: nproc)\n" " --verbose|-v enable verbose logging\n" " -d -o debug enable debug output (implies -f)\n" -" -f foreground operation\n" "\n"; struct steve_read_waiter { @@ -321,33 +324,56 @@ static void steve_handle_sigusr1(int, siginfo_t *, void *) { int main(int argc, char **argv) { - struct fuse_args args = FUSE_ARGS_INIT(argc, argv); - const char *dev_name = "DEVNAME=steve"; - const char *dev_info_argv[] = { dev_name }; - struct cuse_info ci = { 0 }; steve_state state = { 0 }; - struct sigaction sigact = { 0 }; - int ret; + struct fuse_args args = FUSE_ARGS_INIT(argc, argv); if (fuse_opt_parse(&args, &state, steve_opts, steve_process_arg)) { fprintf(stderr, "failed to parse option\n"); fuse_opt_free_args(&args); return 1; } - /* probably not worth bothering with multithreading */ - fuse_opt_add_arg(&args, "-s"); + int cuse_fd = open("/dev/cuse", O_RDWR); + if (cuse_fd == -1) { + perror("unable to open /dev/cuse"); + fuse_opt_free_args(&args); + return 1; + } + + const char *dev_name = "DEVNAME=steve"; + const char *dev_info_argv[] = { dev_name }; + struct cuse_info ci = { 0 }; ci.dev_info_argc = 1; ci.dev_info_argv = dev_info_argv; if (state.jobs == 0) state.jobs = sysconf(_SC_NPROCESSORS_ONLN); + std::unique_ptr<struct fuse_session, std::function<void(struct fuse_session*)>> session{ + cuse_lowlevel_new(&args, &ci, &steve_ops, &state), fuse_session_destroy}; + if (!session) { + fprintf(stderr, "failed to initialize FUSE"); + close(cuse_fd); + fuse_opt_free_args(&args); + return 1; + } + + std::string mountpoint = "/dev/fd/" + std::to_string(cuse_fd); + if (fuse_session_mount(session.get(), mountpoint.c_str()) == -1) { + fprintf(stderr, "failed to mount the filesystem"); + close(cuse_fd); + fuse_opt_free_args(&args); + return 1; + } + steve_global_state = &state; + struct sigaction sigact = { 0 }; sigact.sa_flags = SA_SIGINFO; sigact.sa_sigaction = steve_handle_sigusr1; sigaction(SIGUSR1, &sigact, NULL); - ret = cuse_lowlevel_main(args.argc, args.argv, &ci, &steve_ops, &state); + int ret = fuse_session_loop(session.get()); + fuse_session_unmount(session.get()); + close(cuse_fd); fuse_opt_free_args(&args); - return ret; + return !!ret; }
