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;
 }

Reply via email to