#include #include #include #include #include "test.h" #include "tests.h" #define NFD 3 typedef struct priv PRIV; struct priv { const char *co; int lfd; int cfd; } ; static void run_connect_completion_run_l(void *pv) { PRIV *p; pid_t mypid; int fd; char c; int fd2; LLI lts; LLI cts; LLI d; p = pv; mypid = getpid(); printf("connect-completion: listener is %d\n",(int)mypid); mustwrite(p->lfd,&mypid,sizeof(pid_t)); printf("connect-completion: listener doing PIDCONN_LISTEN\n"); sleep(1); SET_PIDCONN(fd,PIDCONN_LISTEN,0,0); mustwrite(p->lfd,"",1); mustread(p->lfd,&c,1); mustwrite(p->lfd,"",1); mustread(p->lfd,&c,1); sleep(1); SET_PIDCONN(fd2,PIDCONN_ACCEPT,fd,0); lts = tstamp(); sleep(1); mustwrite(p->lfd,"",1); mustread(p->lfd,&cts,sizeof(cts)); d = lts - cts; if ((d < -250000LL) || (d > 250000LL)) { printf("connect-completion: time delta %lld too large\n",d); test_fail(); } printf("connect-completion: time delta %lld\n",d); printf("connect-completion: listener done\n"); } static void run_connect_completion_run_c(void *pv) { PRIV *p; pid_t lpid; int fd; char c; struct pollfd pfd; LLI ts; int i; p = pv; printf("connect-completion: connecter is %d\n",(int)getpid()); mustread(p->cfd,&lpid,sizeof(pid_t)); printf("connect-completion: connecter doing PIDCONN_CONNECT to %d\n",(int)lpid); mustread(p->cfd,&c,1); mustwrite(p->cfd,"",1); SET_PIDCONN(fd,PIDCONN_CONNECT,0,lpid); mustread(p->cfd,&c,1); mustwrite(p->cfd,"",1); pfd.fd = fd; pfd.events = POLLOUT | POLLWRNORM; while (1) { i = poll(&pfd,1,5000); if (i < 0) { i = errno; printf("connect-completion: poll: %s\n",strerror(i)); if (i == EINTR) continue; test_fail(); } if (i == 0) { printf("connect-completion: connecter poll() timed out\n"); test_fail(); } break; } ts = tstamp(); sleep(1); mustread(p->cfd,&c,1); mustwrite(p->cfd,&ts,sizeof(ts)); sleep(1); printf("connect-completion: connecter done\n"); } static void run_connect_completion(void) { PRIV p; KID *kl; KID *kc; local_socketpair(&p.lfd,&p.cfd); kl = fork_kid(&run_connect_completion_run_l,&p); kc = fork_kid(&run_connect_completion_run_c,&p); close(p.lfd); close(p.cfd); reap_kid(kl); reap_kid(kc); printf("connect-completion: done\n"); } const TEST test_connect_completion = { &run_connect_completion };