1 #include <sys/types.h> 2 #include <sys/socket.h> 3 #include <sys/time.h> 4 5 #include <arpa/inet.h> 6 #include <netinet/in.h> 7 8 #include <err.h> 9 #include <errno.h> 10 #include <signal.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <unistd.h> 15 16 #define READ_BLOCK_TIME 5 /* unit: sec */ 17 18 static void 19 sig_alarm(int sig __unused) 20 { 21 #define PANIC_STRING "read blocks\n" 22 23 write(2, PANIC_STRING, strlen(PANIC_STRING)); 24 abort(); 25 } 26 27 static void 28 usage(const char *cmd) 29 { 30 fprintf(stderr, "%s -p port\n", cmd); 31 exit(1); 32 } 33 34 int 35 main(int argc, char *argv[]) 36 { 37 struct sockaddr_in in; 38 struct itimerval it; 39 int s, n, error, port, opt; 40 char buf; 41 42 port = 0; 43 while ((opt = getopt(argc, argv, "p:")) != -1) { 44 char *endptr; 45 46 switch (opt) { 47 case 'p': 48 port = strtol(optarg, &endptr, 0); 49 if (*endptr != '\0') 50 errx(1, "invalid -p argument"); 51 break; 52 53 default: 54 usage(argv[0]); 55 } 56 } 57 if (port <= 0) 58 usage(argv[0]); 59 60 s = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0); 61 if (s < 0) 62 err(1, "socket failed"); 63 64 memset(&in, 0, sizeof(in)); 65 in.sin_family = AF_INET; 66 in.sin_port = htons(port); 67 if (bind(s, (const struct sockaddr *)&in, sizeof(in)) < 0) 68 err(1, "bind %d failed", port); 69 70 memset(&it, 0, sizeof(it)); 71 it.it_value.tv_sec = READ_BLOCK_TIME; 72 if (signal(SIGALRM, sig_alarm) == SIG_ERR) 73 err(1, "signal failed"); 74 if (setitimer(ITIMER_REAL, &it, NULL) < 0) 75 err(1, "setitimer failed"); 76 77 n = read(s, &buf, 1); 78 if (n < 0) { 79 error = errno; 80 if (error != EAGAIN) { 81 warnx("invalid errno %d", error); 82 abort(); 83 } 84 } else { 85 warnx("read works"); 86 abort(); 87 } 88 89 fprintf(stderr, "passed\n"); 90 exit(0); 91 } 92