1 /* $OpenBSD: connect.c,v 1.3 2017/05/27 16:04:38 bluhm Exp $ */ 2 /* 3 * Federico G. Schwindt <fgsch@openbsd.org>, 2011. Public Domain. 4 */ 5 #include <sys/types.h> 6 #include <sys/socket.h> 7 #include <netinet/in.h> 8 #include <pthread.h> 9 #include <signal.h> 10 #include <unistd.h> 11 #include "test.h" 12 13 volatile sig_atomic_t hits = 0; 14 15 void 16 handler(int sig) 17 { 18 hits++; 19 } 20 21 void * 22 thr_connect(void *arg) 23 { 24 struct sockaddr_in sa; 25 socklen_t len; 26 int l, s; 27 28 /* Create a bound TCP socket without listen on loopback. */ 29 CHECKe(l = socket(AF_INET, SOCK_STREAM, 0)); 30 bzero(&sa, sizeof(sa)); 31 sa.sin_family = AF_INET; 32 sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 33 CHECKe(bind(l, (struct sockaddr *)&sa, sizeof(sa))); 34 len = sizeof(sa); 35 CHECKe(getsockname(l, (struct sockaddr *)&sa, &len)); 36 37 /* Connect to the non listen socket will not reply to SYN. */ 38 CHECKe(s = socket(AF_INET, SOCK_STREAM, 0)); 39 ASSERT(connect(s, (struct sockaddr *)&sa, sizeof(sa)) == -1); 40 int err = errno; 41 ASSERT(connect(s, (struct sockaddr *)&sa, sizeof(sa)) == -1); 42 ASSERT(errno == EALREADY); 43 return ((caddr_t)NULL + err); 44 } 45 46 int 47 main(int argc, char **argv) 48 { 49 struct sigaction sa; 50 pthread_t tid; 51 void *retval; 52 53 bzero(&sa, sizeof(sa)); 54 sa.sa_handler = handler; 55 sa.sa_flags = SA_RESTART; 56 CHECKe(sigaction(SIGUSR1, &sa, NULL)); 57 58 CHECKr(pthread_create(&tid, NULL, thr_connect, NULL)); 59 sleep(2); 60 61 /* Should interrupt it. */ 62 CHECKr(pthread_kill(tid, SIGUSR1)); 63 sleep(1); 64 65 CHECKr(pthread_join(tid, &retval)); 66 ASSERT(retval == (void *)EINTR); 67 ASSERT(hits == 1); 68 SUCCEED; 69 } 70