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