From 25d6447555199c34cc388030a5f69d98cbae163f Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Fri, 20 Mar 2026 14:01:40 -0500 Subject: [PATCH] Convert vendored/libfuse C sources to C++17 Convert all C source files in vendored/libfuse/ to C++17: - lib/crc32b.c -> crc32b.cpp (const void* cast) - lib/fuse_opt.c -> fuse_opt.cpp (designated init, void* arithmetic) - lib/fuse_signals.c -> fuse_signals.cpp - lib/helper.c -> helper.cpp (void* data cast) - lib/mount.c -> mount.cpp (thin wrapper) - lib/mount_generic.c -> mount_generic.h (static inline, #pragma once) - lib/mount_bsd.c -> mount_bsd.h (static inline, #pragma once) - lib/mount_util.c -> mount_util.h (static inline, #pragma once) - util/fusermount.c -> fusermount.cpp - util/mount.mergerfs.c -> mount.mergerfs.cpp Key changes: - Replace C99 designated initializer in fuse_opt_parse with field-by-field init - Fix void* pointer arithmetic via char* base + offset pattern - All C-style (T*)voidptr casts replaced with static_cast/reinterpret_cast - Remove redundant #define _GNU_SOURCE (already in FUSE_FLAGS) - Wrap __clone2 declaration in extern "C" for ia64 path - Update Makefile: empty SRC_C, build utils with $(CXX) instead of $(CC) - Remove stale .c files now replaced by .cpp/.h counterparts All binaries build cleanly: mergerfs, mergerfs-fusermount, mount.mergerfs --- vendored/libfuse/Makefile | 15 +- vendored/libfuse/lib/{crc32b.c => crc32b.cpp} | 4 +- .../libfuse/lib/{fuse_opt.c => fuse_opt.cpp} | 29 +- .../lib/{fuse_signals.c => fuse_signals.cpp} | 0 vendored/libfuse/lib/{helper.c => helper.cpp} | 2 +- vendored/libfuse/lib/mount.cpp | 19 + vendored/libfuse/lib/{mount.c => mount.hpp} | 8 +- .../libfuse/lib/{mount_bsd.c => mount_bsd.h} | 4 +- .../lib/{mount_generic.c => mount_generic.h} | 12 +- vendored/libfuse/lib/mount_util.c | 331 ------------------ vendored/libfuse/lib/mount_util.h | 325 ++++++++++++++++- .../util/{fusermount.c => fusermount.cpp} | 20 +- .../{mount.mergerfs.c => mount.mergerfs.cpp} | 6 +- vendored/libfuse/util/mount_util.c | 330 ----------------- 14 files changed, 391 insertions(+), 714 deletions(-) rename vendored/libfuse/lib/{crc32b.c => crc32b.cpp} (98%) rename vendored/libfuse/lib/{fuse_opt.c => fuse_opt.cpp} (93%) rename vendored/libfuse/lib/{fuse_signals.c => fuse_signals.cpp} (100%) rename vendored/libfuse/lib/{helper.c => helper.cpp} (99%) create mode 100644 vendored/libfuse/lib/mount.cpp rename vendored/libfuse/lib/{mount.c => mount.hpp} (90%) rename vendored/libfuse/lib/{mount_bsd.c => mount_bsd.h} (98%) rename vendored/libfuse/lib/{mount_generic.c => mount_generic.h} (97%) delete mode 100644 vendored/libfuse/lib/mount_util.c rename vendored/libfuse/util/{fusermount.c => fusermount.cpp} (98%) rename vendored/libfuse/util/{mount.mergerfs.c => mount.mergerfs.cpp} (96%) delete mode 100644 vendored/libfuse/util/mount_util.c diff --git a/vendored/libfuse/Makefile b/vendored/libfuse/Makefile index b639b003..10117691 100644 --- a/vendored/libfuse/Makefile +++ b/vendored/libfuse/Makefile @@ -76,12 +76,7 @@ INSTALLMAN1DIR ?= $(DESTDIR)$(MAN1DIR) BUILDDIR := build -SRC_C = \ - lib/crc32b.c \ - lib/fuse_opt.c \ - lib/fuse_signals.c \ - lib/helper.c \ - lib/mount.c +SRC_C = SRC_CXX = $(wildcard lib/*.cpp) OBJS := $(SRC_C:lib/%.c=$(BUILDDIR)/.objs/%.c.o) @@ -144,14 +139,14 @@ $(BUILDDIR)/libfuse.a: $(OBJS) .PHONY: utils utils: mergerfs-fusermount mount.mergerfs -$(BUILDDIR)/mergerfs-fusermount: util/fusermount.c lib/mount_util.c - $(CC) $(CFLAGS) $(FUSE_FLAGS) -Ilib -o $(BUILDDIR)/mergerfs-fusermount util/fusermount.c lib/mount_util.c +$(BUILDDIR)/mergerfs-fusermount: util/fusermount.cpp + $(CXX) $(CXXFLAGS) $(FUSE_FLAGS) -Ilib -o $(BUILDDIR)/mergerfs-fusermount util/fusermount.cpp mergerfs-fusermount: $(BUILDDIR)/mergerfs-fusermount -$(BUILDDIR)/mount.mergerfs: $(BUILDDIR)/libfuse.a util/mount.mergerfs.c +$(BUILDDIR)/mount.mergerfs: $(BUILDDIR)/libfuse.a util/mount.mergerfs.cpp echo STATIC=$(STATIC) $(STATIC_FLAGS) - $(CC) $(CFLAGS) $(FUSE_FLAGS) -o $(BUILDDIR)/mount.mergerfs util/mount.mergerfs.c $(BUILDDIR)/libfuse.a $(LDFLAGS) + $(CXX) $(CXXFLAGS) $(FUSE_FLAGS) -o $(BUILDDIR)/mount.mergerfs util/mount.mergerfs.cpp $(BUILDDIR)/libfuse.a $(LDFLAGS) mount.mergerfs: $(BUILDDIR)/mount.mergerfs diff --git a/vendored/libfuse/lib/crc32b.c b/vendored/libfuse/lib/crc32b.cpp similarity index 98% rename from vendored/libfuse/lib/crc32b.c rename to vendored/libfuse/lib/crc32b.cpp index f51605a9..980340a8 100644 --- a/vendored/libfuse/lib/crc32b.c +++ b/vendored/libfuse/lib/crc32b.cpp @@ -78,12 +78,12 @@ crc32b_continue(const void *buf_, const crc32b_t len_, const crc32b_t crc_) { - char *buf; + const char *buf; crc32b_t i; crc32b_t crc; crc = crc_; - buf = (char*)buf_; + buf = static_cast(buf_); for(i = 0; i < len_; i++) { crc = (CRC32BTABLE[(crc ^ buf[i]) & 0xFFL] ^ (crc >> 8)); diff --git a/vendored/libfuse/lib/fuse_opt.c b/vendored/libfuse/lib/fuse_opt.cpp similarity index 93% rename from vendored/libfuse/lib/fuse_opt.c rename to vendored/libfuse/lib/fuse_opt.cpp index f363e17c..89bd9e80 100644 --- a/vendored/libfuse/lib/fuse_opt.c +++ b/vendored/libfuse/lib/fuse_opt.cpp @@ -64,7 +64,7 @@ fuse_opt_add_arg(struct fuse_args *args, const char *arg) if (!newarg) return alloc_failed(); - newargv = realloc(args->argv, (args->argc + 2) * sizeof(char *)); + newargv = static_cast(realloc(args->argv, (args->argc + 2) * sizeof(char *))); if (!newargv) { free(newarg); @@ -120,7 +120,7 @@ static int add_arg(struct fuse_opt_context *ctx, const char *arg) static int add_opt_common(char **opts, const char *opt, int esc) { unsigned oldlen = *opts ? strlen(*opts) : 0; - char *d = realloc(*opts, oldlen + 1 + strlen(opt) * 2 + 1); + char *d = static_cast(realloc(*opts, oldlen + 1 + strlen(opt) * 2 + 1)); if (!d) return alloc_failed(); @@ -224,9 +224,9 @@ static int process_opt_param(void *var, const char *format, const char *param, if (!copy) return alloc_failed(); - *(char **) var = copy; + *static_cast(var) = copy; } else { - if (sscanf(param, format, var) != 1) { + if (sscanf(param, format, static_cast(var)) != 1) { fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg); return -1; } @@ -243,7 +243,7 @@ static int process_opt(struct fuse_opt_context *ctx, if (call_proc(ctx, arg, opt->value, iso) == -1) return -1; } else { - void *var = ctx->data + opt->offset; + char *var = static_cast(ctx->data) + opt->offset; if (sep && opt->templ[sep + 1]) { const char *param = arg + sep; @@ -253,7 +253,7 @@ static int process_opt(struct fuse_opt_context *ctx, param, arg) == -1) return -1; } else - *(int *)var = opt->value; + *static_cast(static_cast(var)) = opt->value; } return 0; } @@ -270,7 +270,7 @@ static int process_opt_sep_arg(struct fuse_opt_context *ctx, return -1; param = ctx->argv[ctx->argctr]; - newarg = malloc(sep + strlen(param) + 1); + newarg = static_cast(malloc(sep + strlen(param) + 1)); if (!newarg) return alloc_failed(); @@ -423,11 +423,16 @@ int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc) { int res; - struct fuse_opt_context ctx = { - .data = data, - .opt = opts, - .proc = proc, - }; + struct fuse_opt_context ctx; + ctx.data = data; + ctx.opt = opts; + ctx.proc = proc; + ctx.argctr = 0; + ctx.argc = 0; + ctx.argv = nullptr; + ctx.outargs = {}; + ctx.opts = nullptr; + ctx.nonopt = 0; if (!args || !args->argv || !args->argc) return 0; diff --git a/vendored/libfuse/lib/fuse_signals.c b/vendored/libfuse/lib/fuse_signals.cpp similarity index 100% rename from vendored/libfuse/lib/fuse_signals.c rename to vendored/libfuse/lib/fuse_signals.cpp diff --git a/vendored/libfuse/lib/helper.c b/vendored/libfuse/lib/helper.cpp similarity index 99% rename from vendored/libfuse/lib/helper.c rename to vendored/libfuse/lib/helper.cpp index 739ac58a..1c162700 100644 --- a/vendored/libfuse/lib/helper.c +++ b/vendored/libfuse/lib/helper.cpp @@ -56,7 +56,7 @@ fuse_helper_opt_proc(void *data, int key, struct fuse_args *outargs) { - struct helper_opts *hopts = data; + struct helper_opts *hopts = static_cast(data); switch (key) { diff --git a/vendored/libfuse/lib/mount.cpp b/vendored/libfuse/lib/mount.cpp new file mode 100644 index 00000000..d4c3fa0b --- /dev/null +++ b/vendored/libfuse/lib/mount.cpp @@ -0,0 +1,19 @@ +/* + ISC License + + Copyright (c) 2019, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "mount.hpp" diff --git a/vendored/libfuse/lib/mount.c b/vendored/libfuse/lib/mount.hpp similarity index 90% rename from vendored/libfuse/lib/mount.c rename to vendored/libfuse/lib/mount.hpp index ba8fc03e..89ee0ff4 100644 --- a/vendored/libfuse/lib/mount.c +++ b/vendored/libfuse/lib/mount.hpp @@ -16,9 +16,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#pragma once + #if defined __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ -# include "mount_bsd.c" +# include "mount_bsd.h" #else -# include "mount_generic.c" -# include "mount_util.c" +# include "mount_generic.h" +# include "mount_util.h" #endif diff --git a/vendored/libfuse/lib/mount_bsd.c b/vendored/libfuse/lib/mount_bsd.h similarity index 98% rename from vendored/libfuse/lib/mount_bsd.c rename to vendored/libfuse/lib/mount_bsd.h index 2a6d248c..def3837c 100644 --- a/vendored/libfuse/lib/mount_bsd.c +++ b/vendored/libfuse/lib/mount_bsd.h @@ -6,6 +6,8 @@ See the file COPYING.LIB. */ +#pragma once + #include "fuse_opt.h" #include @@ -106,7 +108,7 @@ static void mount_version(void) static int fuse_mount_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) { - struct mount_opts *mo = data; + struct mount_opts *mo = static_cast(data); switch (key) { case KEY_RO: diff --git a/vendored/libfuse/lib/mount_generic.c b/vendored/libfuse/lib/mount_generic.h similarity index 97% rename from vendored/libfuse/lib/mount_generic.c rename to vendored/libfuse/lib/mount_generic.h index 304dc9bd..a1849ddc 100644 --- a/vendored/libfuse/lib/mount_generic.c +++ b/vendored/libfuse/lib/mount_generic.h @@ -6,6 +6,8 @@ See the file COPYING.LIB. */ +#pragma once + #include "fuse_opt.h" #include "mount_util.h" @@ -189,7 +191,7 @@ set_mount_flag(const char *s, static int fuse_mount_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) { - struct mount_opts *mo = data; + struct mount_opts *mo = static_cast(data); switch (key) { @@ -273,7 +275,7 @@ static int receive_fd(int fd) return -1; } - return *(int*)CMSG_DATA(cmsg); + return *reinterpret_cast(CMSG_DATA(cmsg)); } void fuse_kern_unmount(const char *mountpoint, int fd) @@ -476,11 +478,11 @@ fuse_mount_sys(const char *mnt, if (res == -1) goto out_close; - source = malloc((mo->fsname ? strlen(mo->fsname) : 0) + + source = static_cast(malloc((mo->fsname ? strlen(mo->fsname) : 0) + (mo->subtype ? strlen(mo->subtype) : 0) + - strlen(devname) + 32); + strlen(devname) + 32)); - type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32); + type = static_cast(malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32)); if (!type || !source) { fprintf(stderr, "mergerfs: failed to allocate memory\n"); goto out_close; diff --git a/vendored/libfuse/lib/mount_util.c b/vendored/libfuse/lib/mount_util.c deleted file mode 100644 index e0f2f3ce..00000000 --- a/vendored/libfuse/lib/mount_util.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - FUSE: Filesystem in Userspace - Copyright (C) 2001-2007 Miklos Szeredi - - This program can be distributed under the terms of the GNU LGPLv2. - See the file COPYING.LIB. -*/ - -#include "mount_util.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef __NetBSD__ -#include -#endif -#include -#include -#include -#include - -#ifdef __NetBSD__ -#define umount2(mnt, flags) unmount(mnt, (flags == 2) ? MNT_FORCE : 0) -#define mtab_needs_update(mnt) 0 -#else -static int mtab_needs_update(const char *mnt) -{ - int res; - struct stat stbuf; - - /* If mtab is within new mount, don't touch it */ - if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 && - _PATH_MOUNTED[strlen(mnt)] == '/') - return 0; - - /* - * Skip mtab update if /etc/mtab: - * - * - doesn't exist, - * - is a symlink, - * - is on a read-only filesystem. - */ - res = lstat(_PATH_MOUNTED, &stbuf); - if (res == -1) { - if (errno == ENOENT) - return 0; - } else { - uid_t ruid; - int err; - - if (S_ISLNK(stbuf.st_mode)) - return 0; - - ruid = getuid(); - if (ruid != 0) - setreuid(0, -1); - - res = access(_PATH_MOUNTED, W_OK); - err = (res == -1) ? errno : 0; - if (ruid != 0) - setreuid(ruid, -1); - - if (err == EROFS) - return 0; - } - - return 1; -} -#endif /* __NetBSD__ */ - -static int add_mount(const char *progname, const char *fsname, - const char *mnt, const char *type, const char *opts) -{ - int res; - int status; - sigset_t blockmask; - sigset_t oldmask; - - sigemptyset(&blockmask); - sigaddset(&blockmask, SIGCHLD); - res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); - if (res == -1) { - fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); - return -1; - } - - res = fork(); - if (res == -1) { - fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); - goto out_restore; - } - if (res == 0) { - char *env = NULL; - - sigprocmask(SIG_SETMASK, &oldmask, NULL); - setuid(geteuid()); - execle("/bin/mount", "/bin/mount", "--no-canonicalize", "-i", - "-f", "-t", type, "-o", opts, fsname, mnt, NULL, &env); - fprintf(stderr, "%s: failed to execute /bin/mount: %s\n", - progname, strerror(errno)); - exit(1); - } - res = waitpid(res, &status, 0); - if (res == -1) - fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); - - if (status != 0) - res = -1; - - out_restore: - sigprocmask(SIG_SETMASK, &oldmask, NULL); - - return res; -} - -int fuse_mnt_add_mount(const char *progname, const char *fsname, - const char *mnt, const char *type, const char *opts) -{ - if (!mtab_needs_update(mnt)) - return 0; - - return add_mount(progname, fsname, mnt, type, opts); -} - -static int exec_umount(const char *progname, const char *rel_mnt, int lazy) -{ - int res; - int status; - sigset_t blockmask; - sigset_t oldmask; - - sigemptyset(&blockmask); - sigaddset(&blockmask, SIGCHLD); - res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); - if (res == -1) { - fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); - return -1; - } - - res = fork(); - if (res == -1) { - fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); - goto out_restore; - } - if (res == 0) { - char *env = NULL; - - sigprocmask(SIG_SETMASK, &oldmask, NULL); - setuid(geteuid()); - if (lazy) { - execle("/bin/umount", "/bin/umount", "-i", rel_mnt, - "-l", NULL, &env); - } else { - execle("/bin/umount", "/bin/umount", "-i", rel_mnt, - NULL, &env); - } - fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", - progname, strerror(errno)); - exit(1); - } - res = waitpid(res, &status, 0); - if (res == -1) - fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); - - if (status != 0) { - res = -1; - } - - out_restore: - sigprocmask(SIG_SETMASK, &oldmask, NULL); - return res; - -} - -int fuse_mnt_umount(const char *progname, const char *abs_mnt, - const char *rel_mnt, int lazy) -{ - int res; - - if (!mtab_needs_update(abs_mnt)) { - res = umount2(rel_mnt, lazy ? MNT_DETACH : 0); - if (res == -1) - fprintf(stderr, "%s: failed to unmount %s: %s\n", - progname, abs_mnt, strerror(errno)); - return res; - } - - return exec_umount(progname, rel_mnt, lazy); -} - -static int remove_mount(const char *progname, const char *mnt) -{ - int res; - int status; - sigset_t blockmask; - sigset_t oldmask; - - sigemptyset(&blockmask); - sigaddset(&blockmask, SIGCHLD); - res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); - if (res == -1) { - fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); - return -1; - } - - res = fork(); - if (res == -1) { - fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); - goto out_restore; - } - if (res == 0) { - char *env = NULL; - - sigprocmask(SIG_SETMASK, &oldmask, NULL); - setuid(geteuid()); - execle("/bin/umount", "/bin/umount", "--no-canonicalize", "-i", - "--fake", mnt, NULL, &env); - fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", - progname, strerror(errno)); - exit(1); - } - res = waitpid(res, &status, 0); - if (res == -1) - fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); - - if (status != 0) - res = -1; - - out_restore: - sigprocmask(SIG_SETMASK, &oldmask, NULL); - return res; -} - -int fuse_mnt_remove_mount(const char *progname, const char *mnt) -{ - if (!mtab_needs_update(mnt)) - return 0; - - return remove_mount(progname, mnt); -} - -char *fuse_mnt_resolve_path(const char *progname, const char *orig) -{ - char buf[PATH_MAX]; - char *copy; - char *dst; - char *end; - char *lastcomp; - const char *toresolv; - - if (!orig[0]) { - fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname, - orig); - return NULL; - } - - copy = strdup(orig); - if (copy == NULL) { - fprintf(stderr, "%s: failed to allocate memory\n", progname); - return NULL; - } - - toresolv = copy; - lastcomp = NULL; - for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --); - if (end[0] != '/') { - char *tmp; - end[1] = '\0'; - tmp = strrchr(copy, '/'); - if (tmp == NULL) { - lastcomp = copy; - toresolv = "."; - } else { - lastcomp = tmp + 1; - if (tmp == copy) - toresolv = "/"; - } - if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) { - lastcomp = NULL; - toresolv = copy; - } - else if (tmp) - tmp[0] = '\0'; - } - if (realpath(toresolv, buf) == NULL) { - fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig, - strerror(errno)); - free(copy); - return NULL; - } - if (lastcomp == NULL) - dst = strdup(buf); - else { - unsigned buflen = strlen(buf); - size_t dstlen = buflen + 1 + strlen(lastcomp) + 1; - dst = (char *) malloc(dstlen); - if (dst) { - if (buflen && buf[buflen-1] == '/') - snprintf(dst, dstlen, "%s%s", buf, lastcomp); - else - snprintf(dst, dstlen, "%s/%s", buf, lastcomp); - } - } - free(copy); - if (dst == NULL) - fprintf(stderr, "%s: failed to allocate memory\n", progname); - return dst; -} - -int fuse_mnt_check_fuseblk(void) -{ - char buf[256]; - FILE *f = fopen("/proc/filesystems", "r"); - if (!f) - return 1; - - while (fgets(buf, sizeof(buf), f)) - if (strstr(buf, "fuseblk\n")) { - fclose(f); - return 1; - } - - fclose(f); - return 0; -} diff --git a/vendored/libfuse/lib/mount_util.h b/vendored/libfuse/lib/mount_util.h index 5e8b0fb2..ecd6d9f9 100644 --- a/vendored/libfuse/lib/mount_util.h +++ b/vendored/libfuse/lib/mount_util.h @@ -8,12 +8,325 @@ #pragma once -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef __NetBSD__ +#include +#endif +#include +#include +#include +#include + +#ifdef __NetBSD__ +#define umount2(mnt, flags) unmount(mnt, (flags == 2) ? MNT_FORCE : 0) +#define mtab_needs_update(mnt) 0 +#else +static int mtab_needs_update(const char *mnt) +{ + int res; + struct stat stbuf; + + /* If mtab is within new mount, don't touch it */ + if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 && + _PATH_MOUNTED[strlen(mnt)] == '/') + return 0; + + /* + * Skip mtab update if /etc/mtab: + * + * - doesn't exist, + * - is a symlink, + * - is on a read-only filesystem. + */ + res = lstat(_PATH_MOUNTED, &stbuf); + if (res == -1) { + if (errno == ENOENT) + return 0; + } else { + uid_t ruid; + int err; + + if (S_ISLNK(stbuf.st_mode)) + return 0; + + ruid = getuid(); + if (ruid != 0) + setreuid(0, -1); + + res = access(_PATH_MOUNTED, W_OK); + err = (res == -1) ? errno : 0; + if (ruid != 0) + setreuid(ruid, -1); + + if (err == EROFS) + return 0; + } + + return 1; +} +#endif /* __NetBSD__ */ + +static int add_mount(const char *progname, const char *fsname, + const char *mnt, const char *type, const char *opts) +{ + int res; + int status; + sigset_t blockmask; + sigset_t oldmask; + + sigemptyset(&blockmask); + sigaddset(&blockmask, SIGCHLD); + res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); + if (res == -1) { + fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); + return -1; + } + + res = fork(); + if (res == -1) { + fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); + goto out_restore; + } + if (res == 0) { + char *env = NULL; + + sigprocmask(SIG_SETMASK, &oldmask, NULL); + setuid(geteuid()); + execle("/bin/mount", "/bin/mount", "--no-canonicalize", "-i", + "-f", "-t", type, "-o", opts, fsname, mnt, NULL, &env); + fprintf(stderr, "%s: failed to execute /bin/mount: %s\n", + progname, strerror(errno)); + exit(1); + } + res = waitpid(res, &status, 0); + if (res == -1) + fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); + + if (status != 0) + res = -1; + + out_restore: + sigprocmask(SIG_SETMASK, &oldmask, NULL); + + return res; +} int fuse_mnt_add_mount(const char *progname, const char *fsname, - const char *mnt, const char *type, const char *opts); -int fuse_mnt_remove_mount(const char *progname, const char *mnt); + const char *mnt, const char *type, const char *opts) +{ + if (!mtab_needs_update(mnt)) + return 0; + + return add_mount(progname, fsname, mnt, type, opts); +} + +static int exec_umount(const char *progname, const char *rel_mnt, int lazy) +{ + int res; + int status; + sigset_t blockmask; + sigset_t oldmask; + + sigemptyset(&blockmask); + sigaddset(&blockmask, SIGCHLD); + res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); + if (res == -1) { + fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); + return -1; + } + + res = fork(); + if (res == -1) { + fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); + goto out_restore; + } + if (res == 0) { + char *env = NULL; + + sigprocmask(SIG_SETMASK, &oldmask, NULL); + setuid(geteuid()); + if (lazy) { + execle("/bin/umount", "/bin/umount", "-i", rel_mnt, + "-l", NULL, &env); + } else { + execle("/bin/umount", "/bin/umount", "-i", rel_mnt, + NULL, &env); + } + fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", + progname, strerror(errno)); + exit(1); + } + res = waitpid(res, &status, 0); + if (res == -1) + fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); + + if (status != 0) { + res = -1; + } + + out_restore: + sigprocmask(SIG_SETMASK, &oldmask, NULL); + return res; + +} + int fuse_mnt_umount(const char *progname, const char *abs_mnt, - const char *rel_mnt, int lazy); -char *fuse_mnt_resolve_path(const char *progname, const char *orig); -int fuse_mnt_check_fuseblk(void); + const char *rel_mnt, int lazy) +{ + int res; + + if (!mtab_needs_update(abs_mnt)) { + res = umount2(rel_mnt, lazy ? MNT_DETACH : 0); + if (res == -1) + fprintf(stderr, "%s: failed to unmount %s: %s\n", + progname, abs_mnt, strerror(errno)); + return res; + } + + return exec_umount(progname, rel_mnt, lazy); +} + +static int remove_mount(const char *progname, const char *mnt) +{ + int res; + int status; + sigset_t blockmask; + sigset_t oldmask; + + sigemptyset(&blockmask); + sigaddset(&blockmask, SIGCHLD); + res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); + if (res == -1) { + fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); + return -1; + } + + res = fork(); + if (res == -1) { + fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); + goto out_restore; + } + if (res == 0) { + char *env = NULL; + + sigprocmask(SIG_SETMASK, &oldmask, NULL); + setuid(geteuid()); + execle("/bin/umount", "/bin/umount", "--no-canonicalize", "-i", + "--fake", mnt, NULL, &env); + fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", + progname, strerror(errno)); + exit(1); + } + res = waitpid(res, &status, 0); + if (res == -1) + fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); + + if (status != 0) + res = -1; + + out_restore: + sigprocmask(SIG_SETMASK, &oldmask, NULL); + return res; +} + +int fuse_mnt_remove_mount(const char *progname, const char *mnt) +{ + if (!mtab_needs_update(mnt)) + return 0; + + return remove_mount(progname, mnt); +} + +char *fuse_mnt_resolve_path(const char *progname, const char *orig) +{ + char buf[PATH_MAX]; + char *copy; + char *dst; + char *end; + char *lastcomp; + const char *toresolv; + + if (!orig[0]) { + fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname, + orig); + return NULL; + } + + copy = strdup(orig); + if (copy == NULL) { + fprintf(stderr, "%s: failed to allocate memory\n", progname); + return NULL; + } + + toresolv = copy; + lastcomp = NULL; + for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --); + if (end[0] != '/') { + char *tmp; + end[1] = '\0'; + tmp = strrchr(copy, '/'); + if (tmp == NULL) { + lastcomp = copy; + toresolv = "."; + } else { + lastcomp = tmp + 1; + if (tmp == copy) + toresolv = "/"; + } + if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) { + lastcomp = NULL; + toresolv = copy; + } + else if (tmp) + tmp[0] = '\0'; + } + if (realpath(toresolv, buf) == NULL) { + fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig, + strerror(errno)); + free(copy); + return NULL; + } + if (lastcomp == NULL) + dst = strdup(buf); + else { + unsigned buflen = strlen(buf); + size_t dstlen = buflen + 1 + strlen(lastcomp) + 1; + dst = static_cast(malloc(dstlen)); + if (dst) { + if (buflen && buf[buflen-1] == '/') + snprintf(dst, dstlen, "%s%s", buf, lastcomp); + else + snprintf(dst, dstlen, "%s/%s", buf, lastcomp); + } + } + free(copy); + if (dst == NULL) + fprintf(stderr, "%s: failed to allocate memory\n", progname); + return dst; +} + +int fuse_mnt_check_fuseblk(void) +{ + char buf[256]; + FILE *f = fopen("/proc/filesystems", "r"); + if (!f) + return 1; + + while (fgets(buf, sizeof(buf), f)) + if (strstr(buf, "fuseblk\n")) { + fclose(f); + return 1; + } + + fclose(f); + return 0; +} diff --git a/vendored/libfuse/util/fusermount.c b/vendored/libfuse/util/fusermount.cpp similarity index 98% rename from vendored/libfuse/util/fusermount.c rename to vendored/libfuse/util/fusermount.cpp index 982d3345..23b1be0b 100644 --- a/vendored/libfuse/util/fusermount.c +++ b/vendored/libfuse/util/fusermount.cpp @@ -7,8 +7,6 @@ */ /* This program does the mounting and unmounting of FUSE filesystems */ -#define _GNU_SOURCE /* for clone */ - #include "mount_util.h" #include #include @@ -234,7 +232,7 @@ static int may_unmount(const char *mnt, int quiet) */ static int check_is_mount_child(void *p) { - const char **a = p; + const char **a = static_cast(p); const char *last = a[0]; const char *mnt = a[1]; int res; @@ -305,10 +303,12 @@ static pid_t clone_newns(void *a) char *stack = buf + (sizeof(buf) / 2 - ((size_t) buf & 15)); #ifdef __ia64__ + extern "C" { extern int __clone2(int (*fn)(void *), void *child_stack_base, size_t stack_size, int flags, void *arg, pid_t *ptid, void *tls, pid_t *ctid); + } return __clone2(check_is_mount_child, stack, sizeof(buf) / 2, CLONE_NEWNS, a, NULL, NULL, NULL); @@ -649,7 +649,7 @@ static int add_option(char **optsp, const char *opt, unsigned expand) else { unsigned oldsize = strlen(*optsp); unsigned newsize = oldsize + 1 + strlen(opt) + expand + 1; - newopts = (char *) realloc(*optsp, newsize); + newopts = static_cast(realloc(*optsp, newsize)); if (newopts) sprintf(newopts + oldsize, ",%s", opt); } @@ -713,7 +713,7 @@ get_string_opt(const char *s, if (*val) free(*val); - *val = (char *) malloc(len - opt_len + 1); + *val = static_cast(malloc(len - opt_len + 1)); if (!*val) { fprintf(stderr, "%s: failed to allocate memory\n", progname); return 0; @@ -747,7 +747,7 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode, char *type = NULL; int blkdev = 0; - optbuf = (char *) malloc(strlen(opts) + 128); + optbuf = static_cast(malloc(strlen(opts) + 128)); if (!optbuf) { fprintf(stderr, "%s: failed to allocate memory\n", progname); return -1; @@ -827,10 +827,10 @@ static int do_mount(const char *mnt, char **typep, mode_t rootmode, sprintf(d, "fd=%i,rootmode=%o,user_id=%u,group_id=%u", fd, rootmode, getuid(), getgid()); - source = malloc((fsname ? strlen(fsname) : 0) + - (subtype ? strlen(subtype) : 0) + strlen(dev) + 32); + source = static_cast(malloc((fsname ? strlen(fsname) : 0) + + (subtype ? strlen(subtype) : 0) + strlen(dev) + 32)); - type = malloc((subtype ? strlen(subtype) : 0) + 32); + type = static_cast(malloc((subtype ? strlen(subtype) : 0) + 32)); if (!type || !source) { fprintf(stderr, "%s: failed to allocate memory\n", progname); goto err; @@ -1147,7 +1147,7 @@ static int send_fd(int sock_fd, int fd) p_cmsg->cmsg_level = SOL_SOCKET; p_cmsg->cmsg_type = SCM_RIGHTS; p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); - p_fds = (int *) CMSG_DATA(p_cmsg); + p_fds = reinterpret_cast(CMSG_DATA(p_cmsg)); *p_fds = fd; msg.msg_controllen = p_cmsg->cmsg_len; msg.msg_name = NULL; diff --git a/vendored/libfuse/util/mount.mergerfs.c b/vendored/libfuse/util/mount.mergerfs.cpp similarity index 96% rename from vendored/libfuse/util/mount.mergerfs.c rename to vendored/libfuse/util/mount.mergerfs.cpp index 854bbdb6..34589aad 100644 --- a/vendored/libfuse/util/mount.mergerfs.c +++ b/vendored/libfuse/util/mount.mergerfs.cpp @@ -38,7 +38,7 @@ static void add_arg(char **cmdp, const char *opt) { size_t optlen = strlen(opt); size_t cmdlen = *cmdp ? strlen(*cmdp) : 0; - char *cmd = xrealloc(*cmdp, cmdlen + optlen * 4 + 4); + char *cmd = static_cast(xrealloc(*cmdp, cmdlen + optlen * 4 + 4)); char *s; s = cmd + cmdlen; if (*cmdp) @@ -63,7 +63,7 @@ static char *add_option(const char *opt, char *options) { int oldlen = options ? strlen(options) : 0; - options = xrealloc(options, oldlen + 1 + strlen(opt) + 1); + options = static_cast(xrealloc(options, oldlen + 1 + strlen(opt) + 1)); if (!oldlen) strcpy(options, opt); else { @@ -93,7 +93,7 @@ int main(int argc, char *argv[]) else basename = argv[0]; - type = "mergerfs"; + type = const_cast("mergerfs"); if (strncmp(basename, "mount.fuse.", 11) == 0) type = basename + 11; if (strncmp(basename, "mount.fuseblk.", 14) == 0) diff --git a/vendored/libfuse/util/mount_util.c b/vendored/libfuse/util/mount_util.c deleted file mode 100644 index 6f094ec3..00000000 --- a/vendored/libfuse/util/mount_util.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - FUSE: Filesystem in Userspace - Copyright (C) 2001-2007 Miklos Szeredi - - This program can be distributed under the terms of the GNU LGPLv2. - See the file COPYING.LIB. -*/ - -#include "mount_util.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef __NetBSD__ -#include -#endif -#include -#include -#include -#include - -#ifdef __NetBSD__ -#define umount2(mnt, flags) unmount(mnt, (flags == 2) ? MNT_FORCE : 0) -#define mtab_needs_update(mnt) 0 -#else -static int mtab_needs_update(const char *mnt) -{ - int res; - struct stat stbuf; - - /* If mtab is within new mount, don't touch it */ - if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 && - _PATH_MOUNTED[strlen(mnt)] == '/') - return 0; - - /* - * Skip mtab update if /etc/mtab: - * - * - doesn't exist, - * - is a symlink, - * - is on a read-only filesystem. - */ - res = lstat(_PATH_MOUNTED, &stbuf); - if (res == -1) { - if (errno == ENOENT) - return 0; - } else { - uid_t ruid; - int err; - - if (S_ISLNK(stbuf.st_mode)) - return 0; - - ruid = getuid(); - if (ruid != 0) - setreuid(0, -1); - - res = access(_PATH_MOUNTED, W_OK); - err = (res == -1) ? errno : 0; - if (ruid != 0) - setreuid(ruid, -1); - - if (err == EROFS) - return 0; - } - - return 1; -} -#endif /* __NetBSD__ */ - -static int add_mount(const char *progname, const char *fsname, - const char *mnt, const char *type, const char *opts) -{ - int res; - int status; - sigset_t blockmask; - sigset_t oldmask; - - sigemptyset(&blockmask); - sigaddset(&blockmask, SIGCHLD); - res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); - if (res == -1) { - fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); - return -1; - } - - res = fork(); - if (res == -1) { - fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); - goto out_restore; - } - if (res == 0) { - char *env = NULL; - - sigprocmask(SIG_SETMASK, &oldmask, NULL); - setuid(geteuid()); - execle("/bin/mount", "/bin/mount", "--no-canonicalize", "-i", - "-f", "-t", type, "-o", opts, fsname, mnt, NULL, &env); - fprintf(stderr, "%s: failed to execute /bin/mount: %s\n", - progname, strerror(errno)); - exit(1); - } - res = waitpid(res, &status, 0); - if (res == -1) - fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); - - if (status != 0) - res = -1; - - out_restore: - sigprocmask(SIG_SETMASK, &oldmask, NULL); - - return res; -} - -int fuse_mnt_add_mount(const char *progname, const char *fsname, - const char *mnt, const char *type, const char *opts) -{ - if (!mtab_needs_update(mnt)) - return 0; - - return add_mount(progname, fsname, mnt, type, opts); -} - -static int exec_umount(const char *progname, const char *rel_mnt, int lazy) -{ - int res; - int status; - sigset_t blockmask; - sigset_t oldmask; - - sigemptyset(&blockmask); - sigaddset(&blockmask, SIGCHLD); - res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); - if (res == -1) { - fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); - return -1; - } - - res = fork(); - if (res == -1) { - fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); - goto out_restore; - } - if (res == 0) { - char *env = NULL; - - sigprocmask(SIG_SETMASK, &oldmask, NULL); - setuid(geteuid()); - if (lazy) { - execle("/bin/umount", "/bin/umount", "-i", rel_mnt, - "-l", NULL, &env); - } else { - execle("/bin/umount", "/bin/umount", "-i", rel_mnt, - NULL, &env); - } - fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", - progname, strerror(errno)); - exit(1); - } - res = waitpid(res, &status, 0); - if (res == -1) - fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); - - if (status != 0) { - res = -1; - } - - out_restore: - sigprocmask(SIG_SETMASK, &oldmask, NULL); - return res; - -} - -int fuse_mnt_umount(const char *progname, const char *abs_mnt, - const char *rel_mnt, int lazy) -{ - int res; - - if (!mtab_needs_update(abs_mnt)) { - res = umount2(rel_mnt, lazy ? 2 : 0); - if (res == -1) - fprintf(stderr, "%s: failed to unmount %s: %s\n", - progname, abs_mnt, strerror(errno)); - return res; - } - - return exec_umount(progname, rel_mnt, lazy); -} - -static int remove_mount(const char *progname, const char *mnt) -{ - int res; - int status; - sigset_t blockmask; - sigset_t oldmask; - - sigemptyset(&blockmask); - sigaddset(&blockmask, SIGCHLD); - res = sigprocmask(SIG_BLOCK, &blockmask, &oldmask); - if (res == -1) { - fprintf(stderr, "%s: sigprocmask: %s\n", progname, strerror(errno)); - return -1; - } - - res = fork(); - if (res == -1) { - fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); - goto out_restore; - } - if (res == 0) { - char *env = NULL; - - sigprocmask(SIG_SETMASK, &oldmask, NULL); - setuid(geteuid()); - execle("/bin/umount", "/bin/umount", "--no-canonicalize", "-i", - "--fake", mnt, NULL, &env); - fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", - progname, strerror(errno)); - exit(1); - } - res = waitpid(res, &status, 0); - if (res == -1) - fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno)); - - if (status != 0) - res = -1; - - out_restore: - sigprocmask(SIG_SETMASK, &oldmask, NULL); - return res; -} - -int fuse_mnt_remove_mount(const char *progname, const char *mnt) -{ - if (!mtab_needs_update(mnt)) - return 0; - - return remove_mount(progname, mnt); -} - -char *fuse_mnt_resolve_path(const char *progname, const char *orig) -{ - char buf[PATH_MAX]; - char *copy; - char *dst; - char *end; - char *lastcomp; - const char *toresolv; - - if (!orig[0]) { - fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname, - orig); - return NULL; - } - - copy = strdup(orig); - if (copy == NULL) { - fprintf(stderr, "%s: failed to allocate memory\n", progname); - return NULL; - } - - toresolv = copy; - lastcomp = NULL; - for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --); - if (end[0] != '/') { - char *tmp; - end[1] = '\0'; - tmp = strrchr(copy, '/'); - if (tmp == NULL) { - lastcomp = copy; - toresolv = "."; - } else { - lastcomp = tmp + 1; - if (tmp == copy) - toresolv = "/"; - } - if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) { - lastcomp = NULL; - toresolv = copy; - } - else if (tmp) - tmp[0] = '\0'; - } - if (realpath(toresolv, buf) == NULL) { - fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig, - strerror(errno)); - free(copy); - return NULL; - } - if (lastcomp == NULL) - dst = strdup(buf); - else { - dst = (char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1); - if (dst) { - unsigned buflen = strlen(buf); - if (buflen && buf[buflen-1] == '/') - sprintf(dst, "%s%s", buf, lastcomp); - else - sprintf(dst, "%s/%s", buf, lastcomp); - } - } - free(copy); - if (dst == NULL) - fprintf(stderr, "%s: failed to allocate memory\n", progname); - return dst; -} - -int fuse_mnt_check_fuseblk(void) -{ - char buf[256]; - FILE *f = fopen("/proc/filesystems", "r"); - if (!f) - return 1; - - while (fgets(buf, sizeof(buf), f)) - if (strstr(buf, "fuseblk\n")) { - fclose(f); - return 1; - } - - fclose(f); - return 0; -}