about summary refs log tree commit diff stats
path: root/src/io/sendfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/io/sendfd.c')
-rw-r--r--src/io/sendfd.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/io/sendfd.c b/src/io/sendfd.c
new file mode 100644
index 00000000..578009c2
--- /dev/null
+++ b/src/io/sendfd.c
@@ -0,0 +1,28 @@
+#include <sys/socket.h>
+#include <string.h>
+
+/* See https://stackoverflow.com/a/4491203
+ * Send a file handle to socket `sock`.
+ * Returns: 1 on success, -1 on error. I *think* this never returns * 0. */
+ssize_t sendfd(int sock, int fd)
+{
+	struct msghdr hdr;
+	struct iovec iov;
+	int cmsgbuf[CMSG_SPACE(sizeof(int))];
+	char buf = '\0';
+	struct cmsghdr *cmsg;
+
+	memset(&hdr, 0, sizeof(hdr));
+	iov.iov_base = &buf;
+	iov.iov_len = 1;
+	hdr.msg_iov = &iov;
+	hdr.msg_iovlen = 1;
+	hdr.msg_control = &cmsgbuf[0];
+	hdr.msg_controllen = CMSG_LEN(sizeof(fd));
+	cmsg = CMSG_FIRSTHDR(&hdr);
+	cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	*((int *)CMSG_DATA(cmsg)) = fd;
+	return sendmsg(sock, &hdr, 0);
+}