~james-w/+junk/fuse-debian-upstream

« back to all changes in this revision

Viewing changes to lib/mount.c

  • Committer: James Westby
  • Date: 2008-05-16 12:57:40 UTC
  • Revision ID: jw+debian@jameswestby.net-20080516125740-fn2iqsxtfd3olmib
Tags: upstream-debian-2.2.1
Import upstream from fuse_2.2.1.orig.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    FUSE: Filesystem in Userspace
 
3
    Copyright (C) 2001-2005  Miklos Szeredi <miklos@szeredi.hu>
 
4
 
 
5
    This program can be distributed under the terms of the GNU LGPL.
 
6
    See the file COPYING.LIB.
 
7
*/
 
8
 
 
9
#include "fuse.h"
 
10
#include "fuse_compat.h"
 
11
 
 
12
#include <stdio.h>
 
13
#include <stdlib.h>
 
14
#include <unistd.h>
 
15
#include <fcntl.h>
 
16
#include <errno.h>
 
17
#include <sys/socket.h>
 
18
#include <sys/un.h>
 
19
#include <sys/wait.h>
 
20
 
 
21
#define FUSERMOUNT_PROG         "fusermount"
 
22
#define FUSE_COMMFD_ENV         "_FUSE_COMMFD"
 
23
 
 
24
 
 
25
/* return value:
 
26
 * >= 0  => fd
 
27
 * -1    => error
 
28
 */
 
29
static int receive_fd(int fd)
 
30
{
 
31
    struct msghdr msg;
 
32
    struct iovec iov;
 
33
    char buf[1];
 
34
    int rv;
 
35
    int connfd = -1;
 
36
    char ccmsg[CMSG_SPACE(sizeof(connfd))];
 
37
    struct cmsghdr *cmsg;
 
38
 
 
39
    iov.iov_base = buf;
 
40
    iov.iov_len = 1;
 
41
 
 
42
    msg.msg_name = 0;
 
43
    msg.msg_namelen = 0;
 
44
    msg.msg_iov = &iov;
 
45
    msg.msg_iovlen = 1;
 
46
    /* old BSD implementations should use msg_accrights instead of
 
47
     * msg_control; the interface is different. */
 
48
    msg.msg_control = ccmsg;
 
49
    msg.msg_controllen = sizeof(ccmsg);
 
50
 
 
51
    while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR);
 
52
    if (rv == -1) {
 
53
        perror("recvmsg");
 
54
        return -1;
 
55
    }
 
56
    if(!rv) {
 
57
        /* EOF */
 
58
        return -1;
 
59
    }
 
60
 
 
61
    cmsg = CMSG_FIRSTHDR(&msg);
 
62
    if (!cmsg->cmsg_type == SCM_RIGHTS) {
 
63
        fprintf(stderr, "got control message of unknown type %d\n",
 
64
                cmsg->cmsg_type);
 
65
        return -1;
 
66
    }
 
67
    return *(int*)CMSG_DATA(cmsg);
 
68
}
 
69
 
 
70
void fuse_unmount(const char *mountpoint)
 
71
{
 
72
    const char *mountprog = FUSERMOUNT_PROG;
 
73
    char umount_cmd[1024];
 
74
 
 
75
    snprintf(umount_cmd, sizeof(umount_cmd) - 1, "%s -u -q -z %s", mountprog,
 
76
             mountpoint);
 
77
 
 
78
    umount_cmd[sizeof(umount_cmd) - 1] = '\0';
 
79
    system(umount_cmd);
 
80
}
 
81
 
 
82
int fuse_mount(const char *mountpoint, const char *opts)
 
83
{
 
84
    const char *mountprog = FUSERMOUNT_PROG;
 
85
    int fds[2], pid;
 
86
    int res;
 
87
    int rv;
 
88
 
 
89
    res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
 
90
    if(res == -1) {
 
91
        perror("fuse: socketpair() failed");
 
92
        return -1;
 
93
    }
 
94
 
 
95
#ifndef USE_UCLIBC
 
96
    pid = fork();
 
97
#else
 
98
    pid = vfork();
 
99
#endif
 
100
    if(pid == -1) {
 
101
        perror("fuse: fork() failed");
 
102
        close(fds[0]);
 
103
        close(fds[1]);
 
104
        return -1;
 
105
    }
 
106
 
 
107
    if(pid == 0) {
 
108
        char env[10];
 
109
        const char *argv[] = {mountprog, opts ? "-o" : mountpoint, opts,
 
110
                              mountpoint, NULL};
 
111
 
 
112
        close(fds[1]);
 
113
        fcntl(fds[0], F_SETFD, 0);
 
114
        snprintf(env, sizeof(env), "%i", fds[0]);
 
115
        setenv(FUSE_COMMFD_ENV, env, 1);
 
116
        execvp(mountprog, (char **) argv);
 
117
        perror("fuse: failed to exec fusermount");
 
118
        exit(1);
 
119
    }
 
120
 
 
121
    close(fds[0]);
 
122
    rv = receive_fd(fds[1]);
 
123
    close(fds[1]);
 
124
    waitpid(pid, NULL, 0); /* bury zombie */
 
125
 
 
126
    return rv;
 
127
}
 
128
 
 
129
int fuse_mount_compat1(const char *mountpoint, const char *args[])
 
130
{
 
131
    /* just ignore mount args for now */
 
132
    (void) args;
 
133
    return fuse_mount(mountpoint, NULL);
 
134
}