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