1#include <assert.h> 2#include <string.h> 3#include <stdlib.h> 4#include <unistd.h> 5#include <errno.h> 6#include <fcntl.h> 7#include <sys/socket.h> 8#include <sys/wait.h> 9 10int main(void) 11{ 12 union { 13 struct cmsghdr cmsghdr; 14 char buf[CMSG_SPACE(sizeof(int))]; 15 } control = {}; 16 17 int fd; 18 int data = 0; 19 struct iovec iov = { 20 .iov_base = &data, 21 .iov_len = sizeof(iov) 22 }; 23 24 struct msghdr mh = { 25 .msg_iov = &iov, 26 .msg_iovlen = 1, 27 .msg_control = &control, 28 .msg_controllen = sizeof(control) 29 }; 30 31 while ((fd = open("/dev/null", O_RDWR)) < 3) 32 assert(fd >= 0); 33 (void) close(3); 34 35 int sv[2]; 36 assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); 37 38 pid_t pid = fork(); 39 assert(pid >= 0); 40 41 if (pid) { 42 assert(close(sv[0]) == 0); 43 assert(dup2(sv[1], 1) == 1); 44 assert(close(sv[1]) == 0); 45 46 assert((fd = open("/dev/null", O_RDWR)) == 3); 47 48 struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh); 49 cmsg->cmsg_level = SOL_SOCKET; 50 cmsg->cmsg_type = SCM_RIGHTS; 51 cmsg->cmsg_len = CMSG_LEN(sizeof fd); 52 memcpy(CMSG_DATA(cmsg), &fd, sizeof fd); 53 mh.msg_controllen = cmsg->cmsg_len; 54 55 assert(sendmsg(1, &mh, 0) == sizeof(iov)); 56 assert(close(1) == 0); 57 58 int status; 59 assert(waitpid(pid, &status, 0) == pid); 60 assert(status == 0); 61 } else { 62 assert(close(sv[1]) == 0); 63 assert(dup2(sv[0], 0) == 0); 64 assert(close(sv[0]) == 0); 65 66 assert(recvmsg(0, &mh, 0) == sizeof(iov)); 67 assert(close(0) == 0); 68 } 69 70 return 0; 71} 72