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 *
sock_connect(void * arg)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 *
sock_accept(void * arg)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
main(int argc,char ** argv)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