1 /* $OpenBSD: setsockopt3.c,v 1.4 2012/02/22 20:33:51 fgsch Exp $ */ 2 /* 3 * Federico G. Schwindt <fgsch@openbsd.org>, 2009. Public Domain. 4 */ 5 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <sys/wait.h> 9 #include <netinet/in.h> 10 #include <err.h> 11 #include <netdb.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <unistd.h> 15 #include "test.h" 16 17 static void * 18 sock_connect(void *arg) 19 { 20 struct timeval to; 21 pid_t child_pid; 22 int status; 23 int s; 24 25 CHECKe(s = socket(AF_INET, SOCK_STREAM, 0)); 26 to.tv_sec = 2; 27 to.tv_usec = 0.5 * 1e6; 28 CHECKe(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to))); 29 CHECKe(child_pid = fork()); 30 if (child_pid == 0) { 31 char *argv[3]; 32 char fdstr[3]; 33 snprintf(fdstr, sizeof(fdstr), "%d", s); 34 argv[0] = "setsockopt3a"; 35 argv[1] = fdstr; 36 argv[2] = NULL; 37 execv(argv[0], argv); 38 _exit(NOTOK); 39 } 40 ASSERTe(wait(&status), == child_pid); 41 ASSERT(WIFEXITED(status)); 42 ASSERT(WEXITSTATUS(status) == 0); 43 return (NULL); 44 } 45 46 static void * 47 sock_accept(void *arg) 48 { 49 pthread_t connect_thread; 50 struct sockaddr_in sin; 51 int s; 52 53 CHECKe(s = socket(AF_INET, SOCK_STREAM, 0)); 54 bzero(&sin, sizeof(sin)); 55 sin.sin_family = AF_INET; 56 sin.sin_len = sizeof(sin); 57 sin.sin_port = htons(6545); 58 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 59 CHECKe(bind(s, (struct sockaddr *)&sin, sizeof(sin))); 60 CHECKe(listen(s, 2)); 61 62 CHECKr(pthread_create(&connect_thread, NULL, sock_connect, NULL)); 63 CHECKr(pthread_join(connect_thread, NULL)); 64 return (NULL); 65 } 66 67 int 68 main(int argc, char **argv) 69 { 70 pthread_t accept_thread; 71 72 CHECKr(pthread_create(&accept_thread, NULL, sock_accept, NULL)); 73 CHECKr(pthread_join(accept_thread, NULL)); 74 SUCCEED; 75 } 76