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