1*aae38d10SBaptiste Daroussin /**************************************************************************** 2*aae38d10SBaptiste Daroussin * Copyright (c) 2016-2017,2019 Free Software Foundation, Inc. * 3*aae38d10SBaptiste Daroussin * * 4*aae38d10SBaptiste Daroussin * Permission is hereby granted, free of charge, to any person obtaining a * 5*aae38d10SBaptiste Daroussin * copy of this software and associated documentation files (the * 6*aae38d10SBaptiste Daroussin * "Software"), to deal in the Software without restriction, including * 7*aae38d10SBaptiste Daroussin * without limitation the rights to use, copy, modify, merge, publish, * 8*aae38d10SBaptiste Daroussin * distribute, distribute with modifications, sublicense, and/or sell * 9*aae38d10SBaptiste Daroussin * copies of the Software, and to permit persons to whom the Software is * 10*aae38d10SBaptiste Daroussin * furnished to do so, subject to the following conditions: * 11*aae38d10SBaptiste Daroussin * * 12*aae38d10SBaptiste Daroussin * The above copyright notice and this permission notice shall be included * 13*aae38d10SBaptiste Daroussin * in all copies or substantial portions of the Software. * 14*aae38d10SBaptiste Daroussin * * 15*aae38d10SBaptiste Daroussin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16*aae38d10SBaptiste Daroussin * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17*aae38d10SBaptiste Daroussin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18*aae38d10SBaptiste Daroussin * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19*aae38d10SBaptiste Daroussin * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20*aae38d10SBaptiste Daroussin * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21*aae38d10SBaptiste Daroussin * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22*aae38d10SBaptiste Daroussin * * 23*aae38d10SBaptiste Daroussin * Except as contained in this notice, the name(s) of the above copyright * 24*aae38d10SBaptiste Daroussin * holders shall not be used in advertising or otherwise to promote the * 25*aae38d10SBaptiste Daroussin * sale, use or other dealings in this Software without prior written * 26*aae38d10SBaptiste Daroussin * authorization. * 27*aae38d10SBaptiste Daroussin ****************************************************************************/ 28*aae38d10SBaptiste Daroussin 29*aae38d10SBaptiste Daroussin /**************************************************************************** 30*aae38d10SBaptiste Daroussin * Author: Thomas E. Dickey * 31*aae38d10SBaptiste Daroussin ****************************************************************************/ 32*aae38d10SBaptiste Daroussin 33*aae38d10SBaptiste Daroussin #include <reset_cmd.h> 34*aae38d10SBaptiste Daroussin #include <tty_settings.h> 35*aae38d10SBaptiste Daroussin 36*aae38d10SBaptiste Daroussin #include <errno.h> 37*aae38d10SBaptiste Daroussin #include <stdio.h> 38*aae38d10SBaptiste Daroussin #include <fcntl.h> 39*aae38d10SBaptiste Daroussin 40*aae38d10SBaptiste Daroussin #if HAVE_SIZECHANGE 41*aae38d10SBaptiste Daroussin # if !defined(sun) || !TERMIOS 42*aae38d10SBaptiste Daroussin # if HAVE_SYS_IOCTL_H 43*aae38d10SBaptiste Daroussin # include <sys/ioctl.h> 44*aae38d10SBaptiste Daroussin # endif 45*aae38d10SBaptiste Daroussin # endif 46*aae38d10SBaptiste Daroussin #endif 47*aae38d10SBaptiste Daroussin 48*aae38d10SBaptiste Daroussin #if NEED_PTEM_H 49*aae38d10SBaptiste Daroussin /* they neglected to define struct winsize in termios.h -- it's only 50*aae38d10SBaptiste Daroussin in termio.h */ 51*aae38d10SBaptiste Daroussin #include <sys/stream.h> 52*aae38d10SBaptiste Daroussin #include <sys/ptem.h> 53*aae38d10SBaptiste Daroussin #endif 54*aae38d10SBaptiste Daroussin 55*aae38d10SBaptiste Daroussin MODULE_ID("$Id: reset_cmd.c,v 1.18 2019/07/13 21:35:13 tom Exp $") 56*aae38d10SBaptiste Daroussin 57*aae38d10SBaptiste Daroussin /* 58*aae38d10SBaptiste Daroussin * SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS, 59*aae38d10SBaptiste Daroussin * Solaris, IRIX) define TIOCGWINSZ and struct winsize. 60*aae38d10SBaptiste Daroussin */ 61*aae38d10SBaptiste Daroussin #ifdef TIOCGSIZE 62*aae38d10SBaptiste Daroussin # define IOCTL_GET_WINSIZE TIOCGSIZE 63*aae38d10SBaptiste Daroussin # define IOCTL_SET_WINSIZE TIOCSSIZE 64*aae38d10SBaptiste Daroussin # define STRUCT_WINSIZE struct ttysize 65*aae38d10SBaptiste Daroussin # define WINSIZE_ROWS(n) n.ts_lines 66*aae38d10SBaptiste Daroussin # define WINSIZE_COLS(n) n.ts_cols 67*aae38d10SBaptiste Daroussin #else 68*aae38d10SBaptiste Daroussin # ifdef TIOCGWINSZ 69*aae38d10SBaptiste Daroussin # define IOCTL_GET_WINSIZE TIOCGWINSZ 70*aae38d10SBaptiste Daroussin # define IOCTL_SET_WINSIZE TIOCSWINSZ 71*aae38d10SBaptiste Daroussin # define STRUCT_WINSIZE struct winsize 72*aae38d10SBaptiste Daroussin # define WINSIZE_ROWS(n) n.ws_row 73*aae38d10SBaptiste Daroussin # define WINSIZE_COLS(n) n.ws_col 74*aae38d10SBaptiste Daroussin # endif 75*aae38d10SBaptiste Daroussin #endif 76*aae38d10SBaptiste Daroussin 77*aae38d10SBaptiste Daroussin static FILE *my_file; 78*aae38d10SBaptiste Daroussin 79*aae38d10SBaptiste Daroussin static bool use_reset = FALSE; /* invoked as reset */ 80*aae38d10SBaptiste Daroussin static bool use_init = FALSE; /* invoked as init */ 81*aae38d10SBaptiste Daroussin 82*aae38d10SBaptiste Daroussin static void 83*aae38d10SBaptiste Daroussin failed(const char *msg) 84*aae38d10SBaptiste Daroussin { 85*aae38d10SBaptiste Daroussin int code = errno; 86*aae38d10SBaptiste Daroussin 87*aae38d10SBaptiste Daroussin (void) fprintf(stderr, "%s: %s: %s\n", _nc_progname, msg, strerror(code)); 88*aae38d10SBaptiste Daroussin restore_tty_settings(); 89*aae38d10SBaptiste Daroussin (void) fprintf(my_file, "\n"); 90*aae38d10SBaptiste Daroussin fflush(my_file); 91*aae38d10SBaptiste Daroussin ExitProgram(ErrSystem(code)); 92*aae38d10SBaptiste Daroussin /* NOTREACHED */ 93*aae38d10SBaptiste Daroussin } 94*aae38d10SBaptiste Daroussin 95*aae38d10SBaptiste Daroussin static bool 96*aae38d10SBaptiste Daroussin cat_file(char *file) 97*aae38d10SBaptiste Daroussin { 98*aae38d10SBaptiste Daroussin FILE *fp; 99*aae38d10SBaptiste Daroussin size_t nr; 100*aae38d10SBaptiste Daroussin char buf[BUFSIZ]; 101*aae38d10SBaptiste Daroussin bool sent = FALSE; 102*aae38d10SBaptiste Daroussin 103*aae38d10SBaptiste Daroussin if (file != 0) { 104*aae38d10SBaptiste Daroussin if ((fp = fopen(file, "r")) == 0) 105*aae38d10SBaptiste Daroussin failed(file); 106*aae38d10SBaptiste Daroussin 107*aae38d10SBaptiste Daroussin while ((nr = fread(buf, sizeof(char), sizeof(buf), fp)) != 0) { 108*aae38d10SBaptiste Daroussin if (fwrite(buf, sizeof(char), nr, my_file) != nr) { 109*aae38d10SBaptiste Daroussin failed(file); 110*aae38d10SBaptiste Daroussin } 111*aae38d10SBaptiste Daroussin sent = TRUE; 112*aae38d10SBaptiste Daroussin } 113*aae38d10SBaptiste Daroussin fclose(fp); 114*aae38d10SBaptiste Daroussin } 115*aae38d10SBaptiste Daroussin return sent; 116*aae38d10SBaptiste Daroussin } 117*aae38d10SBaptiste Daroussin 118*aae38d10SBaptiste Daroussin static int 119*aae38d10SBaptiste Daroussin out_char(int c) 120*aae38d10SBaptiste Daroussin { 121*aae38d10SBaptiste Daroussin return putc(c, my_file); 122*aae38d10SBaptiste Daroussin } 123*aae38d10SBaptiste Daroussin 124*aae38d10SBaptiste Daroussin /************************************************************************** 125*aae38d10SBaptiste Daroussin * Mode-setting logic 126*aae38d10SBaptiste Daroussin **************************************************************************/ 127*aae38d10SBaptiste Daroussin 128*aae38d10SBaptiste Daroussin /* some BSD systems have these built in, some systems are missing 129*aae38d10SBaptiste Daroussin * one or more definitions. The safest solution is to override unless the 130*aae38d10SBaptiste Daroussin * commonly-altered ones are defined. 131*aae38d10SBaptiste Daroussin */ 132*aae38d10SBaptiste Daroussin #if !(defined(CERASE) && defined(CINTR) && defined(CKILL) && defined(CQUIT)) 133*aae38d10SBaptiste Daroussin #undef CEOF 134*aae38d10SBaptiste Daroussin #undef CERASE 135*aae38d10SBaptiste Daroussin #undef CINTR 136*aae38d10SBaptiste Daroussin #undef CKILL 137*aae38d10SBaptiste Daroussin #undef CLNEXT 138*aae38d10SBaptiste Daroussin #undef CRPRNT 139*aae38d10SBaptiste Daroussin #undef CQUIT 140*aae38d10SBaptiste Daroussin #undef CSTART 141*aae38d10SBaptiste Daroussin #undef CSTOP 142*aae38d10SBaptiste Daroussin #undef CSUSP 143*aae38d10SBaptiste Daroussin #endif 144*aae38d10SBaptiste Daroussin 145*aae38d10SBaptiste Daroussin /* control-character defaults */ 146*aae38d10SBaptiste Daroussin #ifndef CEOF 147*aae38d10SBaptiste Daroussin #define CEOF CTRL('D') 148*aae38d10SBaptiste Daroussin #endif 149*aae38d10SBaptiste Daroussin #ifndef CERASE 150*aae38d10SBaptiste Daroussin #define CERASE CTRL('H') 151*aae38d10SBaptiste Daroussin #endif 152*aae38d10SBaptiste Daroussin #ifndef CINTR 153*aae38d10SBaptiste Daroussin #define CINTR 127 /* ^? */ 154*aae38d10SBaptiste Daroussin #endif 155*aae38d10SBaptiste Daroussin #ifndef CKILL 156*aae38d10SBaptiste Daroussin #define CKILL CTRL('U') 157*aae38d10SBaptiste Daroussin #endif 158*aae38d10SBaptiste Daroussin #ifndef CLNEXT 159*aae38d10SBaptiste Daroussin #define CLNEXT CTRL('v') 160*aae38d10SBaptiste Daroussin #endif 161*aae38d10SBaptiste Daroussin #ifndef CRPRNT 162*aae38d10SBaptiste Daroussin #define CRPRNT CTRL('r') 163*aae38d10SBaptiste Daroussin #endif 164*aae38d10SBaptiste Daroussin #ifndef CQUIT 165*aae38d10SBaptiste Daroussin #define CQUIT CTRL('\\') 166*aae38d10SBaptiste Daroussin #endif 167*aae38d10SBaptiste Daroussin #ifndef CSTART 168*aae38d10SBaptiste Daroussin #define CSTART CTRL('Q') 169*aae38d10SBaptiste Daroussin #endif 170*aae38d10SBaptiste Daroussin #ifndef CSTOP 171*aae38d10SBaptiste Daroussin #define CSTOP CTRL('S') 172*aae38d10SBaptiste Daroussin #endif 173*aae38d10SBaptiste Daroussin #ifndef CSUSP 174*aae38d10SBaptiste Daroussin #define CSUSP CTRL('Z') 175*aae38d10SBaptiste Daroussin #endif 176*aae38d10SBaptiste Daroussin 177*aae38d10SBaptiste Daroussin #if defined(_POSIX_VDISABLE) 178*aae38d10SBaptiste Daroussin #define DISABLED(val) (((_POSIX_VDISABLE != -1) \ 179*aae38d10SBaptiste Daroussin && ((val) == _POSIX_VDISABLE)) \ 180*aae38d10SBaptiste Daroussin || ((val) <= 0)) 181*aae38d10SBaptiste Daroussin #else 182*aae38d10SBaptiste Daroussin #define DISABLED(val) ((int)(val) <= 0) 183*aae38d10SBaptiste Daroussin #endif 184*aae38d10SBaptiste Daroussin 185*aae38d10SBaptiste Daroussin #define CHK(val, dft) (unsigned char) (DISABLED(val) ? dft : val) 186*aae38d10SBaptiste Daroussin 187*aae38d10SBaptiste Daroussin #define reset_char(item, value) \ 188*aae38d10SBaptiste Daroussin tty_settings->c_cc[item] = CHK(tty_settings->c_cc[item], value) 189*aae38d10SBaptiste Daroussin 190*aae38d10SBaptiste Daroussin /* 191*aae38d10SBaptiste Daroussin * Reset the terminal mode bits to a sensible state. Very useful after 192*aae38d10SBaptiste Daroussin * a child program dies in raw mode. 193*aae38d10SBaptiste Daroussin */ 194*aae38d10SBaptiste Daroussin void 195*aae38d10SBaptiste Daroussin reset_tty_settings(int fd, TTY * tty_settings) 196*aae38d10SBaptiste Daroussin { 197*aae38d10SBaptiste Daroussin GET_TTY(fd, tty_settings); 198*aae38d10SBaptiste Daroussin 199*aae38d10SBaptiste Daroussin #ifdef TERMIOS 200*aae38d10SBaptiste Daroussin #if defined(VDISCARD) && defined(CDISCARD) 201*aae38d10SBaptiste Daroussin reset_char(VDISCARD, CDISCARD); 202*aae38d10SBaptiste Daroussin #endif 203*aae38d10SBaptiste Daroussin reset_char(VEOF, CEOF); 204*aae38d10SBaptiste Daroussin reset_char(VERASE, CERASE); 205*aae38d10SBaptiste Daroussin #if defined(VFLUSH) && defined(CFLUSH) 206*aae38d10SBaptiste Daroussin reset_char(VFLUSH, CFLUSH); 207*aae38d10SBaptiste Daroussin #endif 208*aae38d10SBaptiste Daroussin reset_char(VINTR, CINTR); 209*aae38d10SBaptiste Daroussin reset_char(VKILL, CKILL); 210*aae38d10SBaptiste Daroussin #if defined(VLNEXT) && defined(CLNEXT) 211*aae38d10SBaptiste Daroussin reset_char(VLNEXT, CLNEXT); 212*aae38d10SBaptiste Daroussin #endif 213*aae38d10SBaptiste Daroussin reset_char(VQUIT, CQUIT); 214*aae38d10SBaptiste Daroussin #if defined(VREPRINT) && defined(CRPRNT) 215*aae38d10SBaptiste Daroussin reset_char(VREPRINT, CRPRNT); 216*aae38d10SBaptiste Daroussin #endif 217*aae38d10SBaptiste Daroussin #if defined(VSTART) && defined(CSTART) 218*aae38d10SBaptiste Daroussin reset_char(VSTART, CSTART); 219*aae38d10SBaptiste Daroussin #endif 220*aae38d10SBaptiste Daroussin #if defined(VSTOP) && defined(CSTOP) 221*aae38d10SBaptiste Daroussin reset_char(VSTOP, CSTOP); 222*aae38d10SBaptiste Daroussin #endif 223*aae38d10SBaptiste Daroussin #if defined(VSUSP) && defined(CSUSP) 224*aae38d10SBaptiste Daroussin reset_char(VSUSP, CSUSP); 225*aae38d10SBaptiste Daroussin #endif 226*aae38d10SBaptiste Daroussin #if defined(VWERASE) && defined(CWERASE) 227*aae38d10SBaptiste Daroussin reset_char(VWERASE, CWERASE); 228*aae38d10SBaptiste Daroussin #endif 229*aae38d10SBaptiste Daroussin 230*aae38d10SBaptiste Daroussin tty_settings->c_iflag &= ~((unsigned) (IGNBRK 231*aae38d10SBaptiste Daroussin | PARMRK 232*aae38d10SBaptiste Daroussin | INPCK 233*aae38d10SBaptiste Daroussin | ISTRIP 234*aae38d10SBaptiste Daroussin | INLCR 235*aae38d10SBaptiste Daroussin | IGNCR 236*aae38d10SBaptiste Daroussin #ifdef IUCLC 237*aae38d10SBaptiste Daroussin | IUCLC 238*aae38d10SBaptiste Daroussin #endif 239*aae38d10SBaptiste Daroussin #ifdef IXANY 240*aae38d10SBaptiste Daroussin | IXANY 241*aae38d10SBaptiste Daroussin #endif 242*aae38d10SBaptiste Daroussin | IXOFF)); 243*aae38d10SBaptiste Daroussin 244*aae38d10SBaptiste Daroussin tty_settings->c_iflag |= (BRKINT 245*aae38d10SBaptiste Daroussin | IGNPAR 246*aae38d10SBaptiste Daroussin | ICRNL 247*aae38d10SBaptiste Daroussin | IXON 248*aae38d10SBaptiste Daroussin #ifdef IMAXBEL 249*aae38d10SBaptiste Daroussin | IMAXBEL 250*aae38d10SBaptiste Daroussin #endif 251*aae38d10SBaptiste Daroussin ); 252*aae38d10SBaptiste Daroussin 253*aae38d10SBaptiste Daroussin tty_settings->c_oflag &= ~((unsigned) (0 254*aae38d10SBaptiste Daroussin #ifdef OLCUC 255*aae38d10SBaptiste Daroussin | OLCUC 256*aae38d10SBaptiste Daroussin #endif 257*aae38d10SBaptiste Daroussin #ifdef OCRNL 258*aae38d10SBaptiste Daroussin | OCRNL 259*aae38d10SBaptiste Daroussin #endif 260*aae38d10SBaptiste Daroussin #ifdef ONOCR 261*aae38d10SBaptiste Daroussin | ONOCR 262*aae38d10SBaptiste Daroussin #endif 263*aae38d10SBaptiste Daroussin #ifdef ONLRET 264*aae38d10SBaptiste Daroussin | ONLRET 265*aae38d10SBaptiste Daroussin #endif 266*aae38d10SBaptiste Daroussin #ifdef OFILL 267*aae38d10SBaptiste Daroussin | OFILL 268*aae38d10SBaptiste Daroussin #endif 269*aae38d10SBaptiste Daroussin #ifdef OFDEL 270*aae38d10SBaptiste Daroussin | OFDEL 271*aae38d10SBaptiste Daroussin #endif 272*aae38d10SBaptiste Daroussin #ifdef NLDLY 273*aae38d10SBaptiste Daroussin | NLDLY 274*aae38d10SBaptiste Daroussin #endif 275*aae38d10SBaptiste Daroussin #ifdef CRDLY 276*aae38d10SBaptiste Daroussin | CRDLY 277*aae38d10SBaptiste Daroussin #endif 278*aae38d10SBaptiste Daroussin #ifdef TABDLY 279*aae38d10SBaptiste Daroussin | TABDLY 280*aae38d10SBaptiste Daroussin #endif 281*aae38d10SBaptiste Daroussin #ifdef BSDLY 282*aae38d10SBaptiste Daroussin | BSDLY 283*aae38d10SBaptiste Daroussin #endif 284*aae38d10SBaptiste Daroussin #ifdef VTDLY 285*aae38d10SBaptiste Daroussin | VTDLY 286*aae38d10SBaptiste Daroussin #endif 287*aae38d10SBaptiste Daroussin #ifdef FFDLY 288*aae38d10SBaptiste Daroussin | FFDLY 289*aae38d10SBaptiste Daroussin #endif 290*aae38d10SBaptiste Daroussin )); 291*aae38d10SBaptiste Daroussin 292*aae38d10SBaptiste Daroussin tty_settings->c_oflag |= (OPOST 293*aae38d10SBaptiste Daroussin #ifdef ONLCR 294*aae38d10SBaptiste Daroussin | ONLCR 295*aae38d10SBaptiste Daroussin #endif 296*aae38d10SBaptiste Daroussin ); 297*aae38d10SBaptiste Daroussin 298*aae38d10SBaptiste Daroussin tty_settings->c_cflag &= ~((unsigned) (CSIZE 299*aae38d10SBaptiste Daroussin | CSTOPB 300*aae38d10SBaptiste Daroussin | PARENB 301*aae38d10SBaptiste Daroussin | PARODD 302*aae38d10SBaptiste Daroussin | CLOCAL)); 303*aae38d10SBaptiste Daroussin tty_settings->c_cflag |= (CS8 | CREAD); 304*aae38d10SBaptiste Daroussin tty_settings->c_lflag &= ~((unsigned) (ECHONL 305*aae38d10SBaptiste Daroussin | NOFLSH 306*aae38d10SBaptiste Daroussin #ifdef TOSTOP 307*aae38d10SBaptiste Daroussin | TOSTOP 308*aae38d10SBaptiste Daroussin #endif 309*aae38d10SBaptiste Daroussin #ifdef ECHOPTR 310*aae38d10SBaptiste Daroussin | ECHOPRT 311*aae38d10SBaptiste Daroussin #endif 312*aae38d10SBaptiste Daroussin #ifdef XCASE 313*aae38d10SBaptiste Daroussin | XCASE 314*aae38d10SBaptiste Daroussin #endif 315*aae38d10SBaptiste Daroussin )); 316*aae38d10SBaptiste Daroussin 317*aae38d10SBaptiste Daroussin tty_settings->c_lflag |= (ISIG 318*aae38d10SBaptiste Daroussin | ICANON 319*aae38d10SBaptiste Daroussin | ECHO 320*aae38d10SBaptiste Daroussin | ECHOE 321*aae38d10SBaptiste Daroussin | ECHOK 322*aae38d10SBaptiste Daroussin #ifdef ECHOCTL 323*aae38d10SBaptiste Daroussin | ECHOCTL 324*aae38d10SBaptiste Daroussin #endif 325*aae38d10SBaptiste Daroussin #ifdef ECHOKE 326*aae38d10SBaptiste Daroussin | ECHOKE 327*aae38d10SBaptiste Daroussin #endif 328*aae38d10SBaptiste Daroussin ); 329*aae38d10SBaptiste Daroussin #endif 330*aae38d10SBaptiste Daroussin 331*aae38d10SBaptiste Daroussin SET_TTY(fd, tty_settings); 332*aae38d10SBaptiste Daroussin } 333*aae38d10SBaptiste Daroussin 334*aae38d10SBaptiste Daroussin /* 335*aae38d10SBaptiste Daroussin * Returns a "good" value for the erase character. This is loosely based on 336*aae38d10SBaptiste Daroussin * the BSD4.4 logic. 337*aae38d10SBaptiste Daroussin */ 338*aae38d10SBaptiste Daroussin static int 339*aae38d10SBaptiste Daroussin default_erase(void) 340*aae38d10SBaptiste Daroussin { 341*aae38d10SBaptiste Daroussin int result; 342*aae38d10SBaptiste Daroussin 343*aae38d10SBaptiste Daroussin if (over_strike 344*aae38d10SBaptiste Daroussin && VALID_STRING(key_backspace) 345*aae38d10SBaptiste Daroussin && strlen(key_backspace) == 1) { 346*aae38d10SBaptiste Daroussin result = key_backspace[0]; 347*aae38d10SBaptiste Daroussin } else { 348*aae38d10SBaptiste Daroussin result = CERASE; 349*aae38d10SBaptiste Daroussin } 350*aae38d10SBaptiste Daroussin 351*aae38d10SBaptiste Daroussin return result; 352*aae38d10SBaptiste Daroussin } 353*aae38d10SBaptiste Daroussin 354*aae38d10SBaptiste Daroussin /* 355*aae38d10SBaptiste Daroussin * Update the values of the erase, interrupt, and kill characters in the TTY 356*aae38d10SBaptiste Daroussin * parameter. 357*aae38d10SBaptiste Daroussin * 358*aae38d10SBaptiste Daroussin * SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase 359*aae38d10SBaptiste Daroussin * characters if they're unset, or if we specify them as options. This differs 360*aae38d10SBaptiste Daroussin * from BSD 4.4 tset, which always sets erase. 361*aae38d10SBaptiste Daroussin */ 362*aae38d10SBaptiste Daroussin void 363*aae38d10SBaptiste Daroussin set_control_chars(TTY * tty_settings, int my_erase, int my_intr, int my_kill) 364*aae38d10SBaptiste Daroussin { 365*aae38d10SBaptiste Daroussin if (DISABLED(tty_settings->c_cc[VERASE]) || my_erase >= 0) { 366*aae38d10SBaptiste Daroussin tty_settings->c_cc[VERASE] = UChar((my_erase >= 0) 367*aae38d10SBaptiste Daroussin ? my_erase 368*aae38d10SBaptiste Daroussin : default_erase()); 369*aae38d10SBaptiste Daroussin } 370*aae38d10SBaptiste Daroussin 371*aae38d10SBaptiste Daroussin if (DISABLED(tty_settings->c_cc[VINTR]) || my_intr >= 0) { 372*aae38d10SBaptiste Daroussin tty_settings->c_cc[VINTR] = UChar((my_intr >= 0) 373*aae38d10SBaptiste Daroussin ? my_intr 374*aae38d10SBaptiste Daroussin : CINTR); 375*aae38d10SBaptiste Daroussin } 376*aae38d10SBaptiste Daroussin 377*aae38d10SBaptiste Daroussin if (DISABLED(tty_settings->c_cc[VKILL]) || my_kill >= 0) { 378*aae38d10SBaptiste Daroussin tty_settings->c_cc[VKILL] = UChar((my_kill >= 0) 379*aae38d10SBaptiste Daroussin ? my_kill 380*aae38d10SBaptiste Daroussin : CKILL); 381*aae38d10SBaptiste Daroussin } 382*aae38d10SBaptiste Daroussin } 383*aae38d10SBaptiste Daroussin 384*aae38d10SBaptiste Daroussin /* 385*aae38d10SBaptiste Daroussin * Set up various conversions in the TTY parameter, including parity, tabs, 386*aae38d10SBaptiste Daroussin * returns, echo, and case, according to the termcap entry. 387*aae38d10SBaptiste Daroussin */ 388*aae38d10SBaptiste Daroussin void 389*aae38d10SBaptiste Daroussin set_conversions(TTY * tty_settings) 390*aae38d10SBaptiste Daroussin { 391*aae38d10SBaptiste Daroussin #ifdef ONLCR 392*aae38d10SBaptiste Daroussin tty_settings->c_oflag |= ONLCR; 393*aae38d10SBaptiste Daroussin #endif 394*aae38d10SBaptiste Daroussin tty_settings->c_iflag |= ICRNL; 395*aae38d10SBaptiste Daroussin tty_settings->c_lflag |= ECHO; 396*aae38d10SBaptiste Daroussin #ifdef OXTABS 397*aae38d10SBaptiste Daroussin tty_settings->c_oflag |= OXTABS; 398*aae38d10SBaptiste Daroussin #endif /* OXTABS */ 399*aae38d10SBaptiste Daroussin 400*aae38d10SBaptiste Daroussin /* test used to be tgetflag("NL") */ 401*aae38d10SBaptiste Daroussin if (VALID_STRING(newline) && newline[0] == '\n' && !newline[1]) { 402*aae38d10SBaptiste Daroussin /* Newline, not linefeed. */ 403*aae38d10SBaptiste Daroussin #ifdef ONLCR 404*aae38d10SBaptiste Daroussin tty_settings->c_oflag &= ~((unsigned) ONLCR); 405*aae38d10SBaptiste Daroussin #endif 406*aae38d10SBaptiste Daroussin tty_settings->c_iflag &= ~((unsigned) ICRNL); 407*aae38d10SBaptiste Daroussin } 408*aae38d10SBaptiste Daroussin #ifdef OXTABS 409*aae38d10SBaptiste Daroussin /* test used to be tgetflag("pt") */ 410*aae38d10SBaptiste Daroussin if (VALID_STRING(set_tab) && VALID_STRING(clear_all_tabs)) 411*aae38d10SBaptiste Daroussin tty_settings->c_oflag &= ~OXTABS; 412*aae38d10SBaptiste Daroussin #endif /* OXTABS */ 413*aae38d10SBaptiste Daroussin tty_settings->c_lflag |= (ECHOE | ECHOK); 414*aae38d10SBaptiste Daroussin } 415*aae38d10SBaptiste Daroussin 416*aae38d10SBaptiste Daroussin static bool 417*aae38d10SBaptiste Daroussin sent_string(const char *s) 418*aae38d10SBaptiste Daroussin { 419*aae38d10SBaptiste Daroussin bool sent = FALSE; 420*aae38d10SBaptiste Daroussin if (VALID_STRING(s)) { 421*aae38d10SBaptiste Daroussin tputs(s, 0, out_char); 422*aae38d10SBaptiste Daroussin sent = TRUE; 423*aae38d10SBaptiste Daroussin } 424*aae38d10SBaptiste Daroussin return sent; 425*aae38d10SBaptiste Daroussin } 426*aae38d10SBaptiste Daroussin 427*aae38d10SBaptiste Daroussin static bool 428*aae38d10SBaptiste Daroussin to_left_margin(void) 429*aae38d10SBaptiste Daroussin { 430*aae38d10SBaptiste Daroussin if (VALID_STRING(carriage_return)) { 431*aae38d10SBaptiste Daroussin sent_string(carriage_return); 432*aae38d10SBaptiste Daroussin } else { 433*aae38d10SBaptiste Daroussin out_char('\r'); 434*aae38d10SBaptiste Daroussin } 435*aae38d10SBaptiste Daroussin return TRUE; 436*aae38d10SBaptiste Daroussin } 437*aae38d10SBaptiste Daroussin 438*aae38d10SBaptiste Daroussin /* 439*aae38d10SBaptiste Daroussin * Set the hardware tabs on the terminal, using the 'ct' (clear all tabs), 440*aae38d10SBaptiste Daroussin * 'st' (set one tab) and 'ch' (horizontal cursor addressing) capabilities. 441*aae38d10SBaptiste Daroussin * This is done before 'if' and 'is', so they can recover in case of error. 442*aae38d10SBaptiste Daroussin * 443*aae38d10SBaptiste Daroussin * Return TRUE if we set any tab stops, FALSE if not. 444*aae38d10SBaptiste Daroussin */ 445*aae38d10SBaptiste Daroussin static bool 446*aae38d10SBaptiste Daroussin reset_tabstops(int wide) 447*aae38d10SBaptiste Daroussin { 448*aae38d10SBaptiste Daroussin if ((init_tabs != 8) 449*aae38d10SBaptiste Daroussin && VALID_NUMERIC(init_tabs) 450*aae38d10SBaptiste Daroussin && VALID_STRING(set_tab) 451*aae38d10SBaptiste Daroussin && VALID_STRING(clear_all_tabs)) { 452*aae38d10SBaptiste Daroussin int c; 453*aae38d10SBaptiste Daroussin 454*aae38d10SBaptiste Daroussin to_left_margin(); 455*aae38d10SBaptiste Daroussin tputs(clear_all_tabs, 0, out_char); 456*aae38d10SBaptiste Daroussin if (init_tabs > 1) { 457*aae38d10SBaptiste Daroussin if (init_tabs > wide) 458*aae38d10SBaptiste Daroussin init_tabs = (short) wide; 459*aae38d10SBaptiste Daroussin for (c = init_tabs; c < wide; c += init_tabs) { 460*aae38d10SBaptiste Daroussin fprintf(my_file, "%*s", init_tabs, " "); 461*aae38d10SBaptiste Daroussin tputs(set_tab, 0, out_char); 462*aae38d10SBaptiste Daroussin } 463*aae38d10SBaptiste Daroussin to_left_margin(); 464*aae38d10SBaptiste Daroussin } 465*aae38d10SBaptiste Daroussin return (TRUE); 466*aae38d10SBaptiste Daroussin } 467*aae38d10SBaptiste Daroussin return (FALSE); 468*aae38d10SBaptiste Daroussin } 469*aae38d10SBaptiste Daroussin 470*aae38d10SBaptiste Daroussin /* Output startup string. */ 471*aae38d10SBaptiste Daroussin bool 472*aae38d10SBaptiste Daroussin send_init_strings(int fd GCC_UNUSED, TTY * old_settings) 473*aae38d10SBaptiste Daroussin { 474*aae38d10SBaptiste Daroussin int i; 475*aae38d10SBaptiste Daroussin bool need_flush = FALSE; 476*aae38d10SBaptiste Daroussin 477*aae38d10SBaptiste Daroussin (void) old_settings; 478*aae38d10SBaptiste Daroussin #ifdef TAB3 479*aae38d10SBaptiste Daroussin if (old_settings != 0 && 480*aae38d10SBaptiste Daroussin old_settings->c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) { 481*aae38d10SBaptiste Daroussin old_settings->c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET); 482*aae38d10SBaptiste Daroussin SET_TTY(fd, old_settings); 483*aae38d10SBaptiste Daroussin } 484*aae38d10SBaptiste Daroussin #endif 485*aae38d10SBaptiste Daroussin if (use_reset || use_init) { 486*aae38d10SBaptiste Daroussin if (VALID_STRING(init_prog)) { 487*aae38d10SBaptiste Daroussin IGNORE_RC(system(init_prog)); 488*aae38d10SBaptiste Daroussin } 489*aae38d10SBaptiste Daroussin 490*aae38d10SBaptiste Daroussin need_flush |= sent_string((use_reset && (reset_1string != 0)) 491*aae38d10SBaptiste Daroussin ? reset_1string 492*aae38d10SBaptiste Daroussin : init_1string); 493*aae38d10SBaptiste Daroussin 494*aae38d10SBaptiste Daroussin need_flush |= sent_string((use_reset && (reset_2string != 0)) 495*aae38d10SBaptiste Daroussin ? reset_2string 496*aae38d10SBaptiste Daroussin : init_2string); 497*aae38d10SBaptiste Daroussin 498*aae38d10SBaptiste Daroussin if (VALID_STRING(clear_margins)) { 499*aae38d10SBaptiste Daroussin need_flush |= sent_string(clear_margins); 500*aae38d10SBaptiste Daroussin } else 501*aae38d10SBaptiste Daroussin #if defined(set_lr_margin) 502*aae38d10SBaptiste Daroussin if (VALID_STRING(set_lr_margin)) { 503*aae38d10SBaptiste Daroussin need_flush |= sent_string(TPARM_2(set_lr_margin, 0, 504*aae38d10SBaptiste Daroussin columns - 1)); 505*aae38d10SBaptiste Daroussin } else 506*aae38d10SBaptiste Daroussin #endif 507*aae38d10SBaptiste Daroussin #if defined(set_left_margin_parm) && defined(set_right_margin_parm) 508*aae38d10SBaptiste Daroussin if (VALID_STRING(set_left_margin_parm) 509*aae38d10SBaptiste Daroussin && VALID_STRING(set_right_margin_parm)) { 510*aae38d10SBaptiste Daroussin need_flush |= sent_string(TPARM_1(set_left_margin_parm, 0)); 511*aae38d10SBaptiste Daroussin need_flush |= sent_string(TPARM_1(set_right_margin_parm, 512*aae38d10SBaptiste Daroussin columns - 1)); 513*aae38d10SBaptiste Daroussin } else 514*aae38d10SBaptiste Daroussin #endif 515*aae38d10SBaptiste Daroussin if (VALID_STRING(set_left_margin) 516*aae38d10SBaptiste Daroussin && VALID_STRING(set_right_margin)) { 517*aae38d10SBaptiste Daroussin need_flush |= to_left_margin(); 518*aae38d10SBaptiste Daroussin need_flush |= sent_string(set_left_margin); 519*aae38d10SBaptiste Daroussin if (VALID_STRING(parm_right_cursor)) { 520*aae38d10SBaptiste Daroussin need_flush |= sent_string(TPARM_1(parm_right_cursor, 521*aae38d10SBaptiste Daroussin columns - 1)); 522*aae38d10SBaptiste Daroussin } else { 523*aae38d10SBaptiste Daroussin for (i = 0; i < columns - 1; i++) { 524*aae38d10SBaptiste Daroussin out_char(' '); 525*aae38d10SBaptiste Daroussin need_flush = TRUE; 526*aae38d10SBaptiste Daroussin } 527*aae38d10SBaptiste Daroussin } 528*aae38d10SBaptiste Daroussin need_flush |= sent_string(set_right_margin); 529*aae38d10SBaptiste Daroussin need_flush |= to_left_margin(); 530*aae38d10SBaptiste Daroussin } 531*aae38d10SBaptiste Daroussin 532*aae38d10SBaptiste Daroussin need_flush |= reset_tabstops(columns); 533*aae38d10SBaptiste Daroussin 534*aae38d10SBaptiste Daroussin need_flush |= cat_file((use_reset && reset_file) ? reset_file : init_file); 535*aae38d10SBaptiste Daroussin 536*aae38d10SBaptiste Daroussin need_flush |= sent_string((use_reset && (reset_3string != 0)) 537*aae38d10SBaptiste Daroussin ? reset_3string 538*aae38d10SBaptiste Daroussin : init_3string); 539*aae38d10SBaptiste Daroussin } 540*aae38d10SBaptiste Daroussin 541*aae38d10SBaptiste Daroussin return need_flush; 542*aae38d10SBaptiste Daroussin } 543*aae38d10SBaptiste Daroussin 544*aae38d10SBaptiste Daroussin /* 545*aae38d10SBaptiste Daroussin * Tell the user if a control key has been changed from the default value. 546*aae38d10SBaptiste Daroussin */ 547*aae38d10SBaptiste Daroussin static void 548*aae38d10SBaptiste Daroussin show_tty_change(TTY * old_settings, 549*aae38d10SBaptiste Daroussin TTY * new_settings, 550*aae38d10SBaptiste Daroussin const char *name, 551*aae38d10SBaptiste Daroussin int which, 552*aae38d10SBaptiste Daroussin unsigned def) 553*aae38d10SBaptiste Daroussin { 554*aae38d10SBaptiste Daroussin unsigned older, newer; 555*aae38d10SBaptiste Daroussin char *p; 556*aae38d10SBaptiste Daroussin 557*aae38d10SBaptiste Daroussin newer = new_settings->c_cc[which]; 558*aae38d10SBaptiste Daroussin older = old_settings->c_cc[which]; 559*aae38d10SBaptiste Daroussin 560*aae38d10SBaptiste Daroussin if (older == newer && older == def) 561*aae38d10SBaptiste Daroussin return; 562*aae38d10SBaptiste Daroussin 563*aae38d10SBaptiste Daroussin (void) fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to"); 564*aae38d10SBaptiste Daroussin 565*aae38d10SBaptiste Daroussin if (DISABLED(newer)) { 566*aae38d10SBaptiste Daroussin (void) fprintf(stderr, "undef.\n"); 567*aae38d10SBaptiste Daroussin /* 568*aae38d10SBaptiste Daroussin * Check 'delete' before 'backspace', since the key_backspace value 569*aae38d10SBaptiste Daroussin * is ambiguous. 570*aae38d10SBaptiste Daroussin */ 571*aae38d10SBaptiste Daroussin } else if (newer == 0177) { 572*aae38d10SBaptiste Daroussin (void) fprintf(stderr, "delete.\n"); 573*aae38d10SBaptiste Daroussin } else if ((p = key_backspace) != 0 574*aae38d10SBaptiste Daroussin && newer == (unsigned char) p[0] 575*aae38d10SBaptiste Daroussin && p[1] == '\0') { 576*aae38d10SBaptiste Daroussin (void) fprintf(stderr, "backspace.\n"); 577*aae38d10SBaptiste Daroussin } else if (newer < 040) { 578*aae38d10SBaptiste Daroussin newer ^= 0100; 579*aae38d10SBaptiste Daroussin (void) fprintf(stderr, "control-%c (^%c).\n", UChar(newer), UChar(newer)); 580*aae38d10SBaptiste Daroussin } else 581*aae38d10SBaptiste Daroussin (void) fprintf(stderr, "%c.\n", UChar(newer)); 582*aae38d10SBaptiste Daroussin } 583*aae38d10SBaptiste Daroussin 584*aae38d10SBaptiste Daroussin /************************************************************************** 585*aae38d10SBaptiste Daroussin * Miscellaneous. 586*aae38d10SBaptiste Daroussin **************************************************************************/ 587*aae38d10SBaptiste Daroussin 588*aae38d10SBaptiste Daroussin void 589*aae38d10SBaptiste Daroussin reset_start(FILE *fp, bool is_reset, bool is_init) 590*aae38d10SBaptiste Daroussin { 591*aae38d10SBaptiste Daroussin my_file = fp; 592*aae38d10SBaptiste Daroussin use_reset = is_reset; 593*aae38d10SBaptiste Daroussin use_init = is_init; 594*aae38d10SBaptiste Daroussin } 595*aae38d10SBaptiste Daroussin 596*aae38d10SBaptiste Daroussin void 597*aae38d10SBaptiste Daroussin reset_flush(void) 598*aae38d10SBaptiste Daroussin { 599*aae38d10SBaptiste Daroussin if (my_file != 0) 600*aae38d10SBaptiste Daroussin fflush(my_file); 601*aae38d10SBaptiste Daroussin } 602*aae38d10SBaptiste Daroussin 603*aae38d10SBaptiste Daroussin void 604*aae38d10SBaptiste Daroussin print_tty_chars(TTY * old_settings, TTY * new_settings) 605*aae38d10SBaptiste Daroussin { 606*aae38d10SBaptiste Daroussin show_tty_change(old_settings, new_settings, "Erase", VERASE, CERASE); 607*aae38d10SBaptiste Daroussin show_tty_change(old_settings, new_settings, "Kill", VKILL, CKILL); 608*aae38d10SBaptiste Daroussin show_tty_change(old_settings, new_settings, "Interrupt", VINTR, CINTR); 609*aae38d10SBaptiste Daroussin } 610*aae38d10SBaptiste Daroussin 611*aae38d10SBaptiste Daroussin #if HAVE_SIZECHANGE 612*aae38d10SBaptiste Daroussin /* 613*aae38d10SBaptiste Daroussin * Set window size if not set already, but update our copy of the values if the 614*aae38d10SBaptiste Daroussin * size was set. 615*aae38d10SBaptiste Daroussin */ 616*aae38d10SBaptiste Daroussin void 617*aae38d10SBaptiste Daroussin set_window_size(int fd, short *high, short *wide) 618*aae38d10SBaptiste Daroussin { 619*aae38d10SBaptiste Daroussin STRUCT_WINSIZE win; 620*aae38d10SBaptiste Daroussin (void) ioctl(fd, IOCTL_GET_WINSIZE, &win); 621*aae38d10SBaptiste Daroussin if (WINSIZE_ROWS(win) == 0 && 622*aae38d10SBaptiste Daroussin WINSIZE_COLS(win) == 0) { 623*aae38d10SBaptiste Daroussin if (*high > 0 && *wide > 0) { 624*aae38d10SBaptiste Daroussin WINSIZE_ROWS(win) = (unsigned short) *high; 625*aae38d10SBaptiste Daroussin WINSIZE_COLS(win) = (unsigned short) *wide; 626*aae38d10SBaptiste Daroussin (void) ioctl(fd, IOCTL_SET_WINSIZE, &win); 627*aae38d10SBaptiste Daroussin } 628*aae38d10SBaptiste Daroussin } else if (WINSIZE_ROWS(win) > 0 && 629*aae38d10SBaptiste Daroussin WINSIZE_COLS(win) > 0) { 630*aae38d10SBaptiste Daroussin *high = (short) WINSIZE_ROWS(win); 631*aae38d10SBaptiste Daroussin *wide = (short) WINSIZE_COLS(win); 632*aae38d10SBaptiste Daroussin } 633*aae38d10SBaptiste Daroussin } 634*aae38d10SBaptiste Daroussin #endif 635