maint: update all copyright year number ranges
[gnulib.git] / tests / test-poll.c
1 /* Test of poll() function.
2    Copyright (C) 2008-2012 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* Written by Paolo Bonzini.  */
19
20 #include <config.h>
21
22 /* Specification.  */
23 #include <poll.h>
24
25 #include "signature.h"
26 SIGNATURE_CHECK (poll, int, (struct pollfd[], nfds_t, int));
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <fcntl.h>
34 #include <stdlib.h>
35 #include <stdbool.h>
36 #include <sys/ioctl.h>
37 #include <errno.h>
38
39 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
40 # define WIN32_NATIVE
41 #endif
42
43 #ifdef WIN32_NATIVE
44 #include <io.h>
45 #define pipe(x) _pipe(x, 256, O_BINARY)
46 #endif
47 #ifdef HAVE_UNISTD_H
48 #include <unistd.h>
49 #endif
50 #ifdef HAVE_SYS_WAIT_H
51 #include <sys/wait.h>
52 #endif
53
54 #ifndef SO_REUSEPORT
55 #define SO_REUSEPORT    SO_REUSEADDR
56 #endif
57
58 #define TEST_PORT       12345
59
60
61 /* Minimal testing infrastructure.  */
62
63 static int failures;
64
65 static void
66 failed (const char *reason)
67 {
68   if (++failures > 1)
69     printf ("  ");
70   printf ("failed (%s)\n", reason);
71 }
72
73 static int
74 test (void (*fn) (void), const char *msg)
75 {
76   failures = 0;
77   printf ("%s... ", msg);
78   fflush (stdout);
79   fn ();
80
81   if (!failures)
82     printf ("passed\n");
83
84   return failures;
85 }
86
87
88 /* Funny socket code.  */
89
90 static int
91 open_server_socket ()
92 {
93   int s, x;
94   struct sockaddr_in ia;
95
96   s = socket (AF_INET, SOCK_STREAM, 0);
97
98   memset (&ia, 0, sizeof (ia));
99   ia.sin_family = AF_INET;
100   inet_pton (AF_INET, "127.0.0.1", &ia.sin_addr);
101   ia.sin_port = htons (TEST_PORT);
102   if (bind (s, (struct sockaddr *) &ia, sizeof (ia)) < 0)
103     {
104       perror ("bind");
105       exit (77);
106     }
107
108   x = 1;
109   setsockopt (s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof (x));
110
111   if (listen (s, 1) < 0)
112     {
113       perror ("listen");
114       exit (77);
115     }
116
117   return s;
118 }
119
120 static int
121 connect_to_socket (int blocking)
122 {
123   int s;
124   struct sockaddr_in ia;
125
126   s = socket (AF_INET, SOCK_STREAM, 0);
127
128   memset (&ia, 0, sizeof (ia));
129   ia.sin_family = AF_INET;
130   inet_pton (AF_INET, "127.0.0.1", &ia.sin_addr);
131   ia.sin_port = htons (TEST_PORT);
132
133   if (!blocking)
134     {
135 #ifdef WIN32_NATIVE
136       unsigned long iMode = 1;
137       ioctl (s, FIONBIO, (char *) &iMode);
138
139 #elif defined F_GETFL
140       int oldflags = fcntl (s, F_GETFL, NULL);
141
142       if (!(oldflags & O_NONBLOCK))
143         fcntl (s, F_SETFL, oldflags | O_NONBLOCK);
144 #endif
145     }
146
147   if (connect (s, (struct sockaddr *) &ia, sizeof (ia)) < 0
148       && (blocking || errno != EINPROGRESS))
149     {
150       perror ("connect");
151       exit (77);
152     }
153
154   return s;
155 }
156
157
158 /* A slightly more convenient interface to poll(2).  */
159
160 static int
161 poll1 (int fd, int ev, int time)
162 {
163   struct pollfd pfd;
164   int r;
165
166   pfd.fd = fd;
167   pfd.events = ev;
168   pfd.revents = 0;
169   r = poll (&pfd, 1, time);
170   if (r < 0)
171     return r;
172
173   if (pfd.revents & ~(POLLHUP | POLLERR | POLLNVAL | ev))
174     failed ("invalid flag combination (unrequested events)");
175
176   return pfd.revents;
177 }
178
179 static int
180 poll1_nowait (int fd, int ev)
181 {
182   return poll1 (fd, ev, 0);
183 }
184
185 static int
186 poll1_wait (int fd, int ev)
187 {
188   return poll1 (fd, ev, -1);
189 }
190
191
192 /* Test poll(2) for TTYs.  */
193
194 #ifdef INTERACTIVE
195 static void
196 test_tty (void)
197 {
198   if (poll1_nowait (0, POLLIN | POLLRDNORM) != 0)
199     failed ("can read");
200   if (poll1_nowait (0, POLLOUT) == 0)
201     failed ("cannot write");
202
203   if (poll1_wait (0, POLLIN | POLLRDNORM) == 0)
204     failed ("return with infinite timeout");
205
206   getchar ();
207   if (poll1_nowait (0, POLLIN | POLLRDNORM) != 0)
208     failed ("can read after getc");
209 }
210 #endif
211
212
213 /* Test poll(2) for unconnected nonblocking sockets.  */
214
215 static void
216 test_connect_first (void)
217 {
218   int s = open_server_socket ();
219   struct sockaddr_in ia;
220   socklen_t addrlen;
221
222   int c1, c2;
223
224   if (poll1_nowait (s, POLLIN | POLLRDNORM | POLLRDBAND) != 0)
225     failed ("can read, socket not connected");
226
227   c1 = connect_to_socket (false);
228
229   if (poll1_wait (s, POLLIN | POLLRDNORM | POLLRDBAND) != (POLLIN | POLLRDNORM))
230     failed ("expecting POLLIN | POLLRDNORM on passive socket");
231   if (poll1_nowait (s, POLLIN | POLLRDBAND) != POLLIN)
232     failed ("expecting POLLIN on passive socket");
233   if (poll1_nowait (s, POLLRDNORM | POLLRDBAND) != POLLRDNORM)
234     failed ("expecting POLLRDNORM on passive socket");
235
236   addrlen = sizeof (ia);
237   c2 = accept (s, (struct sockaddr *) &ia, &addrlen);
238   close (s);
239   close (c1);
240   close (c2);
241 }
242
243
244 /* Test poll(2) for unconnected blocking sockets.  */
245
246 static void
247 test_accept_first (void)
248 {
249 #ifndef WIN32_NATIVE
250   int s = open_server_socket ();
251   struct sockaddr_in ia;
252   socklen_t addrlen;
253   char buf[3];
254   int c, pid;
255
256   pid = fork ();
257   if (pid < 0)
258     return;
259
260   if (pid == 0)
261     {
262       addrlen = sizeof (ia);
263       c = accept (s, (struct sockaddr *) &ia, &addrlen);
264       close (s);
265       write (c, "foo", 3);
266       read (c, buf, 3);
267       shutdown (c, SHUT_RD);
268       close (c);
269       exit (0);
270     }
271   else
272     {
273       close (s);
274       c = connect_to_socket (true);
275       if (poll1_nowait (c, POLLOUT | POLLWRNORM | POLLRDBAND)
276           != (POLLOUT | POLLWRNORM))
277         failed ("cannot write after blocking connect");
278       write (c, "foo", 3);
279       wait (&pid);
280       if (poll1_wait (c, POLLIN) != POLLIN)
281         failed ("cannot read data left in the socket by closed process");
282       read (c, buf, 3);
283       write (c, "foo", 3);
284       if ((poll1_wait (c, POLLIN | POLLOUT) & (POLLHUP | POLLERR)) == 0)
285         failed ("expecting POLLHUP after shutdown");
286       close (c);
287     }
288 #endif
289 }
290
291
292 /* Common code for pipes and connected sockets.  */
293
294 static void
295 test_pair (int rd, int wd)
296 {
297   char buf[3];
298   if (poll1_wait (wd, POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND)
299       != (POLLOUT | POLLWRNORM))
300     failed ("expecting POLLOUT | POLLWRNORM before writing");
301   if (poll1_nowait (wd, POLLIN | POLLRDNORM | POLLOUT | POLLRDBAND) != POLLOUT)
302     failed ("expecting POLLOUT before writing");
303   if (poll1_nowait (wd, POLLIN | POLLRDNORM | POLLWRNORM | POLLRDBAND)
304       != POLLWRNORM)
305     failed ("expecting POLLWRNORM before writing");
306
307   write (wd, "foo", 3);
308   if (poll1_wait (rd, POLLIN | POLLRDNORM) != (POLLIN | POLLRDNORM))
309     failed ("expecting POLLIN | POLLRDNORM after writing");
310   if (poll1_nowait (rd, POLLIN) != POLLIN)
311     failed ("expecting POLLIN after writing");
312   if (poll1_nowait (rd, POLLRDNORM) != POLLRDNORM)
313     failed ("expecting POLLRDNORM after writing");
314
315   read (rd, buf, 3);
316 }
317
318
319 /* Test poll(2) on connected sockets.  */
320
321 static void
322 test_socket_pair (void)
323 {
324   struct sockaddr_in ia;
325
326   socklen_t addrlen = sizeof (ia);
327   int s = open_server_socket ();
328   int c1 = connect_to_socket (false);
329   int c2 = accept (s, (struct sockaddr *) &ia, &addrlen);
330
331   close (s);
332
333   test_pair (c1, c2);
334   close (c1);
335   write (c2, "foo", 3);
336   if ((poll1_nowait (c2, POLLIN | POLLOUT) & (POLLHUP | POLLERR)) == 0)
337     failed ("expecting POLLHUP after shutdown");
338
339   close (c2);
340 }
341
342
343 /* Test poll(2) on pipes.  */
344
345 static void
346 test_pipe (void)
347 {
348   int fd[2];
349
350   pipe (fd);
351   test_pair (fd[0], fd[1]);
352   close (fd[0]);
353   if ((poll1_wait (fd[1], POLLIN | POLLOUT) & (POLLHUP | POLLERR)) == 0)
354     failed ("expecting POLLHUP after shutdown");
355
356   close (fd[1]);
357 }
358
359
360 /* Do them all.  */
361
362 int
363 main ()
364 {
365   int result;
366
367 #ifdef INTERACTIVE
368   printf ("Please press Enter\n");
369   test (test_tty, "TTY");
370 #endif
371
372   result = test (test_connect_first, "Unconnected socket test");
373   result += test (test_socket_pair, "Connected sockets test");
374   result += test (test_accept_first, "General socket test with fork");
375   result += test (test_pipe, "Pipe test");
376
377   exit (result);
378 }