#include #include #include #include #include #include #include #include #include #include // From libnv. extern int fd_send(int sock, const int *fds, size_t nfds); extern int fd_recv(int sock, int *fds, size_t nfds); int main() { for (;;) { pid_t pid; int child_fd; int sock[2]; fprintf(stderr, "next gen\n"); if (socketpair(PF_UNIX, SOCK_STREAM, 0, sock) < 0) { err(1, "socketpair"); } pid = pdfork(&child_fd, PD_CLOEXEC); if (pid < 0) { err(1, "pdfork"); } if (pid == 0) { close(sock[0]); int sock_child[2]; int dummy = 0; if (socketpair(PF_UNIX, SOCK_STREAM, /**/ 0, sock_child) < 0) { err(1, "socketpair"); } // fprintf(stderr, "dummy write/read\n"); // if (write(sock_child[1], &dummy, 1) != 1) { // err(1, "write"); // } // if (read(sock_child[0], &dummy, 1) != 1) { // err(1, "read"); // } fprintf(stderr, "sending socket...\n"); if (fd_send(sock[1], &sock_child[0], 1) != 0) { errx(1, "fd_send failed"); } if (read(sock[1], &dummy, 1) != 1) { err(1, "write"); } fprintf(stderr, "sent socket\n"); close(sock_child[0]); if (write(sock_child[1], &dummy, 1) != 1) { err(1, "write"); } ssize_t ret; if ((ret = read(sock_child[1], &dummy, 1)) != 1) { errx(1, "read failed in child: %d", (int)ret); } close(sock_child[1]); _exit(0); } close(sock[1]); int sock_child; uint8_t dummy; fprintf(stderr, "recv socket...\n"); if (fd_recv(sock[0], &sock_child, 1) != 0) { errx(1, "fd_recv failed"); } if (write(sock[0], &dummy, 1) != 1) { err(1, "write"); } fprintf(stderr, "recved socket\n"); ssize_t ret; fprintf(stderr, "reading one byte...\n"); if ((ret = read(sock_child, &dummy, 1)) != 1) { int error; socklen_t err_len = sizeof(error); if (getsockopt(sock_child, SOL_SOCKET, SO_ERROR, &error, &err_len) < 0) { err(1, "getsockopt"); } fprintf(stderr, "got err\n"); ssize_t ret2 = read(sock_child, &dummy, 1); errx(1, "read failed in parent: %d, so_error: %s (%d), ret2: %d", (int)ret, strerror(error), error, (int)ret2); } if (write(sock_child, &dummy, 1) != 1) { err(1, "write"); } close(sock_child); struct pollfd pfd = { .fd = child_fd }; poll(&pfd, 1, -1); close(child_fd); close(sock[0]); } }