#define _GNU_SOURCE 1 #include #include #include #include #include #include #include #include #include #include #include #include int main(void) { int fds[2]; struct msghdr msg; struct iovec iov[1]; union { /* union for &snd_u.control alignment */ struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int))]; } snd_u; union { /* union for &rcv_u.control alignment */ struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred))]; } rcv_u; char buf[1]; struct cmsghdr *hdr = NULL; if (socketpair(PF_LOCAL, SOCK_STREAM, IPPROTO_IP, fds) == -1) exit (EXIT_FAILURE); iov[0].iov_base = buf; iov[0].iov_len = 1; msg.msg_control = snd_u.control; msg.msg_controllen = sizeof(snd_u.control); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_flags = 0; hdr = CMSG_FIRSTHDR(&msg); hdr->cmsg_len = CMSG_LEN(sizeof(int)); hdr->cmsg_level = SOL_SOCKET; hdr->cmsg_type = SCM_RIGHTS; *((int *)CMSG_DATA(hdr)) = fds[0]; if (sendmsg(fds[0], &msg, 0) == -1) exit (EXIT_FAILURE); /* now recv is at the other end... */ iov[0].iov_base = buf; iov[0].iov_len = 1; msg.msg_control = rcv_u.control; msg.msg_controllen = sizeof(rcv_u.control); msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_flags = 0; { socklen_t len = sizeof(int); int val = 1; if (setsockopt(fds[1], SOL_SOCKET, SO_PASSCRED, &val, len) == -1) exit (EXIT_FAILURE); } if (recvmsg(fds[1], &msg, 0) == -1) exit (EXIT_FAILURE); hdr = CMSG_FIRSTHDR(&msg); if (!hdr || (hdr->cmsg_level != SOL_SOCKET) || ((hdr->cmsg_type != SCM_RIGHTS) && (hdr->cmsg_type != SCM_CREDENTIALS))) exit (EXIT_FAILURE); hdr = CMSG_NXTHDR(&msg, hdr); if (!hdr || (hdr->cmsg_level != SOL_SOCKET) || ((hdr->cmsg_type != SCM_RIGHTS) && (hdr->cmsg_type != SCM_CREDENTIALS))) exit (EXIT_FAILURE); hdr = CMSG_NXTHDR(&msg, hdr); if (hdr) exit (EXIT_FAILURE); exit (EXIT_SUCCESS); }