rendered paste body/* child process opens a connection and sends the socket fd back to the parent */#include <stdio.h>#include <sys/types.h> // socketpair#include <sys/socket.h> // socketpair#include <unistd.h> // close/fork#include <string.h> // memsetint send_socket(int sock, int dest){ struct msghdr msg; struct cmsghdr *cmsg; union { struct cmsghdr align; char msgbuf[CMSG_SPACE(sizeof(int))]; } u; struct iovec iov[1]; char iov_data[] = { 0 }; memset(&msg, 0, sizeof(struct msghdr)); memset(iov, 0, sizeof(struct iovec)); iov[0].iov_base = iov_data; iov[0].iov_len = 1; msg.msg_control = u.msgbuf; msg.msg_controllen = sizeof(u.msgbuf); msg.msg_iov = iov; msg.msg_iovlen = 1; cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(int)); *((int*)CMSG_DATA(cmsg)) = sock; if (sendmsg(dest, &msg, 0) == -1) { perror("sendmsg()"); return 1; } printf("sent socket %i to parent as message type %i\n", sock, SCM_RIGHTS); return 0;}int receive_socket(int src){ struct msghdr msg; struct cmsghdr *cmsg; union { struct cmsghdr align; char msgbuf[CMSG_SPACE(sizeof(int))]; } u; struct iovec iov[1]; char iov_data[1]; memset(&msg, 0, sizeof(struct msghdr)); memset(iov, 0, sizeof(struct iovec)); iov[0].iov_base = iov_data; iov[0].iov_len = 1; msg.msg_control = u.msgbuf; msg.msg_controllen = sizeof(u.msgbuf); msg.msg_iov = iov; msg.msg_iovlen = 1; if (recvmsg(src, &msg, 0) == -1) { perror("recvmsg()"); return -1; } printf("parent reading message\n"); for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { printf("next message type is %i\n", cmsg->cmsg_type); if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS && cmsg->cmsg_len >= sizeof(int)) return *((int*)CMSG_DATA(cmsg)); } printf("parent did not receive expected message\n"); return -1;}int child(int sock_parent){ int sock_inet = socket(PF_INET, SOCK_STREAM, 0); if (sock_inet == -1) { perror("socket()"); close(sock_parent); return 1; } printf("child made socket %i\n", sock_inet); // do things with inet socket -- set params, connect() // then send it back to the parent int result = send_socket(sock_inet, sock_parent); close(sock_parent); if (result != 0) close(sock_inet); return result;}int parent(int sock_child){ int sock_inet = receive_socket(sock_child); close(sock_child); if (sock_inet == -1) return 1; printf("parent receives socket %i\n", sock_inet); // do things with the (connected) socket // then clean up close(sock_inet); return 0;}int main(){ // make a socketpair for the parent & child to communicate via int socks[2]; if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, socks) == -1) { perror("socketpair()"); return 1; } switch (fork()) { case -1: perror("fork()"); close(socks[0]); close(socks[1]); return 1; case 0: return child(socks[0]); break; default: return parent(socks[1]); }}