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