#include #include #include #include #include "test.h" #include "tests.h" typedef struct priv PRIV; struct priv { int l2c; int l2k; int c2l; int c2k; int k2c; int k2l; int kc; int wf; } ; static void run_kill_read_run_l(void *pv) { PRIV *p; pid_t mypid; int lfd; int fd; char ch[2]; int nr; int e; p = pv; close(p->c2l); close(p->c2k); close(p->k2c); close(p->k2l); mypid = getpid(); printf("kill-read: listener is %d\n",(int)mypid); printf("kill-read: listener establishing connection\n"); mustwrite(p->l2k,&mypid,sizeof(pid_t)); mustwrite(p->l2c,&mypid,sizeof(pid_t)); mustwrite(p->l2c,"",1); mustread(p->l2c,&ch[0],1); sleep(1); lfd = pidconn(PIDCONN_LISTEN,0,0); mustwrite(p->l2c,"",1); mustread(p->l2c,&ch[0],1); sleep(1); fd = pidconn(PIDCONN_ACCEPT,lfd,0); sleep(1); mustwrite(p->l2c,"",1); mustread(p->l2c,&ch[0],1); if (p->wf) { write(fd,"",1); sleep(1); mustwrite(p->l2c,"",1); mustread(p->l2c,&ch[0],1); } mustwrite(p->l2k,"",1); nr = read(fd,&ch[0],2); if (nr != 0) { e = errno; printf("kill-read: listener read returned %d",nr); if (nr < 0) printf(", errno %d [%s]",e,strerror(e)); printf("\n"); } printf("kill-read: listener done\n"); sleep(1); } static void run_kill_read_run_c(void *pv) { PRIV *p; pid_t lpid; int mypid; int fd; char ch[2]; int nr; int e; p = pv; close(p->l2c); close(p->l2k); close(p->k2c); close(p->k2l); mypid = getpid(); printf("kill-read: connecter is %d\n",(int)mypid); printf("kill-read: connecter establishing connection\n"); mustwrite(p->c2k,&mypid,sizeof(pid_t)); mustread(p->c2l,&lpid,sizeof(pid_t)); printf("kill-read: connecter connecting to %d\n",(int)lpid); mustread(p->c2l,&ch[0],1); mustwrite(p->c2l,"",1); mustread(p->c2l,&ch[0],1); mustwrite(p->c2l,"",1); sleep(1); fd = pidconn(PIDCONN_CONNECT,0,lpid); sleep(1); mustread(p->c2l,&ch[0],1); mustwrite(p->c2l,"",1); if (p->wf) { write(fd,"",1); sleep(1); mustread(p->c2l,&ch[0],1); mustwrite(p->c2l,"",1); } mustwrite(p->c2k,"",1); nr = read(fd,&ch[0],2); if (nr != 0) { e = errno; printf("kill-read: connecter read returned %d",nr); if (nr < 0) printf(", errno %d [%s]",e,strerror(e)); printf("\n"); } printf("kill-read: connecter done\n"); sleep(1); } static void run_kill_read_run_k(void *pv) { PRIV *p; pid_t mypid; int lpid; int cpid; char ch; p = pv; close(p->c2l); close(p->c2k); close(p->l2c); close(p->l2k); mypid = getpid(); printf("kill-read: killer is %d\n",(int)mypid); mustread(p->k2l,&lpid,sizeof(pid_t)); mustread(p->k2c,&cpid,sizeof(pid_t)); printf("kill-read: killer sees listener at %d, connecter at %d\n",(int)lpid,(int)cpid); sleep(1); mustread(p->k2l,&ch,1); mustread(p->k2c,&ch,1); sleep(1); printf("kill-read: killer killing %d\n",(int)(p->kc?cpid:lpid)); sleep(1); kill(p->kc?cpid:lpid,SIGINT); sleep(1); printf("kill-read: killer done\n"); sleep(1); } static void do_kill_read(int killc, int writefirst) { PRIV p; KID *kl; KID *kc; KID *kk; printf("kill-read: kill %s, writefirst %d\n",killc?"connecter":"listener",writefirst); local_socketpair(&p.l2c,&p.c2l); local_socketpair(&p.k2l,&p.l2k); local_socketpair(&p.c2k,&p.k2c); p.kc = killc; p.wf = writefirst; kl = fork_kid(&run_kill_read_run_l,&p); kc = fork_kid(&run_kill_read_run_c,&p); kk = fork_kid(&run_kill_read_run_k,&p); close(p.l2c); close(p.c2l); close(p.k2l); close(p.l2k); close(p.c2k); close(p.k2c); reap_kid(kl); reap_kid(kc); reap_kid(kk); printf("kill-read: done\n"); } static void run_kill_read(void) { do_kill_read(0,0); do_kill_read(1,0); do_kill_read(0,1); do_kill_read(1,1); } const TEST test_kill_read = { &run_kill_read };