~ubuntu-branches/ubuntu/trusty/gnutls26/trusty-security

« back to all changes in this revision

Viewing changes to gl/select.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Metzler
  • Date: 2010-04-22 19:29:52 UTC
  • mto: (12.4.3 experimental) (1.5.1)
  • mto: This revision was merged to the branch mainline in revision 26.
  • Revision ID: james.westby@ubuntu.com-20100422192952-gbj6cvaan8e4ejck
Tags: upstream-2.9.10
ImportĀ upstreamĀ versionĀ 2.9.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Emulation for select(2)
2
2
   Contributed by Paolo Bonzini.
3
3
 
4
 
   Copyright 2008-2009 Free Software Foundation, Inc.
 
4
   Copyright 2008-2010 Free Software Foundation, Inc.
5
5
 
6
6
   This file is part of gnulib.
7
7
 
71
71
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
72
72
 
73
73
typedef DWORD (WINAPI *PNtQueryInformationFile)
74
 
         (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
 
74
         (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
75
75
 
76
76
#ifndef PIPE_BUF
77
 
#define PIPE_BUF        512
 
77
#define PIPE_BUF        512
78
78
#endif
79
79
 
80
80
#define IsConsoleHandle(h) (((long) (h) & 3) == 3)
81
81
 
82
82
static BOOL
83
 
IsSocketHandle(HANDLE h)
 
83
IsSocketHandle (HANDLE h)
84
84
{
85
85
  WSANETWORKEVENTS ev;
86
86
 
98
98
 
99
99
static int
100
100
win32_poll_handle (HANDLE h, int fd, struct bitset *rbits, struct bitset *wbits,
101
 
                   struct bitset *xbits)
 
101
                   struct bitset *xbits)
102
102
{
103
103
  BOOL read, write, except;
104
104
  int i, ret;
120
120
 
121
121
    case FILE_TYPE_PIPE:
122
122
      if (!once_only)
123
 
        {
124
 
          NtQueryInformationFile = (PNtQueryInformationFile)
125
 
            GetProcAddress (GetModuleHandle ("ntdll.dll"),
126
 
                            "NtQueryInformationFile");
127
 
          once_only = TRUE;
128
 
        }
 
123
        {
 
124
          NtQueryInformationFile = (PNtQueryInformationFile)
 
125
            GetProcAddress (GetModuleHandle ("ntdll.dll"),
 
126
                            "NtQueryInformationFile");
 
127
          once_only = TRUE;
 
128
        }
129
129
 
130
130
      if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
131
 
        {
132
 
          if (avail)
133
 
            read = TRUE;
134
 
        }
 
131
        {
 
132
          if (avail)
 
133
            read = TRUE;
 
134
        }
135
135
 
136
136
      else
137
 
        {
138
 
          /* It was the write-end of the pipe.  Check if it is writable.
139
 
             If NtQueryInformationFile fails, optimistically assume the pipe is
140
 
             writable.  This could happen on Win9x, where NtQueryInformationFile
141
 
             is not available, or if we inherit a pipe that doesn't permit
142
 
             FILE_READ_ATTRIBUTES access on the write end (I think this should
143
 
             not happen since WinXP SP2; WINE seems fine too).  Otherwise,
144
 
             ensure that enough space is available for atomic writes.  */
 
137
        {
 
138
          /* It was the write-end of the pipe.  Check if it is writable.
 
139
             If NtQueryInformationFile fails, optimistically assume the pipe is
 
140
             writable.  This could happen on Win9x, where NtQueryInformationFile
 
141
             is not available, or if we inherit a pipe that doesn't permit
 
142
             FILE_READ_ATTRIBUTES access on the write end (I think this should
 
143
             not happen since WinXP SP2; WINE seems fine too).  Otherwise,
 
144
             ensure that enough space is available for atomic writes.  */
145
145
          memset (&iosb, 0, sizeof (iosb));
146
146
          memset (&fpli, 0, sizeof (fpli));
147
147
 
148
148
          if (!NtQueryInformationFile
149
149
              || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
150
 
                                         FilePipeLocalInformation)
151
 
              || fpli.WriteQuotaAvailable >= PIPE_BUF
152
 
              || (fpli.OutboundQuota < PIPE_BUF &&
153
 
                  fpli.WriteQuotaAvailable == fpli.OutboundQuota))
154
 
            write = TRUE;
155
 
        }
 
150
                                         FilePipeLocalInformation)
 
151
              || fpli.WriteQuotaAvailable >= PIPE_BUF
 
152
              || (fpli.OutboundQuota < PIPE_BUF &&
 
153
                  fpli.WriteQuotaAvailable == fpli.OutboundQuota))
 
154
            write = TRUE;
 
155
        }
156
156
      break;
157
157
 
158
158
    case FILE_TYPE_CHAR:
159
159
      write = TRUE;
160
160
      if (!(rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
161
 
        break;
 
161
        break;
162
162
 
163
163
      ret = WaitForSingleObject (h, 0);
164
164
      if (ret == WAIT_OBJECT_0)
165
165
        {
166
 
          if (!IsConsoleHandle (h))
167
 
            {
168
 
              read = TRUE;
169
 
              break;
170
 
            }
171
 
 
172
 
          nbuffer = avail = 0;
173
 
          bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
174
 
 
175
 
          /* Screen buffers handles are filtered earlier.  */
176
 
          assert (bRet);
177
 
          if (nbuffer == 0)
178
 
            {
179
 
              except = TRUE;
180
 
              break;
181
 
            }
182
 
 
183
 
          irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
184
 
          bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
185
 
          if (!bRet || avail == 0)
186
 
            {
187
 
              except = TRUE;
188
 
              break;
189
 
            }
190
 
 
191
 
          for (i = 0; i < avail; i++)
192
 
            if (irbuffer[i].EventType == KEY_EVENT)
193
 
              read = TRUE;
194
 
        }
 
166
          if (!IsConsoleHandle (h))
 
167
            {
 
168
              read = TRUE;
 
169
              break;
 
170
            }
 
171
 
 
172
          nbuffer = avail = 0;
 
173
          bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
 
174
 
 
175
          /* Screen buffers handles are filtered earlier.  */
 
176
          assert (bRet);
 
177
          if (nbuffer == 0)
 
178
            {
 
179
              except = TRUE;
 
180
              break;
 
181
            }
 
182
 
 
183
          irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
 
184
          bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
 
185
          if (!bRet || avail == 0)
 
186
            {
 
187
              except = TRUE;
 
188
              break;
 
189
            }
 
190
 
 
191
          for (i = 0; i < avail; i++)
 
192
            if (irbuffer[i].EventType == KEY_EVENT)
 
193
              read = TRUE;
 
194
        }
195
195
      break;
196
196
 
197
197
    default:
275
275
    for (i = 0; i < rfds->fd_count; i++)
276
276
      {
277
277
        fd = rfds->fd_array[i];
278
 
        h = (HANDLE) _get_osfhandle (fd);
279
 
        if (IsConsoleHandle (h)
280
 
            && !GetNumberOfConsoleInputEvents (h, &nbuffer))
281
 
          continue;
 
278
        h = (HANDLE) _get_osfhandle (fd);
 
279
        if (IsConsoleHandle (h)
 
280
            && !GetNumberOfConsoleInputEvents (h, &nbuffer))
 
281
          continue;
282
282
 
283
283
        rbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
284
284
        anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
290
290
    for (i = 0; i < wfds->fd_count; i++)
291
291
      {
292
292
        fd = wfds->fd_array[i];
293
 
        h = (HANDLE) _get_osfhandle (fd);
294
 
        if (IsConsoleHandle (h)
295
 
            && GetNumberOfConsoleInputEvents (h, &nbuffer))
296
 
          continue;
 
293
        h = (HANDLE) _get_osfhandle (fd);
 
294
        if (IsConsoleHandle (h)
 
295
            && GetNumberOfConsoleInputEvents (h, &nbuffer))
 
296
          continue;
297
297
 
298
298
        wbits.in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
299
299
        anyfds_in[fd / CHAR_BIT] |= 1 << (fd & (CHAR_BIT - 1));
322
322
  /* Classify handles.  Create fd sets for sockets, poll the others. */
323
323
  for (i = 0; i < nfds; i++)
324
324
    {
325
 
      WSANETWORKEVENTS ev;
326
 
 
327
325
      if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
328
 
        continue;
 
326
        continue;
329
327
 
330
328
      h = (HANDLE) _get_osfhandle (i);
331
329
      if (!h)
332
330
        {
333
 
          errno = EBADF;
334
 
          return -1;
 
331
          errno = EBADF;
 
332
          return -1;
335
333
        }
336
334
 
337
335
      if (IsSocketHandle (h))
339
337
          int requested = FD_CLOSE;
340
338
 
341
339
          /* See above; socket handles are mapped onto select, but we
342
 
             need to map descriptors to handles.  */
 
340
             need to map descriptors to handles.  */
343
341
          if (rbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
344
 
            {
 
342
            {
345
343
              requested |= FD_READ | FD_ACCEPT;
346
 
              FD_SET ((SOCKET) h, rfds);
347
 
              FD_SET ((SOCKET) h, &handle_rfds);
348
 
            }
 
344
              FD_SET ((SOCKET) h, rfds);
 
345
              FD_SET ((SOCKET) h, &handle_rfds);
 
346
            }
349
347
          if (wbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
350
 
            {
 
348
            {
351
349
              requested |= FD_WRITE | FD_CONNECT;
352
 
              FD_SET ((SOCKET) h, wfds);
353
 
              FD_SET ((SOCKET) h, &handle_wfds);
354
 
            }
 
350
              FD_SET ((SOCKET) h, wfds);
 
351
              FD_SET ((SOCKET) h, &handle_wfds);
 
352
            }
355
353
          if (xbits.in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
356
 
            {
 
354
            {
357
355
              requested |= FD_OOB;
358
 
              FD_SET ((SOCKET) h, xfds);
359
 
              FD_SET ((SOCKET) h, &handle_xfds);
360
 
            }
 
356
              FD_SET ((SOCKET) h, xfds);
 
357
              FD_SET ((SOCKET) h, &handle_xfds);
 
358
            }
361
359
 
362
360
          WSAEventSelect ((SOCKET) h, hEvent, requested);
363
 
          nsock++;
 
361
          nsock++;
364
362
        }
365
363
      else
366
364
        {
367
365
          handle_array[nhandles++] = h;
368
366
 
369
 
          /* Poll now.  If we get an event, do not wait below.  */
 
367
          /* Poll now.  If we get an event, do not wait below.  */
370
368
          if (wait_timeout != 0
371
 
              && win32_poll_handle (h, i, &rbits, &wbits, &xbits))
372
 
            wait_timeout = 0;
 
369
              && win32_poll_handle (h, i, &rbits, &wbits, &xbits))
 
370
            wait_timeout = 0;
373
371
        }
374
372
    }
375
373
 
382
380
         no need to call select again.  */
383
381
      rc = select (0, &handle_rfds, &handle_wfds, &handle_xfds, &tv0);
384
382
      if (rc == 0)
385
 
        {
386
 
          /* Restore the fd_sets for the other select we do below.  */
 
383
        {
 
384
          /* Restore the fd_sets for the other select we do below.  */
387
385
          memcpy (&handle_rfds, rfds, sizeof (fd_set));
388
386
          memcpy (&handle_wfds, wfds, sizeof (fd_set));
389
387
          memcpy (&handle_xfds, xfds, sizeof (fd_set));
390
 
        }
 
388
        }
391
389
      else
392
390
        wait_timeout = 0;
393
391
    }
395
393
  for (;;)
396
394
    {
397
395
      ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
398
 
                                       wait_timeout, QS_ALLINPUT);
 
396
                                       wait_timeout, QS_ALLINPUT);
399
397
 
400
398
      if (ret == WAIT_OBJECT_0 + nhandles)
401
 
        {
 
399
        {
402
400
          /* new input of some other kind */
403
 
          BOOL bRet;
 
401
          BOOL bRet;
404
402
          while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
405
403
            {
406
404
              TranslateMessage (&msg);
407
405
              DispatchMessage (&msg);
408
406
            }
409
 
        }
 
407
        }
410
408
      else
411
 
        break;
 
409
        break;
412
410
    }
413
411
 
414
412
  /* If we haven't done it yet, check the status of the sockets.  */
426
424
  for (i = 0; i < nfds; i++)
427
425
    {
428
426
      if ((anyfds_in[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1)))) == 0)
429
 
        continue;
 
427
        continue;
430
428
 
431
429
      h = (HANDLE) _get_osfhandle (i);
432
430
      if (h != handle_array[nhandles])
433
 
        {
434
 
          /* Perform handle->descriptor mapping.  Don't update rc, as these
435
 
             results are counted in the return value of Winsock's select.  */
 
431
        {
 
432
          /* Perform handle->descriptor mapping.  Don't update rc, as these
 
433
             results are counted in the return value of Winsock's select.  */
436
434
          WSAEventSelect ((SOCKET) h, NULL, 0);
437
435
          if (FD_ISSET (h, &handle_rfds))
438
436
            FD_SET (i, rfds);
440
438
            FD_SET (i, wfds);
441
439
          if (FD_ISSET (h, &handle_xfds))
442
440
            FD_SET (i, xfds);
443
 
        }
 
441
        }
444
442
      else
445
443
        {
446
444
          /* Not a socket.  */
448
446
          win32_poll_handle (h, i, &rbits, &wbits, &xbits);
449
447
          if (rbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
450
448
            {
451
 
              rc++;
452
 
              FD_SET (i, rfds);
453
 
            }
 
449
              rc++;
 
450
              FD_SET (i, rfds);
 
451
            }
454
452
          if (wbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
455
453
            {
456
 
              rc++;
457
 
              FD_SET (i, wfds);
458
 
            }
 
454
              rc++;
 
455
              FD_SET (i, wfds);
 
456
            }
459
457
          if (xbits.out[i / CHAR_BIT] & (1 << (i & (CHAR_BIT - 1))))
460
458
            {
461
 
              rc++;
462
 
              FD_SET (i, xfds);
463
 
            }
 
459
              rc++;
 
460
              FD_SET (i, xfds);
 
461
            }
464
462
        }
465
463
    }
466
464