update NEWS.stable
[gnulib.git] / lib / poll.c
1 /* Emulation for poll(2)
2    Contributed by Paolo Bonzini.
3
4    Copyright 2001-2003, 2006-2012 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       else
307         happened |= POLLERR;
308     }
309
310   if (FD_ISSET (fd, wfds))
311     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
312
313   if (FD_ISSET (fd, efds))
314     happened |= (POLLPRI | POLLRDBAND) & sought;
315
316   return happened;
317 }
318 #endif /* !MinGW */
319
320 int
321 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
322 {
323 #ifndef WINDOWS_NATIVE
324   fd_set rfds, wfds, efds;
325   struct timeval tv;
326   struct timeval *ptv;
327   int maxfd, rc;
328   nfds_t i;
329
330 # ifdef _SC_OPEN_MAX
331   static int sc_open_max = -1;
332
333   if (nfd < 0
334       || (nfd > sc_open_max
335           && (sc_open_max != -1
336               || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
337     {
338       errno = EINVAL;
339       return -1;
340     }
341 # else /* !_SC_OPEN_MAX */
342 #  ifdef OPEN_MAX
343   if (nfd < 0 || nfd > OPEN_MAX)
344     {
345       errno = EINVAL;
346       return -1;
347     }
348 #  endif /* OPEN_MAX -- else, no check is needed */
349 # endif /* !_SC_OPEN_MAX */
350
351   /* EFAULT is not necessary to implement, but let's do it in the
352      simplest case. */
353   if (!pfd)
354     {
355       errno = EFAULT;
356       return -1;
357     }
358
359   /* convert timeout number into a timeval structure */
360   if (timeout == 0)
361     {
362       ptv = &tv;
363       ptv->tv_sec = 0;
364       ptv->tv_usec = 0;
365     }
366   else if (timeout > 0)
367     {
368       ptv = &tv;
369       ptv->tv_sec = timeout / 1000;
370       ptv->tv_usec = (timeout % 1000) * 1000;
371     }
372   else if (timeout == INFTIM)
373     /* wait forever */
374     ptv = NULL;
375   else
376     {
377       errno = EINVAL;
378       return -1;
379     }
380
381   /* create fd sets and determine max fd */
382   maxfd = -1;
383   FD_ZERO (&rfds);
384   FD_ZERO (&wfds);
385   FD_ZERO (&efds);
386   for (i = 0; i < nfd; i++)
387     {
388       if (pfd[i].fd < 0)
389         continue;
390
391       if (pfd[i].events & (POLLIN | POLLRDNORM))
392         FD_SET (pfd[i].fd, &rfds);
393
394       /* see select(2): "the only exceptional condition detectable
395          is out-of-band data received on a socket", hence we push
396          POLLWRBAND events onto wfds instead of efds. */
397       if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
398         FD_SET (pfd[i].fd, &wfds);
399       if (pfd[i].events & (POLLPRI | POLLRDBAND))
400         FD_SET (pfd[i].fd, &efds);
401       if (pfd[i].fd >= maxfd
402           && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
403                                | POLLRDNORM | POLLRDBAND
404                                | POLLWRNORM | POLLWRBAND)))
405         {
406           maxfd = pfd[i].fd;
407           if (maxfd > FD_SETSIZE)
408             {
409               errno = EOVERFLOW;
410               return -1;
411             }
412         }
413     }
414
415   /* examine fd sets */
416   rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
417   if (rc < 0)
418     return rc;
419
420   /* establish results */
421   rc = 0;
422   for (i = 0; i < nfd; i++)
423     if (pfd[i].fd < 0)
424       pfd[i].revents = 0;
425     else
426       {
427         int happened = compute_revents (pfd[i].fd, pfd[i].events,
428                                         &rfds, &wfds, &efds);
429         if (happened)
430           {
431             pfd[i].revents = happened;
432             rc++;
433           }
434       }
435
436   return rc;
437 #else
438   static struct timeval tv0;
439   static HANDLE hEvent;
440   WSANETWORKEVENTS ev;
441   HANDLE h, handle_array[FD_SETSIZE + 2];
442   DWORD ret, wait_timeout, nhandles;
443   fd_set rfds, wfds, xfds;
444   BOOL poll_again;
445   MSG msg;
446   int rc = 0;
447   nfds_t i;
448
449   if (nfd < 0 || timeout < -1)
450     {
451       errno = EINVAL;
452       return -1;
453     }
454
455   if (!hEvent)
456     hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
457
458 restart:
459   handle_array[0] = hEvent;
460   nhandles = 1;
461   FD_ZERO (&rfds);
462   FD_ZERO (&wfds);
463   FD_ZERO (&xfds);
464
465   /* Classify socket handles and create fd sets. */
466   for (i = 0; i < nfd; i++)
467     {
468       int sought = pfd[i].events;
469       pfd[i].revents = 0;
470       if (pfd[i].fd < 0)
471         continue;
472       if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
473                       | POLLPRI | POLLRDBAND)))
474         continue;
475
476       h = (HANDLE) _get_osfhandle (pfd[i].fd);
477       assert (h != NULL);
478       if (IsSocketHandle (h))
479         {
480           int requested = FD_CLOSE;
481
482           /* see above; socket handles are mapped onto select.  */
483           if (sought & (POLLIN | POLLRDNORM))
484             {
485               requested |= FD_READ | FD_ACCEPT;
486               FD_SET ((SOCKET) h, &rfds);
487             }
488           if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
489             {
490               requested |= FD_WRITE | FD_CONNECT;
491               FD_SET ((SOCKET) h, &wfds);
492             }
493           if (sought & (POLLPRI | POLLRDBAND))
494             {
495               requested |= FD_OOB;
496               FD_SET ((SOCKET) h, &xfds);
497             }
498
499           if (requested)
500             WSAEventSelect ((SOCKET) h, hEvent, requested);
501         }
502       else
503         {
504           /* Poll now.  If we get an event, do not poll again.  Also,
505              screen buffer handles are waitable, and they'll block until
506              a character is available.  windows_compute_revents eliminates
507              bits for the "wrong" direction. */
508           pfd[i].revents = windows_compute_revents (h, &sought);
509           if (sought)
510             handle_array[nhandles++] = h;
511           if (pfd[i].revents)
512             timeout = 0;
513         }
514     }
515
516   if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
517     {
518       /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
519          no need to call select again.  */
520       poll_again = FALSE;
521       wait_timeout = 0;
522     }
523   else
524     {
525       poll_again = TRUE;
526       if (timeout == INFTIM)
527         wait_timeout = INFINITE;
528       else
529         wait_timeout = timeout;
530     }
531
532   for (;;)
533     {
534       ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
535                                        wait_timeout, QS_ALLINPUT);
536
537       if (ret == WAIT_OBJECT_0 + nhandles)
538         {
539           /* new input of some other kind */
540           BOOL bRet;
541           while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
542             {
543               TranslateMessage (&msg);
544               DispatchMessage (&msg);
545             }
546         }
547       else
548         break;
549     }
550
551   if (poll_again)
552     select (0, &rfds, &wfds, &xfds, &tv0);
553
554   /* Place a sentinel at the end of the array.  */
555   handle_array[nhandles] = NULL;
556   nhandles = 1;
557   for (i = 0; i < nfd; i++)
558     {
559       int happened;
560
561       if (pfd[i].fd < 0)
562         continue;
563       if (!(pfd[i].events & (POLLIN | POLLRDNORM |
564                              POLLOUT | POLLWRNORM | POLLWRBAND)))
565         continue;
566
567       h = (HANDLE) _get_osfhandle (pfd[i].fd);
568       if (h != handle_array[nhandles])
569         {
570           /* It's a socket.  */
571           WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
572           WSAEventSelect ((SOCKET) h, 0, 0);
573
574           /* If we're lucky, WSAEnumNetworkEvents already provided a way
575              to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */
576           if (FD_ISSET ((SOCKET) h, &rfds)
577               && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
578             ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
579           if (FD_ISSET ((SOCKET) h, &wfds))
580             ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
581           if (FD_ISSET ((SOCKET) h, &xfds))
582             ev.lNetworkEvents |= FD_OOB;
583
584           happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
585                                                      ev.lNetworkEvents);
586         }
587       else
588         {
589           /* Not a socket.  */
590           int sought = pfd[i].events;
591           happened = windows_compute_revents (h, &sought);
592           nhandles++;
593         }
594
595        if ((pfd[i].revents |= happened) != 0)
596         rc++;
597     }
598
599   if (!rc && timeout == INFTIM)
600     {
601       SwitchToThread();
602       goto restart;
603     }
604
605   return rc;
606 #endif
607 }