1*8a272653SPeter Holm#!/bin/sh 2*8a272653SPeter Holm 3*8a272653SPeter Holm# Bug 227285 - File descriptor passing does not work reliably on SMP system 4*8a272653SPeter Holm# (cache coherency issue?) 5*8a272653SPeter Holm# "socketpair3: read failed in parent: 0, so_error: No error: 0 (0), ret2: 0" 6*8a272653SPeter Holm# seen. 7*8a272653SPeter Holm 8*8a272653SPeter Holm# Original test scenario by: jan.kokemueller@gmail.com 9*8a272653SPeter Holm 10*8a272653SPeter Holm# Page fault seen in WiP socket code. 11*8a272653SPeter Holm 12*8a272653SPeter Holm. ../default.cfg 13*8a272653SPeter Holmdir=/tmp 14*8a272653SPeter Holmodir=`pwd` 15*8a272653SPeter Holmcd $dir 16*8a272653SPeter Holmsed '1,/^EOF/d' < $odir/$0 > $dir/socketpair3.c 17*8a272653SPeter Holmmycc -o socketpair3 -Wall -Wextra -O0 -g socketpair3.c -lnv || exit 1 18*8a272653SPeter Holmrm -f socketpair3.c 19*8a272653SPeter Holmcd $odir 20*8a272653SPeter Holm 21*8a272653SPeter Holmfor i in `jot 6`; do 22*8a272653SPeter Holm $dir/socketpair3 & 23*8a272653SPeter Holm pids="$pids $!" 24*8a272653SPeter Holmdone 25*8a272653SPeter Holms=0 26*8a272653SPeter Holmfor i in $pids; do 27*8a272653SPeter Holm wait $i 28*8a272653SPeter Holm [ $? -ne 0 ] && s=1 29*8a272653SPeter Holmdone 30*8a272653SPeter Holm[ -f socketpair3.core -a $s -eq 0 ] && 31*8a272653SPeter Holm { ls -l socketpair3.core; mv socketpair3.core /tmp; s=1; } 32*8a272653SPeter Holm 33*8a272653SPeter Holmrm -rf $dir/socketpair3 34*8a272653SPeter Holmexit $s 35*8a272653SPeter Holm 36*8a272653SPeter HolmEOF 37*8a272653SPeter Holm#include <sys/types.h> 38*8a272653SPeter Holm 39*8a272653SPeter Holm#include <sys/procdesc.h> 40*8a272653SPeter Holm#include <sys/socket.h> 41*8a272653SPeter Holm#include <sys/wait.h> 42*8a272653SPeter Holm 43*8a272653SPeter Holm#include <err.h> 44*8a272653SPeter Holm#include <poll.h> 45*8a272653SPeter Holm#include <signal.h> 46*8a272653SPeter Holm#include <stdio.h> 47*8a272653SPeter Holm#include <string.h> 48*8a272653SPeter Holm#include <time.h> 49*8a272653SPeter Holm#include <unistd.h> 50*8a272653SPeter Holm 51*8a272653SPeter Holm// From libnv. 52*8a272653SPeter Holmextern int fd_send(int sock, const int *fds, size_t nfds); 53*8a272653SPeter Holmextern int fd_recv(int sock, int *fds, size_t nfds); 54*8a272653SPeter Holm 55*8a272653SPeter Holmint main(void) 56*8a272653SPeter Holm{ 57*8a272653SPeter Holm pid_t pid; 58*8a272653SPeter Holm time_t start; 59*8a272653SPeter Holm int child_fd; 60*8a272653SPeter Holm int sock[2]; 61*8a272653SPeter Holm 62*8a272653SPeter Holm start = time(NULL); 63*8a272653SPeter Holm while (time(NULL) - start < 60) { 64*8a272653SPeter Holm if (socketpair(PF_UNIX, SOCK_STREAM, 0, sock) < 0) 65*8a272653SPeter Holm err(1, "socketpair"); 66*8a272653SPeter Holm 67*8a272653SPeter Holm pid = pdfork(&child_fd, PD_CLOEXEC); 68*8a272653SPeter Holm if (pid < 0) 69*8a272653SPeter Holm err(1, "pdfork"); 70*8a272653SPeter Holm 71*8a272653SPeter Holm if (pid == 0) { 72*8a272653SPeter Holm ssize_t ret; 73*8a272653SPeter Holm int sock_child[2]; 74*8a272653SPeter Holm int dummy = 0; 75*8a272653SPeter Holm 76*8a272653SPeter Holm close(sock[0]); 77*8a272653SPeter Holm if (socketpair(PF_UNIX, SOCK_STREAM, /**/ 78*8a272653SPeter Holm 0, sock_child) < 0) 79*8a272653SPeter Holm err(1, "socketpair"); 80*8a272653SPeter Holm 81*8a272653SPeter Holm if (fd_send(sock[1], &sock_child[0], 1) != 0) 82*8a272653SPeter Holm errx(1, "fd_send failed"); 83*8a272653SPeter Holm#ifdef WORKAROUND 84*8a272653SPeter Holm if (read(sock[1], &dummy, 1) != 1) 85*8a272653SPeter Holm err(1, "write"); 86*8a272653SPeter Holm#endif 87*8a272653SPeter Holm 88*8a272653SPeter Holm close(sock_child[0]); 89*8a272653SPeter Holm 90*8a272653SPeter Holm if (write(sock_child[1], &dummy, 1) != 1) 91*8a272653SPeter Holm err(1, "write"); 92*8a272653SPeter Holm 93*8a272653SPeter Holm if ((ret = read(sock_child[1], &dummy, 1)) != 1) 94*8a272653SPeter Holm errx(1, "read failed in child: %d", 95*8a272653SPeter Holm (int)ret); 96*8a272653SPeter Holm 97*8a272653SPeter Holm close(sock_child[1]); 98*8a272653SPeter Holm 99*8a272653SPeter Holm _exit(0); 100*8a272653SPeter Holm } 101*8a272653SPeter Holm 102*8a272653SPeter Holm close(sock[1]); 103*8a272653SPeter Holm 104*8a272653SPeter Holm int sock_child; 105*8a272653SPeter Holm uint8_t dummy; 106*8a272653SPeter Holm 107*8a272653SPeter Holm if (fd_recv(sock[0], &sock_child, 1) != 0) 108*8a272653SPeter Holm errx(1, "fd_recv failed"); 109*8a272653SPeter Holm#ifdef WORKAROUND 110*8a272653SPeter Holm if (write(sock[0], &dummy, 1) != 1) 111*8a272653SPeter Holm err(1, "write"); 112*8a272653SPeter Holm#endif 113*8a272653SPeter Holm 114*8a272653SPeter Holm ssize_t ret; 115*8a272653SPeter Holm if ((ret = read(sock_child, &dummy, 1)) != 1) { 116*8a272653SPeter Holm int error; 117*8a272653SPeter Holm socklen_t err_len = sizeof(error); 118*8a272653SPeter Holm 119*8a272653SPeter Holm if (getsockopt(sock_child, SOL_SOCKET, SO_ERROR, 120*8a272653SPeter Holm &error, &err_len) < 0) 121*8a272653SPeter Holm err(1, "getsockopt"); 122*8a272653SPeter Holm 123*8a272653SPeter Holm ssize_t ret2 = read(sock_child, &dummy, 1); 124*8a272653SPeter Holm 125*8a272653SPeter Holm errx(1, 126*8a272653SPeter Holm "read failed in parent: %d, so_error: %s (%d), " 127*8a272653SPeter Holm "ret2: %d", (int)ret, strerror(error), error, 128*8a272653SPeter Holm (int)ret2); 129*8a272653SPeter Holm } 130*8a272653SPeter Holm 131*8a272653SPeter Holm if (write(sock_child, &dummy, 1) != 1) 132*8a272653SPeter Holm err(1, "write"); 133*8a272653SPeter Holm 134*8a272653SPeter Holm close(sock_child); 135*8a272653SPeter Holm 136*8a272653SPeter Holm struct pollfd pfd = { .fd = child_fd }; 137*8a272653SPeter Holm poll(&pfd, 1, -1); 138*8a272653SPeter Holm 139*8a272653SPeter Holm close(child_fd); 140*8a272653SPeter Holm close(sock[0]); 141*8a272653SPeter Holm } 142*8a272653SPeter Holm 143*8a272653SPeter Holm return (0); 144*8a272653SPeter Holm} 145