xref: /openbsd/regress/sys/kern/rcvtimeo/rcvtimeo.c (revision fc61954a)
1 /*	$OpenBSD: rcvtimeo.c,v 1.5 2014/07/19 18:11:12 miod Exp $	*/
2 
3 /*	Written by Michael Shalayeff, 2002, Public Domain */
4 
5 #include <sys/param.h>
6 #include <sys/socket.h>
7 
8 #include <netinet/in.h>
9 
10 #include <signal.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <err.h>
17 
18 volatile int back;
19 
20 static void
21 sigalarm(int sig, siginfo_t *sip, void *scp)
22 {
23 	if (!back)
24 		_exit(1);
25 }
26 
27 int
28 main(int argc, char *argv[])
29 {
30 	struct sockaddr_in sin;
31 	struct sigaction sa;
32 	struct timeval tv;
33 	u_char buf[16];
34 	int s;
35 
36 	sa.sa_sigaction = &sigalarm;
37 	sa.sa_flags = SA_SIGINFO;
38 	sigemptyset(&sa.sa_mask);
39 	sigaction(SIGALRM, &sa, NULL);
40 
41 	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
42 		err(1, "socket");
43 
44 	memset(&sin, 0, sizeof(sin));
45 	sin.sin_len = sizeof(sin);
46 	sin.sin_family = AF_INET;
47 	sin.sin_port = htons(30000);	/* XXX assuming nothing is there */
48 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
49 	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
50 		err(1, "bind");
51 
52 	tv.tv_sec = 1;
53 	tv.tv_usec = 0;
54 	if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
55 		err(1, "setsockopt1");
56 
57 	back = 0;
58 	alarm(2);
59 	errno = 0;
60 	if (recv(s, buf, sizeof(buf), 0) < 0 && errno != EAGAIN)
61 		err(1, "recv1");
62 	back = 1;
63 
64 	tv.tv_sec = 0;
65 	tv.tv_usec = 1;
66 	if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
67 		err(1, "setsockopt2");
68 
69 	back = 0;
70 	alarm(2);
71 	errno = 0;
72 	if (recv(s, buf, sizeof(buf), 0) < 0 && errno != EAGAIN)
73 		err(1, "recv2");
74 	back = 1;
75 
76 	exit (0);
77 }
78