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