#include /* fprintf */ #include /* errno */ #include /* strerror */ #include /* read,write,close */ #include /* getenv,strtol */ #include /* select */ #include /* send, recv */ #include /* 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; }