aboutsummaryrefslogtreecommitdiffstats
path: root/util/fuse_ioslave.c
blob: 1fa3bbf5b803a57ac183f7385847b0bf089c0611 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <stdio.h>                /* fprintf */
#include <errno.h>                /* errno */
#include <string.h>                /* strerror */
#include <unistd.h>                /* read,write,close */
#include <stdlib.h>                /* getenv,strtol */
#include <sys/select.h>            /* select */
#include <sys/socket.h>            /* send, recv */
#include <sys/un.h>                /* struct sockaddr_un */
#define BUFSIZE (2<<16)
#undef IOSLAVE_DEBUG
char *scratch;

int send_fd(int sock_fd, int send_fd) {
    int retval;
    struct msghdr msg;
    struct cmsghdr *p_cmsg;
    struct iovec vec;
    char cmsgbuf[CMSG_SPACE(sizeof(send_fd))];
    int *p_fds;
    char sendchar = 0;
    msg.msg_control = cmsgbuf;
    msg.msg_controllen = sizeof(cmsgbuf);
    p_cmsg = CMSG_FIRSTHDR(&msg);
    p_cmsg->cmsg_level = SOL_SOCKET;
    p_cmsg->cmsg_type = SCM_RIGHTS;
    p_cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
    p_fds = (int *) CMSG_DATA(p_cmsg);
    *p_fds = send_fd;
    msg.msg_controllen = p_cmsg->cmsg_len;
    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov = &vec;
    msg.msg_iovlen = 1;
    msg.msg_flags = 0;
    /* "To pass file descriptors or credentials you need to send/read at
     * least one byte" (man 7 unix)
     */
    vec.iov_base = &sendchar;
    vec.iov_len = sizeof(sendchar);
    retval = sendmsg(sock_fd, &msg, 0);
    if (retval != 1) {
        perror("sendmsg");
    }
    return retval;
}

int main() {
    char *env = getenv("_FUSE_IOSLAVE_FD");
    int fd;
    if (!env)
        exit(fprintf(stderr, "fuse_ioslave: do not run me directly\n"));
    fd = strtol(env, NULL, 0);
    while (send_fd(fd, 0) < 0) {
        sleep(5);
    }
    return 0;
}