verify: new macro 'assume'
[gnulib.git] / lib / poll.c
1 /* Emulation for poll(2)
2    Contributed by Paolo Bonzini.
3
4    Copyright 2001-2003, 2006-2013 Free Software Foundation, Inc.
5
6    This file is part of gnulib.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License along
19    with this program; if not, see <http://www.gnu.org/licenses/>.  */
20
21 /* Tell gcc not to warn about the (nfd < 0) tests, below.  */
22 #if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
23 # pragma GCC diagnostic ignored "-Wtype-limits"
24 #endif
25
26 #include <config.h>
27 #include <alloca.h>
28
29 #include <sys/types.h>
30
31 /* Specification.  */
32 #include <poll.h>
33
34 #include <errno.h>
35 #include <limits.h>
36 #include <assert.h>
37
38 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
39 # define WINDOWS_NATIVE
40 # include <winsock2.h>
41 # include <windows.h>
42 # include <io.h>
43 # include <stdio.h>
44 # include <conio.h>
45 # include "msvc-nothrow.h"
46 #else
47 # include <sys/time.h>
48 # include <sys/socket.h>
49 # include <sys/select.h>
50 # include <unistd.h>
51 #endif
52
53 #ifdef HAVE_SYS_IOCTL_H
54 # include <sys/ioctl.h>
55 #endif
56 #ifdef HAVE_SYS_FILIO_H
57 # include <sys/filio.h>
58 #endif
59
60 #include <time.h>
61
62 #ifndef INFTIM
63 # define INFTIM (-1)
64 #endif
65
66 /* BeOS does not have MSG_PEEK.  */
67 #ifndef MSG_PEEK
68 # define MSG_PEEK 0
69 #endif
70
71 #ifdef WINDOWS_NATIVE
72
73 /* Optimized test whether a HANDLE refers to a console.
74    See <http://lists.gnu.org/archive/html/bug-gnulib/2009-08/msg00065.html>.  */
75 #define IsConsoleHandle(h) (((intptr_t) (h) & 3) == 3)
76
77 static BOOL
78 IsSocketHandle (HANDLE h)
79 {
80   WSANETWORKEVENTS ev;
81
82   if (IsConsoleHandle (h))
83     return FALSE;
84
85   /* Under Wine, it seems that getsockopt returns 0 for pipes too.
86      WSAEnumNetworkEvents instead distinguishes the two correctly.  */
87   ev.lNetworkEvents = 0xDEADBEEF;
88   WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
89   return ev.lNetworkEvents != 0xDEADBEEF;
90 }
91
92 /* Declare data structures for ntdll functions.  */
93 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
94   ULONG NamedPipeType;
95   ULONG NamedPipeConfiguration;
96   ULONG MaximumInstances;
97   ULONG CurrentInstances;
98   ULONG InboundQuota;
99   ULONG ReadDataAvailable;
100   ULONG OutboundQuota;
101   ULONG WriteQuotaAvailable;
102   ULONG NamedPipeState;
103   ULONG NamedPipeEnd;
104 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
105
106 typedef struct _IO_STATUS_BLOCK
107 {
108   union {
109     DWORD Status;
110     PVOID Pointer;
111   } u;
112   ULONG_PTR Information;
113 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
114
115 typedef enum _FILE_INFORMATION_CLASS {
116   FilePipeLocalInformation = 24
117 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
118
119 typedef DWORD (WINAPI *PNtQueryInformationFile)
120          (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
121
122 # ifndef PIPE_BUF
123 #  define PIPE_BUF      512
124 # endif
125
126 /* Compute revents values for file handle H.  If some events cannot happen
127    for the handle, eliminate them from *P_SOUGHT.  */
128
129 static int
130 windows_compute_revents (HANDLE h, int *p_sought)
131 {
132   int i, ret, happened;
133   INPUT_RECORD *irbuffer;
134   DWORD avail, nbuffer;
135   BOOL bRet;
136   IO_STATUS_BLOCK iosb;
137   FILE_PIPE_LOCAL_INFORMATION fpli;
138   static PNtQueryInformationFile NtQueryInformationFile;
139   static BOOL once_only;
140
141   switch (GetFileType (h))
142     {
143     case FILE_TYPE_PIPE:
144       if (!once_only)
145         {
146           NtQueryInformationFile = (PNtQueryInformationFile)
147             GetProcAddress (GetModuleHandle ("ntdll.dll"),
148                             "NtQueryInformationFile");
149           once_only = TRUE;
150         }
151
152       happened = 0;
153       if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
154         {
155           if (avail)
156             happened |= *p_sought & (POLLIN | POLLRDNORM);
157         }
158       else if (GetLastError () == ERROR_BROKEN_PIPE)
159         happened |= POLLHUP;
160
161       else
162         {
163           /* It was the write-end of the pipe.  Check if it is writable.
164              If NtQueryInformationFile fails, optimistically assume the pipe is
165              writable.  This could happen on Windows 9x, where
166              NtQueryInformationFile is not available, or if we inherit a pipe
167              that doesn't permit FILE_READ_ATTRIBUTES access on the write end
168              (I think this should not happen since Windows XP SP2; WINE seems
169              fine too).  Otherwise, ensure that enough space is available for
170              atomic writes.  */
171           memset (&iosb, 0, sizeof (iosb));
172           memset (&fpli, 0, sizeof (fpli));
173
174           if (!NtQueryInformationFile
175               || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
176                                          FilePipeLocalInformation)
177               || fpli.WriteQuotaAvailable >= PIPE_BUF
178               || (fpli.OutboundQuota < PIPE_BUF &&
179                   fpli.WriteQuotaAvailable == fpli.OutboundQuota))
180             happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
181         }
182       return happened;
183
184     case FILE_TYPE_CHAR:
185       ret = WaitForSingleObject (h, 0);
186       if (!IsConsoleHandle (h))
187         return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
188
189       nbuffer = avail = 0;
190       bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
191       if (bRet)
192         {
193           /* Input buffer.  */
194           *p_sought &= POLLIN | POLLRDNORM;
195           if (nbuffer == 0)
196             return POLLHUP;
197           if (!*p_sought)
198             return 0;
199
200           irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
201           bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
202           if (!bRet || avail == 0)
203             return POLLHUP;
204
205           for (i = 0; i < avail; i++)
206             if (irbuffer[i].EventType == KEY_EVENT)
207               return *p_sought;
208           return 0;
209         }
210       else
211         {
212           /* Screen buffer.  */
213           *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
214           return *p_sought;
215         }
216
217     default:
218       ret = WaitForSingleObject (h, 0);
219       if (ret == WAIT_OBJECT_0)
220         return *p_sought & ~(POLLPRI | POLLRDBAND);
221
222       return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
223     }
224 }
225
226 /* Convert fd_sets returned by select into revents values.  */
227
228 static int
229 windows_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
230 {
231   int happened = 0;
232
233   if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
234     happened |= (POLLIN | POLLRDNORM) & sought;
235
236   else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
237     {
238       int r, error;
239
240       char data[64];
241       WSASetLastError (0);
242       r = recv (h, data, sizeof (data), MSG_PEEK);
243       error = WSAGetLastError ();
244       WSASetLastError (0);
245
246       if (r > 0 || error == WSAENOTCONN)
247         happened |= (POLLIN | POLLRDNORM) & sought;
248
249       /* Distinguish hung-up sockets from other errors.  */
250       else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
251                || error == WSAECONNABORTED || error == WSAENETRESET)
252         happened |= POLLHUP;
253
254       else
255         happened |= POLLERR;
256     }
257
258   if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
259     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
260
261   if (lNetworkEvents & FD_OOB)
262     happened |= (POLLPRI | POLLRDBAND) & sought;
263
264   return happened;
265 }
266
267 #else /* !MinGW */
268
269 /* Convert select(2) returned fd_sets into poll(2) revents values.  */
270 static int
271 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
272 {
273   int happened = 0;
274   if (FD_ISSET (fd, rfds))
275     {
276       int r;
277       int socket_errno;
278
279 # if defined __MACH__ && defined __APPLE__
280       /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
281          for some kinds of descriptors.  Detect if this descriptor is a
282          connected socket, a server socket, or something else using a
283          0-byte recv, and use ioctl(2) to detect POLLHUP.  */
284       r = recv (fd, NULL, 0, MSG_PEEK);
285       socket_errno = (r < 0) ? errno : 0;
286       if (r == 0 || socket_errno == ENOTSOCK)
287         ioctl (fd, FIONREAD, &r);
288 # else
289       char data[64];
290       r = recv (fd, data, sizeof (data), MSG_PEEK);
291       socket_errno = (r < 0) ? errno : 0;
292 # endif
293       if (r == 0)
294         happened |= POLLHUP;
295
296       /* If the event happened on an unconnected server socket,
297          that's fine. */
298       else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
299         happened |= (POLLIN | POLLRDNORM) & sought;
300
301       /* Distinguish hung-up sockets from other errors.  */
302       else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
303                || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
304         happened |= POLLHUP;
305
306       /* some systems can't use recv() on non-socket, including HP NonStop */
307       else if (socket_errno == ENOTSOCK)
308         happened |= (POLLIN | POLLRDNORM) & sought;
309
310       else
311         happened |= POLLERR;
312     }
313
314   if (FD_ISSET (fd, wfds))
315     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
316
317   if (FD_ISSET (fd, efds))
318     happened |= (POLLPRI | POLLRDBAND) & sought;
319
320   return happened;
321 }
322 #endif /* !MinGW */
323
324 int
325 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
326 {
327 #ifndef WINDOWS_NATIVE
328   fd_set rfds, wfds, efds;
329   struct timeval tv;
330   struct timeval *ptv;
331   int maxfd, rc;
332   nfds_t i;
333
334 # ifdef _SC_OPEN_MAX
335   static int sc_open_max = -1;
336
337   if (nfd < 0
338       || (nfd > sc_open_max
339           && (sc_open_max != -1
340               || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
341     {
342       errno = EINVAL;
343       return -1;
344     }
345 # else /* !_SC_OPEN_MAX */
346 #  ifdef OPEN_MAX
347   if (nfd < 0 || nfd > OPEN_MAX)
348     {
349       errno = EINVAL;
350       return -1;
351     }
352 #  endif /* OPEN_MAX -- else, no check is needed */
353 # endif /* !_SC_OPEN_MAX */
354
355   /* EFAULT is not necessary to implement, but let's do it in the
356      simplest case. */
357   if (!pfd && nfd)
358     {
359       errno = EFAULT;
360       return -1;
361     }
362
363   /* convert timeout number into a timeval structure */
364   if (timeout == 0)
365     {
366       ptv = &tv;
367       ptv->tv_sec = 0;
368       ptv->tv_usec = 0;
369     }
370   else if (timeout > 0)
371     {
372       ptv = &tv;
373       ptv->tv_sec = timeout / 1000;
374       ptv->tv_usec = (timeout % 1000) * 1000;
375     }
376   else if (timeout == INFTIM)
377     /* wait forever */
378     ptv = NULL;
379   else
380     {
381       errno = EINVAL;
382       return -1;
383     }
384
385   /* create fd sets and determine max fd */
386   maxfd = -1;
387   FD_ZERO (&rfds);
388   FD_ZERO (&wfds);
389   FD_ZERO (&efds);
390   for (i = 0; i < nfd; i++)
391     {
392       if (pfd[i].fd < 0)
393         continue;
394
395       if (pfd[i].events & (POLLIN | POLLRDNORM))
396         FD_SET (pfd[i].fd, &rfds);
397
398       /* see select(2): "the only exceptional condition detectable
399          is out-of-band data received on a socket", hence we push
400          POLLWRBAND events onto wfds instead of efds. */
401       if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
402         FD_SET (pfd[i].fd, &wfds);
403       if (pfd[i].events & (POLLPRI | POLLRDBAND))
404         FD_SET (pfd[i].fd, &efds);
405       if (pfd[i].fd >= maxfd
406           && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
407                                | POLLRDNORM | POLLRDBAND
408                                | POLLWRNORM | POLLWRBAND)))
409         {
410           maxfd = pfd[i].fd;
411           if (maxfd > FD_SETSIZE)
412             {
413               errno = EOVERFLOW;
414               return -1;
415             }
416         }
417     }
418
419   /* examine fd sets */
420   rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
421   if (rc < 0)
422     return rc;
423
424   /* establish results */
425   rc = 0;
426   for (i = 0; i < nfd; i++)
427     if (pfd[i].fd < 0)
428       pfd[i].revents = 0;
429     else
430       {
431         int happened = compute_revents (pfd[i].fd, pfd[i].events,
432                                         &rfds, &wfds, &efds);
433         if (happened)
434           {
435             pfd[i].revents = happened;
436             rc++;
437           }
438       }
439
440   return rc;
441 #else
442   static struct timeval tv0;
443   static HANDLE hEvent;
444   WSANETWORKEVENTS ev;
445   HANDLE h, handle_array[FD_SETSIZE + 2];
446   DWORD ret, wait_timeout, nhandles;
447   fd_set rfds, wfds, xfds;
448   BOOL poll_again;
449   MSG msg;
450   int rc = 0;
451   nfds_t i;
452
453   if (nfd < 0 || timeout < -1)
454     {
455       errno = EINVAL;
456       return -1;
457     }
458
459   if (!hEvent)
460     hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
461
462 restart:
463   handle_array[0] = hEvent;
464   nhandles = 1;
465   FD_ZERO (&rfds);
466   FD_ZERO (&wfds);
467   FD_ZERO (&xfds);
468
469   /* Classify socket handles and create fd sets. */
470   for (i = 0; i < nfd; i++)
471     {
472       int sought = pfd[i].events;
473       pfd[i].revents = 0;
474       if (pfd[i].fd < 0)
475         continue;
476       if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
477                       | POLLPRI | POLLRDBAND)))
478         continue;
479
480       h = (HANDLE) _get_osfhandle (pfd[i].fd);
481       assert (h != NULL);
482       if (IsSocketHandle (h))
483         {
484           int requested = FD_CLOSE;
485
486           /* see above; socket handles are mapped onto select.  */
487           if (sought & (POLLIN | POLLRDNORM))
488             {
489               requested |= FD_READ | FD_ACCEPT;
490               FD_SET ((SOCKET) h, &rfds);
491             }
492           if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
493             {
494               requested |= FD_WRITE | FD_CONNECT;
495               FD_SET ((SOCKET) h, &wfds);
496             }
497           if (sought & (POLLPRI | POLLRDBAND))
498             {
499               requested |= FD_OOB;
500               FD_SET ((SOCKET) h, &xfds);
501             }
502
503           if (requested)
504             WSAEventSelect ((SOCKET) h, hEvent, requested);
505         }
506       else
507         {
508           /* Poll now.  If we get an event, do not poll again.  Also,
509              screen buffer handles are waitable, and they'll block until
510              a character is available.  windows_compute_revents eliminates
511              bits for the "wrong" direction. */
512           pfd[i].revents = windows_compute_revents (h, &sought);
513           if (sought)
514             handle_array[nhandles++] = h;
515           if (pfd[i].revents)
516             timeout = 0;
517         }
518     }
519
520   if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
521     {
522       /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
523          no need to call select again.  */
524       poll_again = FALSE;
525       wait_timeout = 0;
526     }
527   else
528     {
529       poll_again = TRUE;
530       if (timeout == INFTIM)
531         wait_timeout = INFINITE;
532       else
533         wait_timeout = timeout;
534     }
535
536   for (;;)
537     {
538       ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
539                                        wait_timeout, QS_ALLINPUT);
540
541       if (ret == WAIT_OBJECT_0 + nhandles)
542         {
543           /* new input of some other kind */
544           BOOL bRet;
545           while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
546             {
547               TranslateMessage (&msg);
548               DispatchMessage (&msg);
549             }
550         }
551       else
552         break;
553     }
554
555   if (poll_again)
556     select (0, &rfds, &wfds, &xfds, &tv0);
557
558   /* Place a sentinel at the end of the array.  */
559   handle_array[nhandles] = NULL;
560   nhandles = 1;
561   for (i = 0; i < nfd; i++)
562     {
563       int happened;
564
565       if (pfd[i].fd < 0)
566         continue;
567       if (!(pfd[i].events & (POLLIN | POLLRDNORM |
568                              POLLOUT | POLLWRNORM | POLLWRBAND)))
569         continue;
570
571       h = (HANDLE) _get_osfhandle (pfd[i].fd);
572       if (h != handle_array[nhandles])
573         {
574           /* It's a socket.  */
575           WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
576           WSAEventSelect ((SOCKET) h, 0, 0);
577
578           /* If we're lucky, WSAEnumNetworkEvents already provided a way
579              to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */
580           if (FD_ISSET ((SOCKET) h, &rfds)
581               && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
582             ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
583           if (FD_ISSET ((SOCKET) h, &wfds))
584             ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
585           if (FD_ISSET ((SOCKET) h, &xfds))
586             ev.lNetworkEvents |= FD_OOB;
587
588           happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
589                                                      ev.lNetworkEvents);
590         }
591       else
592         {
593           /* Not a socket.  */
594           int sought = pfd[i].events;
595           happened = windows_compute_revents (h, &sought);
596           nhandles++;
597         }
598
599        if ((pfd[i].revents |= happened) != 0)
600         rc++;
601     }
602
603   if (!rc && timeout == INFTIM)
604     {
605       SleepEx (1, TRUE);
606       goto restart;
607     }
608
609   return rc;
610 #endif
611 }