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