Created
April 24, 2018 09:29
-
-
Save bennydictor/875f0be8f3306b71ddc9c3d5f36051d8 to your computer and use it in GitHub Desktop.
Sending file descriptors over unix domain sockets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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