[project @ 1999-09-12 16:24:46 by sof]
[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.5 1999/09/12 16:24:46 sof 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 #ifndef mingw32_TARGET_OS
61     fd_set rfd;
62     struct timeval tv;
63 #endif
64
65     if ( FILEOBJ_IS_EOF(fo) )
66         return 0;
67
68     if ( !FILEOBJ_BUFFER_EMPTY(fo) ) {
69            /* Don't look any further, there's stuff in the buffer */
70            return 1;
71     }
72
73 #ifdef mingw32_TARGET_OS
74     return 1;
75 #else
76     fd = fo->fd;
77
78     /* Now try to get a character */
79     FD_ZERO(&rfd);
80     FD_SET(fd, &rfd);
81     /* select() will consider the descriptor set in the range of 0 to (maxfd-1) */
82     maxfd = fd + 1;
83     tv.tv_sec  = msecs / 1000;
84     tv.tv_usec = msecs % 1000;
85     while ((ready = select(maxfd, &rfd, NULL, NULL, &tv)) < 0 ) {
86       if (errno != EINTR ) {
87                 cvtErrno();
88                 stdErrno();
89                 ready = -1;
90                 break;
91       }
92    }
93
94     /* 1 => Input ready, 0 => time expired  (-1 error) */
95     return (ready);
96 #endif
97 }