malloc-h: New module.
[gnulib.git] / lib / poll.c
blob61dd639eeaa52c58510cd3e22a6c07704260746c
1 /* Emulation for poll(2)
2 Contributed by Paolo Bonzini.
4 Copyright 2001-2003, 2006-2020 Free Software Foundation, Inc.
6 This file is part of gnulib.
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.
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.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, see <https://www.gnu.org/licenses/>. */
21 /* Tell gcc not to warn about the (nfd < 0) tests, below. */
22 #if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
23 # pragma GCC diagnostic ignored "-Wtype-limits"
24 #endif
26 #include <config.h>
27 #include <alloca.h>
29 #include <sys/types.h>
31 /* Specification. */
32 #include <poll.h>
34 #include <errno.h>
35 #include <limits.h>
37 #if defined _WIN32 && ! defined __CYGWIN__
38 # define WINDOWS_NATIVE
39 # include <winsock2.h>
40 # include <windows.h>
41 # include <io.h>
42 # include <stdio.h>
43 # include <conio.h>
44 # if GNULIB_MSVC_NOTHROW
45 # include "msvc-nothrow.h"
46 # else
47 # include <io.h>
48 # endif
49 #else
50 # include <sys/time.h>
51 # include <unistd.h>
52 #endif
54 #include <sys/select.h>
55 #include <sys/socket.h>
57 #ifdef HAVE_SYS_IOCTL_H
58 # include <sys/ioctl.h>
59 #endif
60 #ifdef HAVE_SYS_FILIO_H
61 # include <sys/filio.h>
62 #endif
64 #include <time.h>
66 #include "assure.h"
68 #ifndef INFTIM
69 # define INFTIM (-1)
70 #endif
72 /* BeOS does not have MSG_PEEK. */
73 #ifndef MSG_PEEK
74 # define MSG_PEEK 0
75 #endif
77 #ifdef WINDOWS_NATIVE
79 /* Don't assume that UNICODE is not defined. */
80 # undef GetModuleHandle
81 # define GetModuleHandle GetModuleHandleA
82 # undef PeekConsoleInput
83 # define PeekConsoleInput PeekConsoleInputA
84 # undef CreateEvent
85 # define CreateEvent CreateEventA
86 # undef PeekMessage
87 # define PeekMessage PeekMessageA
88 # undef DispatchMessage
89 # define DispatchMessage DispatchMessageA
91 /* Do *not* use the function WSAPoll
92 <https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-wsapoll>
93 because there is a bug named “Windows 8 Bugs 309411 - WSAPoll does not
94 report failed connections” that Microsoft won't fix.
95 See Daniel Stenberg: "WASPoll is broken"
96 <https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/>. */
98 /* Here we need the recv() function from Windows, that takes a SOCKET as
99 first argument, not any possible gnulib override. */
100 # undef recv
102 /* Here we need the select() function from Windows, because we pass bit masks
103 of SOCKETs, not bit masks of FDs. */
104 # undef select
106 /* Here we need timeval from Windows since this is what the select() function
107 from Windows requires. */
108 # undef timeval
110 /* Avoid warnings from gcc -Wcast-function-type. */
111 # define GetProcAddress \
112 (void *) GetProcAddress
114 static BOOL IsConsoleHandle (HANDLE h)
116 DWORD mode;
117 return GetConsoleMode (h, &mode) != 0;
120 static BOOL
121 IsSocketHandle (HANDLE h)
123 WSANETWORKEVENTS ev;
125 if (IsConsoleHandle (h))
126 return FALSE;
128 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
129 WSAEnumNetworkEvents instead distinguishes the two correctly. */
130 ev.lNetworkEvents = 0xDEADBEEF;
131 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
132 return ev.lNetworkEvents != 0xDEADBEEF;
135 /* Declare data structures for ntdll functions. */
136 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
137 ULONG NamedPipeType;
138 ULONG NamedPipeConfiguration;
139 ULONG MaximumInstances;
140 ULONG CurrentInstances;
141 ULONG InboundQuota;
142 ULONG ReadDataAvailable;
143 ULONG OutboundQuota;
144 ULONG WriteQuotaAvailable;
145 ULONG NamedPipeState;
146 ULONG NamedPipeEnd;
147 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
149 typedef struct _IO_STATUS_BLOCK
151 union {
152 DWORD Status;
153 PVOID Pointer;
154 } u;
155 ULONG_PTR Information;
156 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
158 typedef enum _FILE_INFORMATION_CLASS {
159 FilePipeLocalInformation = 24
160 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
162 typedef DWORD (WINAPI *PNtQueryInformationFile)
163 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
165 # ifndef PIPE_BUF
166 # define PIPE_BUF 512
167 # endif
169 /* Compute revents values for file handle H. If some events cannot happen
170 for the handle, eliminate them from *P_SOUGHT. */
172 static int
173 windows_compute_revents (HANDLE h, int *p_sought)
175 int i, ret, happened;
176 INPUT_RECORD *irbuffer;
177 DWORD avail, nbuffer;
178 BOOL bRet;
179 IO_STATUS_BLOCK iosb;
180 FILE_PIPE_LOCAL_INFORMATION fpli;
181 static PNtQueryInformationFile NtQueryInformationFile;
182 static BOOL once_only;
184 switch (GetFileType (h))
186 case FILE_TYPE_PIPE:
187 if (!once_only)
189 NtQueryInformationFile = (PNtQueryInformationFile)
190 GetProcAddress (GetModuleHandle ("ntdll.dll"),
191 "NtQueryInformationFile");
192 once_only = TRUE;
195 happened = 0;
196 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
198 if (avail)
199 happened |= *p_sought & (POLLIN | POLLRDNORM);
201 else if (GetLastError () == ERROR_BROKEN_PIPE)
202 happened |= POLLHUP;
204 else
206 /* It was the write-end of the pipe. Check if it is writable.
207 If NtQueryInformationFile fails, optimistically assume the pipe is
208 writable. This could happen on Windows 9x, where
209 NtQueryInformationFile is not available, or if we inherit a pipe
210 that doesn't permit FILE_READ_ATTRIBUTES access on the write end
211 (I think this should not happen since Windows XP SP2; WINE seems
212 fine too). Otherwise, ensure that enough space is available for
213 atomic writes. */
214 memset (&iosb, 0, sizeof (iosb));
215 memset (&fpli, 0, sizeof (fpli));
217 if (!NtQueryInformationFile
218 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
219 FilePipeLocalInformation)
220 || fpli.WriteQuotaAvailable >= PIPE_BUF
221 || (fpli.OutboundQuota < PIPE_BUF &&
222 fpli.WriteQuotaAvailable == fpli.OutboundQuota))
223 happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
225 return happened;
227 case FILE_TYPE_CHAR:
228 ret = WaitForSingleObject (h, 0);
229 if (!IsConsoleHandle (h))
230 return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
232 nbuffer = avail = 0;
233 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
234 if (bRet)
236 /* Input buffer. */
237 *p_sought &= POLLIN | POLLRDNORM;
238 if (nbuffer == 0)
239 return POLLHUP;
240 if (!*p_sought)
241 return 0;
243 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
244 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
245 if (!bRet || avail == 0)
246 return POLLHUP;
248 for (i = 0; i < avail; i++)
249 if (irbuffer[i].EventType == KEY_EVENT)
250 return *p_sought;
251 return 0;
253 else
255 /* Screen buffer. */
256 *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
257 return *p_sought;
260 default:
261 ret = WaitForSingleObject (h, 0);
262 if (ret == WAIT_OBJECT_0)
263 return *p_sought & ~(POLLPRI | POLLRDBAND);
265 return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
269 /* Convert fd_sets returned by select into revents values. */
271 static int
272 windows_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
274 int happened = 0;
276 if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
277 happened |= (POLLIN | POLLRDNORM) & sought;
279 else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
281 int r, error;
283 char data[64];
284 WSASetLastError (0);
285 r = recv (h, data, sizeof (data), MSG_PEEK);
286 error = WSAGetLastError ();
287 WSASetLastError (0);
289 if (r > 0 || error == WSAENOTCONN)
290 happened |= (POLLIN | POLLRDNORM) & sought;
292 /* Distinguish hung-up sockets from other errors. */
293 else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
294 || error == WSAECONNABORTED || error == WSAENETRESET)
295 happened |= POLLHUP;
297 else
298 happened |= POLLERR;
301 if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
302 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
304 if (lNetworkEvents & FD_OOB)
305 happened |= (POLLPRI | POLLRDBAND) & sought;
307 return happened;
310 #else /* !MinGW */
312 /* Convert select(2) returned fd_sets into poll(2) revents values. */
313 static int
314 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
316 int happened = 0;
317 if (FD_ISSET (fd, rfds))
319 int r;
320 int socket_errno;
322 # if defined __MACH__ && defined __APPLE__
323 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
324 for some kinds of descriptors. Detect if this descriptor is a
325 connected socket, a server socket, or something else using a
326 0-byte recv, and use ioctl(2) to detect POLLHUP. */
327 r = recv (fd, NULL, 0, MSG_PEEK);
328 socket_errno = (r < 0) ? errno : 0;
329 if (r == 0 || socket_errno == ENOTSOCK)
330 ioctl (fd, FIONREAD, &r);
331 # else
332 char data[64];
333 r = recv (fd, data, sizeof (data), MSG_PEEK);
334 socket_errno = (r < 0) ? errno : 0;
335 # endif
336 if (r == 0)
337 happened |= POLLHUP;
339 /* If the event happened on an unconnected server socket,
340 that's fine. */
341 else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
342 happened |= (POLLIN | POLLRDNORM) & sought;
344 /* Distinguish hung-up sockets from other errors. */
345 else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
346 || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
347 happened |= POLLHUP;
349 /* some systems can't use recv() on non-socket, including HP NonStop */
350 else if (socket_errno == ENOTSOCK)
351 happened |= (POLLIN | POLLRDNORM) & sought;
353 else
354 happened |= POLLERR;
357 if (FD_ISSET (fd, wfds))
358 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
360 if (FD_ISSET (fd, efds))
361 happened |= (POLLPRI | POLLRDBAND) & sought;
363 return happened;
365 #endif /* !MinGW */
368 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
370 #ifndef WINDOWS_NATIVE
371 fd_set rfds, wfds, efds;
372 struct timeval tv;
373 struct timeval *ptv;
374 int maxfd, rc;
375 nfds_t i;
377 if (nfd > INT_MAX)
379 errno = EINVAL;
380 return -1;
382 /* Don't check directly for NFD greater than OPEN_MAX. Any practical use
383 of a too-large NFD is caught by one of the other checks below, and
384 checking directly for getdtablesize is too much of a portability
385 and/or performance and/or correctness hassle. */
387 /* EFAULT is not necessary to implement, but let's do it in the
388 simplest case. */
389 if (!pfd && nfd)
391 errno = EFAULT;
392 return -1;
395 /* convert timeout number into a timeval structure */
396 if (timeout == 0)
398 ptv = &tv;
399 ptv->tv_sec = 0;
400 ptv->tv_usec = 0;
402 else if (timeout > 0)
404 ptv = &tv;
405 ptv->tv_sec = timeout / 1000;
406 ptv->tv_usec = (timeout % 1000) * 1000;
408 else if (timeout == INFTIM)
409 /* wait forever */
410 ptv = NULL;
411 else
413 errno = EINVAL;
414 return -1;
417 /* create fd sets and determine max fd */
418 maxfd = -1;
419 FD_ZERO (&rfds);
420 FD_ZERO (&wfds);
421 FD_ZERO (&efds);
422 for (i = 0; i < nfd; i++)
424 if (pfd[i].fd < 0)
425 continue;
426 if (maxfd < pfd[i].fd)
428 maxfd = pfd[i].fd;
429 if (FD_SETSIZE <= maxfd)
431 errno = EINVAL;
432 return -1;
435 if (pfd[i].events & (POLLIN | POLLRDNORM))
436 FD_SET (pfd[i].fd, &rfds);
437 /* see select(2): "the only exceptional condition detectable
438 is out-of-band data received on a socket", hence we push
439 POLLWRBAND events onto wfds instead of efds. */
440 if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
441 FD_SET (pfd[i].fd, &wfds);
442 if (pfd[i].events & (POLLPRI | POLLRDBAND))
443 FD_SET (pfd[i].fd, &efds);
446 /* examine fd sets */
447 rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
448 if (rc < 0)
449 return rc;
451 /* establish results */
452 rc = 0;
453 for (i = 0; i < nfd; i++)
455 pfd[i].revents = (pfd[i].fd < 0
457 : compute_revents (pfd[i].fd, pfd[i].events,
458 &rfds, &wfds, &efds));
459 rc += pfd[i].revents != 0;
462 return rc;
463 #else
464 static struct timeval tv0;
465 static HANDLE hEvent;
466 WSANETWORKEVENTS ev;
467 HANDLE h, handle_array[FD_SETSIZE + 2];
468 DWORD ret, wait_timeout, nhandles;
469 fd_set rfds, wfds, xfds;
470 BOOL poll_again;
471 MSG msg;
472 int rc = 0;
473 nfds_t i;
475 if (nfd > INT_MAX || timeout < -1)
477 errno = EINVAL;
478 return -1;
481 if (!hEvent)
482 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
484 restart:
485 handle_array[0] = hEvent;
486 nhandles = 1;
487 FD_ZERO (&rfds);
488 FD_ZERO (&wfds);
489 FD_ZERO (&xfds);
491 /* Classify socket handles and create fd sets. */
492 for (i = 0; i < nfd; i++)
494 int sought = pfd[i].events;
495 pfd[i].revents = 0;
496 if (pfd[i].fd < 0)
497 continue;
498 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
499 | POLLPRI | POLLRDBAND)))
500 continue;
502 h = (HANDLE) _get_osfhandle (pfd[i].fd);
503 assure (h != NULL);
504 if (IsSocketHandle (h))
506 int requested = FD_CLOSE;
508 /* see above; socket handles are mapped onto select. */
509 if (sought & (POLLIN | POLLRDNORM))
511 requested |= FD_READ | FD_ACCEPT;
512 FD_SET ((SOCKET) h, &rfds);
514 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
516 requested |= FD_WRITE | FD_CONNECT;
517 FD_SET ((SOCKET) h, &wfds);
519 if (sought & (POLLPRI | POLLRDBAND))
521 requested |= FD_OOB;
522 FD_SET ((SOCKET) h, &xfds);
525 if (requested)
526 WSAEventSelect ((SOCKET) h, hEvent, requested);
528 else
530 /* Poll now. If we get an event, do not poll again. Also,
531 screen buffer handles are waitable, and they'll block until
532 a character is available. windows_compute_revents eliminates
533 bits for the "wrong" direction. */
534 pfd[i].revents = windows_compute_revents (h, &sought);
535 if (sought)
536 handle_array[nhandles++] = h;
537 if (pfd[i].revents)
538 timeout = 0;
542 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
544 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
545 no need to call select again. */
546 poll_again = FALSE;
547 wait_timeout = 0;
549 else
551 poll_again = TRUE;
552 if (timeout == INFTIM)
553 wait_timeout = INFINITE;
554 else
555 wait_timeout = timeout;
558 for (;;)
560 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
561 wait_timeout, QS_ALLINPUT);
563 if (ret == WAIT_OBJECT_0 + nhandles)
565 /* new input of some other kind */
566 BOOL bRet;
567 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
569 TranslateMessage (&msg);
570 DispatchMessage (&msg);
573 else
574 break;
577 if (poll_again)
578 select (0, &rfds, &wfds, &xfds, &tv0);
580 /* Place a sentinel at the end of the array. */
581 handle_array[nhandles] = NULL;
582 nhandles = 1;
583 for (i = 0; i < nfd; i++)
585 int happened;
587 if (pfd[i].fd < 0)
588 continue;
589 if (!(pfd[i].events & (POLLIN | POLLRDNORM |
590 POLLOUT | POLLWRNORM | POLLWRBAND)))
591 continue;
593 h = (HANDLE) _get_osfhandle (pfd[i].fd);
594 if (h != handle_array[nhandles])
596 /* It's a socket. */
597 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
598 WSAEventSelect ((SOCKET) h, 0, 0);
600 /* If we're lucky, WSAEnumNetworkEvents already provided a way
601 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
602 if (FD_ISSET ((SOCKET) h, &rfds)
603 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
604 ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
605 if (FD_ISSET ((SOCKET) h, &wfds))
606 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
607 if (FD_ISSET ((SOCKET) h, &xfds))
608 ev.lNetworkEvents |= FD_OOB;
610 happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
611 ev.lNetworkEvents);
613 else
615 /* Not a socket. */
616 int sought = pfd[i].events;
617 happened = windows_compute_revents (h, &sought);
618 nhandles++;
621 if ((pfd[i].revents |= happened) != 0)
622 rc++;
625 if (!rc && timeout == INFTIM)
627 SleepEx (1, TRUE);
628 goto restart;
631 return rc;
632 #endif