Bump to 1.14.1
[platform/upstream/augeas.git] / lib / poll.c
1 /* Emulation for poll(2)
2    Contributed by Paolo Bonzini.
3
4    Copyright 2001-2003, 2006-2016 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
37 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
38 # define WINDOWS_NATIVE
39 # include <winsock2.h>
40 # include <windows.h>
41 # include <io.h>
42 # include <stdio.h>
43 # include <conio.h>
44 # include "msvc-nothrow.h"
45 #else
46 # include <sys/time.h>
47 # include <unistd.h>
48 #endif
49
50 #include <sys/select.h>
51 #include <sys/socket.h>
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 #include "assure.h"
63
64 #ifndef INFTIM
65 # define INFTIM (-1)
66 #endif
67
68 /* BeOS does not have MSG_PEEK.  */
69 #ifndef MSG_PEEK
70 # define MSG_PEEK 0
71 #endif
72
73 #ifdef WINDOWS_NATIVE
74
75 static BOOL IsConsoleHandle (HANDLE h)
76 {
77   DWORD mode;
78   return GetConsoleMode (h, &mode) != 0;
79 }
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 windows_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 Windows 9x, where
170              NtQueryInformationFile is not available, or if we inherit a pipe
171              that doesn't permit FILE_READ_ATTRIBUTES access on the write end
172              (I think this should not happen since Windows XP SP2; WINE seems
173              fine too).  Otherwise, ensure that enough space is available for
174              atomic writes.  */
175           memset (&iosb, 0, sizeof (iosb));
176           memset (&fpli, 0, sizeof (fpli));
177
178           if (!NtQueryInformationFile
179               || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
180                                          FilePipeLocalInformation)
181               || fpli.WriteQuotaAvailable >= PIPE_BUF
182               || (fpli.OutboundQuota < PIPE_BUF &&
183                   fpli.WriteQuotaAvailable == fpli.OutboundQuota))
184             happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
185         }
186       return happened;
187
188     case FILE_TYPE_CHAR:
189       ret = WaitForSingleObject (h, 0);
190       if (!IsConsoleHandle (h))
191         return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
192
193       nbuffer = avail = 0;
194       bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
195       if (bRet)
196         {
197           /* Input buffer.  */
198           *p_sought &= POLLIN | POLLRDNORM;
199           if (nbuffer == 0)
200             return POLLHUP;
201           if (!*p_sought)
202             return 0;
203
204           irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
205           bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
206           if (!bRet || avail == 0)
207             return POLLHUP;
208
209           for (i = 0; i < avail; i++)
210             if (irbuffer[i].EventType == KEY_EVENT)
211               return *p_sought;
212           return 0;
213         }
214       else
215         {
216           /* Screen buffer.  */
217           *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
218           return *p_sought;
219         }
220
221     default:
222       ret = WaitForSingleObject (h, 0);
223       if (ret == WAIT_OBJECT_0)
224         return *p_sought & ~(POLLPRI | POLLRDBAND);
225
226       return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
227     }
228 }
229
230 /* Convert fd_sets returned by select into revents values.  */
231
232 static int
233 windows_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
234 {
235   int happened = 0;
236
237   if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
238     happened |= (POLLIN | POLLRDNORM) & sought;
239
240   else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
241     {
242       int r, error;
243
244       char data[64];
245       WSASetLastError (0);
246       r = recv (h, data, sizeof (data), MSG_PEEK);
247       error = WSAGetLastError ();
248       WSASetLastError (0);
249
250       if (r > 0 || error == WSAENOTCONN)
251         happened |= (POLLIN | POLLRDNORM) & sought;
252
253       /* Distinguish hung-up sockets from other errors.  */
254       else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
255                || error == WSAECONNABORTED || error == WSAENETRESET)
256         happened |= POLLHUP;
257
258       else
259         happened |= POLLERR;
260     }
261
262   if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
263     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
264
265   if (lNetworkEvents & FD_OOB)
266     happened |= (POLLPRI | POLLRDBAND) & sought;
267
268   return happened;
269 }
270
271 #else /* !MinGW */
272
273 /* Convert select(2) returned fd_sets into poll(2) revents values.  */
274 static int
275 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
276 {
277   int happened = 0;
278   if (FD_ISSET (fd, rfds))
279     {
280       int r;
281       int socket_errno;
282
283 # if defined __MACH__ && defined __APPLE__
284       /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
285          for some kinds of descriptors.  Detect if this descriptor is a
286          connected socket, a server socket, or something else using a
287          0-byte recv, and use ioctl(2) to detect POLLHUP.  */
288       r = recv (fd, NULL, 0, MSG_PEEK);
289       socket_errno = (r < 0) ? errno : 0;
290       if (r == 0 || socket_errno == ENOTSOCK)
291         ioctl (fd, FIONREAD, &r);
292 # else
293       char data[64];
294       r = recv (fd, data, sizeof (data), MSG_PEEK);
295       socket_errno = (r < 0) ? errno : 0;
296 # endif
297       if (r == 0)
298         happened |= POLLHUP;
299
300       /* If the event happened on an unconnected server socket,
301          that's fine. */
302       else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
303         happened |= (POLLIN | POLLRDNORM) & sought;
304
305       /* Distinguish hung-up sockets from other errors.  */
306       else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
307                || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
308         happened |= POLLHUP;
309
310       /* some systems can't use recv() on non-socket, including HP NonStop */
311       else if (socket_errno == ENOTSOCK)
312         happened |= (POLLIN | POLLRDNORM) & sought;
313
314       else
315         happened |= POLLERR;
316     }
317
318   if (FD_ISSET (fd, wfds))
319     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
320
321   if (FD_ISSET (fd, efds))
322     happened |= (POLLPRI | POLLRDBAND) & sought;
323
324   return happened;
325 }
326 #endif /* !MinGW */
327
328 int
329 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
330 {
331 #ifndef WINDOWS_NATIVE
332   fd_set rfds, wfds, efds;
333   struct timeval tv;
334   struct timeval *ptv;
335   int maxfd, rc;
336   nfds_t i;
337
338   if (nfd < 0)
339     {
340       errno = EINVAL;
341       return -1;
342     }
343   /* Don't check directly for NFD too large.  Any practical use of a
344      too-large NFD is caught by one of the other checks below, and
345      checking directly for getdtablesize is too much of a portability
346      and/or performance and/or correctness hassle.  */
347
348   /* EFAULT is not necessary to implement, but let's do it in the
349      simplest case. */
350   if (!pfd && nfd)
351     {
352       errno = EFAULT;
353       return -1;
354     }
355
356   /* convert timeout number into a timeval structure */
357   if (timeout == 0)
358     {
359       ptv = &tv;
360       ptv->tv_sec = 0;
361       ptv->tv_usec = 0;
362     }
363   else if (timeout > 0)
364     {
365       ptv = &tv;
366       ptv->tv_sec = timeout / 1000;
367       ptv->tv_usec = (timeout % 1000) * 1000;
368     }
369   else if (timeout == INFTIM)
370     /* wait forever */
371     ptv = NULL;
372   else
373     {
374       errno = EINVAL;
375       return -1;
376     }
377
378   /* create fd sets and determine max fd */
379   maxfd = -1;
380   FD_ZERO (&rfds);
381   FD_ZERO (&wfds);
382   FD_ZERO (&efds);
383   for (i = 0; i < nfd; i++)
384     {
385       if (pfd[i].fd < 0)
386         continue;
387       if (maxfd < pfd[i].fd)
388         {
389           maxfd = pfd[i].fd;
390           if (FD_SETSIZE <= maxfd)
391             {
392               errno = EINVAL;
393               return -1;
394             }
395         }
396       if (pfd[i].events & (POLLIN | POLLRDNORM))
397         FD_SET (pfd[i].fd, &rfds);
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     }
406
407   /* examine fd sets */
408   rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
409   if (rc < 0)
410     return rc;
411
412   /* establish results */
413   rc = 0;
414   for (i = 0; i < nfd; i++)
415     {
416       pfd[i].revents = (pfd[i].fd < 0
417                         ? 0
418                         : compute_revents (pfd[i].fd, pfd[i].events,
419                                            &rfds, &wfds, &efds));
420       rc += pfd[i].revents != 0;
421     }
422
423   return rc;
424 #else
425   static struct timeval tv0;
426   static HANDLE hEvent;
427   WSANETWORKEVENTS ev;
428   HANDLE h, handle_array[FD_SETSIZE + 2];
429   DWORD ret, wait_timeout, nhandles;
430   fd_set rfds, wfds, xfds;
431   BOOL poll_again;
432   MSG msg;
433   int rc = 0;
434   nfds_t i;
435
436   if (nfd < 0 || timeout < -1)
437     {
438       errno = EINVAL;
439       return -1;
440     }
441
442   if (!hEvent)
443     hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
444
445 restart:
446   handle_array[0] = hEvent;
447   nhandles = 1;
448   FD_ZERO (&rfds);
449   FD_ZERO (&wfds);
450   FD_ZERO (&xfds);
451
452   /* Classify socket handles and create fd sets. */
453   for (i = 0; i < nfd; i++)
454     {
455       int sought = pfd[i].events;
456       pfd[i].revents = 0;
457       if (pfd[i].fd < 0)
458         continue;
459       if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
460                       | POLLPRI | POLLRDBAND)))
461         continue;
462
463       h = (HANDLE) _get_osfhandle (pfd[i].fd);
464       assure (h != NULL);
465       if (IsSocketHandle (h))
466         {
467           int requested = FD_CLOSE;
468
469           /* see above; socket handles are mapped onto select.  */
470           if (sought & (POLLIN | POLLRDNORM))
471             {
472               requested |= FD_READ | FD_ACCEPT;
473               FD_SET ((SOCKET) h, &rfds);
474             }
475           if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
476             {
477               requested |= FD_WRITE | FD_CONNECT;
478               FD_SET ((SOCKET) h, &wfds);
479             }
480           if (sought & (POLLPRI | POLLRDBAND))
481             {
482               requested |= FD_OOB;
483               FD_SET ((SOCKET) h, &xfds);
484             }
485
486           if (requested)
487             WSAEventSelect ((SOCKET) h, hEvent, requested);
488         }
489       else
490         {
491           /* Poll now.  If we get an event, do not poll again.  Also,
492              screen buffer handles are waitable, and they'll block until
493              a character is available.  windows_compute_revents eliminates
494              bits for the "wrong" direction. */
495           pfd[i].revents = windows_compute_revents (h, &sought);
496           if (sought)
497             handle_array[nhandles++] = h;
498           if (pfd[i].revents)
499             timeout = 0;
500         }
501     }
502
503   if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
504     {
505       /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
506          no need to call select again.  */
507       poll_again = FALSE;
508       wait_timeout = 0;
509     }
510   else
511     {
512       poll_again = TRUE;
513       if (timeout == INFTIM)
514         wait_timeout = INFINITE;
515       else
516         wait_timeout = timeout;
517     }
518
519   for (;;)
520     {
521       ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
522                                        wait_timeout, QS_ALLINPUT);
523
524       if (ret == WAIT_OBJECT_0 + nhandles)
525         {
526           /* new input of some other kind */
527           BOOL bRet;
528           while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
529             {
530               TranslateMessage (&msg);
531               DispatchMessage (&msg);
532             }
533         }
534       else
535         break;
536     }
537
538   if (poll_again)
539     select (0, &rfds, &wfds, &xfds, &tv0);
540
541   /* Place a sentinel at the end of the array.  */
542   handle_array[nhandles] = NULL;
543   nhandles = 1;
544   for (i = 0; i < nfd; i++)
545     {
546       int happened;
547
548       if (pfd[i].fd < 0)
549         continue;
550       if (!(pfd[i].events & (POLLIN | POLLRDNORM |
551                              POLLOUT | POLLWRNORM | POLLWRBAND)))
552         continue;
553
554       h = (HANDLE) _get_osfhandle (pfd[i].fd);
555       if (h != handle_array[nhandles])
556         {
557           /* It's a socket.  */
558           WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
559           WSAEventSelect ((SOCKET) h, 0, 0);
560
561           /* If we're lucky, WSAEnumNetworkEvents already provided a way
562              to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */
563           if (FD_ISSET ((SOCKET) h, &rfds)
564               && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
565             ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
566           if (FD_ISSET ((SOCKET) h, &wfds))
567             ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
568           if (FD_ISSET ((SOCKET) h, &xfds))
569             ev.lNetworkEvents |= FD_OOB;
570
571           happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
572                                                      ev.lNetworkEvents);
573         }
574       else
575         {
576           /* Not a socket.  */
577           int sought = pfd[i].events;
578           happened = windows_compute_revents (h, &sought);
579           nhandles++;
580         }
581
582        if ((pfd[i].revents |= happened) != 0)
583         rc++;
584     }
585
586   if (!rc && timeout == INFTIM)
587     {
588       SleepEx (1, TRUE);
589       goto restart;
590     }
591
592   return rc;
593 #endif
594 }