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