X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=cbits%2FinputReady.c;h=2949e9494bbef90696f4c1d613018dc5b9f3cf30;hb=0a41af38169035a4359c0c29bc1219af564dce64;hp=79a605a67beb3c024402311921f013f7ebfa0347;hpb=3d39b8130899c46c9c96b941fddb4e4784e860dc;p=ghc-base.git diff --git a/cbits/inputReady.c b/cbits/inputReady.c index 79a605a..2949e94 100644 --- a/cbits/inputReady.c +++ b/cbits/inputReady.c @@ -1,14 +1,12 @@ /* - * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998 + * (c) The GRASP/AQUA Project, Glasgow University, 1994-2002 * - * $Id: inputReady.c,v 1.3 2001/08/17 12:50:34 simonmar Exp $ - * - * hReady Runtime Support + * hWaitForInput Runtime Support */ /* select and supporting types is not Posix */ /* #include "PosixSource.h" */ -#include "HsCore.h" +#include "HsBase.h" /* * inputReady(fd) checks to see whether input is available on the file @@ -16,35 +14,78 @@ * *character* from this file object without blocking?' */ int -inputReady(int fd, int msecs) +inputReady(int fd, int msecs, int isSock) { -#ifndef mingw32_TARGET_OS - int maxfd, ready; - fd_set rfd; - struct timeval tv; -#endif - -#ifdef mingw32_TARGET_OS - return 1; + if +#ifndef mingw32_HOST_OS + ( 1 ) { #else - FD_ZERO(&rfd); - FD_SET(fd, &rfd); - - /* select() will consider the descriptor set in the range of 0 to - * (maxfd-1) - */ - maxfd = fd + 1; - tv.tv_sec = msecs / 1000; - tv.tv_usec = msecs % 1000; - - while ((ready = select(maxfd, &rfd, NULL, NULL, &tv)) < 0 ) { - if (errno != EINTR ) { - return -1; - } - } + ( isSock ) { +#endif + int maxfd, ready; + fd_set rfd; + struct timeval tv; + + FD_ZERO(&rfd); + FD_SET(fd, &rfd); + + /* select() will consider the descriptor set in the range of 0 to + * (maxfd-1) + */ + maxfd = fd + 1; + tv.tv_sec = msecs / 1000; + tv.tv_usec = (msecs % 1000) * 1000; + + while ((ready = select(maxfd, &rfd, NULL, NULL, &tv)) < 0 ) { + if (errno != EINTR ) { + return -1; + } + } + + /* 1 => Input ready, 0 => not ready, -1 => error */ + return (ready); + } +#ifdef mingw32_HOST_OS + else { + DWORD rc; + HANDLE hFile = (HANDLE)_get_osfhandle(fd); + DWORD avail; - /* 1 => Input ready, 0 => not ready, -1 => error */ - return (ready); + // WaitForMultipleObjects() works for Console input, but it + // doesn't work for pipes (it always returns WAIT_OBJECT_0 + // even when no data is available). There doesn't seem to be + // an easy way to distinguish the two kinds of HANDLE, so we + // try to detect pipe input first, and if that fails we try + // WaitForMultipleObjects(). + // + rc = PeekNamedPipe( hFile, NULL, 0, NULL, &avail, NULL ); + if (rc != 0) { + if (avail != 0) { + return 1; + } else { + return 0; + } + } else { + rc = GetLastError(); + if (rc == ERROR_BROKEN_PIPE) { + return 1; // this is probably what we want + } + if (rc != ERROR_INVALID_HANDLE) { + return -1; + } + } + rc = WaitForMultipleObjects( 1, + &hFile, + TRUE, /* wait all */ + msecs); /*millisecs*/ + + /* 1 => Input ready, 0 => not ready, -1 => error */ + switch (rc) { + case WAIT_TIMEOUT: return 0; + case WAIT_OBJECT_0: return 1; + default: return -1; + } + } #endif -} +}