poll, select: handle ERROR_BROKEN_PIPE.
[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       else if (GetLastError () == ERROR_BROKEN_PIPE)
154         happened |= POLLHUP;
155
156       else
157         {
158           /* It was the write-end of the pipe.  Check if it is writable.
159              If NtQueryInformationFile fails, optimistically assume the pipe is
160              writable.  This could happen on Win9x, where NtQueryInformationFile
161              is not available, or if we inherit a pipe that doesn't permit
162              FILE_READ_ATTRIBUTES access on the write end (I think this should
163              not happen since WinXP SP2; WINE seems fine too).  Otherwise,
164              ensure that enough space is available for atomic writes.  */
165           memset (&iosb, 0, sizeof (iosb));
166           memset (&fpli, 0, sizeof (fpli));
167
168           if (!NtQueryInformationFile
169               || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
170                                          FilePipeLocalInformation)
171               || fpli.WriteQuotaAvailable >= PIPE_BUF
172               || (fpli.OutboundQuota < PIPE_BUF &&
173                   fpli.WriteQuotaAvailable == fpli.OutboundQuota))
174             happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
175         }
176       return happened;
177
178     case FILE_TYPE_CHAR:
179       ret = WaitForSingleObject (h, 0);
180       if (!IsConsoleHandle (h))
181         return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
182
183       nbuffer = avail = 0;
184       bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
185       if (bRet)
186         {
187           /* Input buffer.  */
188           *p_sought &= POLLIN | POLLRDNORM;
189           if (nbuffer == 0)
190             return POLLHUP;
191           if (!*p_sought)
192             return 0;
193
194           irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
195           bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
196           if (!bRet || avail == 0)
197             return POLLHUP;
198
199           for (i = 0; i < avail; i++)
200             if (irbuffer[i].EventType == KEY_EVENT)
201               return *p_sought;
202           return 0;
203         }
204       else
205         {
206           /* Screen buffer.  */
207           *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
208           return *p_sought;
209         }
210
211     default:
212       ret = WaitForSingleObject (h, 0);
213       if (ret == WAIT_OBJECT_0)
214         return *p_sought & ~(POLLPRI | POLLRDBAND);
215
216       return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
217     }
218 }
219
220 /* Convert fd_sets returned by select into revents values.  */
221
222 static int
223 win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
224 {
225   int happened = 0;
226
227   if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
228     happened |= (POLLIN | POLLRDNORM) & sought;
229
230   else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
231     {
232       int r, error;
233
234       char data[64];
235       WSASetLastError (0);
236       r = recv (h, data, sizeof (data), MSG_PEEK);
237       error = WSAGetLastError ();
238       WSASetLastError (0);
239
240       if (r > 0 || error == WSAENOTCONN)
241         happened |= (POLLIN | POLLRDNORM) & sought;
242
243       /* Distinguish hung-up sockets from other errors.  */
244       else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
245                || error == WSAECONNABORTED || error == WSAENETRESET)
246         happened |= POLLHUP;
247
248       else
249         happened |= POLLERR;
250     }
251
252   if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
253     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
254
255   if (lNetworkEvents & FD_OOB)
256     happened |= (POLLPRI | POLLRDBAND) & sought;
257
258   return happened;
259 }
260
261 #else /* !MinGW */
262
263 /* Convert select(2) returned fd_sets into poll(2) revents values.  */
264 static int
265 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
266 {
267   int happened = 0;
268   if (FD_ISSET (fd, rfds))
269     {
270       int r;
271       int socket_errno;
272
273 # if defined __MACH__ && defined __APPLE__
274       /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
275          for some kinds of descriptors.  Detect if this descriptor is a
276          connected socket, a server socket, or something else using a
277          0-byte recv, and use ioctl(2) to detect POLLHUP.  */
278       r = recv (fd, NULL, 0, MSG_PEEK);
279       socket_errno = (r < 0) ? errno : 0;
280       if (r == 0 || socket_errno == ENOTSOCK)
281         ioctl (fd, FIONREAD, &r);
282 # else
283       char data[64];
284       r = recv (fd, data, sizeof (data), MSG_PEEK);
285       socket_errno = (r < 0) ? errno : 0;
286 # endif
287       if (r == 0)
288         happened |= POLLHUP;
289
290       /* If the event happened on an unconnected server socket,
291          that's fine. */
292       else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
293         happened |= (POLLIN | POLLRDNORM) & sought;
294
295       /* Distinguish hung-up sockets from other errors.  */
296       else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
297                || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
298         happened |= POLLHUP;
299
300       else
301         happened |= POLLERR;
302     }
303
304   if (FD_ISSET (fd, wfds))
305     happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
306
307   if (FD_ISSET (fd, efds))
308     happened |= (POLLPRI | POLLRDBAND) & sought;
309
310   return happened;
311 }
312 #endif /* !MinGW */
313
314 int
315 poll (pfd, nfd, timeout)
316      struct pollfd *pfd;
317      nfds_t nfd;
318      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   handle_array[0] = hEvent;
456   nhandles = 1;
457   FD_ZERO (&rfds);
458   FD_ZERO (&wfds);
459   FD_ZERO (&xfds);
460
461   /* Classify socket handles and create fd sets. */
462   for (i = 0; i < nfd; i++)
463     {
464       int sought = pfd[i].events;
465       pfd[i].revents = 0;
466       if (pfd[i].fd < 0)
467         continue;
468       if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
469                       | POLLPRI | POLLRDBAND)))
470         continue;
471
472       h = (HANDLE) _get_osfhandle (pfd[i].fd);
473       assert (h != NULL);
474       if (IsSocketHandle (h))
475         {
476           int requested = FD_CLOSE;
477
478           /* see above; socket handles are mapped onto select.  */
479           if (sought & (POLLIN | POLLRDNORM))
480             {
481               requested |= FD_READ | FD_ACCEPT;
482               FD_SET ((SOCKET) h, &rfds);
483             }
484           if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
485             {
486               requested |= FD_WRITE | FD_CONNECT;
487               FD_SET ((SOCKET) h, &wfds);
488             }
489           if (sought & (POLLPRI | POLLRDBAND))
490             {
491               requested |= FD_OOB;
492               FD_SET ((SOCKET) h, &xfds);
493             }
494
495           if (requested)
496             WSAEventSelect ((SOCKET) h, hEvent, requested);
497         }
498       else
499         {
500           /* Poll now.  If we get an event, do not poll again.  Also,
501              screen buffer handles are waitable, and they'll block until
502              a character is available.  win32_compute_revents eliminates
503              bits for the "wrong" direction. */
504           pfd[i].revents = win32_compute_revents (h, &sought);
505           if (sought)
506             handle_array[nhandles++] = h;
507           if (pfd[i].revents)
508             wait_timeout = 0;
509         }
510     }
511
512   if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
513     {
514       /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
515          no need to call select again.  */
516       poll_again = FALSE;
517       wait_timeout = 0;
518     }
519   else
520     {
521       poll_again = TRUE;
522       if (timeout == INFTIM)
523         wait_timeout = INFINITE;
524       else
525         wait_timeout = timeout;
526     }
527
528   for (;;)
529     {
530       ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
531                                        wait_timeout, QS_ALLINPUT);
532
533       if (ret == WAIT_OBJECT_0 + nhandles)
534         {
535           /* new input of some other kind */
536           BOOL bRet;
537           while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
538             {
539               TranslateMessage (&msg);
540               DispatchMessage (&msg);
541             }
542         }
543       else
544         break;
545     }
546
547   if (poll_again)
548     select (0, &rfds, &wfds, &xfds, &tv0);
549
550   /* Place a sentinel at the end of the array.  */
551   handle_array[nhandles] = NULL;
552   nhandles = 1;
553   for (i = 0; i < nfd; i++)
554     {
555       int happened;
556
557       if (pfd[i].fd < 0)
558         continue;
559       if (!(pfd[i].events & (POLLIN | POLLRDNORM |
560                              POLLOUT | POLLWRNORM | POLLWRBAND)))
561         continue;
562
563       h = (HANDLE) _get_osfhandle (pfd[i].fd);
564       if (h != handle_array[nhandles])
565         {
566           /* It's a socket.  */
567           WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
568           WSAEventSelect ((SOCKET) h, 0, 0);
569
570           /* If we're lucky, WSAEnumNetworkEvents already provided a way
571              to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */
572           if (FD_ISSET ((SOCKET) h, &rfds)
573               && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
574             ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
575           if (FD_ISSET ((SOCKET) h, &wfds))
576             ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
577           if (FD_ISSET ((SOCKET) h, &xfds))
578             ev.lNetworkEvents |= FD_OOB;
579
580           happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events,
581                                                    ev.lNetworkEvents);
582         }
583       else
584         {
585           /* Not a socket.  */
586           int sought = pfd[i].events;
587           happened = win32_compute_revents (h, &sought);
588           nhandles++;
589         }
590
591        if ((pfd[i].revents |= happened) != 0)
592         rc++;
593     }
594
595   return rc;
596 #endif
597 }