[project @ 1998-04-10 11:33:12 by simonm]
[ghc-hetmet.git] / ghc / lib / std / cbits / inputReady.lc
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1994
3 %
4 \subsection[inputReady.lc]{hReady Runtime Support}
5
6 \begin{code}
7
8 /* select and supporting types is not */
9 #ifndef _AIX
10 #define NON_POSIX_SOURCE  
11 #endif
12
13 #include "rtsdefs.h"
14 #include "stgio.h"
15
16 #ifdef HAVE_SYS_TYPES_H
17 #include <sys/types.h>
18 #endif
19
20 #ifdef _AIX 
21 /* this is included from sys/types.h only if _BSD is defined. */
22 /* Since it is not, I include it here. - andre */
23 #include <sys/select.h>
24 #endif
25
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29
30 #ifdef HAVE_FCNTL_H
31 #include <fcntl.h>
32 #endif
33
34 #ifdef HAVE_SYS_TIME_H
35 #include <sys/time.h>
36 #endif
37
38 StgInt
39 inputReady(fp, nsecs)
40 StgForeignObj fp;
41 StgInt nsecs;
42 {
43     int flags, c, fd, maxfd, ready;
44     fd_set rfd;
45     struct timeval tv;
46
47     if (feof((FILE *) fp))
48         return 0;
49
50     fd = fileno((FILE *)fp);
51
52     /* Get the original file status flags */
53     while ((flags = fcntl(fd, F_GETFL)) < 0) {
54         /* highly unlikely */
55         if (errno != EINTR) {
56             cvtErrno();
57             stdErrno();
58             return -1;
59         }
60     }
61
62     /* If it's not already non-blocking, make it so */
63     if (!(flags & O_NONBLOCK)) {
64         while (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
65             /* still highly unlikely */
66             if (errno != EINTR) {
67                 cvtErrno();
68                 stdErrno();
69                 return -1;
70             }
71         }
72     }
73     /* Now try to get a character */
74     FD_ZERO(&rfd);
75     FD_SET(fd, &rfd);
76     /* select() will consider the descriptor set in the range of 0 to (maxfd-1) */
77     maxfd = fd + 1;
78     tv.tv_usec = 0;
79     tv.tv_sec  = nsecs;
80     while ((ready = select(maxfd, &rfd, NULL, NULL, &tv)) < 0 ) {
81       if (errno != EINTR ) {
82                 cvtErrno();
83                 stdErrno();
84                 ready = -1;
85                 break;
86       }
87    }
88    /*
89     while ((c = getc((FILE *) fp)) == EOF && errno == EINTR)
90         clearerr((FILE *) fp);
91    */
92
93     /* If we made it non-blocking for this, switch it back */
94     if (!(flags & O_NONBLOCK)) {
95         while (fcntl(fd, F_SETFL, flags) < 0) {
96             /* still highly unlikely */
97             if (errno != EINTR) {
98                 cvtErrno();
99                 stdErrno();
100                 return -1;
101             }
102         }
103     }
104     /* 1 => Input ready, 0 => time expired  (-1 error) */
105     return (ready);
106
107     /*
108     if (c == EOF) {
109         if (errno == EAGAIN || feof((FILE *) fp)) {
110             clearerr((FILE *) fp);
111             return 0;
112         } else {
113             cvtErrno();
114             stdErrno();
115             return -1;
116         }
117     } else if (ungetc(c, (FILE *) fp) == EOF) {
118         cvtErrno();
119         stdErrno();
120         return -1;
121     } else
122         return 1;
123     */
124 }
125
126 \end{code}