Created
August 22, 2018 14:53
-
-
Save jim3ma/c12db698290978d55627e865a0590afe to your computer and use it in GitHub Desktop.
Send a file descriptor over an abstract unix domain socket
This file contains hidden or 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 <stdlib.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <sys/un.h> | |
#include <stdio.h> | |
#include <strings.h> | |
#include <errno.h> | |
#define NAME ".socket" | |
int recvfd(int socket) { | |
int len; | |
int fd; | |
char buf[1]; | |
struct iovec iov; | |
struct msghdr msg; | |
struct cmsghdr *cmsg; | |
char cms[CMSG_SPACE(sizeof(int))]; | |
iov.iov_base = buf; | |
iov.iov_len = sizeof(buf); | |
msg.msg_name = 0; | |
msg.msg_namelen = 0; | |
msg.msg_iov = &iov; | |
msg.msg_iovlen = 1; | |
msg.msg_flags = 0; | |
msg.msg_control = (caddr_t) cms; | |
msg.msg_controllen = sizeof cms; | |
len = recvmsg(socket, &msg, 0); | |
if (len < 0) { | |
printf("recvmsg failed with %s", strerror(errno)); | |
return -1; | |
} | |
if (len == 0) { | |
printf("recvmsg failed no data"); | |
return -1; | |
} | |
cmsg = CMSG_FIRSTHDR(&msg); | |
memmove(&fd, CMSG_DATA(cmsg), sizeof(int)); | |
return fd; | |
} | |
main() | |
{ | |
int fd, sock, msgsock, rval; | |
struct sockaddr_un server; | |
char buf[1024]; | |
sock = socket(AF_UNIX, SOCK_STREAM, 0); | |
if (sock < 0) { | |
perror("opening stream socket"); | |
exit(1); | |
} | |
server.sun_family = AF_UNIX; | |
strcpy(server.sun_path, NAME); | |
if (bind(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un))) { | |
perror("binding stream socket"); | |
exit(1); | |
} | |
printf("Socket has name %s\n", server.sun_path); | |
listen(sock, 5); | |
for (;;) { | |
msgsock = accept(sock, 0, 0); | |
if (msgsock == -1) | |
perror("accept"); | |
fd = recvfd(msgsock); | |
printf("-->%d\n", fd); | |
close(msgsock); | |
} | |
close(sock); | |
unlink(NAME); | |
} |
This file contains hidden or 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 <stdlib.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <sys/un.h> | |
#include <stdio.h> | |
/** | |
* Sends given file descriptior via given socket | |
* | |
* @param socket to be used for fd sending | |
* @param fd to be sent | |
* @return sendmsg result | |
* | |
* @note socket should be (PF_UNIX, SOCK_DGRAM) | |
*/ | |
int send_fd(int sock, int fd){ | |
// This function does the arcane magic for sending | |
// file descriptors over unix domain sockets | |
struct msghdr msg; | |
struct iovec iov[1]; | |
struct cmsghdr *cmsg = NULL; | |
char ctrl_buf[CMSG_SPACE(sizeof(int))]; | |
char data[1]; | |
memset(&msg, 0, sizeof(struct msghdr)); | |
memset(ctrl_buf, 0, CMSG_SPACE(sizeof(int))); | |
data[0] = ' '; | |
iov[0].iov_base = data; | |
iov[0].iov_len = sizeof(data); | |
msg.msg_name = NULL; | |
msg.msg_namelen = 0; | |
msg.msg_iov = iov; | |
msg.msg_iovlen = 1; | |
msg.msg_controllen = CMSG_SPACE(sizeof(int)); | |
msg.msg_control = ctrl_buf; | |
cmsg = CMSG_FIRSTHDR(&msg); | |
cmsg->cmsg_level = SOL_SOCKET; | |
cmsg->cmsg_type = SCM_RIGHTS; | |
cmsg->cmsg_len = CMSG_LEN(sizeof(int)); | |
*((int *) CMSG_DATA(cmsg)) = fd; | |
return sendmsg(sock, &msg, 0); | |
} | |
main(argc, argv) | |
int argc; | |
char *argv[]; | |
{ | |
int fd, sock; | |
struct sockaddr_un server; | |
char buf[1024]; | |
if (argc < 3) { | |
printf("usage:%s <sock path> <file name>", argv[0]); | |
exit(1); | |
} | |
sock = socket(AF_UNIX, SOCK_STREAM, 0); | |
if (sock < 0) { | |
perror("opening stream socket"); | |
exit(1); | |
} | |
server.sun_family = AF_UNIX; | |
strcpy(server.sun_path, argv[1]); | |
if (connect(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) { | |
close(sock); | |
perror("connecting stream socket"); | |
exit(1); | |
} | |
// Open the file descriptor we want to send | |
fd = open(argv[2], 0); | |
send_fd(sock, fd); | |
close(sock); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment