xref: /openbsd/regress/sys/kern/rcvtimeo/rcvtimeo.c (revision d415bd75)
1 /*	$OpenBSD: rcvtimeo.c,v 1.6 2021/12/13 16:56:50 deraadt Exp $	*/
2 
3 /*	Written by Michael Shalayeff, 2002, Public Domain */
4 
5 #include <sys/socket.h>
6 
7 #include <netinet/in.h>
8 
9 #include <signal.h>
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.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 	memset(&sin, 0, sizeof(sin));
44 	sin.sin_len = sizeof(sin);
45 	sin.sin_family = AF_INET;
46 	sin.sin_port = htons(30000);	/* XXX assuming nothing is there */
47 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
48 	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
49 		err(1, "bind");
50 
51 	tv.tv_sec = 1;
52 	tv.tv_usec = 0;
53 	if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
54 		err(1, "setsockopt1");
55 
56 	back = 0;
57 	alarm(2);
58 	errno = 0;
59 	if (recv(s, buf, sizeof(buf), 0) < 0 && errno != EAGAIN)
60 		err(1, "recv1");
61 	back = 1;
62 
63 	tv.tv_sec = 0;
64 	tv.tv_usec = 1;
65 	if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
66 		err(1, "setsockopt2");
67 
68 	back = 0;
69 	alarm(2);
70 	errno = 0;
71 	if (recv(s, buf, sizeof(buf), 0) < 0 && errno != EAGAIN)
72 		err(1, "recv2");
73 	back = 1;
74 
75 	exit (0);
76 }
77