From 959343899a38dd5bf2b2efb8de41eba15e078e22 Mon Sep 17 00:00:00 2001
From: Sapan Bhatia <sapanb@cs.princeton.edu>
Date: Fri, 3 Apr 2009 02:27:06 +0000
Subject: [PATCH] Looking like I forgot to add this.

---
 lib/fdpass.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/fdpass.h |  5 +++
 2 files changed, 98 insertions(+)
 create mode 100644 lib/fdpass.c
 create mode 100644 lib/fdpass.h

diff --git a/lib/fdpass.c b/lib/fdpass.c
new file mode 100644
index 0000000..5548064
--- /dev/null
+++ b/lib/fdpass.c
@@ -0,0 +1,93 @@
+// Modified version of library functions in FUSE
+//
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+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);
+}
+
diff --git a/lib/fdpass.h b/lib/fdpass.h
new file mode 100644
index 0000000..f00a6fb
--- /dev/null
+++ b/lib/fdpass.h
@@ -0,0 +1,5 @@
+// Modified version of library functions in FUSE
+//
+int send_fd(int sock_fd, int fd);
+int receive_fd(int fd);
+
-- 
2.47.0