New module 'poll-h'.
[gnulib.git] / lib / poll.c
1 /* Emulation for poll(2)
2    Contributed by Paolo Bonzini.
3
4    Copyright 2001-2003, 2006-2010 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, write to the Free Software Foundation,
20    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
21
22 /* Tell gcc not to warn about the (nfd < 0) tests, below.  */
23 #if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
24 # pragma GCC diagnostic ignored "-Wtype-limits"
25 #endif
26
27 #include <config.h>
28 #include <alloca.h>
29
30 #include <sys/types.h>
31
32 /* Specification.  */
33 #include <poll.h>
34
35 #include <errno.h>
36 #include <limits.h>
37 #include <assert.h>
38
39 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
40 # define WIN32_NATIVE
41 # include <winsock2.h>
42 # include <windows.h>
43 # include <io.h>
44 # include <stdio.h>
45 # include <conio.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 WIN32_NATIVE
72
73 #define IsConsoleHandle(h) (((long) (h) & 3) == 3)
74
75 static BOOL
76 IsSocketHandle (HANDLE h)
77 {
78   WSANETWORKEVENTS ev;
79
80   if (IsConsoleHandle (h))
81     return FALSE;
82
83   /* Under Wine, it seems that getsockopt returns 0 for pipes too.
84      WSAEnumNetworkEvents instead distinguishes the two correctly.  */
85   ev.lNetworkEvents = 0xDEADBEEF;
86   WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
87   return ev.lNetworkEvents != 0xDEADBEEF;
88 }
89
90 /* Declare data structures for ntdll functions.  */
91 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
92   ULONG NamedPipeType;
93   ULONG NamedPipeConfiguration;
94   ULONG MaximumInstances;
95   ULONG CurrentInstances;
96   ULONG InboundQuota;
97   ULONG ReadDataAvailable;
98   ULONG OutboundQuota;
99   ULONG WriteQuotaAvailable;
100   ULONG NamedPipeState;
101   ULONG NamedPipeEnd;
102 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
103
104 typedef struct _IO_STATUS_BLOCK
105 {
106   union {
107     DWORD Status;
108     PVOID Pointer;
109   } u;
110   ULONG_PTR Information;
111 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
112
113 typedef enum _FILE_INFORMATION_CLASS {
114   FilePipeLocalInformation = 24
115 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
116
117 typedef DWORD (WINAPI *PNtQueryInformationFile)
118          (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
119
120 # ifndef PIPE_BUF
121 #  define PIPE_BUF      512
122 # endif
123
124 /* Compute revents values for file handle H.  If some events cannot happen
125    for the handle, eliminate them from *P_SOUGHT.  */
126
127 static int
128 win32_compute_revents (HANDLE h, int *p_sought)
129 {
130   int i, ret, happened;
131   INPUT_RECORD *irbuffer;
132   DWORD avail, nbuffer;
133   BOOL bRet;
134   IO_STATUS_BLOCK iosb;
135   FILE_PIPE_LOCAL_INFORMATION fpli;
136   static PNtQueryInformationFile NtQueryInformationFile;
137   static BOOL once_only;
138
139   switch (GetFileType (h))
140     {
141     case FILE_TYPE_PIPE:
142       if (!once_only)
143         {
144           NtQueryInformationFile = (PNtQueryInformationFile)
145             GetProcAddress (GetModuleHandle ("ntdll.dll"),
146                             "NtQueryInformationFile");
147           once_only = TRUE;
148         }
149
150       happened = 0;
151       if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
152         {
153           if (avail)
154             happened |= *p_sought & (POLLIN | POLLRDNORM);
155         }
156       else if (GetLastError () == ERROR_BROKEN_PIPE)
157         happened |= POLLHUP;
158
159       else
160         {
161           /* It was the write-end of the pipe.  Check if it is writable.
162              If NtQueryInformationFile fails, optimistically assume the pipe is
163              writable.  This could happen on Win9x, where NtQueryInformationFile
164              is not available, or if we inherit a pipe that doesn't permit
165              FILE_READ_ATTRIBUTES access on the write end (I think this should
166              not happen since WinXP SP2; WINE seems fine too).  Otherwise,
167              ensure that enough space is available for atomic writes.  */
168           memset (&iosb, 0, sizeof (iosb));
169           memset (&fpli, 0, sizeof (fpli));
170
171           if (!NtQueryInformationFile
172               || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
173                                          FilePipeLocalInformation)
174               || fpli.WriteQuotaAvailable >= PIPE_BUF
175               || (fpli.OutboundQuota < PIPE_BUF &&
176                   fpli.WriteQuotaAvailable == fpli.OutboundQuota))
177             happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
178         }
179       return happened;
180
181     case FILE_TYPE_CHAR:
182       ret = WaitForSingleObject (h, 0);
183       if (!IsConsoleHandle (h))
184         return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
185
186       nbuffer = avail = 0;
187       bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
188       if (bRet)
189         {
190           /* Input buffer.  */
191           *p_sought &= POLLIN | POLLRDNORM;
192           if (nbuffer == 0)
193             return POLLHUP;
194           if (!*p_sought)
195             return 0;
196
197           irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
198           bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
199           if (!bRet || avail == 0)
200             return POLLHUP;
201
202           for (i = 0; i < avail; i++)
203             if (irbuffer[i].EventType == KEY_EVENT)
204               return *p_sought;
205           return 0;
206         }
207       else
208         {
209           /* Screen buffer.  */
210           *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
211           return *p_sought;
212         }
213
214     default:
215       ret = WaitForSingleObject (h, 0);
216       if (ret == WAIT_OBJECT_0)
217         return *p_sought & ~(POLLPRI | POLLRDBAND);
218
219       return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
220     }
221 }
222
223 /* Convert fd_sets returned by select into revents values.  */
224
225 static int
226 win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
227 {
228   int happened = 0;
229
230   if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
231     happened |= (POLLIN | POLLRDNORM) & sought;
232
233   else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
234     {
235       int r, error;
236
237       char data[64];
238       WSASetLastError (0);
239       r = recv (h, data, sizeof (data), MSG_PEEK);
240       error = WSAGetLastError ();
241       WSASetLastError (0);
242
243       if (r > 0 || error == WSAENOTCONN)
244         happened |= (POLLIN | POLLRDNORM) & sought;
245
246       /* Distinguish hung-up sockets from other errors.  */
247       else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
248                || error == WSAECONNABORTED || error == WSAENETRESET)
249         happened |= POLLHUP;
250
251       else
252         happened |= POLLERR;
253     }
254
255   if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
256     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
257
258   if (lNetworkEvents & FD_OOB)
259     happened |= (POLLPRI | POLLRDBAND) & sought;
260
261   return happened;
262 }
263
264 #else /* !MinGW */
265
266 /* Convert select(2) returned fd_sets into poll(2) revents values.  */
267 static int
268 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
269 {
270   int happened = 0;
271   if (FD_ISSET (fd, rfds))
272     {
273       int r;
274       int socket_errno;
275
276 # if defined __MACH__ && defined __APPLE__
277       /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
278          for some kinds of descriptors.  Detect if this descriptor is a
279          connected socket, a server socket, or something else using a
280          0-byte recv, and use ioctl(2) to detect POLLHUP.  */
281       r = recv (fd, NULL, 0, MSG_PEEK);
282       socket_errno = (r < 0) ? errno : 0;
283       if (r == 0 || socket_errno == ENOTSOCK)
284         ioctl (fd, FIONREAD, &r);
285 # else
286       char data[64];
287       r = recv (fd, data, sizeof (data), MSG_PEEK);
288       socket_errno = (r < 0) ? errno : 0;
289 # endif
290       if (r == 0)
291         happened |= POLLHUP;
292
293       /* If the event happened on an unconnected server socket,
294          that's fine. */
295       else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
296         happened |= (POLLIN | POLLRDNORM) & sought;
297
298       /* Distinguish hung-up sockets from other errors.  */
299       else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
300                || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
301         happened |= POLLHUP;
302
303       else
304         happened |= POLLERR;
305     }
306
307   if (FD_ISSET (fd, wfds))
308     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
309
310   if (FD_ISSET (fd, efds))
311     happened |= (POLLPRI | POLLRDBAND) & sought;
312
313   return happened;
314 }
315 #endif /* !MinGW */
316
317 int
318 poll (pfd, nfd, timeout)
319      struct pollfd *pfd;
320      nfds_t nfd;
321      int timeout;
322 {
323 #ifndef WIN32_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   handle_array[0] = hEvent;
459   nhandles = 1;
460   FD_ZERO (&rfds);
461   FD_ZERO (&wfds);
462   FD_ZERO (&xfds);
463
464   /* Classify socket handles and create fd sets. */
465   for (i = 0; i < nfd; i++)
466     {
467       int sought = pfd[i].events;
468       pfd[i].revents = 0;
469       if (pfd[i].fd < 0)
470         continue;
471       if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
472                       | POLLPRI | POLLRDBAND)))
473         continue;
474
475       h = (HANDLE) _get_osfhandle (pfd[i].fd);
476       assert (h != NULL);
477       if (IsSocketHandle (h))
478         {
479           int requested = FD_CLOSE;
480
481           /* see above; socket handles are mapped onto select.  */
482           if (sought & (POLLIN | POLLRDNORM))
483             {
484               requested |= FD_READ | FD_ACCEPT;
485               FD_SET ((SOCKET) h, &rfds);
486             }
487           if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
488             {
489               requested |= FD_WRITE | FD_CONNECT;
490               FD_SET ((SOCKET) h, &wfds);
491             }
492           if (sought & (POLLPRI | POLLRDBAND))
493             {
494               requested |= FD_OOB;
495               FD_SET ((SOCKET) h, &xfds);
496             }
497
498           if (requested)
499             WSAEventSelect ((SOCKET) h, hEvent, requested);
500         }
501       else
502         {
503           /* Poll now.  If we get an event, do not poll again.  Also,
504              screen buffer handles are waitable, and they'll block until
505              a character is available.  win32_compute_revents eliminates
506              bits for the "wrong" direction. */
507           pfd[i].revents = win32_compute_revents (h, &sought);
508           if (sought)
509             handle_array[nhandles++] = h;
510           if (pfd[i].revents)
511             timeout = 0;
512         }
513     }
514
515   if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
516     {
517       /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
518          no need to call select again.  */
519       poll_again = FALSE;
520       wait_timeout = 0;
521     }
522   else
523     {
524       poll_again = TRUE;
525       if (timeout == INFTIM)
526         wait_timeout = INFINITE;
527       else
528         wait_timeout = timeout;
529     }
530
531   for (;;)
532     {
533       ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
534                                        wait_timeout, QS_ALLINPUT);
535
536       if (ret == WAIT_OBJECT_0 + nhandles)
537         {
538           /* new input of some other kind */
539           BOOL bRet;
540           while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
541             {
542               TranslateMessage (&msg);
543               DispatchMessage (&msg);
544             }
545         }
546       else
547         break;
548     }
549
550   if (poll_again)
551     select (0, &rfds, &wfds, &xfds, &tv0);
552
553   /* Place a sentinel at the end of the array.  */
554   handle_array[nhandles] = NULL;
555   nhandles = 1;
556   for (i = 0; i < nfd; i++)
557     {
558       int happened;
559
560       if (pfd[i].fd < 0)
561         continue;
562       if (!(pfd[i].events & (POLLIN | POLLRDNORM |
563                              POLLOUT | POLLWRNORM | POLLWRBAND)))
564         continue;
565
566       h = (HANDLE) _get_osfhandle (pfd[i].fd);
567       if (h != handle_array[nhandles])
568         {
569           /* It's a socket.  */
570           WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
571           WSAEventSelect ((SOCKET) h, 0, 0);
572
573           /* If we're lucky, WSAEnumNetworkEvents already provided a way
574              to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */
575           if (FD_ISSET ((SOCKET) h, &rfds)
576               && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
577             ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
578           if (FD_ISSET ((SOCKET) h, &wfds))
579             ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
580           if (FD_ISSET ((SOCKET) h, &xfds))
581             ev.lNetworkEvents |= FD_OOB;
582
583           happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events,
584                                                    ev.lNetworkEvents);
585         }
586       else
587         {
588           /* Not a socket.  */
589           int sought = pfd[i].events;
590           happened = win32_compute_revents (h, &sought);
591           nhandles++;
592         }
593
594        if ((pfd[i].revents |= happened) != 0)
595         rc++;
596     }
597
598   return rc;
599 #endif
600 }