-
Notifications
You must be signed in to change notification settings - Fork 1
/
io.c
210 lines (174 loc) · 4.41 KB
/
io.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#ident "$Id: io.c,v 4.2 1997/06/28 20:41:29 gert Exp $ Copyright (c) Gert Doering"
/* io.c
*
* This module contains a few low-level I/O functions
* (will be extended)
*/
#include <stdio.h>
#include <unistd.h>
#include "syslibs.h"
#include <signal.h>
#include <errno.h>
#include "mgetty.h"
/* warning: these includes have to appear *after* "mgetty.h"! */
#ifdef USE_POLL
# include <poll.h>
# ifndef _AIX
int poll _PROTO(( struct pollfd fds[], unsigned long nfds, int timeout ));
# endif /* AIX */
#endif /* USE_POLL */
/* SCO Unix defines XENIX as well, which will confuse the code below */
#if defined(M_XENIX) && defined(M_UNIX)
# undef M_XENIX
#endif
#ifdef USE_SELECT
# include <string.h>
# if defined (linux) || defined (sunos4) || defined (SVR4) || \
defined (__hpux) || defined (MEIBE) || defined(sgi) || \
defined (ISC) || defined (BSD) || defined(sysV68) || \
defined(m88k) || defined(M_XENIX)
# include <sys/types.h>
# include <sys/time.h>
# ifdef ISC
# include <sys/bsdtypes.h>
# endif /* ISC */
# ifdef M_XENIX
# include <sys/select.h>
# endif
# else /* not sys/types.h + sys/time.h */
# include <sys/select.h>
# endif
# ifdef NEED_BZERO
# define bzero( ptr, length ) memset( ptr, 0, length )
# endif
#endif /* USE_SELECT */
void delay _P1( (waittime),
int waittime ) /* wait waittime milliseconds */
{
#ifdef USE_USLEEP
usleep( waittime * 1000 );
#else
#ifdef USE_POLL
struct pollfd sdummy;
poll( &sdummy, 0, waittime );
#else
#ifdef USE_NAP
nap( (long) waittime );
#else
#ifdef USE_SELECT
struct timeval s;
s.tv_sec = waittime / 1000;
s.tv_usec = (waittime % 1000) * 1000;
select( 0, (fd_set *) NULL, (fd_set *) NULL, (fd_set *) NULL, &s );
#else /* neither poll nor nap nor select available */
if ( waittime < 2000 ) waittime = 2000; /* round up */
sleep( waittime / 1000); /* a sleep of 1 may not sleep at all */
#endif /* use select */
#endif /* use nap */
#endif /* use poll */
#endif /* use usleep */
}
/* check_for_input( open file deskriptor )
*
* returns TRUE if there's something to read on filedes, FALSE otherwise
*/
boolean check_for_input _P1( (filedes),
int filedes )
{
#ifdef USE_SELECT
fd_set readfds;
struct timeval timeout;
#endif
#ifdef USE_POLL
struct pollfd fds;
#endif
int ret;
#ifdef USE_SELECT
FD_ZERO( &readfds );
FD_SET( filedes, &readfds );
timeout.tv_sec = timeout.tv_usec = 0;
ret = select( FD_SETSIZE , &readfds, NULL, NULL, &timeout );
#else
# ifdef USE_POLL
fds.fd = filedes;
fds.events = POLLIN;
fds.revents= 0;
ret = poll( &fds, 1, 0 );
# else
ret = 0; /* CHEAT! */
# endif
#endif
if ( ret < 0 ) lprintf( L_ERROR, "poll / select failed" );
return ( ret > 0 );
}
#if !defined( USE_SELECT) && !defined( USE_POLL )
static RETSIGTYPE wfi_timeout(SIG_HDLR_ARGS) {}
#endif
/* wait until a character is available
* where select() or poll() exists, no characters will be read,
* if only read() can be used, at least one character will be dropped
*
* return TRUE if data is found, FALSE if "msecs" milliseconds have passed
*/
boolean wait_for_input _P2( (fd, msecs), int fd, int msecs )
{
#ifdef USE_SELECT
fd_set readfds;
struct timeval timeout, *tptr;
#endif
#ifdef USE_POLL
struct pollfd fds;
int timeout;
#endif
int slct;
#ifdef USE_SELECT
FD_ZERO( &readfds );
FD_SET( fd, &readfds );
if ( msecs >= 0 )
{
timeout.tv_sec = msecs / 1000;
timeout.tv_usec = (msecs % 1000) * 1000; /* microsecs! */
tptr = &timeout;
}
else
tptr = NULL;
slct = select( FD_SETSIZE, &readfds, NULL, NULL, tptr );
lprintf( L_JUNK, "select returned %d", slct );
#else /* use poll */
# ifdef USE_POLL
if ( msecs < 0 ) timeout = -1;
else timeout = msecs;
fds.fd = fd;
fds.events = POLLIN;
fds.revents= 0;
slct = poll( &fds, 1, timeout );
lprintf( L_JUNK, "poll returned %d", slct );
# else
{
char t;
int oerrno;
if ( msecs > 0 )
{
signal( SIGALRM, wfi_timeout );
alarm( (msecs+999)/1000 );
}
slct = read( fd, &t, 1 );
oerrno = errno;
alarm(0); signal( SIGALRM, SIG_DFL );
errno = oerrno;
if ( slct < 0 )
{
if ( errno == EINTR )
lprintf( L_JUNK, "read: timeout" );
else
lprintf( L_ERROR, "read: error" );
}
else
{
lprintf(L_JUNK, "read returned: "); lputc(L_JUNK, t );
}
}
# endif
#endif
return ( slct>0 );
}