[project @ 1998-12-02 13:17:09 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.3 1998/12/02 13:27:42 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 /*
40  * inputReady(ptr, msecs) checks to see whether input is available
41  * on the file object 'ptr', timing out after (approx.) 'msec' milliseconds.
42  * Input meaning 'can I safely read at least a *character* from this file
43  * object without blocking?'
44  * 
45  * If the file object has a non-empty buffer, the test is trivial. If not,
46  * we select() on the (readable) file descriptor.
47  *
48  * Notice that for file descriptors connected to ttys in non-canonical mode
49  * (i.e., it's buffered), inputReady will not return true until a *complete
50  * line* can be read.
51  */
52
53 StgInt
54 inputReady(ptr, msecs)
55 StgForeignPtr ptr;
56 StgInt msecs;
57 {
58     IOFileObject* fo = (IOFileObject*)ptr;
59     int c, fd, maxfd, ready;
60     fd_set rfd;
61     struct timeval tv;
62
63     if ( FILEOBJ_IS_EOF(fo) )
64         return 0;
65
66     if ( !FILEOBJ_BUFFER_EMPTY(fo) ) {
67            /* Don't look any further, there's stuff in the buffer */
68            return 1;
69     }
70
71     fd = fo->fd;
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_sec  = msecs / 1000;
79     tv.tv_usec = msecs % 1000;
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     /* 1 => Input ready, 0 => time expired  (-1 error) */
90     return (ready);
91
92 }