Skip to content

Instantly share code, notes, and snippets.

@bennydictor
Created April 24, 2018 09:29
Show Gist options
  • Save bennydictor/875f0be8f3306b71ddc9c3d5f36051d8 to your computer and use it in GitHub Desktop.
Save bennydictor/875f0be8f3306b71ddc9c3d5f36051d8 to your computer and use it in GitHub Desktop.
Sending file descriptors over unix domain sockets
#include <err.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <unistd.h>
int main() {
int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (sock == -1)
err(1, "socket() failed");
struct sockaddr_un addr;
socklen_t addr_len = sizeof addr;
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, "send_fd.sock", sizeof addr.sun_path);
if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1)
err(1, "connect() failed");
int fd;
char cmsg_buf[CMSG_SPACE(sizeof fd)];
struct msghdr msg;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = NULL;
msg.msg_iovlen = 0;
msg.msg_control = cmsg_buf;
msg.msg_controllen = sizeof cmsg_buf;
msg.msg_flags = 0;
if (recvmsg(sock, &msg, 0) == -1)
err(1, "recvmsg() failed");
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
unsigned char *cmsg_data = CMSG_DATA(cmsg);
fd = *(int *)cmsg_data;
char second_half[] = "world!\n";
if (write(fd, second_half, strlen(second_half)) == -1)
err(1, "write() failed");
exit(0);
}
#include <err.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <unistd.h>
int main() {
int fd = open("file.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (fd == -1)
err(1, "open() failed");
char first_half[] = "Hello, ";
if (write(fd, first_half, strlen(first_half)) == -1)
err(1, "write() failed");
int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (sock == -1)
err(1, "socket() failed");
unlink("send_fd.sock");
struct sockaddr_un addr;
socklen_t addr_len = sizeof addr;
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, "send_fd.sock", sizeof addr.sun_path);
if (bind(sock, (struct sockaddr *)&addr, addr_len) == -1)
err(1, "bind() failed");
if (listen(sock, 5) == -1)
err(1, "listen() falied");
struct sockaddr_un raddr;
socklen_t raddr_len = sizeof raddr;
int client = accept(sock, (struct sockaddr *)&raddr, &raddr_len);
if (client == -1)
err(1, "accept() failed");
struct msghdr msg;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = NULL;
msg.msg_iovlen = 0;
msg.msg_flags = 0;
char cmsg_buf[CMSG_SPACE(sizeof fd)];
msg.msg_control = cmsg_buf;
msg.msg_controllen = sizeof cmsg_buf;
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof fd);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
unsigned char *cmsg_data = CMSG_DATA(cmsg);
*(int *)cmsg_data = fd;
msg.msg_controllen = cmsg->cmsg_len;
if (sendmsg(client, &msg, 0) == -1)
err(1, "sendmsg() failed");
unlink("send_fd.sock");
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment