rebase --root: fix amending root commit messages
[git.git] / compat / poll / poll.c
blob7ed3fbbea13c994467280ed3e981ae9f37f15c09
1 /* Emulation for poll(2)
2 Contributed by Paolo Bonzini.
4 Copyright 2001-2003, 2006-2011 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 <http://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 #if defined(WIN32)
27 # include <malloc.h>
28 #endif
30 #include <sys/types.h>
32 /* Specification. */
33 #include <poll.h>
35 #include <errno.h>
36 #include <limits.h>
37 #include <assert.h>
39 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
40 # define WIN32_NATIVE
41 # if defined (_MSC_VER) && !defined(_WIN32_WINNT)
42 # define _WIN32_WINNT 0x0502
43 # endif
44 # include <winsock2.h>
45 # include <windows.h>
46 # include <io.h>
47 # include <stdio.h>
48 # include <conio.h>
49 #else
50 # include <sys/time.h>
51 # include <sys/socket.h>
52 # ifndef NO_SYS_SELECT_H
53 # include <sys/select.h>
54 # endif
55 # include <unistd.h>
56 #endif
58 #ifdef HAVE_SYS_IOCTL_H
59 # include <sys/ioctl.h>
60 #endif
61 #ifdef HAVE_SYS_FILIO_H
62 # include <sys/filio.h>
63 #endif
65 #include <time.h>
67 #ifndef INFTIM
68 # define INFTIM (-1)
69 #endif
71 /* BeOS does not have MSG_PEEK. */
72 #ifndef MSG_PEEK
73 # define MSG_PEEK 0
74 #endif
76 #ifdef WIN32_NATIVE
78 #define IsConsoleHandle(h) (((long) (intptr_t) (h) & 3) == 3)
80 static BOOL
81 IsSocketHandle (HANDLE h)
83 WSANETWORKEVENTS ev;
85 if (IsConsoleHandle (h))
86 return FALSE;
88 /* Under Wine, it seems that getsockopt returns 0 for pipes too.
89 WSAEnumNetworkEvents instead distinguishes the two correctly. */
90 ev.lNetworkEvents = 0xDEADBEEF;
91 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
92 return ev.lNetworkEvents != 0xDEADBEEF;
95 /* Declare data structures for ntdll functions. */
96 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
97 ULONG NamedPipeType;
98 ULONG NamedPipeConfiguration;
99 ULONG MaximumInstances;
100 ULONG CurrentInstances;
101 ULONG InboundQuota;
102 ULONG ReadDataAvailable;
103 ULONG OutboundQuota;
104 ULONG WriteQuotaAvailable;
105 ULONG NamedPipeState;
106 ULONG NamedPipeEnd;
107 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
109 typedef struct _IO_STATUS_BLOCK
111 union {
112 DWORD Status;
113 PVOID Pointer;
114 } u;
115 ULONG_PTR Information;
116 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
118 typedef enum _FILE_INFORMATION_CLASS {
119 FilePipeLocalInformation = 24
120 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
122 typedef DWORD (WINAPI *PNtQueryInformationFile)
123 (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
125 # ifndef PIPE_BUF
126 # define PIPE_BUF 512
127 # endif
129 /* Compute revents values for file handle H. If some events cannot happen
130 for the handle, eliminate them from *P_SOUGHT. */
132 static int
133 win32_compute_revents (HANDLE h, int *p_sought)
135 int i, ret, happened;
136 INPUT_RECORD *irbuffer;
137 DWORD avail, nbuffer;
138 BOOL bRet;
139 IO_STATUS_BLOCK iosb;
140 FILE_PIPE_LOCAL_INFORMATION fpli;
141 static PNtQueryInformationFile NtQueryInformationFile;
142 static BOOL once_only;
144 switch (GetFileType (h))
146 case FILE_TYPE_PIPE:
147 if (!once_only)
149 NtQueryInformationFile = (PNtQueryInformationFile)
150 GetProcAddress (GetModuleHandle ("ntdll.dll"),
151 "NtQueryInformationFile");
152 once_only = TRUE;
155 happened = 0;
156 if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
158 if (avail)
159 happened |= *p_sought & (POLLIN | POLLRDNORM);
161 else if (GetLastError () == ERROR_BROKEN_PIPE)
162 happened |= POLLHUP;
164 else
166 /* It was the write-end of the pipe. Check if it is writable.
167 If NtQueryInformationFile fails, optimistically assume the pipe is
168 writable. This could happen on Win9x, where NtQueryInformationFile
169 is not available, or if we inherit a pipe that doesn't permit
170 FILE_READ_ATTRIBUTES access on the write end (I think this should
171 not happen since WinXP SP2; WINE seems fine too). Otherwise,
172 ensure that enough space is available for atomic writes. */
173 memset (&iosb, 0, sizeof (iosb));
174 memset (&fpli, 0, sizeof (fpli));
176 if (!NtQueryInformationFile
177 || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
178 FilePipeLocalInformation)
179 || fpli.WriteQuotaAvailable >= PIPE_BUF
180 || (fpli.OutboundQuota < PIPE_BUF &&
181 fpli.WriteQuotaAvailable == fpli.OutboundQuota))
182 happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
184 return happened;
186 case FILE_TYPE_CHAR:
187 ret = WaitForSingleObject (h, 0);
188 if (!IsConsoleHandle (h))
189 return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
191 nbuffer = avail = 0;
192 bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
193 if (bRet)
195 /* Input buffer. */
196 *p_sought &= POLLIN | POLLRDNORM;
197 if (nbuffer == 0)
198 return POLLHUP;
199 if (!*p_sought)
200 return 0;
202 irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
203 bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
204 if (!bRet || avail == 0)
205 return POLLHUP;
207 for (i = 0; i < avail; i++)
208 if (irbuffer[i].EventType == KEY_EVENT)
209 return *p_sought;
210 return 0;
212 else
214 /* Screen buffer. */
215 *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
216 return *p_sought;
219 default:
220 ret = WaitForSingleObject (h, 0);
221 if (ret == WAIT_OBJECT_0)
222 return *p_sought & ~(POLLPRI | POLLRDBAND);
224 return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
228 /* Convert fd_sets returned by select into revents values. */
230 static int
231 win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
233 int happened = 0;
235 if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
236 happened |= (POLLIN | POLLRDNORM) & sought;
238 else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
240 int r, error;
242 char data[64];
243 WSASetLastError (0);
244 r = recv (h, data, sizeof (data), MSG_PEEK);
245 error = WSAGetLastError ();
246 WSASetLastError (0);
248 if (r > 0 || error == WSAENOTCONN)
249 happened |= (POLLIN | POLLRDNORM) & sought;
251 /* Distinguish hung-up sockets from other errors. */
252 else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
253 || error == WSAECONNABORTED || error == WSAENETRESET)
254 happened |= POLLHUP;
256 else
257 happened |= POLLERR;
260 if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
261 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
263 if (lNetworkEvents & FD_OOB)
264 happened |= (POLLPRI | POLLRDBAND) & sought;
266 return happened;
269 #else /* !MinGW */
271 /* Convert select(2) returned fd_sets into poll(2) revents values. */
272 static int
273 compute_revents (int fd, int sought, fd_set *rfds, fd_set *wfds, fd_set *efds)
275 int happened = 0;
276 if (FD_ISSET (fd, rfds))
278 int r;
279 int socket_errno;
281 # if defined __MACH__ && defined __APPLE__
282 /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
283 for some kinds of descriptors. Detect if this descriptor is a
284 connected socket, a server socket, or something else using a
285 0-byte recv, and use ioctl(2) to detect POLLHUP. */
286 r = recv (fd, NULL, 0, MSG_PEEK);
287 socket_errno = (r < 0) ? errno : 0;
288 if (r == 0 || socket_errno == ENOTSOCK)
289 ioctl (fd, FIONREAD, &r);
290 # else
291 char data[64];
292 r = recv (fd, data, sizeof (data), MSG_PEEK);
293 socket_errno = (r < 0) ? errno : 0;
294 # endif
295 if (r == 0)
296 happened |= POLLHUP;
298 /* If the event happened on an unconnected server socket,
299 that's fine. */
300 else if (r > 0 || ( /* (r == -1) && */ socket_errno == ENOTCONN))
301 happened |= (POLLIN | POLLRDNORM) & sought;
303 /* Distinguish hung-up sockets from other errors. */
304 else if (socket_errno == ESHUTDOWN || socket_errno == ECONNRESET
305 || socket_errno == ECONNABORTED || socket_errno == ENETRESET)
306 happened |= POLLHUP;
308 /* some systems can't use recv() on non-socket, including HP NonStop */
309 else if (/* (r == -1) && */ socket_errno == ENOTSOCK)
310 happened |= (POLLIN | POLLRDNORM) & sought;
312 else
313 happened |= POLLERR;
316 if (FD_ISSET (fd, wfds))
317 happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
319 if (FD_ISSET (fd, efds))
320 happened |= (POLLPRI | POLLRDBAND) & sought;
322 return happened;
324 #endif /* !MinGW */
327 poll (struct pollfd *pfd, nfds_t nfd, int timeout)
329 #ifndef WIN32_NATIVE
330 fd_set rfds, wfds, efds;
331 struct timeval tv;
332 struct timeval *ptv;
333 int maxfd, rc;
334 nfds_t i;
336 # ifdef _SC_OPEN_MAX
337 static int sc_open_max = -1;
339 if (nfd < 0
340 || (nfd > sc_open_max
341 && (sc_open_max != -1
342 || nfd > (sc_open_max = sysconf (_SC_OPEN_MAX)))))
344 errno = EINVAL;
345 return -1;
347 # else /* !_SC_OPEN_MAX */
348 # ifdef OPEN_MAX
349 if (nfd < 0 || nfd > OPEN_MAX)
351 errno = EINVAL;
352 return -1;
354 # endif /* OPEN_MAX -- else, no check is needed */
355 # endif /* !_SC_OPEN_MAX */
357 /* EFAULT is not necessary to implement, but let's do it in the
358 simplest case. */
359 if (!pfd && nfd)
361 errno = EFAULT;
362 return -1;
365 /* convert timeout number into a timeval structure */
366 if (timeout == 0)
368 ptv = &tv;
369 ptv->tv_sec = 0;
370 ptv->tv_usec = 0;
372 else if (timeout > 0)
374 ptv = &tv;
375 ptv->tv_sec = timeout / 1000;
376 ptv->tv_usec = (timeout % 1000) * 1000;
378 else if (timeout == INFTIM)
379 /* wait forever */
380 ptv = NULL;
381 else
383 errno = EINVAL;
384 return -1;
387 /* create fd sets and determine max fd */
388 maxfd = -1;
389 FD_ZERO (&rfds);
390 FD_ZERO (&wfds);
391 FD_ZERO (&efds);
392 for (i = 0; i < nfd; i++)
394 if (pfd[i].fd < 0)
395 continue;
397 if (pfd[i].events & (POLLIN | POLLRDNORM))
398 FD_SET (pfd[i].fd, &rfds);
400 /* see select(2): "the only exceptional condition detectable
401 is out-of-band data received on a socket", hence we push
402 POLLWRBAND events onto wfds instead of efds. */
403 if (pfd[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND))
404 FD_SET (pfd[i].fd, &wfds);
405 if (pfd[i].events & (POLLPRI | POLLRDBAND))
406 FD_SET (pfd[i].fd, &efds);
407 if (pfd[i].fd >= maxfd
408 && (pfd[i].events & (POLLIN | POLLOUT | POLLPRI
409 | POLLRDNORM | POLLRDBAND
410 | POLLWRNORM | POLLWRBAND)))
412 maxfd = pfd[i].fd;
413 if (maxfd > FD_SETSIZE)
415 errno = EOVERFLOW;
416 return -1;
421 /* examine fd sets */
422 rc = select (maxfd + 1, &rfds, &wfds, &efds, ptv);
423 if (rc < 0)
424 return rc;
426 /* establish results */
427 rc = 0;
428 for (i = 0; i < nfd; i++)
429 if (pfd[i].fd < 0)
430 pfd[i].revents = 0;
431 else
433 int happened = compute_revents (pfd[i].fd, pfd[i].events,
434 &rfds, &wfds, &efds);
435 if (happened)
437 pfd[i].revents = happened;
438 rc++;
440 else
442 pfd[i].revents = 0;
446 return rc;
447 #else
448 static struct timeval tv0;
449 static HANDLE hEvent;
450 WSANETWORKEVENTS ev;
451 HANDLE h, handle_array[FD_SETSIZE + 2];
452 DWORD ret, wait_timeout, nhandles, start = 0, elapsed, orig_timeout = 0;
453 fd_set rfds, wfds, xfds;
454 BOOL poll_again;
455 MSG msg;
456 int rc = 0;
457 nfds_t i;
459 if (nfd < 0 || timeout < -1)
461 errno = EINVAL;
462 return -1;
465 if (timeout != INFTIM)
467 orig_timeout = timeout;
468 start = GetTickCount();
471 if (!hEvent)
472 hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
474 restart:
475 handle_array[0] = hEvent;
476 nhandles = 1;
477 FD_ZERO (&rfds);
478 FD_ZERO (&wfds);
479 FD_ZERO (&xfds);
481 /* Classify socket handles and create fd sets. */
482 for (i = 0; i < nfd; i++)
484 int sought = pfd[i].events;
485 pfd[i].revents = 0;
486 if (pfd[i].fd < 0)
487 continue;
488 if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
489 | POLLPRI | POLLRDBAND)))
490 continue;
492 h = (HANDLE) _get_osfhandle (pfd[i].fd);
493 assert (h != NULL);
494 if (IsSocketHandle (h))
496 int requested = FD_CLOSE;
498 /* see above; socket handles are mapped onto select. */
499 if (sought & (POLLIN | POLLRDNORM))
501 requested |= FD_READ | FD_ACCEPT;
502 FD_SET ((SOCKET) h, &rfds);
504 if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
506 requested |= FD_WRITE | FD_CONNECT;
507 FD_SET ((SOCKET) h, &wfds);
509 if (sought & (POLLPRI | POLLRDBAND))
511 requested |= FD_OOB;
512 FD_SET ((SOCKET) h, &xfds);
515 if (requested)
516 WSAEventSelect ((SOCKET) h, hEvent, requested);
518 else
520 /* Poll now. If we get an event, do not poll again. Also,
521 screen buffer handles are waitable, and they'll block until
522 a character is available. win32_compute_revents eliminates
523 bits for the "wrong" direction. */
524 pfd[i].revents = win32_compute_revents (h, &sought);
525 if (sought)
526 handle_array[nhandles++] = h;
527 if (pfd[i].revents)
528 timeout = 0;
532 if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
534 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
535 no need to call select again. */
536 poll_again = FALSE;
537 wait_timeout = 0;
539 else
541 poll_again = TRUE;
542 if (timeout == INFTIM)
543 wait_timeout = INFINITE;
544 else
545 wait_timeout = timeout;
548 for (;;)
550 ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
551 wait_timeout, QS_ALLINPUT);
553 if (ret == WAIT_OBJECT_0 + nhandles)
555 /* new input of some other kind */
556 BOOL bRet;
557 while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
559 TranslateMessage (&msg);
560 DispatchMessage (&msg);
563 else
564 break;
567 if (poll_again)
568 select (0, &rfds, &wfds, &xfds, &tv0);
570 /* Place a sentinel at the end of the array. */
571 handle_array[nhandles] = NULL;
572 nhandles = 1;
573 for (i = 0; i < nfd; i++)
575 int happened;
577 if (pfd[i].fd < 0)
578 continue;
579 if (!(pfd[i].events & (POLLIN | POLLRDNORM |
580 POLLOUT | POLLWRNORM | POLLWRBAND)))
581 continue;
583 h = (HANDLE) _get_osfhandle (pfd[i].fd);
584 if (h != handle_array[nhandles])
586 /* It's a socket. */
587 WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
588 WSAEventSelect ((SOCKET) h, NULL, 0);
590 /* If we're lucky, WSAEnumNetworkEvents already provided a way
591 to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */
592 if (FD_ISSET ((SOCKET) h, &rfds)
593 && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
594 ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
595 if (FD_ISSET ((SOCKET) h, &wfds))
596 ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
597 if (FD_ISSET ((SOCKET) h, &xfds))
598 ev.lNetworkEvents |= FD_OOB;
600 happened = win32_compute_revents_socket ((SOCKET) h, pfd[i].events,
601 ev.lNetworkEvents);
603 else
605 /* Not a socket. */
606 int sought = pfd[i].events;
607 happened = win32_compute_revents (h, &sought);
608 nhandles++;
611 if ((pfd[i].revents |= happened) != 0)
612 rc++;
615 if (!rc && orig_timeout && timeout != INFTIM)
617 elapsed = GetTickCount() - start;
618 timeout = elapsed >= orig_timeout ? 0 : orig_timeout - elapsed;
621 if (!rc && timeout)
623 SleepEx (1, TRUE);
624 goto restart;
627 return rc;
628 #endif