-
-
Save legionus/aef922106f6173f071c2f8fabd20d418 to your computer and use it in GitHub Desktop.
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
#define _GNU_SOURCE | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <sys/un.h> | |
#include <stdio.h> | |
int main(int argc, const char *argv[]) | |
{ | |
int sock_pair[2]; | |
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sock_pair) < 0) { | |
perror("socketpair: "); | |
return -1; | |
} | |
int reader_fd = sock_pair[0]; | |
int writer_fd = sock_pair[1]; | |
int enable = 1; | |
if (setsockopt(reader_fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable)) < 0) { | |
perror("setsockopt: "); | |
return -1; | |
} | |
char buf[] = "hello"; | |
const size_t length = sizeof(buf); | |
struct iovec iov = { buf, length }; | |
struct msghdr msg = {}; | |
msg.msg_iov = &iov; | |
msg.msg_iovlen = 1; | |
const ssize_t control_len_snd = CMSG_SPACE(sizeof(int)); | |
char control_buf_snd[control_len_snd]; | |
msg.msg_control = control_buf_snd; | |
msg.msg_controllen = control_len_snd; | |
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); | |
cmsg->cmsg_level = SOL_SOCKET; | |
cmsg->cmsg_type = SCM_RIGHTS; | |
cmsg->cmsg_len = CMSG_LEN(sizeof(int)); | |
memcpy(CMSG_DATA(cmsg), &reader_fd, sizeof(int)); | |
if (sendmsg(writer_fd, &msg, 0) < 0) { | |
perror("sendmesg: "); | |
return -1; | |
} | |
char recv_buf[sizeof(buf)] = {}; | |
struct iovec iov2 = { recv_buf, length }; | |
msg.msg_iov = &iov2; | |
msg.msg_iovlen = 1; | |
const ssize_t control_len_rcv = CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int)); | |
char control_buf_rcv[control_len_rcv]; | |
msg.msg_control = control_buf_rcv; | |
msg.msg_controllen = control_len_rcv; | |
if (recvmsg(reader_fd, &msg, 0) < 0) { | |
perror("recvmesg: "); | |
return -1; | |
} | |
int got_fd = -1; | |
pid_t got_pid = -1; | |
if (msg.msg_controllen > 0) { | |
struct cmsghdr *cmsg; // hides | |
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { | |
const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); | |
if (cmsg->cmsg_level != SOL_SOCKET) | |
continue; | |
switch (cmsg->cmsg_type) { | |
case SCM_RIGHTS: | |
if (payload_len != sizeof(int)) { | |
fprintf(stderr, "expected fd payload sizeof(int)\n"); | |
return -1; | |
} | |
got_fd = *((int *)(CMSG_DATA(cmsg))); | |
printf("got fd: %d\n", got_fd); | |
break; | |
case SCM_CREDENTIALS: | |
if (payload_len != sizeof(struct ucred)) { | |
fprintf(stderr, "expected rights payload sizeof(struct ucred)\n"); | |
return -1; | |
} | |
got_pid = ((struct ucred *)(CMSG_DATA(cmsg)))->pid; | |
printf("got pid: %d\n", got_pid); | |
break; | |
} | |
} | |
} | |
printf("got message buffer: %s\n", recv_buf); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment