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
sigalarm(int sig,siginfo_t * sip,void * scp)20 sigalarm(int sig, siginfo_t *sip, void *scp)
21 {
22 if (!back)
23 _exit(1);
24 }
25
26 int
main(int argc,char * argv[])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