[project @ 1998-02-02 17:27:26 by simonm]
[ghc-hetmet.git] / ghc / lib / std / cbits / inputReady.lc
diff --git a/ghc/lib/std/cbits/inputReady.lc b/ghc/lib/std/cbits/inputReady.lc
new file mode 100644 (file)
index 0000000..8baa582
--- /dev/null
@@ -0,0 +1,126 @@
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1994
+%
+\subsection[inputReady.lc]{hReady Runtime Support}
+
+\begin{code}
+
+/* select and supporting types is not */
+#ifndef _AIX
+#define NON_POSIX_SOURCE  
+#endif
+
+#include "rtsdefs.h"
+#include "stgio.h"
+
+#ifdef HAVE_SYS_TYPES_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
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+StgInt
+inputReady(fp, nsecs)
+StgForeignObj fp;
+StgInt nsecs;
+{
+    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(fd, F_GETFL)) < 0) {
+       /* highly unlikely */
+       if (errno != EINTR) {
+           cvtErrno();
+           stdErrno();
+           return -1;
+       }
+    }
+
+    /* If it's not already non-blocking, make it so */
+    if (!(flags & O_NONBLOCK)) {
+       while (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+           /* still highly unlikely */
+           if (errno != EINTR) {
+               cvtErrno();
+               stdErrno();
+               return -1;
+           }
+       }
+    }
+    /* 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(fd, F_SETFL, flags) < 0) {
+           /* still highly unlikely */
+           if (errno != EINTR) {
+               cvtErrno();
+               stdErrno();
+               return -1;
+           }
+       }
+    }
+    /* 1 => Input ready, 0 => time expired  (-1 error) */
+    return (ready);
+
+    /*
+    if (c == EOF) {
+       if (errno == EAGAIN || feof((FILE *) fp)) {
+           clearerr((FILE *) fp);
+           return 0;
+       } else {
+           cvtErrno();
+           stdErrno();
+           return -1;
+       }
+    } else if (ungetc(c, (FILE *) fp) == EOF) {
+       cvtErrno();
+       stdErrno();
+       return -1;
+    } else
+       return 1;
+    */
+}
+
+\end{code}