File: io.c

package info (click to toggle)
mgetty 1.2.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,872 kB
  • sloc: ansic: 42,728; sh: 6,487; perl: 6,262; makefile: 1,457; tcl: 756; lisp: 283
file content (210 lines) | stat: -rw-r--r-- 4,549 bytes parent folder | download | duplicates (5)
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.3 2014/01/28 13:42:57 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>
# if !defined(_AIX) && !defined(BSD)
int poll _PROTO(( struct pollfd fds[], unsigned long nfds, int timeout ));
# endif		/* AIX / Linux */
#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 );
}