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