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