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