socket: Shortcircuit FIONBIO in soo_ioctl().
[dragonfly.git] / test / sockext / socket / nonblock / socket_nblock.c
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                                 fprintf(stderr, "invalid -p argument\n");
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                         fprintf(stderr, "invalid errno %d\n", error);
82                         abort();
83                 }
84         } else {
85                 fprintf(stderr, "read works\n");
86                 abort();
87         }
88
89         fprintf(stderr, "passed\n");
90         exit(0);
91 }