1 /* $OpenBSD: recvmsg.c,v 1.1 2011/09/13 23:50:17 fgsch Exp $ */ 2 /* 3 * Federico G. Schwindt <fgsch@openbsd.org>, 2011. Public Domain. 4 */ 5 #include <sys/types.h> 6 #include <sys/uio.h> 7 #include <sys/socket.h> 8 #include <netinet/in.h> 9 #include <pthread.h> 10 #include <signal.h> 11 #include <unistd.h> 12 #include "test.h" 13 14 volatile sig_atomic_t hits = 0; 15 16 void 17 handler(int sig) 18 { 19 hits++; 20 } 21 22 void * 23 thr_recvmsg(void *arg) 24 { 25 struct sockaddr_in sa; 26 struct msghdr msg; 27 struct iovec iov; 28 char buf; 29 int s; 30 31 CHECKe(s = socket(AF_INET, SOCK_DGRAM, 0)); 32 bzero(&sa, sizeof(sa)); 33 sa.sin_port = htons(6543); 34 CHECKe(bind(s, (const void*)&sa, sizeof(sa))); 35 bzero(&msg, sizeof(msg)); 36 iov.iov_base = &buf; 37 iov.iov_len = 1; 38 msg.msg_iov = &iov; 39 msg.msg_iovlen = 1; 40 ASSERT(recvmsg(s, &msg, 0) == -1); 41 return ((caddr_t)NULL + errno); 42 } 43 44 int 45 main(int argc, char **argv) 46 { 47 struct sigaction sa; 48 pthread_t tid; 49 void *retval; 50 51 bzero(&sa, sizeof(sa)); 52 sa.sa_handler = handler; 53 sa.sa_flags = SA_RESTART; 54 CHECKe(sigaction(SIGUSR1, &sa, NULL)); 55 sa.sa_flags = 0; 56 CHECKe(sigaction(SIGUSR2, &sa, NULL)); 57 58 CHECKr(pthread_create(&tid, NULL, thr_recvmsg, NULL)); 59 sleep(2); 60 61 /* Should restart it. */ 62 CHECKr(pthread_kill(tid, SIGUSR1)); 63 sleep(1); 64 65 /* Should interrupt it. */ 66 CHECKr(pthread_kill(tid, SIGUSR2)); 67 sleep(1); 68 69 CHECKr(pthread_join(tid, &retval)); 70 ASSERT(retval == (void *)EINTR); 71 ASSERT(hits == 2); 72 SUCCEED; 73 } 74