Bump to 1.14.1
[platform/upstream/augeas.git] / lib / select.c
1 /* Emulation for select(2)
2    Contributed by Paolo Bonzini.
3
4    Copyright 2008-2016 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, see <http://www.gnu.org/licenses/>.  */
20
21 #include <config.h>
22 #include <alloca.h>
23 #include <assert.h>
24
25 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
26 /* Native Windows.  */
27
28 #include <sys/types.h>
29 #include <errno.h>
30 #include <limits.h>
31
32 #include <winsock2.h>
33 #include <windows.h>
34 #include <io.h>
35 #include <stdio.h>
36 #include <conio.h>
37 #include <time.h>
38
39 /* Get the overridden 'struct timeval'.  */
40 #include <sys/time.h>
41
42 #include "msvc-nothrow.h"
43
44 #undef select
45
46 struct bitset {
47   unsigned char in[FD_SETSIZE / CHAR_BIT];
48   unsigned char out[FD_SETSIZE / CHAR_BIT];
49 };
50
51 /* Declare data structures for ntdll functions.  */
52 typedef struct _FILE_PIPE_LOCAL_INFORMATION {
53   ULONG NamedPipeType;
54   ULONG NamedPipeConfiguration;
55   ULONG MaximumInstances;
56   ULONG CurrentInstances;
57   ULONG InboundQuota;
58   ULONG ReadDataAvailable;
59   ULONG OutboundQuota;
60   ULONG WriteQuotaAvailable;
61   ULONG NamedPipeState;
62   ULONG NamedPipeEnd;
63 } FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
64
65 typedef struct _IO_STATUS_BLOCK
66 {
67   union {
68     DWORD Status;
69     PVOID Pointer;
70   } u;
71   ULONG_PTR Information;
72 } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
73
74 typedef enum _FILE_INFORMATION_CLASS {
75   FilePipeLocalInformation = 24
76 } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
77
78 typedef DWORD (WINAPI *PNtQueryInformationFile)
79          (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
80
81 #ifndef PIPE_BUF
82 #define PIPE_BUF        512
83 #endif
84
85 static BOOL IsConsoleHandle (HANDLE h)
86 {
87   DWORD mode;
88   return GetConsoleMode (h, &mode) != 0;
89 }
90
91 static BOOL
92 IsSocketHandle (HANDLE h)
93 {
94   WSANETWORKEVENTS ev;
95
96   if (IsConsoleHandle (h))
97     return FALSE;
98
99   /* Under Wine, it seems that getsockopt returns 0 for pipes too.
100      WSAEnumNetworkEvents instead distinguishes the two correctly.  */
101   ev.lNetworkEvents = 0xDEADBEEF;
102   WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
103   return ev.lNetworkEvents != 0xDEADBEEF;
104 }
105
106 /* Compute output fd_sets for libc descriptor FD (whose Windows handle is
107    H).  */
108
109 static int
110 windows_poll_handle (HANDLE h, int fd,
111                      struct bitset *rbits,
112                      struct bitset *wbits,
113                      struct bitset *xbits)
114 {
115   BOOL read, write, except;
116   int i, ret;
117   INPUT_RECORD *irbuffer;
118   DWORD avail, nbuffer;
119   BOOL bRet;
120   IO_STATUS_BLOCK iosb;
121   FILE_PIPE_LOCAL_INFORMATION fpli;
122   static PNtQueryInformationFile NtQueryInformationFile;
123   static BOOL once_only;
124
125   read = write = except = FALSE;
126   switch (GetFileType (h))
127     {
128     case FILE_TYPE_DISK:
129       read = TRUE;
130       write = TRUE;
131       break;
132
133     case FILE_TYPE_PIPE:
134       if (!once_only)
135         {
136           NtQueryInformationFile = (PNtQueryInformationFile)
137             GetProcAddress (GetModuleHandle ("ntdll.dll"),
138                             "NtQueryInformationFile");
139           once_only = TRUE;
140         }
141
142       if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
143         {
144           if (avail)
145             read = TRUE;
146         }
147       else if (GetLastError () == ERROR_BROKEN_PIPE)
148         ;
149
150       else
151         {
152           /* It was the write-end of the pipe.  Check if it is writable.
153              If NtQueryInformationFile fails, optimistically assume the pipe is
154              writable.  This could happen on Windows 9x, where
155              NtQueryInformationFile is not available, or if we inherit a pipe
156              that doesn't permit FILE_READ_ATTRIBUTES access on the write end
157              (I think this should not happen since Windows XP SP2; WINE seems
158              fine too).  Otherwise, ensure that enough space is available for
159              atomic writes.  */
160           memset (&iosb, 0, sizeof (iosb));
161           memset (&fpli, 0, sizeof (fpli));
162
163           if (!NtQueryInformationFile
164               || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
165                                          FilePipeLocalInformation)
166               || fpli.WriteQuotaAvailable >= PIPE_BUF
167               || (fpli.OutboundQuota < PIPE_BUF &&
168                   fpli.WriteQuotaAvailable == fpli.OutboundQuota))
169             write = TRUE;
170         }
171       break;
172
173     case FILE_TYPE_CHAR:
174       write = TRUE;
175       if (!(rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
176         break;
177
178       ret = WaitForSingleObject (h, 0);
179       if (ret == WAIT_OBJECT_0)
180         {
181           if (!IsConsoleHandle (h))
182             {
183               read = TRUE;
184               break;
185             }
186
187           nbuffer = avail = 0;
188           bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
189
190           /* Screen buffers handles are filtered earlier.  */
191           assert (bRet);
192           if (nbuffer == 0)
193             {
194               except = TRUE;
195               break;
196             }
197
198           irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
199           bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
200           if (!bRet || avail == 0)
201             {
202               except = TRUE;
203               break;
204             }
205
206           for (i = 0; i < avail; i++)
207             if (irbuffer[i].EventType == KEY_EVENT)
208               read = TRUE;
209         }
210       break;
211
212     default:
213       ret = WaitForSingleObject (h, 0);
214       write = TRUE;
215       if (ret == WAIT_OBJECT_0)
216         read = TRUE;
217
218       break;
219     }
220
221   ret = 0;
222   if (read && (rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
223     {
224       rbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
225       ret++;
226     }
227
228   if (write && (wbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
229     {
230       wbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
231       ret++;
232     }
233
234   if (except && (xbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
235     {
236       xbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
237       ret++;
238     }
239
240   return ret;
241 }
242
243 int
244 rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
245             struct timeval *timeout)
246 #undef timeval
247 {
248   static struct timeval tv0;
249   static HANDLE hEvent;
250   HANDLE h, handle_array[FD_SETSIZE + 2];
251   fd_set handle_rfds, handle_wfds, handle_xfds;
252   struct bitset rbits, wbits, xbits;
253   unsigned char anyfds_in[FD_SETSIZE / CHAR_BIT];
254   DWORD ret, wait_timeout, nhandles, nsock, nbuffer;
255   MSG msg;
256   int i, fd, rc;
257   clock_t tend;
258
259   if (nfds > FD_SETSIZE)
260     nfds = FD_SETSIZE;
261
262   if (!timeout)
263     wait_timeout = INFINITE;
264   else
265     {
266       wait_timeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
267
268       /* select is also used as a portable usleep.  */
269       if (!rfds && !wfds && !xfds)
270         {
271           Sleep (wait_timeout);
272           return 0;
273         }
274     }
275
276   if (!hEvent)
277     hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
278
279   handle_array[0] = hEvent;
280   nhandles = 1;
281   nsock = 0;
282
283   /* Copy descriptors to bitsets.  At the same time, eliminate
284      bits in the "wrong" direction for console input buffers
285      and screen buffers, because screen buffers are waitable
286      and they will block until a character is available.  */
287   memset (&rbits, 0, sizeof (rbits));
288   memset (&wbits, 0, sizeof (wbits));
289   memset (&xbits, 0, sizeof (xbits));
290   memset (anyfds_in, 0, sizeof (anyfds_in));
291   if (rfds)
292     for (i = 0; i < rfds->fd_count; i++)
293       {
294         fd = rfds->fd_array[i];
295         h = (HANDLE) _get_osfhandle (fd);
296         if (IsConsoleHandle (h)
297             && !GetNumberOfConsoleInputEvents (h, &nbuffer))
298           continue;
299
300         rbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
301         anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
302       }
303   else
304     rfds = (fd_set *) alloca (sizeof (fd_set));
305
306   if (wfds)
307     for (i = 0; i < wfds->fd_count; i++)
308       {
309         fd = wfds->fd_array[i];
310         h = (HANDLE) _get_osfhandle (fd);
311         if (IsConsoleHandle (h)
312             && GetNumberOfConsoleInputEvents (h, &nbuffer))
313           continue;
314
315         wbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
316         anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
317       }
318   else
319     wfds = (fd_set *) alloca (sizeof (fd_set));
320
321   if (xfds)
322     for (i = 0; i < xfds->fd_count; i++)
323       {
324         fd = xfds->fd_array[i];
325         xbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
326         anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
327       }
328   else
329     xfds = (fd_set *) alloca (sizeof (fd_set));
330
331   /* Zero all the fd_sets, including the application's.  */
332   FD_ZERO (rfds);
333   FD_ZERO (wfds);
334   FD_ZERO (xfds);
335   FD_ZERO (&handle_rfds);
336   FD_ZERO (&handle_wfds);
337   FD_ZERO (&handle_xfds);
338
339   /* Classify handles.  Create fd sets for sockets, poll the others. */
340   for (i = 0; i < nfds; i++)
341     {
342       if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
343         continue;
344
345       h = (HANDLE) _get_osfhandle (i);
346       if (!h)
347         {
348           errno = EBADF;
349           return -1;
350         }
351
352       if (IsSocketHandle (h))
353         {
354           int requested = FD_CLOSE;
355
356           /* See above; socket handles are mapped onto select, but we
357              need to map descriptors to handles.  */
358           if (rbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
359             {
360               requested |= FD_READ | FD_ACCEPT;
361               FD_SET ((SOCKET) h, rfds);
362               FD_SET ((SOCKET) h, &handle_rfds);
363             }
364           if (wbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
365             {
366               requested |= FD_WRITE | FD_CONNECT;
367               FD_SET ((SOCKET) h, wfds);
368               FD_SET ((SOCKET) h, &handle_wfds);
369             }
370           if (xbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
371             {
372               requested |= FD_OOB;
373               FD_SET ((SOCKET) h, xfds);
374               FD_SET ((SOCKET) h, &handle_xfds);
375             }
376
377           WSAEventSelect ((SOCKET) h, hEvent, requested);
378           nsock++;
379         }
380       else
381         {
382           handle_array[nhandles++] = h;
383
384           /* Poll now.  If we get an event, do not wait below.  */
385           if (wait_timeout != 0
386               && windows_poll_handle (h, i, &rbits, &wbits, &xbits))
387             wait_timeout = 0;
388         }
389     }
390
391   /* Place a sentinel at the end of the array.  */
392   handle_array[nhandles] = NULL;
393
394   /* When will the waiting period expire?  */
395   if (wait_timeout != INFINITE)
396     tend = clock () + wait_timeout;
397
398 restart:
399   if (wait_timeout == 0 || nsock == 0)
400     rc = 0;
401   else
402     {
403       /* See if we need to wait in the loop below.  If any select is ready,
404          do MsgWaitForMultipleObjects anyway to dispatch messages, but
405          no need to call select again.  */
406       rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0);
407       if (rc == 0)
408         {
409           /* Restore the fd_sets for the other select we do below.  */
410           memcpy (&handle_rfds, rfds, sizeof (fd_set));
411           memcpy (&handle_wfds, wfds, sizeof (fd_set));
412           memcpy (&handle_xfds, xfds, sizeof (fd_set));
413         }
414       else
415         wait_timeout = 0;
416     }
417
418   /* How much is left to wait?  */
419   if (wait_timeout != INFINITE)
420     {
421       clock_t tnow = clock ();
422       if (tend >= tnow)
423         wait_timeout = tend - tnow;
424       else
425         wait_timeout = 0;
426     }
427
428   for (;;)
429     {
430       ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
431                                        wait_timeout, QS_ALLINPUT);
432
433       if (ret == WAIT_OBJECT_0 + nhandles)
434         {
435           /* new input of some other kind */
436           BOOL bRet;
437           while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
438             {
439               TranslateMessage (&msg);
440               DispatchMessage (&msg);
441             }
442         }
443       else
444         break;
445     }
446
447   /* If we haven't done it yet, check the status of the sockets.  */
448   if (rc == 0 && nsock > 0)
449     rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0);
450
451   if (nhandles > 1)
452     {
453       /* Count results that are not counted in the return value of select.  */
454       nhandles = 1;
455       for (i = 0; i < nfds; i++)
456         {
457           if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
458             continue;
459
460           h = (HANDLE) _get_osfhandle (i);
461           if (h == handle_array[nhandles])
462             {
463               /* Not a socket.  */
464               nhandles++;
465               windows_poll_handle (h, i, &rbits, &wbits, &xbits);
466               if (rbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))
467                   || wbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))
468                   || xbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
469                 rc++;
470             }
471         }
472
473       if (rc == 0
474           && (wait_timeout == INFINITE
475               /* If NHANDLES > 1, but no bits are set, it means we've
476                  been told incorrectly that some handle was signaled.
477                  This happens with anonymous pipes, which always cause
478                  MsgWaitForMultipleObjects to exit immediately, but no
479                  data is found ready to be read by windows_poll_handle.
480                  To avoid a total failure (whereby we return zero and
481                  don't wait at all), let's poll in a more busy loop.  */
482               || (wait_timeout != 0 && nhandles > 1)))
483         {
484           /* Sleep 1 millisecond to avoid busy wait and retry with the
485              original fd_sets.  */
486           memcpy (&handle_rfds, rfds, sizeof (fd_set));
487           memcpy (&handle_wfds, wfds, sizeof (fd_set));
488           memcpy (&handle_xfds, xfds, sizeof (fd_set));
489           SleepEx (1, TRUE);
490           goto restart;
491         }
492       if (timeout && wait_timeout == 0 && rc == 0)
493         timeout->tv_sec = timeout->tv_usec = 0;
494     }
495
496   /* Now fill in the results.  */
497   FD_ZERO (rfds);
498   FD_ZERO (wfds);
499   FD_ZERO (xfds);
500   nhandles = 1;
501   for (i = 0; i < nfds; i++)
502     {
503       if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
504         continue;
505
506       h = (HANDLE) _get_osfhandle (i);
507       if (h != handle_array[nhandles])
508         {
509           /* Perform handle->descriptor mapping.  */
510           WSAEventSelect ((SOCKET) h, NULL, 0);
511           if (FD_ISSET (h, &handle_rfds))
512             FD_SET (i, rfds);
513           if (FD_ISSET (h, &handle_wfds))
514             FD_SET (i, wfds);
515           if (FD_ISSET (h, &handle_xfds))
516             FD_SET (i, xfds);
517         }
518       else
519         {
520           /* Not a socket.  */
521           nhandles++;
522           if (rbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
523             FD_SET (i, rfds);
524           if (wbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
525             FD_SET (i, wfds);
526           if (xbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
527             FD_SET (i, xfds);
528         }
529     }
530
531   return rc;
532 }
533
534 #else /* ! Native Windows.  */
535
536 #include <sys/select.h>
537 #include <stddef.h> /* NULL */
538 #include <errno.h>
539 #include <unistd.h>
540
541 #undef select
542
543 int
544 rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
545             struct timeval *timeout)
546 {
547   int i;
548
549   /* FreeBSD 8.2 has a bug: it does not always detect invalid fds.  */
550   if (nfds < 0 || nfds > FD_SETSIZE)
551     {
552       errno = EINVAL;
553       return -1;
554     }
555   for (i = 0; i < nfds; i++)
556     {
557       if (((rfds && FD_ISSET (i, rfds))
558            || (wfds && FD_ISSET (i, wfds))
559            || (xfds && FD_ISSET (i, xfds)))
560           && dup2 (i, i) != i)
561         return -1;
562     }
563
564   /* Interix 3.5 has a bug: it does not support nfds == 0.  */
565   if (nfds == 0)
566     {
567       nfds = 1;
568       rfds = NULL;
569       wfds = NULL;
570       xfds = NULL;
571     }
572   return select (nfds, rfds, wfds, xfds, timeout);
573 }
574
575 #endif