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