From: Sapan Bhatia Date: Tue, 24 Mar 2009 18:14:59 +0000 (+0000) Subject: Adding some scripts that implement fd passing X-Git-Tag: 0.9-0~25 X-Git-Url: http://git.onelab.eu/?p=vsys-scripts.git;a=commitdiff_plain;h=ec680f4ee67d7026a97bb830e27af71a1764cfe2 Adding some scripts that implement fd passing --- diff --git a/Makefile b/Makefile index 8d4968d..9bb4e8a 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,13 @@ CC=gcc CFLAGS=-g -O2 -all: dcookie +all: dcookie fd_bmsocket dcookie: dcookie.c gcc dcookie.c -o exec/dcookie +fd_bmsocket: fd_bmsocket.c + gcc fd_bmsocket.c -o exec/fd_bmsocket + clean: rm -f exec/* diff --git a/fdpass.c b/fdpass.c new file mode 100644 index 0000000..5548064 --- /dev/null +++ b/fdpass.c @@ -0,0 +1,93 @@ +// Modified version of library functions in FUSE +// + +#include +#include +#include +#include +#include +#include +#include +#include + +int send_fd(int sock_fd, int fd) +{ + int retval; + struct msghdr msg; + struct cmsghdr *p_cmsg; + struct iovec vec; + size_t cmsgbuf[CMSG_SPACE(sizeof(fd)) / sizeof(size_t)]; + 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(fd)); + p_fds = (int *) CMSG_DATA(p_cmsg); + *p_fds = 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); + while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR); + if (retval != 1) { + perror("sending file descriptor"); + return -1; + } + return 0; +} + + +/* return value: + * >= 0 => fd + * -1 => error + */ +int receive_fd(int fd) +{ + struct msghdr msg; + struct iovec iov; + char buf[1]; + int rv; + size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)]; + struct cmsghdr *cmsg; + + iov.iov_base = buf; + iov.iov_len = 1; + + msg.msg_name = 0; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + /* old BSD implementations should use msg_accrights instead of + * msg_control; the interface is different. */ + msg.msg_control = ccmsg; + msg.msg_controllen = sizeof(ccmsg); + + while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR); + if (rv == -1) { + perror("recvmsg"); + return -1; + } + if(!rv) { + /* EOF */ + return -1; + } + + cmsg = CMSG_FIRSTHDR(&msg); + if (!cmsg->cmsg_type == SCM_RIGHTS) { + fprintf(stderr, "got control message of unknown type %d\n", + cmsg->cmsg_type); + return -1; + } + return *(int*)CMSG_DATA(cmsg); +} +