xref: /openbsd/regress/sys/kern/rcvtimeo/rcvtimeo.c (revision 404b540a)
1 /*	$OpenBSD: rcvtimeo.c,v 1.4 2003/09/02 23:52:17 david 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 <errno.h>
15 #include <err.h>
16 
17 volatile int back;
18 
19 static void
20 sigalarm(int sig, siginfo_t *sip, void *scp)
21 {
22 	if (!back)
23 		_exit(1);
24 }
25 
26 int
27 main(int argc, char *argv[])
28 {
29 	struct sockaddr_in sin;
30 	struct sigaction sa;
31 	struct timeval tv;
32 	u_char buf[16];
33 	int s;
34 
35 	sa.sa_sigaction = &sigalarm;
36 	sa.sa_flags = SA_SIGINFO;
37 	sigemptyset(&sa.sa_mask);
38 	sigaction(SIGALRM, &sa, NULL);
39 
40 	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
41 		err(1, "socket");
42 
43 	sin.sin_len = sizeof(sin);
44 	sin.sin_family = AF_INET;
45 	sin.sin_port = htons(30000);	/* XXX assuming nothing is there */
46 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
47 	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
48 		err(1, "bind");
49 
50 	tv.tv_sec = 1;
51 	tv.tv_usec = 0;
52 	if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
53 		err(1, "setsockopt1");
54 
55 	back = 0;
56 	alarm(2);
57 	errno = 0;
58 	if (recv(s, buf, sizeof(buf), 0) < 0 && errno != EAGAIN)
59 		err(1, "recv1");
60 	back = 1;
61 
62 	tv.tv_sec = 0;
63 	tv.tv_usec = 1;
64 	if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
65 		err(1, "setsockopt2");
66 
67 	back = 0;
68 	alarm(2);
69 	errno = 0;
70 	if (recv(s, buf, sizeof(buf), 0) < 0 && errno != EAGAIN)
71 		err(1, "recv2");
72 	back = 1;
73 
74 	exit (0);
75 }
76