[project @ 1997-05-26 20:49:19 by andre]
[ghc-hetmet.git] / ghc / lib / cbits / inputReady.lc
index fc8184e..2fa65a7 100644 (file)
@@ -5,6 +5,8 @@
 
 \begin{code}
 
+/* select and supporting types is not */
+#define NON_POSIX_SOURCE  
 #include "rtsdefs.h"
 #include "stgio.h"
 
 #include <sys/types.h>
 #endif
 
+#ifdef _AIX 
+/* this is included from sys/types.h only if _BSD is defined. */
+/* Since it is not, I include it here. - andre */
+#include <sys/select.h>
+#endif
+
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 #include <fcntl.h>
 #endif
 
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
 StgInt
-inputReady(fp)
-StgAddr fp;
+inputReady(fp, nsecs)
+StgForeignObj fp;
+StgInt nsecs;
 {
-    int flags;
-    int c;
+    int flags, c, fd, maxfd, ready;
+    fd_set rfd;
+    struct timeval tv;
 
     if (feof((FILE *) fp))
        return 0;
 
+    fd = fileno((FILE *)fp);
+
     /* Get the original file status flags */
-    while ((flags = fcntl(fileno((FILE *) fp), F_GETFL)) < 0) {
+    while ((flags = fcntl(fd, F_GETFL)) < 0) {
        /* highly unlikely */
        if (errno != EINTR) {
            cvtErrno();
@@ -42,7 +58,7 @@ StgAddr fp;
 
     /* If it's not already non-blocking, make it so */
     if (!(flags & O_NONBLOCK)) {
-       while (fcntl(fileno((FILE *) fp), F_SETFL, flags | O_NONBLOCK) < 0) {
+       while (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
            /* still highly unlikely */
            if (errno != EINTR) {
                cvtErrno();
@@ -52,12 +68,28 @@ StgAddr fp;
        }
     }
     /* Now try to get a character */
+    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_usec = 0;
+    tv.tv_sec  = nsecs;
+    while ((ready = select(maxfd, &rfd, NULL, NULL, &tv)) < 0 ) {
+      if (errno != EINTR ) {
+               cvtErrno();
+               stdErrno();
+                ready = -1;
+               break;
+      }
+   }
+   /*
     while ((c = getc((FILE *) fp)) == EOF && errno == EINTR)
        clearerr((FILE *) fp);
+   */
 
     /* If we made it non-blocking for this, switch it back */
     if (!(flags & O_NONBLOCK)) {
-       while (fcntl(fileno((FILE *) fp), F_SETFL, flags) < 0) {
+       while (fcntl(fd, F_SETFL, flags) < 0) {
            /* still highly unlikely */
            if (errno != EINTR) {
                cvtErrno();
@@ -66,7 +98,10 @@ StgAddr fp;
            }
        }
     }
+    /* 1 => Input ready, 0 => time expired  (-1 error) */
+    return (ready);
 
+    /*
     if (c == EOF) {
        if (errno == EAGAIN || feof((FILE *) fp)) {
            clearerr((FILE *) fp);
@@ -82,6 +117,7 @@ StgAddr fp;
        return -1;
     } else
        return 1;
+    */
 }
 
 \end{code}