Merge branch 'rs/archive-tree-in-tip-simplify'
[git] / compat / win32 / 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 <malloc.h>
28
29 #include <sys/types.h>
30
31 /* Specification.  */
32 #include <poll.h>
33
34 #include <errno.h>
35 #include <limits.h>
36 #include <assert.h>
37
38 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
39 # define WIN32_NATIVE
40 # if defined (_MSC_VER)
41 #  define _WIN32_WINNT 0x0502
42 # endif
43 # include <winsock2.h>
44 # include <windows.h>
45 # include <io.h>
46 # include <stdio.h>
47 # include <conio.h>
48 #else
49 # include <sys/time.h>
50 # include <sys/socket.h>
51 # include <sys/select.h>
52 # include <unistd.h>
53 #endif
54
55 #ifdef HAVE_SYS_IOCTL_H
56 # include <sys/ioctl.h>
57 #endif
58 #ifdef HAVE_SYS_FILIO_H
59 # include <sys/filio.h>
60 #endif
61
62 #include <time.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 WIN32_NATIVE
74
75 #define IsConsoleHandle(h) (((long) (h) & 3) == 3)
76
77 static BOOL
78 IsSocketHandle (HANDLE h)
79 {
80   WSANETWORKEVENTS ev;
81
82   if (IsConsoleHandle (h))
83     return FALSE;
84
85   /* Under Wine, it seems that getsockopt returns 0 for pipes too.
86      WSAEnumNetworkEvents instead distinguishes the two correctly.  */
87   ev.lNetworkEvents = 0xDEADBEEF;
88   WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
89   return ev.lNetworkEvents != 0xDEADBEEF;
90 }
91
92 /* Declare data structures for ntdll functions.  */
93 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
94   ULONG NamedPipeType;
95   ULONG NamedPipeConfiguration;
96   ULONG MaximumInstances;
97   ULONG CurrentInstances;
98   ULONG InboundQuota;
99   ULONG ReadDataAvailable;
100   ULONG OutboundQuota;
101   ULONG WriteQuotaAvailable;
102   ULONG NamedPipeState;
103   ULONG NamedPipeEnd;
104 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
105
106 typedef struct _IO_STATUS_BLOCK
107 {
108   union {
109     DWORD Status;
110     PVOID Pointer;
111   } u;
112   ULONG_PTR Information;
113 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
114
115 typedef enum _FILE_INFORMATION_CLASS {
116   FilePipeLocalInformation = 24
117 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
118
119 typedef DWORD (WINAPI *PNtQueryInformationFile)
120          (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
121
122 # ifndef PIPE_BUF
123 #  define PIPE_BUF      512
124 # endif
125
126 /* Compute revents values for file handle H.  If some events cannot happen
127    for the handle, eliminate them from *P_SOUGHT.  */
128
129 static int
130 win32_compute_revents (HANDLE h, int *p_sought)
131 {
132   int i, ret, happened;
133   INPUT_RECORD *irbuffer;
134   DWORD avail, nbuffer;
135   BOOL bRet;
136   IO_STATUS_BLOCK iosb;
137   FILE_PIPE_LOCAL_INFORMATION fpli;
138   static PNtQueryInformationFile NtQueryInformationFile;
139   static BOOL once_only;
140
141   switch (GetFileType (h))
142     {
143     case FILE_TYPE_PIPE:
144       if (!once_only)
145         {
146           NtQueryInformationFile = (PNtQueryInformationFile)
147             GetProcAddress (GetModuleHandle ("ntdll.dll"),
148                             "NtQueryInformationFile");
149           once_only = TRUE;
150         }
151
152       happened = 0;
153       if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
154         {
155           if (avail)
156             happened |= *p_sought & (POLLIN | POLLRDNORM);
157         }
158       else if (GetLastError () == ERROR_BROKEN_PIPE)
159         happened |= POLLHUP;
160
161       else
162         {
163           /* It was the write-end of the pipe.  Check if it is writable.
164              If NtQueryInformationFile fails, optimistically assume the pipe is
165              writable.  This could happen on Win9x, where NtQueryInformationFile
166              is not available, or if we inherit a pipe that doesn't permit
167              FILE_READ_ATTRIBUTES access on the write end (I think this should
168              not happen since WinXP SP2; WINE seems fine too).  Otherwise,
169              ensure that enough space is available for atomic writes.  */
170           memset (&iosb, 0, sizeof (iosb));
171           memset (&fpli, 0, sizeof (fpli));
172
173           if (!NtQueryInformationFile
174               || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
175                                          FilePipeLocalInformation)
176               || fpli.WriteQuotaAvailable >= PIPE_BUF
177               || (fpli.OutboundQuota < PIPE_BUF &&
178                   fpli.WriteQuotaAvailable == fpli.OutboundQuota))
179             happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
180         }
181       return happened;
182
183     case FILE_TYPE_CHAR:
184       ret = WaitForSingleObject (h, 0);
185       if (!IsConsoleHandle (h))
186         return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
187
188       nbuffer = avail = 0;
189       bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
190       if (bRet)
191         {
192           /* Input buffer.  */
193           *p_sought &= POLLIN | POLLRDNORM;
194           if (nbuffer == 0)
195             return POLLHUP;
196           if (!*p_sought)
197             return 0;
198
199           irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
200           bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
201           if (!bRet || avail == 0)
202             return POLLHUP;
203
204           for (i = 0; i < avail; i++)
205             if (irbuffer[i].EventType == KEY_EVENT)
206               return *p_sought;
207           return 0;
208         }
209       else
210         {
211           /* Screen buffer.  */
212           *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
213           return *p_sought;
214         }
215
216     default:
217       ret = WaitForSingleObject (h, 0);
218       if (ret == WAIT_OBJECT_0)
219         return *p_sought & ~(POLLPRI | POLLRDBAND);
220
221       return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
222     }
223 }
224
225 /* Convert fd_sets returned by select into revents values.  */
226
227 static int
228 win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
229 {
230   int happened = 0;
231
232   if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
233     happened |= (POLLIN | POLLRDNORM) & sought;
234
235   else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
236     {
237       int r, error;
238
239       char data[64];
240       WSASetLastError (0);
241       r = recv (h, data, sizeof (data), MSG_PEEK);
242       error = WSAGetLastError ();
243       WSASetLastError (0);
244
245       if (r > 0 || error == WSAENOTCONN)
246         happened |= (POLLIN | POLLRDNORM) & sought;
247
248       /* Distinguish hung-up sockets from other errors.  */
249       else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
250                || error == WSAECONNABORTED || error == WSAENETRESET)
251         happened |= POLLHUP;
252
253       else
254         happened |= POLLERR;
255     }
256
257   if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
258     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
259
260   if (lNetworkEvents & FD_OOB)
261     happened |= (POLLPRI | POLLRDBAND) & sought;
262
263   return happened;
264 }
265
266 #else /* !MinGW */
267
268 /* Convert select(2) returned fd_sets into poll(2) revents values.  */
269 static int
270 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
271 {
272   int happened = 0;
273   if (FD_ISSET (fd, rfds))
274     {
275       int r;
276       int socket_errno;
277
278 # if defined __MACH__ && defined __APPLE__
279       /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
280          for some kinds of descriptors.  Detect if this descriptor is a
281          connected socket, a server socket, or something else using a
282          0-byte recv, and use ioctl(2) to detect POLLHUP.  */
283       r = recv (fd, NULL, 0, MSG_PEEK);
284       socket_errno = (r < 0) ? errno : 0;
285       if (r == 0 || socket_errno == ENOTSOCK)
286         ioctl (fd, FIONREAD, &r);
287 # else
288       char data[64];
289       r = recv (fd, data, sizeof (data), MSG_PEEK);
290       socket_errno = (r < 0) ? errno : 0;
291 # endif
292       if (r == 0)
293         happened |= POLLHUP;
294
295       /* If the event happened on an unconnected server socket,
296          that's fine. */
297       else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
298         happened |= (POLLIN | POLLRDNORM) & sought;
299
300       /* Distinguish hung-up sockets from other errors.  */
301       else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
302                || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
303         happened |= POLLHUP;
304
305       else
306         happened |= POLLERR;
307     }
308
309   if (FD_ISSET (fd, wfds))
310     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
311
312   if (FD_ISSET (fd, efds))
313     happened |= (POLLPRI | POLLRDBAND) & sought;
314
315   return happened;
316 }
317 #endif /* !MinGW */
318
319 int
320 poll (struct pollfd *pfd, nfds_t nfd, 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 restart:
458   handle_array[0] = hEvent;
459   nhandles = 1;
460   FD_ZERO (&rfds);
461   FD_ZERO (&wfds);
462   FD_ZERO (&xfds);
463
464   /* Classify socket handles and create fd sets. */
465   for (i = 0; i < nfd; i++)
466     {
467       int sought = pfd[i].events;
468       pfd[i].revents = 0;
469       if (pfd[i].fd < 0)
470         continue;
471       if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
472                       | POLLPRI | POLLRDBAND)))
473         continue;
474
475       h = (HANDLE) _get_osfhandle (pfd[i].fd);
476       assert (h != NULL);
477       if (IsSocketHandle (h))
478         {
479           int requested = FD_CLOSE;
480
481           /* see above; socket handles are mapped onto select.  */
482           if (sought & (POLLIN | POLLRDNORM))
483             {
484               requested |= FD_READ | FD_ACCEPT;
485               FD_SET ((SOCKET) h, &rfds);
486             }
487           if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
488             {
489               requested |= FD_WRITE | FD_CONNECT;
490               FD_SET ((SOCKET) h, &wfds);
491             }
492           if (sought & (POLLPRI | POLLRDBAND))
493             {
494               requested |= FD_OOB;
495               FD_SET ((SOCKET) h, &xfds);
496             }
497
498           if (requested)
499             WSAEventSelect ((SOCKET) h, hEvent, requested);
500         }
501       else
502         {
503           /* Poll now.  If we get an event, do not poll again.  Also,
504              screen buffer handles are waitable, and they'll block until
505              a character is available.  win32_compute_revents eliminates
506              bits for the "wrong" direction. */
507           pfd[i].revents = win32_compute_revents (h, &sought);
508           if (sought)
509             handle_array[nhandles++] = h;
510           if (pfd[i].revents)
511             timeout = 0;
512         }
513     }
514
515   if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
516     {
517       /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
518          no need to call select again.  */
519       poll_again = FALSE;
520       wait_timeout = 0;
521     }
522   else
523     {
524       poll_again = TRUE;
525       if (timeout == INFTIM)
526         wait_timeout = INFINITE;
527       else
528         wait_timeout = timeout;
529     }
530
531   for (;;)
532     {
533       ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
534                                        wait_timeout, QS_ALLINPUT);
535
536       if (ret == WAIT_OBJECT_0 + nhandles)
537         {
538           /* new input of some other kind */
539           BOOL bRet;
540           while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
541             {
542               TranslateMessage (&msg);
543               DispatchMessage (&msg);
544             }
545         }
546       else
547         break;
548     }
549
550   if (poll_again)
551     select (0, &rfds, &wfds, &xfds, &tv0);
552
553   /* Place a sentinel at the end of the array.  */
554   handle_array[nhandles] = NULL;
555   nhandles = 1;
556   for (i = 0; i < nfd; i++)
557     {
558       int happened;
559
560       if (pfd[i].fd < 0)
561         continue;
562       if (!(pfd[i].events & (POLLIN | POLLRDNORM |
563                              POLLOUT | POLLWRNORM | POLLWRBAND)))
564         continue;
565
566       h = (HANDLE) _get_osfhandle (pfd[i].fd);
567       if (h != handle_array[nhandles])
568         {
569           /* It's a socket.  */
570           WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
571           WSAEventSelect ((SOCKET) h, 0, 0);
572
573           /* If we're lucky, WSAEnumNetworkEvents already provided a way
574              to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */
575           if (FD_ISSET ((SOCKET) h, &rfds)
576               && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
577             ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
578           if (FD_ISSET ((SOCKET) h, &wfds))
579             ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
580           if (FD_ISSET ((SOCKET) h, &xfds))
581             ev.lNetworkEvents |= FD_OOB;
582
583           happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events,
584                                                    ev.lNetworkEvents);
585         }
586       else
587         {
588           /* Not a socket.  */
589           int sought = pfd[i].events;
590           happened = win32_compute_revents (h, &sought);
591           nhandles++;
592         }
593
594        if ((pfd[i].revents |= happened) != 0)
595         rc++;
596     }
597
598   if (!rc && timeout == INFTIM)
599     {
600       SwitchToThread();
601       goto restart;
602     }
603
604   return rc;
605 #endif
606 }