Remove Control.Parallel*, now in package parallel
[packages/random.git] / cbits / inputReady.c
1 /*
2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-2002
3 *
4 * hWaitForInput Runtime Support
5 */
6
7 /* select and supporting types is not Posix */
8 /* #include "PosixSource.h" */
9 #include "HsBase.h"
10
11 /*
12 * inputReady(fd) checks to see whether input is available on the file
13 * descriptor 'fd'. Input meaning 'can I safely read at least a
14 * *character* from this file object without blocking?'
15 */
16 int
17 fdReady(int fd, int write, int msecs, int isSock)
18 {
19 if
20 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
21 ( isSock ) {
22 #else
23 ( 1 ) {
24 #endif
25 int maxfd, ready;
26 fd_set rfd, wfd;
27 struct timeval tv;
28
29 FD_ZERO(&rfd);
30 FD_ZERO(&wfd);
31 if (write) {
32 FD_SET(fd, &wfd);
33 } else {
34 FD_SET(fd, &rfd);
35 }
36
37 /* select() will consider the descriptor set in the range of 0 to
38 * (maxfd-1)
39 */
40 maxfd = fd + 1;
41 tv.tv_sec = msecs / 1000;
42 tv.tv_usec = (msecs % 1000) * 1000;
43
44 while ((ready = select(maxfd, &rfd, &wfd, NULL, &tv)) < 0 ) {
45 if (errno != EINTR ) {
46 return -1;
47 }
48 }
49
50 /* 1 => Input ready, 0 => not ready, -1 => error */
51 return (ready);
52 }
53 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
54 else {
55 DWORD rc;
56 HANDLE hFile = (HANDLE)_get_osfhandle(fd);
57 DWORD avail;
58
59 // WaitForMultipleObjects() works for Console input, but it
60 // doesn't work for pipes (it always returns WAIT_OBJECT_0
61 // even when no data is available). There doesn't seem to be
62 // an easy way to distinguish the two kinds of HANDLE, so we
63 // try to detect pipe input first, and if that fails we try
64 // WaitForMultipleObjects().
65 //
66 rc = PeekNamedPipe( hFile, NULL, 0, NULL, &avail, NULL );
67 if (rc != 0) {
68 if (avail != 0) {
69 return 1;
70 } else {
71 return 0;
72 }
73 } else {
74 rc = GetLastError();
75 if (rc == ERROR_BROKEN_PIPE) {
76 return 1; // this is probably what we want
77 }
78 if (rc != ERROR_INVALID_HANDLE) {
79 return -1;
80 }
81 }
82
83 rc = WaitForMultipleObjects( 1,
84 &hFile,
85 TRUE, /* wait all */
86 msecs); /*millisecs*/
87
88 /* 1 => Input ready, 0 => not ready, -1 => error */
89 switch (rc) {
90 case WAIT_TIMEOUT: return 0;
91 case WAIT_OBJECT_0: return 1;
92 default: return -1;
93 }
94 }
95 #endif
96 }