largefile: fix typo that regressed large file support
[gnulib.git] / lib / 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 #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 (struct pollfd *pfd, nfds_t nfd, int timeout)
319 {
320 #ifndef WIN32_NATIVE
321   fd_set rfds, wfds, efds;
322   struct timeval tv;
323   struct timeval *ptv;
324   int maxfd, rc;
325   nfds_t i;
326
327 # ifdef _SC_OPEN_MAX
328   static int sc_open_max = -1;
329
330   if (nfd < 0
331       || (nfd > sc_open_max
332           && (sc_open_max != -1
333               || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
334     {
335       errno = EINVAL;
336       return -1;
337     }
338 # else /* !_SC_OPEN_MAX */
339 #  ifdef OPEN_MAX
340   if (nfd < 0 || nfd > OPEN_MAX)
341     {
342       errno = EINVAL;
343       return -1;
344     }
345 #  endif /* OPEN_MAX -- else, no check is needed */
346 # endif /* !_SC_OPEN_MAX */
347
348   /* EFAULT is not necessary to implement, but let's do it in the
349      simplest case. */
350   if (!pfd)
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
388       if (pfd[i].events & (POLLIN | POLLRDNORM))
389         FD_SET (pfd[i].fd, &rfds);
390
391       /* see select(2): "the only exceptional condition detectable
392          is out-of-band data received on a socket", hence we push
393          POLLWRBAND events onto wfds instead of efds. */
394       if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
395         FD_SET (pfd[i].fd, &wfds);
396       if (pfd[i].events & (POLLPRI | POLLRDBAND))
397         FD_SET (pfd[i].fd, &efds);
398       if (pfd[i].fd >= maxfd
399           && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
400                                | POLLRDNORM | POLLRDBAND
401                                | POLLWRNORM | POLLWRBAND)))
402         {
403           maxfd = pfd[i].fd;
404           if (maxfd > FD_SETSIZE)
405             {
406               errno = EOVERFLOW;
407               return -1;
408             }
409         }
410     }
411
412   /* examine fd sets */
413   rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
414   if (rc < 0)
415     return rc;
416
417   /* establish results */
418   rc = 0;
419   for (i = 0; i < nfd; i++)
420     if (pfd[i].fd < 0)
421       pfd[i].revents = 0;
422     else
423       {
424         int happened = compute_revents (pfd[i].fd, pfd[i].events,
425                                         &rfds, &wfds, &efds);
426         if (happened)
427           {
428             pfd[i].revents = happened;
429             rc++;
430           }
431       }
432
433   return rc;
434 #else
435   static struct timeval tv0;
436   static HANDLE hEvent;
437   WSANETWORKEVENTS ev;
438   HANDLE h, handle_array[FD_SETSIZE + 2];
439   DWORD ret, wait_timeout, nhandles;
440   fd_set rfds, wfds, xfds;
441   BOOL poll_again;
442   MSG msg;
443   int rc = 0;
444   nfds_t i;
445
446   if (nfd < 0 || timeout < -1)
447     {
448       errno = EINVAL;
449       return -1;
450     }
451
452   if (!hEvent)
453     hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
454
455 restart:
456   handle_array[0] = hEvent;
457   nhandles = 1;
458   FD_ZERO (&rfds);
459   FD_ZERO (&wfds);
460   FD_ZERO (&xfds);
461
462   /* Classify socket handles and create fd sets. */
463   for (i = 0; i < nfd; i++)
464     {
465       int sought = pfd[i].events;
466       pfd[i].revents = 0;
467       if (pfd[i].fd < 0)
468         continue;
469       if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
470                       | POLLPRI | POLLRDBAND)))
471         continue;
472
473       h = (HANDLE) _get_osfhandle (pfd[i].fd);
474       assert (h != NULL);
475       if (IsSocketHandle (h))
476         {
477           int requested = FD_CLOSE;
478
479           /* see above; socket handles are mapped onto select.  */
480           if (sought & (POLLIN | POLLRDNORM))
481             {
482               requested |= FD_READ | FD_ACCEPT;
483               FD_SET ((SOCKET) h, &rfds);
484             }
485           if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
486             {
487               requested |= FD_WRITE | FD_CONNECT;
488               FD_SET ((SOCKET) h, &wfds);
489             }
490           if (sought & (POLLPRI | POLLRDBAND))
491             {
492               requested |= FD_OOB;
493               FD_SET ((SOCKET) h, &xfds);
494             }
495
496           if (requested)
497             WSAEventSelect ((SOCKET) h, hEvent, requested);
498         }
499       else
500         {
501           /* Poll now.  If we get an event, do not poll again.  Also,
502              screen buffer handles are waitable, and they'll block until
503              a character is available.  win32_compute_revents eliminates
504              bits for the "wrong" direction. */
505           pfd[i].revents = win32_compute_revents (h, &sought);
506           if (sought)
507             handle_array[nhandles++] = h;
508           if (pfd[i].revents)
509             timeout = 0;
510         }
511     }
512
513   if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
514     {
515       /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
516          no need to call select again.  */
517       poll_again = FALSE;
518       wait_timeout = 0;
519     }
520   else
521     {
522       poll_again = TRUE;
523       if (timeout == INFTIM)
524         wait_timeout = INFINITE;
525       else
526         wait_timeout = timeout;
527     }
528
529   for (;;)
530     {
531       ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
532                                        wait_timeout, QS_ALLINPUT);
533
534       if (ret == WAIT_OBJECT_0 + nhandles)
535         {
536           /* new input of some other kind */
537           BOOL bRet;
538           while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
539             {
540               TranslateMessage (&msg);
541               DispatchMessage (&msg);
542             }
543         }
544       else
545         break;
546     }
547
548   if (poll_again)
549     select (0, &rfds, &wfds, &xfds, &tv0);
550
551   /* Place a sentinel at the end of the array.  */
552   handle_array[nhandles] = NULL;
553   nhandles = 1;
554   for (i = 0; i < nfd; i++)
555     {
556       int happened;
557
558       if (pfd[i].fd < 0)
559         continue;
560       if (!(pfd[i].events & (POLLIN | POLLRDNORM |
561                              POLLOUT | POLLWRNORM | POLLWRBAND)))
562         continue;
563
564       h = (HANDLE) _get_osfhandle (pfd[i].fd);
565       if (h != handle_array[nhandles])
566         {
567           /* It's a socket.  */
568           WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
569           WSAEventSelect ((SOCKET) h, 0, 0);
570
571           /* If we're lucky, WSAEnumNetworkEvents already provided a way
572              to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */
573           if (FD_ISSET ((SOCKET) h, &rfds)
574               && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
575             ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
576           if (FD_ISSET ((SOCKET) h, &wfds))
577             ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
578           if (FD_ISSET ((SOCKET) h, &xfds))
579             ev.lNetworkEvents |= FD_OOB;
580
581           happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events,
582                                                    ev.lNetworkEvents);
583         }
584       else
585         {
586           /* Not a socket.  */
587           int sought = pfd[i].events;
588           happened = win32_compute_revents (h, &sought);
589           nhandles++;
590         }
591
592        if ((pfd[i].revents |= happened) != 0)
593         rc++;
594     }
595
596   if (!rc && timeout == INFTIM)
597     {
598       SwitchToThread();
599       goto restart;
600     }
601
602   return rc;
603 #endif
604 }