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