7 #include <sys/socket.h>
9 #include "stolen_from_fuse.h"
11 // Most of this code is stolen from FUSE 2.7.4
13 /** Function to pass a file descriptor over a UNIX socket.
15 * Sends the file descriptor fd over the channel sock_fd.
18 int rrm_send_fd(int sock_fd, int fd)
22 struct cmsghdr *p_cmsg;
24 size_t cmsgbuf[CMSG_SPACE(sizeof(fd)) / sizeof(size_t)];
28 msg.msg_control = cmsgbuf;
29 msg.msg_controllen = sizeof(cmsgbuf);
30 p_cmsg = CMSG_FIRSTHDR(&msg);
31 p_cmsg->cmsg_level = SOL_SOCKET;
32 p_cmsg->cmsg_type = SCM_RIGHTS;
33 p_cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
34 p_fds = (int *) CMSG_DATA(p_cmsg);
36 msg.msg_controllen = p_cmsg->cmsg_len;
42 /* "To pass file descriptors or credentials you need to send/read at
43 * least one byte" (man 7 unix) */
44 vec.iov_base = &sendchar;
45 vec.iov_len = sizeof(sendchar);
46 while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
48 perror("sending file descriptor");
59 int rrm_receive_fd(int fd)
65 size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)];
75 /* old BSD implementations should use msg_accrights instead of
76 * msg_control; the interface is different. */
77 msg.msg_control = ccmsg;
78 msg.msg_controllen = sizeof(ccmsg);
80 while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR);
90 cmsg = CMSG_FIRSTHDR(&msg);
91 if (!cmsg->cmsg_type == SCM_RIGHTS) {
92 fprintf(stderr, "got control message of unknown type %d\n",
96 return *(int*)CMSG_DATA(cmsg);
99 int rrm_fuse_mnt_umount(const char *progname, const char *mnt, int lazy)
104 res = umount2(mnt, lazy ? 2 : 0);
106 fprintf(stderr, "%s: failed to unmount %s: %s\n",
107 progname, mnt, strerror(errno));
112 static int rrm_try_open(const char *dev, char **devp, int silent)
114 int fd = open(dev, O_RDWR);
118 fprintf(stderr, "failed to allocate memory\n" );
123 } else if (errno == ENODEV ||
124 errno == ENOENT)/* check for ENOENT too, for the udev case */
127 fprintf(stderr, "failed to open %s: %s\n", dev,
133 static int rrm_try_open_fuse_device(char **devp)
139 fd = rrm_try_open(FUSE_DEV_NEW, devp, 0);
145 fd = rrm_try_open(FUSE_DEV_OLD, devp, 1);
152 int rrm_open_fuse_device(char **devp)
154 int fd = rrm_try_open_fuse_device(devp);
159 "fuse device not found, try 'modprobe fuse' first\n");