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