Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _GNU_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/socket.h>
- #include <sys/wait.h>
- #define pexit(msg) do { perror(msg); exit(1); } while (0)
- static int sendfd(int sockfd, int fd)
- {
- struct msghdr msg = { 0 };
- struct cmsghdr *cmsg;
- int err;
- char iobuf;
- struct iovec io = {
- .iov_base = &iobuf,
- .iov_len = sizeof(iobuf),
- };
- union {
- char buf[CMSG_SPACE(sizeof(fd))];
- struct cmsghdr align;
- } u;
- msg.msg_iov = &io;
- msg.msg_iovlen = 1;
- msg.msg_control = u.buf;
- msg.msg_controllen = sizeof(u.buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
- /* Send the file descriptor with an empty message
- * containing only the ancillary data. */
- msg.msg_iov = NULL;
- msg.msg_iovlen = 0;
- memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
- err = sendmsg(sockfd, &msg, 0);
- if (err < 0)
- pexit("sendmsg");
- if (err != msg.msg_iovlen)
- pexit("sendmsg");
- return 0;
- }
- static int recvfd(int sockfd)
- {
- struct msghdr msg = { 0 };
- struct cmsghdr *cmsg;
- int err;
- int fd;
- union {
- char buf[CMSG_SPACE(sizeof(fd))];
- struct cmsghdr align;
- } u;
- msg.msg_control = u.buf;
- msg.msg_controllen = sizeof(u.buf);
- err = recvmsg(sockfd, &msg, 0);
- if (err < 0)
- pexit("recvmsg");
- cmsg = CMSG_FIRSTHDR(&msg);
- if (!cmsg ||
- cmsg->cmsg_len != CMSG_LEN(sizeof(fd)) ||
- cmsg->cmsg_level != SOL_SOCKET ||
- cmsg->cmsg_type != SCM_RIGHTS)
- pexit("Invalid cmsg");
- memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
- return fd;
- }
- int main(void)
- {
- int scm_fds[2], r;
- r = socketpair(AF_UNIX, SOCK_STREAM, 0, scm_fds);
- if (r < 0)
- pexit("socketpair");
- if (fork()) {
- int fd = open("/", O_PATH | O_DIRECTORY);
- if (fd < 0)
- pexit("open");
- r = sendfd(scm_fds[0], fd);
- if (r < 0)
- pexit("sendfd");
- puts("sent fd");
- } else {
- int fd = recvfd(scm_fds[1]);
- if (fd < 0)
- pexit("recvfd");
- puts("received fd");
- exit(0);
- }
- wait(NULL);
- puts("done");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement