📄 mount.c
字号:
res = umount2(mountpoint, 2); if (res == 0) return; pid = fork(); if(pid == -1) return; if(pid == 0) { const char *argv[] = { FUSERMOUNT_PROG, "-u", "-q", "-z", "--", mountpoint, NULL }; exec_fusermount(argv); _exit(1); } waitpid(pid, NULL, 0);}void fuse_unmount_compat22(const char *mountpoint){ fuse_kern_unmount(mountpoint, -1);}static int fuse_mount_fusermount(const char *mountpoint, const char *opts, int quiet){ int fds[2], pid; int res; int rv; if (!mountpoint) { fprintf(stderr, "fuse: missing mountpoint\n"); return -1; } res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds); if(res == -1) { perror("fuse: socketpair() failed"); return -1; } pid = fork(); if(pid == -1) { perror("fuse: fork() failed"); close(fds[0]); close(fds[1]); return -1; } if(pid == 0) { char env[10]; const char *argv[32]; int a = 0; if (quiet) { int fd = open("/dev/null", O_RDONLY); dup2(fd, 1); dup2(fd, 2); } argv[a++] = FUSERMOUNT_PROG; if (opts) { argv[a++] = "-o"; argv[a++] = opts; } argv[a++] = "--"; argv[a++] = mountpoint; argv[a++] = NULL; close(fds[1]); fcntl(fds[0], F_SETFD, 0); snprintf(env, sizeof(env), "%i", fds[0]); setenv(FUSE_COMMFD_ENV, env, 1); exec_fusermount(argv); perror("fuse: failed to exec fusermount"); _exit(1); } close(fds[0]); rv = receive_fd(fds[1]); close(fds[1]); waitpid(pid, NULL, 0); /* bury zombie */ return rv;}int fuse_mount_compat22(const char *mountpoint, const char *opts){ return fuse_mount_fusermount(mountpoint, opts, 0);}static int fuse_mount_sys(const char *mnt, struct mount_opts *mo, const char *mnt_opts){ char tmp[128]; const char *devname = "/dev/fuse"; char *source = NULL; char *type = NULL; struct stat stbuf; int fd; int res; if (!mnt) { fprintf(stderr, "fuse: missing mountpoint\n"); return -1; } res = lstat(mnt, &stbuf); if (res == -1) { fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n", mnt, strerror(errno)); return -1; } if (!mo->nonempty) { res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode, stbuf.st_size); if (res == -1) return -1; } fd = open(devname, O_RDWR); if (fd == -1) { if (errno == ENODEV || errno == ENOENT) fprintf(stderr, "fuse: device not found, try 'modprobe fuse' first\n"); else fprintf(stderr, "fuse: failed to open %s: %s\n", devname, strerror(errno)); return -1; } snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i", fd, stbuf.st_mode & S_IFMT, getuid(), getgid()); res = fuse_opt_add_opt(&mo->kernel_opts, tmp); if (res == -1) goto out_close; source = malloc((mo->fsname ? strlen(mo->fsname) : 0) + (mo->subtype ? strlen(mo->subtype) : 0) + strlen(devname) + 32); type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32); if (!type || !source) { fprintf(stderr, "fuse: failed to allocate memory\n"); goto out_close; } strcpy(type, mo->blkdev ? "fuseblk" : "fuse"); if (mo->subtype) { strcat(type, "."); strcat(type, mo->subtype); } strcpy(source, mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname)); res = mount(source, mnt, type, mo->flags, mo->kernel_opts); if (res == -1 && errno == ENODEV && mo->subtype) { /* Probably missing subtype support */ strcpy(type, mo->blkdev ? "fuseblk" : "fuse"); if (mo->fsname) { if (!mo->blkdev) sprintf(source, "%s#%s", mo->subtype, mo->fsname); } else { strcpy(source, type); } res = mount(source, mnt, type, mo->flags, mo->kernel_opts); } if (res == -1) { /* * Maybe kernel doesn't support unprivileged mounts, in this * case try falling back to fusermount */ if (errno == EPERM) { res = -2; } else { int errno_save = errno; if (mo->blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk()) fprintf(stderr, "fuse: 'fuseblk' support missing\n"); else fprintf(stderr, "fuse: mount failed: %s\n", strerror(errno_save)); } goto out_close; } if (geteuid() == 0) { char *newmnt = fuse_mnt_resolve_path("fuse", mnt); res = -1; if (!newmnt) goto out_umount; res = fuse_mnt_add_mount("fuse", source, newmnt, type, mnt_opts); free(newmnt); if (res == -1) goto out_umount; } return fd; out_umount: umount2(mnt, 2); /* lazy umount */ out_close: free(type); free(source); close(fd); return res;}static int get_mnt_flag_opts(char **mnt_optsp, int flags){ int i; if (!(flags & MS_RDONLY) && fuse_opt_add_opt(mnt_optsp, "rw") == -1) return -1; for (i = 0; mount_flags[i].opt != NULL; i++) { if (mount_flags[i].on && (flags & mount_flags[i].flag) && fuse_opt_add_opt(mnt_optsp, mount_flags[i].opt) == -1) return -1; } return 0;}int fuse_kern_mount(const char *mountpoint, struct fuse_args *args){ struct mount_opts mo; int res = -1; char *mnt_opts = NULL; memset(&mo, 0, sizeof(mo)); mo.flags = MS_NOSUID | MS_NODEV; if (args && fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1) return -1; if (mo.allow_other && mo.allow_root) { fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n"); goto out; } res = 0; if (mo.ishelp) goto out; res = -1; if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1) goto out; if (mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1) goto out; if (mo.mtab_opts && fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1) goto out; res = fuse_mount_sys(mountpoint, &mo, mnt_opts); if (res == -2) { if (mo.fusermount_opts && fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1) goto out; if (mo.subtype) { char *tmp_opts = NULL; res = -1; if (fuse_opt_add_opt(&tmp_opts, mnt_opts) == -1 || fuse_opt_add_opt(&tmp_opts, mo.subtype_opt) == -1) { free(tmp_opts); goto out; } res = fuse_mount_fusermount(mountpoint, tmp_opts, 1); free(tmp_opts); if (res == -1) res = fuse_mount_fusermount(mountpoint, mnt_opts, 0); } else { res = fuse_mount_fusermount(mountpoint, mnt_opts, 0); } } out: free(mnt_opts); free(mo.fsname); free(mo.subtype); free(mo.fusermount_opts); free(mo.subtype_opt); free(mo.kernel_opts); free(mo.mtab_opts); return res;}__asm__(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2");__asm__(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -