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
|
/* WRITE TTY ROUTINES -- Routine to get user's tty in and out of cbreak mode.
*/
#include "write.h"
#ifdef F_TERMIO
#include <termio.h>
#endif /*F_TERMIO*/
#ifdef F_TERMIOS
#include <termios.h>
#endif /*F_TERMIOS*/
#ifdef F_STTY
#include <sgtty.h>
#endif /*F_STTY*/
#if !defined(TCFLSH) && !defined(TCIFLUSH)
#include <sys/file.h>
#endif
char eof_char; /* User's end of file character */
char bs_char; /* User's backspace character */
char kill_char; /* User's kill character */
/* CBREAK: cbreak(TRUE) turns on cbreak mode, cbreak(FALSE) restores the
* original tty modes.
*/
#ifdef F_STTY
void cbreak(bool flag)
{
struct tchars ctrlchars;
static struct sgttyb sgtty;
static tfg;
if (flag)
{
/* Get current modes */
ioctl(0,TIOCGETP,&sgtty);
tfg= sgtty.sg_flags;
bs_char= sgtty.sg_erase;
kill_char= sgtty.sg_kill;
ioctl(0,TIOCGETC,&ctrlchars);
eof_char= ctrlchars.t_eofc;
/* Remember that we are in cbreak mode */
in_cbreak= TRUE;
/* Turn on cbreak mode */
sgtty.sg_flags &= ~ECHO;
sgtty.sg_flags |= CBREAK;
ioctl(0,TIOCSETN,&sgtty);
}
else
{
/* Turn off cbreak mode - that is restore original modes */
sgtty.sg_flags= tfg;
ioctl(0,TIOCSETN,&sgtty);
in_cbreak= FALSE;
}
}
#endif /*F_STTY*/
#ifdef F_TERMIO
void cbreak(bool flag)
{
static struct termio tio;
static tfg;
static char eol_char;
if (flag)
{
/* Get current modes */
ioctl(0,TCGETA,&tio);
tfg= tio.c_lflag;
eof_char= tio.c_cc[VEOF];
eol_char= tio.c_cc[VEOL];
bs_char= tio.c_cc[VERASE];
kill_char= tio.c_cc[VKILL];
/* Remember that we are in cbreak mode */
in_cbreak= TRUE;
/* Turn on cbreak mode - that is turn off ICANON */
tio.c_lflag= tfg & ~ICANON;
tio.c_lflag &= ~ECHO;
tio.c_cc[VEOF]= 1;
tio.c_cc[VEOL]= 0;
ioctl(0,TCSETA,&tio);
}
else
{
/* Turn off cbreak mode - that is restore original modes */
tio.c_lflag= tfg;
tio.c_cc[VEOF]= eof_char;
tio.c_cc[VEOL]= eol_char;
ioctl(0,TCSETA,&tio);
in_cbreak= FALSE;
}
}
#endif /*F_TERMIO*/
#ifdef F_TERMIOS
void cbreak(bool flag)
{
static struct termios tio;
static tfg;
static char eol_char;
if (flag)
{
/* Get current modes */
tcgetattr(0,&tio);
tfg= tio.c_lflag;
eof_char= tio.c_cc[VEOF];
eol_char= tio.c_cc[VEOL];
bs_char= tio.c_cc[VERASE];
kill_char= tio.c_cc[VKILL];
/* Remember that we are in cbreak mode */
in_cbreak= TRUE;
/* Turn on cbreak mode - that is turn off ICANON */
tio.c_lflag= tfg & ~ICANON;
tio.c_lflag &= ~ECHO;
tio.c_cc[VEOF]= 1;
tio.c_cc[VEOL]= 0;
tcsetattr(0,TCSANOW,&tio);
}
else
{
/* Turn off cbreak mode - that is restore original modes */
tio.c_lflag= tfg;
tio.c_cc[VEOF]= eof_char;
tio.c_cc[VEOL]= eol_char;
tcsetattr(0,TCSANOW,&tio);
in_cbreak= FALSE;
}
}
#endif /*F_TERMIOS*/
/* FLUSHINPUT: Flush input on tty on filedescriptor dev.
*/
void flushinput(int dev)
{
#ifdef TCIFLUSH
tcflush(dev, TCIFLUSH); /* TERMIOS way to flush input */
#else
#ifdef TCFLSH
ioctl(dev,TCFLSH,0); /* SysIII way to flush input */
#else
int flushcode= FREAD;
ioctl(dev,TIOCFLUSH,&flushcode); /* BSD way to flush input */
#endif /*TCFLSH*/
#endif /*TCIFLUSH*/
}
/* GET_COLS: Return number of columns on user's terminal. Sort of. Since
* this is going to be used for wrapping on both my terminal and his, we
* won't let it be more than 80, since his terminal probably doesn't have
* more than 80 columns even if ours does.
*/
int get_cols()
{
#ifdef TIOCGWINSZ
struct winsize x;
ioctl(2,TIOCGWINSZ,&x);
if (x.ws_col == 0 || x.ws_col > 80)
return(80);
else
return(x.ws_col);
#else
return(80);
#endif
}
|