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