* clear out some warnings by gcc 9.3.1.
[alpine.git] / pico / osdep / raw.c
blob8a194f8fd83c6aa9e62eafea186ffc0edd7734ac
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: raw.c 761 2007-10-23 22:35:18Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006 University of Washington
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * ========================================================================
19 * TTY setup routines.
22 #include <system.h>
23 #include <general.h>
25 #include "../estruct.h"
27 #include "raw.h"
30 #if HAS_TERMIOS
32 * These are the TERMIOS-style (POSIX) routines.
35 static struct termios _raw_tty, _original_tty;
37 #elif HAS_TERMIO
39 * These are the TERMIO-style (System V) routines.
42 static struct termio _raw_tty, _original_tty;
44 #else /* RAW_BSD */
46 * These are for the BSD-style routines.
49 static struct sgttyb _raw_tty, _original_tty;
50 static struct ltchars _raw_ltchars, _original_ltchars;
51 static struct tchars _raw_tchars, _original_tchars;
52 static int _raw_lmode, _original_lmode;
54 #endif
57 * current raw state
59 static short _inraw = 0;
62 * Set up the tty driver
64 * Args: state -- which state to put it in. 1 means go into raw (cbreak),
65 * 0 out of raw.
67 * Result: returns 0 if successful and -1 if not.
69 int
70 Raw(int state)
72 /** state is either ON or OFF, as indicated by call **/
73 /* Check return code only on first call. If it fails we're done for and
74 if it goes OK the others will probably go OK too. */
76 if(state == 0 && _inraw){
77 /*----- restore state to original -----*/
79 #if HAS_TERMIOS
81 if(tcsetattr(STDIN_FD, TCSADRAIN, &_original_tty) < 0)
82 return -1;
84 #elif HAS_TERMIO
86 if(ioctl(STDIN_FD, TCSETAW, &_original_tty) < 0)
87 return(-1);
89 #else /* RAW_BSD */
91 if(ioctl(STDIN_FD, TIOCSETP, &_original_tty) < 0)
92 return(-1);
94 (void)ioctl(STDIN_FD, TIOCSLTC, &_original_ltchars);
95 (void)ioctl(STDIN_FD, TIOCSETC, &_original_tchars);
96 (void)ioctl(STDIN_FD, TIOCLSET, &_original_lmode);
98 #endif
100 _inraw = 0;
102 else if(state == 1 && ! _inraw){
103 /*----- Go into raw mode (cbreak actually) ----*/
105 #if HAS_TERMIOS
107 if(tcgetattr(STDIN_FD, &_original_tty) < 0)
108 return -1;
110 tcgetattr(STDIN_FD, &_raw_tty);
111 _raw_tty.c_lflag &= ~(ICANON | ECHO | IEXTEN); /* noecho raw mode */
112 _raw_tty.c_lflag &= ~ISIG; /* disable signals */
113 _raw_tty.c_iflag &= ~ICRNL; /* turn off CR->NL on input */
114 _raw_tty.c_oflag &= ~ONLCR; /* turn off NL->CR on output */
116 _raw_tty.c_cc[VMIN] = '\01'; /* min # of chars to queue */
117 _raw_tty.c_cc[VTIME] = '\0'; /* min time to wait for input*/
118 _raw_tty.c_cc[VINTR] = ctrl('C'); /* make it our special char */
119 _raw_tty.c_cc[VQUIT] = 0;
120 _raw_tty.c_cc[VSUSP] = 0;
121 tcsetattr(STDIN_FD, TCSADRAIN, &_raw_tty);
123 #elif HAS_TERMIO
125 if(ioctl(STDIN_FD, TCGETA, &_original_tty) < 0)
126 return(-1);
128 (void)ioctl(STDIN_FD, TCGETA, &_raw_tty); /** again! **/
129 _raw_tty.c_lflag &= ~(ICANON | ECHO); /* noecho raw mode */
130 _raw_tty.c_lflag &= ~ISIG; /* disable signals */
131 _raw_tty.c_iflag &= ~ICRNL; /* turn off CR->NL on input */
132 _raw_tty.c_oflag &= ~ONLCR; /* turn off NL->CR on output */
133 _raw_tty.c_cc[VMIN] = 1; /* min # of chars to queue */
134 _raw_tty.c_cc[VTIME] = 0; /* min time to wait for input*/
135 _raw_tty.c_cc[VINTR] = ctrl('C'); /* make it our special char */
136 _raw_tty.c_cc[VQUIT] = 0;
137 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
139 #else /* RAW_BSD */
140 if(ioctl(STDIN_FD, TIOCGETP, &_original_tty) < 0)
141 return(-1);
143 (void)ioctl(STDIN_FD, TIOCGETP, &_raw_tty);
144 (void)ioctl(STDIN_FD, TIOCGETC, &_original_tchars);
145 (void)ioctl(STDIN_FD, TIOCGETC, &_raw_tchars);
146 (void)ioctl(STDIN_FD, TIOCGLTC, &_original_ltchars);
147 (void)ioctl(STDIN_FD, TIOCGLTC, &_raw_ltchars);
148 (void)ioctl(STDIN_FD, TIOCLGET, &_original_lmode);
149 (void)ioctl(STDIN_FD, TIOCLGET, &_raw_lmode);
151 _raw_tty.sg_flags &= ~(ECHO); /* echo off */
152 _raw_tty.sg_flags |= CBREAK; /* raw on */
153 _raw_tty.sg_flags &= ~CRMOD; /* Turn off CR -> LF mapping */
155 _raw_tchars.t_intrc = -1; /* Turn off ^C and ^D */
156 _raw_tchars.t_eofc = -1;
158 _raw_ltchars.t_lnextc = -1; /* Turn off ^V so we can use it */
159 _raw_ltchars.t_dsuspc = -1; /* Turn off ^Y so we can use it */
160 _raw_ltchars.t_suspc = -1; /* Turn off ^Z; we just read 'em */
161 _raw_ltchars.t_werasc = -1; /* Turn off ^w word erase */
162 _raw_ltchars.t_rprntc = -1; /* Turn off ^R reprint line */
163 _raw_ltchars.t_flushc = -1; /* Turn off ^O output flush */
165 (void)ioctl(STDIN_FD, TIOCSETP, &_raw_tty);
166 (void)ioctl(STDIN_FD, TIOCSLTC, &_raw_ltchars);
167 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
168 (void)ioctl(STDIN_FD, TIOCLSET, &_raw_lmode);
169 #endif
170 _inraw = 1;
173 return(0);
178 * Set up the tty driver to use XON/XOFF flow control
180 * Args: state -- True to make sure XON/XOFF turned on, FALSE off.
182 * Result: none.
184 void
185 xonxoff_proc(int state)
187 if(_inraw){
188 if(state){
189 #if HAS_TERMIOS
191 if(!(_raw_tty.c_iflag & IXON)){
192 _raw_tty.c_iflag |= IXON;
193 tcsetattr (STDIN_FD, TCSADRAIN, &_raw_tty);
196 #elif HAS_TERMIO
198 if(!(_raw_tty.c_iflag & IXON)){
199 _raw_tty.c_iflag |= IXON; /* turn ON ^S/^Q on input */
200 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
202 #else /* RAW_BSD */
204 if(_raw_tchars.t_startc == -1 || _raw_tchars.t_stopc == -1){
205 _raw_tchars.t_startc = 'Q' - '@'; /* Turn ON ^S/^Q */
206 _raw_tchars.t_stopc = 'S' - '@';
207 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
210 #endif
212 else{
213 #if HAS_TERMIOS
215 if(_raw_tty.c_iflag & IXON){
216 _raw_tty.c_iflag &= ~IXON; /* turn off ^S/^Q on input */
217 tcsetattr (STDIN_FD, TCSADRAIN, &_raw_tty);
220 #elif HAS_TERMIO
222 if(_raw_tty.c_iflag & IXON){
223 _raw_tty.c_iflag &= ~IXON; /* turn off ^S/^Q on input */
224 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
227 #else /* RAW_BSD */
228 if(!(_raw_tchars.t_startc == -1 && _raw_tchars.t_stopc == -1)){
229 _raw_tchars.t_startc = -1; /* Turn off ^S/^Q */
230 _raw_tchars.t_stopc = -1;
231 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
233 #endif
240 * Set up the tty driver to do LF->CR translation
242 * Args: state -- True to turn on translation, false to write raw LF's
244 * Result: none.
246 void
247 crlf_proc(int state)
249 if(_inraw){
250 if(state){ /* turn ON NL->CR on output */
251 #if HAS_TERMIOS
253 if(!(_raw_tty.c_oflag & ONLCR)){
254 _raw_tty.c_oflag |= ONLCR;
255 tcsetattr (STDIN_FD, TCSADRAIN, &_raw_tty);
258 #elif HAS_TERMIO
260 if(!(_raw_tty.c_oflag & ONLCR)){
261 _raw_tty.c_oflag |= ONLCR;
262 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
265 #else /* RAW_BSD */
266 if(!(_raw_tty.sg_flags & CRMOD)){
267 _raw_tty.sg_flags |= CRMOD;
268 (void)ioctl(STDIN_FD, TIOCSETP, &_raw_tty);
270 #endif
272 else{ /* turn OFF NL-CR on output */
273 #if HAS_TERMIOS
275 if(_raw_tty.c_oflag & ONLCR){
276 _raw_tty.c_oflag &= ~ONLCR;
277 tcsetattr (STDIN_FD, TCSADRAIN, &_raw_tty);
280 #elif HAS_TERMIO
282 if(_raw_tty.c_oflag & ONLCR){
283 _raw_tty.c_oflag &= ~ONLCR;
284 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
287 #else /* RAW_BSD */
289 if(_raw_tty.sg_flags & CRMOD){
290 _raw_tty.sg_flags &= ~CRMOD;
291 (void)ioctl(STDIN_FD, TIOCSETP, &_raw_tty);
294 #endif
301 * Set up the tty driver to handle interrupt char
303 * Args: state -- True to turn on interrupt char, false to not
305 * Result: tty driver that'll send us SIGINT or not
307 void
308 intr_proc(int state)
310 if(_inraw){
311 if(state){
312 #if HAS_TERMIOS
314 _raw_tty.c_lflag |= ISIG; /* enable signals */
315 tcsetattr(STDIN_FD, TCSADRAIN, &_raw_tty);
317 #elif HAS_TERMIO
319 _raw_tty.c_lflag |= ISIG; /* enable signals */
320 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
322 #else /* RAW_BSD */
324 _raw_tchars.t_intrc = ctrl('C');
325 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
327 #endif
329 else{
330 #if HAS_TERMIOS
332 _raw_tty.c_lflag &= ~ISIG; /* disable signals */
333 tcsetattr(STDIN_FD, TCSADRAIN, &_raw_tty);
335 #elif HAS_TERMIO
337 _raw_tty.c_lflag &= ~ISIG; /* disable signals */
338 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
340 #else /* RAW_BSD */
341 _raw_tchars.t_intrc = -1;
342 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
343 #endif
350 * Discard any pending input characters
352 * Args: none
354 * Result: pending input buffer flushed
356 void
357 flush_input(void)
359 #if HAS_TERMIOS
361 tcflush(STDIN_FD, TCIFLUSH);
363 #elif HAS_TERMIO
365 ioctl(STDIN_FD, TCFLSH, 0);
367 #else /* RAW_BSD */
369 #ifdef TIOCFLUSH
370 #ifdef FREAD
371 int i = FREAD;
372 #else
373 int i = 1;
374 #endif
375 ioctl(STDIN_FD, TIOCFLUSH, &i);
376 #endif /* TIOCFLUSH */
378 #endif
383 * Turn off hi bit stripping
385 void
386 bit_strip_off(void)
388 #if HAS_TERMIOS
390 _raw_tty.c_iflag &= ~ISTRIP;
391 tcsetattr(STDIN_FD, TCSADRAIN, &_raw_tty);
393 #elif HAS_TERMIO
395 /* no op */
397 #else /* RAW_BSD */
399 #ifdef LPASS8
400 _raw_lmode |= LPASS8;
401 #endif
403 #ifdef LPASS8OUT
404 _raw_lmode |= LPASS8OUT;
405 #endif
407 (void)ioctl(STDIN_FD, TIOCLSET, &_raw_lmode);
409 #endif
414 * Turn off quit character (^\) if possible
416 void
417 quit_char_off(void)
419 #if HAS_TERMIOS
421 #elif HAS_TERMIO
423 #else /* RAW_BSD */
424 _raw_tchars.t_quitc = -1;
425 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
426 #endif
431 * Returns TRUE if tty is < 4800, 0 otherwise.
434 ttisslow(void)
436 #if HAS_TERMIOS
438 return(cfgetospeed(&_raw_tty) < B4800);
440 #elif HAS_TERMIO
442 return((_raw_tty.c_cflag&CBAUD) < (unsigned int)B4800);
444 #else /* RAW_BSD */
446 return((int)_raw_tty.sg_ispeed < B4800);
448 #endif