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