mingw: import poll-emulation from gnulib
copy lib/poll.c and lib/poll.in.h verbatim from commit 0a05120 in git://git.savannah.gnu.org/gnulib.git to compat/win32/sys/poll.[ch] To upgrade this code in the future, branch out from this commit, copy new versions of the files above on top, and merge back the result. Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Erik Faye-Lund committed
Nov 4, 2010 at 02:35 UTC
49521af8a818039f8daf18f2160c4d1e7dbb4270
2 files changed
+650
compat/win32/sys/poll.c
new
+597
@@ -0,0 +1,597 @@
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
+ 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
+}
compat/win32/sys/poll.h
new
+53
@@ -0,0 +1,53 @@
1
+/* Header for poll(2) emulation
2
+ Contributed by Paolo Bonzini.
3
+
4
+ Copyright 2001, 2002, 2003, 2007, 2009, 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
+#ifndef _GL_POLL_H
23
+#define _GL_POLL_H
24
+
25
+/* fake a poll(2) environment */
26
+#define POLLIN 0x0001 /* any readable data available */
27
+#define POLLPRI 0x0002 /* OOB/Urgent readable data */
28
+#define POLLOUT 0x0004 /* file descriptor is writeable */
29
+#define POLLERR 0x0008 /* some poll error occurred */
30
+#define POLLHUP 0x0010 /* file descriptor was "hung up" */
31
+#define POLLNVAL 0x0020 /* requested events "invalid" */
32
+#define POLLRDNORM 0x0040
33
+#define POLLRDBAND 0x0080
34
+#define POLLWRNORM 0x0100
35
+#define POLLWRBAND 0x0200
36
+
37
+struct pollfd
38
+{
39
+ int fd; /* which file descriptor to poll */
40
+ short events; /* events we are interested in */
41
+ short revents; /* events found on return */
42
+};
43
+
44
+typedef unsigned long nfds_t;
45
+
46
+extern int poll (struct pollfd *pfd, nfds_t nfd, int timeout);
47
+
48
+/* Define INFTIM only if doing so conforms to POSIX. */
49
+#if !defined (_POSIX_C_SOURCE) && !defined (_XOPEN_SOURCE)
50
+#define INFTIM (-1)
51
+#endif
52
+
53
+#endif /* _GL_POLL_H */