#include #include #include #include #include #include #include #include #include #include #include #include #define READ_BLOCK_TIME 5 /* unit: sec */ static void sig_alarm(int sig __unused) { #define PANIC_STRING "read blocks\n" write(2, PANIC_STRING, strlen(PANIC_STRING)); abort(); } static void usage(const char *cmd) { fprintf(stderr, "%s -p port\n", cmd); exit(1); } int main(int argc, char *argv[]) { struct sockaddr_in in; struct itimerval it; int s, n, error, port, opt; char buf; port = 0; while ((opt = getopt(argc, argv, "p:")) != -1) { char *endptr; switch (opt) { case 'p': port = strtol(optarg, &endptr, 0); if (*endptr != '\0') errx(1, "invalid -p argument"); break; default: usage(argv[0]); } } if (port <= 0) usage(argv[0]); s = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0); if (s < 0) err(1, "socket failed"); memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; in.sin_port = htons(port); if (bind(s, (const struct sockaddr *)&in, sizeof(in)) < 0) err(1, "bind %d failed", port); memset(&it, 0, sizeof(it)); it.it_value.tv_sec = READ_BLOCK_TIME; if (signal(SIGALRM, sig_alarm) == SIG_ERR) err(1, "signal failed"); if (setitimer(ITIMER_REAL, &it, NULL) < 0) err(1, "setitimer failed"); n = read(s, &buf, 1); if (n < 0) { error = errno; if (error != EAGAIN) { warnx("invalid errno %d", error); abort(); } } else { warnx("read works"); abort(); } fprintf(stderr, "passed\n"); exit(0); }