1: /* 2: * ed.init.c: Editor initializations 3: */ 4: /*- 5: * Copyright (c) 1980, 1991 The Regents of the University of California. 6: * All rights reserved. 7: * 8: * Redistribution and use in source and binary forms, with or without 9: * modification, are permitted provided that the following conditions 10: * are met: 11: * 1. Redistributions of source code must retain the above copyright 12: * notice, this list of conditions and the following disclaimer. 13: * 2. Redistributions in binary form must reproduce the above copyright 14: * notice, this list of conditions and the following disclaimer in the 15: * documentation and/or other materials provided with the distribution. 16: * 3. All advertising materials mentioning features or use of this software 17: * must display the following acknowledgement: 18: * This product includes software developed by the University of 19: * California, Berkeley and its contributors. 20: * 4. Neither the name of the University nor the names of its contributors 21: * may be used to endorse or promote products derived from this software 22: * without specific prior written permission. 23: * 24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34: * SUCH DAMAGE. 35: */ 36: #include "config.h" 37: #if !defined(lint) && !defined(pdp11) 38: static char *rcsid() 39: { return "$Id: ed.init.c,v 3.1 1997/3/28 21:49:28 sms Exp $"; } 40: #endif 41: 42: #include "sh.h" 43: #define EXTERN /* intern */ 44: #include "ed.h" 45: #include "ed.defns.h" 46: 47: #if defined(TERMIO) || defined(POSIX) 48: /* 49: * Aix compatible names 50: */ 51: # if defined(VWERSE) && !defined(VWERASE) 52: # define VWERASE VWERSE 53: # endif /* VWERSE && !VWERASE */ 54: 55: # if defined(VDISCRD) && !defined(VDISCARD) 56: # define VDISCARD VDISCRD 57: # endif /* VDISCRD && !VDISCARD */ 58: 59: # if defined(VSTRT) && !defined(VSTART) 60: # define VSTART VSTRT 61: # endif /* VSTRT && ! VSTART */ 62: 63: # if defined(VSTAT) && !defined(VSTATUS) 64: # define VSTATUS VSTAT 65: # endif /* VSTAT && ! VSTATUS */ 66: 67: # ifndef ONLRET 68: # define ONLRET 0 69: # endif /* ONLRET */ 70: 71: # ifndef TAB3 72: # ifdef OXTABS 73: # define TAB3 OXTABS 74: # else 75: # define TAB3 0 76: # endif /* OXTABS */ 77: # endif /* !TAB3 */ 78: 79: # ifndef ONLCR 80: # define ONLCR 0 81: # endif /* ONLCR */ 82: 83: # ifndef IEXTEN 84: # define IEXTEN 0 85: # endif /* IEXTEN */ 86: 87: # ifndef ECHOCTL 88: # define ECHOCTL 0 89: # endif /* ECHOCTL */ 90: 91: # ifndef PARENB 92: # define PARENB 0 93: # endif /* PARENB */ 94: 95: # ifndef EXTPROC 96: # define EXTPROC 0 97: # endif /* EXTPROC */ 98: 99: # ifndef FLUSHO 100: # define FLUSHO 0 101: # endif /* FLUSHO */ 102: 103: # if defined(VDISABLE) && !defined(_POSIX_VDISABLE) 104: # define _POSIX_VDISABLE VDISABLE 105: # endif /* VDISABLE && ! _POSIX_VDISABLE */ 106: 107: # ifndef _POSIX_VDISABLE 108: # define _POSIX_VDISABLE -1 109: # endif /* _POSIX_VDISABLE */ 110: 111: /* 112: * Work around ISC's definition of IEXTEN which is 113: * XCASE! 114: */ 115: # ifdef ISC 116: # ifdef IEXTEN 117: # undef IEXTEN 118: # endif /* IEXTEN */ 119: # define IEXTEN 0 120: # endif /* ISC */ 121: #endif /* TERMIO || POSIX */ 122: 123: 124: /* ed.init.c -- init routines for the line editor */ 125: 126: int Tty_raw_mode = 0; /* Last tty change was to raw mode */ 127: int MacroLvl = -1; /* pointer to current macro nesting level; */ 128: /* (-1 == none) */ 129: static int Tty_quote_mode = 0; /* Last tty change was to quote mode */ 130: 131: int Tty_eight_bit = -1; /* does the tty handle eight bits */ 132: 133: extern bool GotTermCaps; 134: 135: #ifdef _IBMR2 136: static bool edit_discipline = 0; 137: union txname tx_disc; 138: extern char strPOSIX[]; 139: #endif /* _IBMR2 */ 140: 141: static int dosetkey __P((char *, char *)); 142: 143: #ifdef SIG_WINDOW 144: void 145: check_window_size(force) 146: int force; 147: { 148: #ifdef BSDSIGS 149: sigmask_t omask; 150: #endif /* BSDSIGS */ 151: int lins, cols; 152: 153: /* don't want to confuse things here */ 154: #ifdef BSDSIGS 155: omask = sigblock(sigmask(SIG_WINDOW)) & ~sigmask(SIG_WINDOW); 156: #else /* BSDSIGS */ 157: (void) sighold(SIG_WINDOW); 158: #endif /* BSDSIGS */ 159: 160: /* 161: * From: bret@shark.agps.lanl.gov (Bret Thaeler) Avoid sunview bug, where a 162: * partially hidden window gets a SIG_WINDOW every time the text is 163: * scrolled 164: */ 165: if (GetSize(&lins, &cols) || force) { 166: if (GettingInput) { 167: ClearLines(); 168: ClearDisp(); 169: MoveToLine(0); 170: MoveToChar(0); 171: ChangeSize(lins, cols); 172: Refresh(); 173: } 174: else 175: ChangeSize(lins, cols); 176: } 177: 178: #ifdef BSDSIGS 179: (void) sigsetmask(omask); /* can change it again */ 180: #else /* BSDSIGS */ 181: (void) sigrelse(SIG_WINDOW); 182: #endif /* BSDSIGS */ 183: } 184: 185: sigret_t 186: /*ARGSUSED*/ 187: window_change(snum) 188: int snum; 189: { 190: check_window_size(0); 191: #ifndef SIGVOID 192: return (snum); 193: #endif 194: } 195: 196: #endif /* SIG_WINDOW */ 197: 198: /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */ 199: #ifndef LPASS8 200: # define LPASS8 0 /* we don't have it. Too bad!! */ 201: #endif 202: 203: #ifndef CTRL 204: # define CTRL(c) ('c'&037) 205: #endif 206: 207: void 208: ed_set_tty_eight_bit() 209: { 210: #ifndef POSIX 211: # ifdef TERMIO 212: struct termio ttynio; 213: # else /* GSTTY */ 214: int ttynlb; 215: # endif /* TERMIO */ 216: #else /* POSIX */ 217: struct termios ttynio; 218: #endif /* POSIX */ 219: 220: #ifndef POSIX 221: # ifdef TERMIO 222: (void) ioctl(SHIN, TCGETA, (ioctl_t) & ttynio); 223: # else /* GSTTY */ 224: (void) ioctl(SHIN, TIOCLGET, (ioctl_t) & ttynlb); 225: # endif /* TERMIO */ 226: #else /* POSIX */ 227: (void) tcgetattr(SHIN, &ttynio); 228: #endif /* POSIX */ 229: 230: #if defined(TERMIO) || defined(POSIX) 231: Tty_eight_bit = (ttynio.c_cflag & CSIZE) == CS8; 232: #else /* GSTTY */ 233: Tty_eight_bit = ttynlb & (LPASS8 | LLITOUT); 234: #endif 235: } 236: 237: void 238: ed_I() 239: { 240: static int havesetup = 0; 241: 242: ResetInLine(); /* reset the input pointers */ 243: GettingInput = 0; /* just in case */ 244: LastKill = KillBuf; /* no kill buffer */ 245: 246: #ifdef DEBUG_EDIT 247: CheckMaps(); /* do a little error checking on key maps */ 248: #endif 249: 250: if (!havesetup) { /* if we have never been called */ 251: replacemode = 0; /* start out in insert mode */ 252: ed_IMaps(); 253: Hist_num = 0; 254: Expand = 0; 255: 256: #ifndef POSIX 257: # ifdef TERMIO 258: (void) ioctl(SHIN, TCGETA, (ioctl_t) & nio); 259: # ifdef CBAUD 260: T_Speed = nio.c_cflag & CBAUD; 261: # else 262: T_Speed = 0; 263: # endif 264: # else /* GSTTY */ 265: (void) ioctl(SHIN, TIOCGETP, (ioctl_t) & nb); /* normal setup */ 266: xb = nb; /* new setup */ 267: (void) ioctl(SHIN, TIOCGETC, (ioctl_t) & ntc); 268: xtc = ntc; 269: (void) ioctl(SHIN, TIOCGLTC, (ioctl_t) & nlc); 270: xlc = nlc; 271: # ifdef TIOCGPAGE 272: (void) ioctl(SHIN, TIOCGPAGE, (ioctl_t) & npc); 273: xpc = npc; 274: # endif /* TIOCGPAGE */ 275: (void) ioctl(SHIN, TIOCLGET, (ioctl_t) & nlb); 276: xlb = nlb; 277: T_Speed = nb.sg_ispeed; 278: # endif /* TERMIO */ 279: #else /* POSIX */ 280: (void) tcgetattr(SHIN, &nio); 281: T_Speed = cfgetispeed(&nio); 282: #endif /* POSIX */ 283: 284: #if defined(TERMIO) || defined(POSIX) 285: xio = nio; 286: 287: if ((nio.c_oflag & TAB3) == TAB3) { /* then no tabs */ 288: T_Tabs = 0; 289: } 290: else { 291: T_Tabs = 1; 292: } 293: 294: nio.c_iflag &= ~(INLCR | IGNCR); 295: nio.c_iflag |= (ICRNL); 296: 297: nio.c_oflag &= ~(ONLRET); 298: nio.c_oflag |= (OPOST | ONLCR); 299: /* don't muck with c_cflag */ 300: nio.c_lflag &= ~(NOFLSH | ECHOK | ECHONL | EXTPROC | FLUSHO); 301: nio.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN); 302: 303: # ifdef IRIX3_3 304: nio.c_line = NTTYDISC; 305: # endif /* IRIX3_3 */ 306: nio.c_cc[VINTR] = '\003'; /* ^C */ 307: nio.c_cc[VQUIT] = '\034'; /* ^\ */ 308: nio.c_cc[VERASE] = '\177'; /* ^? */ 309: nio.c_cc[VKILL] = '\025'; /* ^U */ 310: nio.c_cc[VEOF] = '\004';/* ^D */ 311: nio.c_cc[VEOL] = _POSIX_VDISABLE; 312: # ifdef VEOL2 313: nio.c_cc[VEOL2] = _POSIX_VDISABLE; 314: # endif 315: # ifdef VSWTCH 316: nio.c_cc[VSWTCH] = _POSIX_VDISABLE; 317: # endif /* VSWTCH */ 318: # ifdef VSTART 319: nio.c_cc[VSTART] = '\021'; /* ^Q */ 320: # endif /* VSTART */ 321: # ifdef VSTOP 322: nio.c_cc[VSTOP] = '\023'; /* ^S */ 323: # endif /* VSTOP */ 324: # ifdef VWERASE 325: nio.c_cc[VWERASE] = '\027'; /* ^W */ 326: # endif /* VWERASE */ 327: # ifdef VSUSP 328: nio.c_cc[VSUSP] = CSUSP; 329: # endif 330: # ifdef VDSUSP 331: nio.c_cc[VDSUSP] = '\031'; /* ^Y */ 332: # endif /* VDSUSP */ 333: # ifdef VREPRINT 334: nio.c_cc[VREPRINT] = '\022'; /* ^R */ 335: # endif /* WREPRINT */ 336: # ifdef VDISCARD 337: nio.c_cc[VDISCARD] = '\017'; /* ^O */ 338: # endif /* VDISCARD */ 339: # ifdef VLNEXT 340: nio.c_cc[VLNEXT] = '\026'; /* ^V */ 341: # endif /* VLNEXT */ 342: # ifdef VSTATUS 343: nio.c_cc[VSTATUS] = '\024'; /* ^T */ 344: # endif /* VSTATUS */ 345: # ifdef VPGOFF 346: nio.c_cc[VPGOFF] = ' '; /* " " */ 347: # endif /* VPGOFF */ 348: # ifdef VPAGE 349: nio.c_cc[VPAGE] = '\015'; /* ^M */ 350: # endif /* VPAGE */ 351: 352: # if defined(OREO) || defined(hpux) || defined(_IBMR2) 353: 354: (void) ioctl(SHIN, TIOCGLTC, (ioctl_t) & nlc); 355: xlc = nlc; 356: 357: nlc.t_suspc = '\032'; /* stop process signal */ 358: nlc.t_dsuspc = '\031'; /* delayed stop process signal */ 359: # ifdef hpux 360: /* 361: * These must be 0377. (Reserved) 362: */ 363: nlc.t_rprntc = _POSIX_VDISABLE; /* reprint line */ 364: nlc.t_flushc = _POSIX_VDISABLE; /* flush output (toggles) */ 365: nlc.t_werasc = _POSIX_VDISABLE; /* word erase */ 366: nlc.t_lnextc = _POSIX_VDISABLE; /* literal next character */ 367: # else 368: nlc.t_rprntc = '\022'; /* reprint line */ 369: nlc.t_flushc = '\017'; /* flush output (toggles) */ 370: nlc.t_werasc = '\027'; /* word erase */ 371: nlc.t_lnextc = '\026'; /* literal next character */ 372: # endif /* hpux */ 373: # endif /* OREO || hpux || _IBMR2 */ 374: # ifdef SIG_WINDOW 375: (void) sigset(SIG_WINDOW, window_change); /* for window systems */ 376: # endif 377: #else /* GSTTY */ /* V7, Berkeley style tty */ 378: 379: 380: if ((xb.sg_flags & XTABS) == XTABS) { /* check for no tabs mode */ 381: T_Tabs = 0; 382: } 383: else { 384: T_Tabs = 1; 385: } 386: 387: if (T_Tabs) { 388: nb.sg_flags &= ~(CBREAK | RAW | XTABS); 389: nb.sg_flags |= (ECHO | CRMOD | ANYP); 390: } 391: else { 392: nb.sg_flags &= ~(CBREAK | RAW); 393: nb.sg_flags |= (ECHO | CRMOD | XTABS | ANYP); 394: } 395: nlb &= ~(LPRTERA); /* let 8-bit mode stand as set */ 396: nlb |= (LCRTBS | LCRTERA | LCRTKIL); 397: 398: nb.sg_erase = '\177'; /* del prev. char == DEL */ 399: nb.sg_kill = '\025'; /* special case of del region */ 400: 401: ntc.t_intrc = '\003'; /* SIGINTR */ 402: ntc.t_quitc = '\034'; /* SIGQUIT */ 403: ntc.t_startc = '\021'; /* start output */ 404: ntc.t_stopc = '\023'; /* stop output */ 405: ntc.t_eofc = '\004'; /* no eof char during input... */ 406: # ifdef masscomp 407: /* NUL is prefered to <undef> in this char, DAS DEC-90. */ 408: ntc.t_brkc = '\0'; /* input delimiter (like nl) */ 409: # else 410: ntc.t_brkc = -1; /* input delimiter (like nl) */ 411: # endif 412: 413: nlc.t_suspc = '\032'; /* stop process signal */ 414: nlc.t_dsuspc = '\031'; /* delayed stop process signal */ 415: nlc.t_rprntc = '\022'; /* reprint line */ 416: nlc.t_flushc = '\017'; /* flush output (toggles) */ 417: nlc.t_werasc = '\027'; /* word erase */ 418: nlc.t_lnextc = '\026'; /* literal next character */ 419: 420: # ifdef TIOCGPAGE 421: npc.tps_length = 0; 422: npc.tps_lpos = 0; 423: npc.tps_statc = '\024'; /* Show status ^T */ 424: npc.tps_pagec = '\040'; /* show next page " " */ 425: npc.tps_pgoffc = '\015';/* Ignore paging until input ^M */ 426: npc.tps_flag = 0; 427: # endif /* TIOCGPAGE */ 428: 429: # ifdef SIG_WINDOW 430: (void) sigset(SIG_WINDOW, window_change); /* for window systems */ 431: # endif 432: #endif /* TERMIO */ 433: } 434: 435: /* 436: * if we have been called before but GotTermCaps isn't set, our TERM has 437: * changed, so get new t_c_s and try again 438: */ 439: 440: if (!GotTermCaps) 441: GetTermCaps(); /* does the obvious, but gets term type each 442: * time */ 443: 444: #if defined(TERMIO) || defined(POSIX) 445: xio.c_iflag &= ~(IGNCR); 446: xio.c_iflag |= (INLCR | ICRNL); 447: 448: Tty_eight_bit = (xio.c_cflag & CSIZE) == CS8; 449: 450: xio.c_oflag &= ~(ONLRET); 451: xio.c_oflag |= (OPOST | ONLCR); 452: 453: xio.c_lflag &= ~(NOFLSH | ICANON | ECHO | ECHOE | ECHOK | ECHONL | 454: EXTPROC | IEXTEN | FLUSHO); 455: xio.c_lflag |= (ISIG); 456: 457: # ifdef IRIX3_3 458: xio.c_line = NTTYDISC; 459: # endif /* IRIX3_3 */ 460: xio.c_cc[VINTR] = '\003'; /* ^C */ 461: xio.c_cc[VQUIT] = '\034'; /* ^\ */ 462: xio.c_cc[VERASE] = '\177'; /* ^? */ 463: xio.c_cc[VKILL] = '\025'; /* ^U */ 464: xio.c_cc[VMIN] = 1; /* one char at a time input */ 465: xio.c_cc[VTIME] = 0; /* don't time out */ 466: # ifdef VEOL2 467: xio.c_cc[VEOL2] = _POSIX_VDISABLE; 468: # endif /* VEOL2 */ 469: # ifdef VSWTCH 470: xio.c_cc[VSWTCH] = _POSIX_VDISABLE; 471: # endif /* VSWTCH */ 472: # ifdef VSTART 473: xio.c_cc[VSTART] = '\021'; /* ^Q */ 474: # endif /* VSTART */ 475: # ifdef VSTOP 476: xio.c_cc[VSTOP] = '\023'; /* ^S */ 477: # endif /* VSTOP */ 478: # ifdef VWERASE 479: xio.c_cc[VWERASE] = _POSIX_VDISABLE; 480: # endif /* VWERASE */ 481: # ifdef VSUSP 482: xio.c_cc[VSUSP] = _POSIX_VDISABLE; 483: # endif /* VSUSP */ 484: # ifdef VDSUSP 485: xio.c_cc[VDSUSP] = _POSIX_VDISABLE; 486: # endif /* VDSUSP */ 487: # ifdef VREPRINT 488: xio.c_cc[VREPRINT] = _POSIX_VDISABLE; 489: # endif /* VREPRINT */ 490: # ifdef VDISCARD 491: xio.c_cc[VDISCARD] = '\017';/* ^O */ 492: # endif /* VDISCARD */ 493: # ifdef VLNEXT 494: xio.c_cc[VLNEXT] = _POSIX_VDISABLE; 495: # endif /* VLNEXT */ 496: # ifdef VSTATUS 497: xio.c_cc[VSTATUS] = '\024'; /* ^T */ 498: # endif /* VSTATUS */ 499: # ifdef VPGOFF 500: xio.c_cc[VPGOFF] = ' '; /* " " */ 501: # endif /* VPGOFF */ 502: # ifdef VPAGE 503: xio.c_cc[VPAGE] = '\015'; /* ^M */ 504: # endif /* VPAGE */ 505: 506: # if defined(OREO) || defined(hpux) || defined(_IBMR2) 507: xlc.t_suspc = -1; /* stop process signal */ 508: xlc.t_dsuspc = -1; /* delayed stop process signal */ 509: # ifdef hpux 510: /* 511: * These must be 0377. (Reserved) 512: */ 513: xlc.t_rprntc = '\377'; /* reprint line */ 514: xlc.t_flushc = '\377'; /* flush output (toggles) */ 515: xlc.t_werasc = '\377'; /* word erase */ 516: xlc.t_lnextc = '\377'; /* literal next character */ 517: # else 518: xlc.t_rprntc = -1; /* reprint line */ 519: xlc.t_flushc = '\017'; /* flush output */ 520: xlc.t_werasc = -1; /* word erase */ 521: xlc.t_lnextc = -1; /* literal next character */ 522: # endif /* hpux */ 523: # endif /* OREO || hpux || _IBMR2 */ 524: #else /* GSTTY */ 525: if (T_Tabs) { 526: xb.sg_flags &= ~(RAW | ECHO | XTABS); 527: xb.sg_flags |= (CBREAK | CRMOD | ANYP); 528: } 529: else { 530: xb.sg_flags &= ~(RAW | ECHO); 531: xb.sg_flags |= (CBREAK | CRMOD | ANYP | XTABS); 532: } 533: 534: xb.sg_erase = '\177'; /* del prev. char == DEL */ 535: xb.sg_kill = '\025'; /* special case of del region */ 536: /* bugfix by Michael Boom */ 537: 538: xtc.t_intrc = '\003'; /* SIGINTR */ 539: xtc.t_quitc = '\034'; /* SIGQUIT */ 540: xtc.t_startc = '\021'; /* start output */ 541: xtc.t_stopc = '\023'; /* stop output */ 542: xtc.t_eofc = -1; /* no eof char during input... */ 543: # ifdef masscomp 544: /* NUL is prefered to <undef> in this char, DAS DEC-90. */ 545: xtc.t_brkc = '\0'; /* input delimiter (like nl) */ 546: # else 547: xtc.t_brkc = -1; /* input delimiter (like nl) */ 548: # endif 549: 550: xlc.t_suspc = -1; /* stop process signal (was CTRL(z)) */ 551: xlc.t_dsuspc = -1; /* delayed stop process signal */ 552: xlc.t_rprntc = -1; /* reprint line */ 553: xlc.t_flushc = '\017'; /* flush output */ 554: xlc.t_werasc = -1; /* word erase */ 555: xlc.t_lnextc = -1; /* literal next character */ 556: 557: # ifdef TIOCGPAGE 558: xpc.tps_length = 0; 559: xpc.tps_lpos = 0; 560: xpc.tps_statc = -1; /* disable show status */ 561: xpc.tps_pagec = -1; /* disable show next page */ 562: xpc.tps_pgoffc = -1; /* disable Ignore paging until input */ 563: xpc.tps_flag = 0; 564: # endif /* TIOCGPAGE */ 565: 566: xlb &= ~LPRTERA; 567: xlb |= (LCRTBS | LCRTERA | LCRTKIL); 568: Tty_eight_bit = nlb & (LPASS8 | LLITOUT); 569: #endif /* TERMIO || POSIX */ 570: havesetup = 1; 571: 572: /* Make sure the tty has a well-defined initial state */ 573: /* But don't bother to alter the settings if we are not editing */ 574: if (editing) { 575: Tty_raw_mode = 0; 576: (void) Rawmode(); 577: } 578: } 579: 580: static int 581: dosetkey(tcp, ncp) 582: char *tcp, *ncp; 583: { 584: if ((*tcp & 0377) > 0 && (*tcp & 0377) < 0377) { 585: *ncp = *tcp; 586: return 1; 587: } 588: return 0; 589: } 590: 591: /* 592: * Check and re-init the line. set the terminal into 1 char at a time mode. 593: */ 594: int 595: Rawmode() 596: { 597: #ifdef POSIX 598: speed_t tspeed; 599: #endif /* POSIX */ 600: 601: if (Tty_raw_mode) 602: return (0); 603: #ifdef _IBMR2 604: tx_disc.tx_which = 0; 605: if (ioctl(FSHTTY, TXGETLD, (ioctl_t) & tx_disc) < 0) 606: return (-1); 607: if (strcmp(tx_disc.tx_name, strPOSIX) != 0) { 608: edit_discipline = 1; 609: if (ioctl(FSHTTY, TXSETLD, (ioctl_t) strPOSIX) < 0) 610: return (-1); 611: } 612: #endif /* _IBMR2 */ 613: 614: #ifndef POSIX 615: # ifdef TERMIO 616: if (ioctl(SHIN, TCGETA, (ioctl_t) & testio) < 0) 617: return (-1); /* SHIN has been closed */ 618: # else /* GSTTY */ 619: if (ioctl(SHIN, TIOCGETP, (ioctl_t) & testsgb) < 0) 620: return (-1); /* SHIN has been closed */ 621: /* test the normal flags */ 622: # endif /* TERMIO */ 623: #else /* POSIX */ 624: if (tcgetattr(SHIN, &testio) < 0) 625: return (-1); /* SHIN has been closed */ 626: #endif /* POSIX */ 627: 628: #if defined(POSIX) || defined(TERMIO) 629: Tty_eight_bit = (testio.c_cflag & CSIZE) == CS8; 630: if (testio.c_cflag != nio.c_cflag) { 631: nio.c_cflag = testio.c_cflag; 632: xio.c_cflag = testio.c_cflag; 633: } 634: # ifdef POSIX 635: /* 636: * Fix from: Steven (Steve) B. Green <xrsbg@charney.gsfc.nasa.gov> 637: * Speed was not being set up correctly under POSIX. 638: */ 639: if ((tspeed = cfgetispeed(&testio)) == 0) 640: tspeed = cfgetospeed(&testio); 641: if (tspeed != cfgetispeed(&nio)) { 642: T_Speed = tspeed; 643: (void) cfsetispeed(&nio, T_Speed); 644: (void) cfsetospeed(&nio, T_Speed); 645: (void) cfsetispeed(&xio, T_Speed); 646: (void) cfsetospeed(&xio, T_Speed); 647: } 648: # else /* !POSIX */ 649: # ifdef CBAUD 650: T_Speed = nio.c_cflag & CBAUD; 651: # else 652: T_Speed = 0; 653: # endif /* CBAUD */ 654: # endif /* !POSIX */ 655: 656: if ((testio.c_lflag != nio.c_lflag) && 657: (testio.c_lflag != xio.c_lflag)) { 658: /* Christos: There was and ifdef here that would set ECHONL!?? */ 659: nio.c_lflag = testio.c_lflag; 660: nio.c_lflag &= ~(NOFLSH | ECHOK | ECHONL | EXTPROC | FLUSHO); 661: nio.c_lflag |= (ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOCTL); 662: xio.c_lflag = testio.c_lflag; 663: xio.c_lflag &= ~(NOFLSH | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | 664: ECHONL | ECHOCTL | EXTPROC | FLUSHO); 665: xio.c_lflag |= (ISIG); 666: } 667: 668: if ((testio.c_iflag != nio.c_iflag) && 669: (testio.c_iflag != xio.c_iflag)) { 670: nio.c_iflag = testio.c_iflag; 671: nio.c_iflag &= ~(INLCR | IGNCR); 672: nio.c_iflag |= (ICRNL); 673: xio.c_iflag = testio.c_iflag; 674: xio.c_iflag &= ~(INLCR | IGNCR); 675: xio.c_iflag |= (ICRNL); 676: } 677: 678: if ((testio.c_oflag != nio.c_oflag) && 679: (testio.c_oflag != xio.c_oflag)) { 680: /* Christos: There was and ifdef here that would set ONLRET!?? */ 681: nio.c_oflag = testio.c_oflag; 682: nio.c_oflag &= ~(ONLRET); 683: nio.c_oflag |= (OPOST | ONLCR); 684: xio.c_oflag = testio.c_oflag; 685: xio.c_oflag &= ~(ONLRET); 686: xio.c_oflag |= (OPOST | ONLCR); 687: } 688: if ((nio.c_oflag & TAB3) == TAB3) { /* check for no tabs mode */ 689: T_Tabs = 0; 690: } 691: else { 692: T_Tabs = CanWeTab(); 693: } 694: if (dosetkey((char *) &testio.c_cc[VINTR], (char *) &nio.c_cc[VINTR])) 695: (void) dosetkey((char *) &testio.c_cc[VINTR], (char *) &xio.c_cc[VINTR]); 696: if (dosetkey((char *) &testio.c_cc[VQUIT], (char *) &nio.c_cc[VQUIT])) 697: (void) dosetkey((char *) &testio.c_cc[VQUIT], (char *) &xio.c_cc[VQUIT]); 698: if (dosetkey((char *) &testio.c_cc[VERASE], (char *) &nio.c_cc[VERASE])) 699: (void) dosetkey((char *) &testio.c_cc[VERASE], 700: (char *) &xio.c_cc[VERASE]); 701: if (dosetkey((char *) &testio.c_cc[VKILL], (char *) &nio.c_cc[VKILL])) 702: (void) dosetkey((char *) &testio.c_cc[VKILL], 703: (char *) &xio.c_cc[VKILL]); 704: if (testio.c_cc[VEOF] != 1) { /* 'cause VEOL == VNUM, and 1 is raw 705: * mode */ 706: (void) dosetkey((char *) &testio.c_cc[VEOF], (char *) &nio.c_cc[VEOF]); 707: (void) dosetkey((char *) &testio.c_cc[VEOL], (char *) &nio.c_cc[VEOL]); 708: } 709: # ifdef VSWTCH 710: if (dosetkey((char *) &testio.c_cc[VSWTCH], (char *) &nio.c_cc[VSWTCH])) 711: (void) dosetkey((char *) &testio.c_cc[VSWTCH], 712: (char *) &xio.c_cc[VSWTCH]); 713: # endif /* VSWTCH */ 714: # ifdef VEOL2 715: if (dosetkey((char *) &testio.c_cc[VEOL2], (char *) &nio.c_cc[VEOL2])) 716: (void) dosetkey((char *) &testio.c_cc[VEOL2], 717: (char *) &xio.c_cc[VEOL2]); 718: # endif /* VEOL2 */ 719: # ifdef VSTART 720: if (dosetkey((char *) &testio.c_cc[VSTART], (char *) &nio.c_cc[VSTART])) 721: (void) dosetkey((char *) &testio.c_cc[VSTART], 722: (char *) &xio.c_cc[VSTART]); 723: # endif /* VSTART */ 724: # ifdef VSTOP 725: if (dosetkey((char *) &testio.c_cc[VSTOP], (char *) &nio.c_cc[VSTOP])) 726: (void) dosetkey((char *) &testio.c_cc[VSTOP], 727: (char *) &xio.c_cc[VSTOP]); 728: # endif /* VSTOP */ 729: # ifdef VWERASE 730: (void) dosetkey((char *) &testio.c_cc[VWERASE], 731: (char *) &nio.c_cc[VWERASE]); 732: # endif /* VWERASE */ 733: # ifdef VREPRINT 734: (void) dosetkey((char *) &testio.c_cc[VREPRINT], 735: (char *) &nio.c_cc[VREPRINT]); 736: # endif /* VREPRINT */ 737: # ifdef VSUSP 738: (void) dosetkey((char *) &testio.c_cc[VSUSP], (char *) &nio.c_cc[VSUSP]); 739: # endif /* VSUSP */ 740: # ifdef VDSUSP 741: (void) dosetkey((char *) &testio.c_cc[VDSUSP], (char *) &nio.c_cc[VDSUSP]); 742: # endif /* VDSUSP */ 743: # ifdef VLNEXT 744: (void) dosetkey((char *) &testio.c_cc[VLNEXT], (char *) &nio.c_cc[VLNEXT]); 745: # endif /* VLNEXT */ 746: # ifdef VDISCARD 747: if (dosetkey((char *) &testio.c_cc[VDISCARD], (char *) &nio.c_cc[VDISCARD])) 748: (void) dosetkey((char *) &testio.c_cc[VDISCARD], 749: (char *) &xio.c_cc[VDISCARD]); 750: # endif /* VDISCARD */ 751: # ifdef VSTATUS 752: if (dosetkey((char *) &testio.c_cc[VSTATUS], (char *) &nio.c_cc[VSTATUS])) 753: (void) dosetkey((char *) &testio.c_cc[VSTATUS], 754: (char *) &xio.c_cc[VSTATUS]); 755: # endif /* VSTATUS */ 756: # ifdef VPGOFF 757: if (dosetkey((char *) &testio.c_cc[VPGOFF], (char *) &nio.c_cc[VPGOFF])) 758: (void) dosetkey((char *) &testio.c_cc[VPGOFF], 759: (char *) &xio.c_cc[VPGOFF]); 760: # endif /* VPGOFF */ 761: # ifdef VPAGE 762: if (dosetkey((char *) &testio.c_cc[VPAGE], (char *) &nio.c_cc[VPAGE])) 763: (void) dosetkey((char *) &testio.c_cc[VPAGE], 764: (char *) &xio.c_cc[VPAGE]); 765: # endif /* VPAGE */ 766: 767: # ifndef POSIX 768: if (ioctl(SHIN, TCSETAW, (ioctl_t) & xio) < 0) 769: return (-1); 770: # else /* POSIX */ 771: if (tcsetattr(SHIN, TCSADRAIN, &xio) < 0) 772: return (-1); 773: # endif /* POSIX */ 774: 775: # if defined(OREO) || defined(hpux) || defined(_IBMR2) 776: /* get and set the new local chars */ 777: if (ioctl(SHIN, TIOCGLTC, (ioctl_t) & testlc) < 0) 778: return (-1); 779: 780: (void) dosetkey((char *) &testlc.t_suspc, (char *) &nlc.t_suspc); 781: (void) dosetkey((char *) &testlc.t_dsuspc, (char *) &nlc.t_dsuspc); 782: (void) dosetkey((char *) &testlc.t_rprntc, (char *) &nlc.t_rprntc); 783: if (dosetkey((char *) &testlc.t_flushc, (char *) &nlc.t_flushc)) 784: xlc.t_flushc = nlc.t_flushc; 785: (void) dosetkey((char *) &testlc.t_werasc, (char *) &nlc.t_werasc); 786: (void) dosetkey((char *) &testlc.t_lnextc, (char *) &nlc.t_lnextc); 787: if (ioctl(SHIN, TIOCSLTC, (ioctl_t) & xlc) < 0) 788: return (-1); 789: # endif /* OREO || hpux || _IBMR2 */ 790: 791: #else /* GSTTY */ /* for BSD... */ 792: 793: if (testsgb.sg_ispeed != nb.sg_ispeed) { 794: nb.sg_ispeed = testsgb.sg_ispeed; 795: xb.sg_ispeed = testsgb.sg_ispeed; 796: } 797: if (testsgb.sg_ospeed != nb.sg_ospeed) { 798: nb.sg_ospeed = testsgb.sg_ospeed; 799: xb.sg_ospeed = testsgb.sg_ospeed; 800: } 801: T_Speed = nb.sg_ispeed; 802: 803: /* get and set the terminal characters */ 804: /* bugfix by Bruce Robertson <bruce%tigger.gwd.tek.com@relay.cs.net> */ 805: /* include erase and kill in the tests */ 806: if (dosetkey((char *) &testsgb.sg_erase, (char *) &nb.sg_erase)) 807: xb.sg_erase = nb.sg_erase; 808: if (dosetkey((char *) &testsgb.sg_kill, (char *) &nb.sg_kill)) 809: xb.sg_kill = nb.sg_kill; 810: 811: (void) ioctl(SHIN, TIOCGETC, (ioctl_t) & testtc); 812: if (dosetkey((char *) &testtc.t_intrc, (char *) &ntc.t_intrc)) 813: xtc.t_intrc = ntc.t_intrc; 814: if (dosetkey((char *) &testtc.t_quitc, (char *) &ntc.t_quitc)) 815: xtc.t_quitc = ntc.t_quitc; 816: if (dosetkey((char *) &testtc.t_startc, (char *) &ntc.t_startc)) 817: xtc.t_startc = ntc.t_startc; 818: if (dosetkey((char *) &testtc.t_stopc, (char *) &ntc.t_stopc)) 819: xtc.t_stopc = ntc.t_stopc; 820: if (dosetkey((char *) &testtc.t_eofc, (char *) &ntc.t_eofc)) 821: xtc.t_eofc = ntc.t_eofc;/* someone might want to change EOF */ 822: /* in general, t_brkc shouldn't change */ 823: (void) dosetkey((char *) &testtc.t_brkc, (char *) &ntc.t_brkc); 824: 825: if (ioctl(SHIN, TIOCLGET, (ioctl_t) & testnlb) < 0) 826: return (-1); 827: 828: Tty_eight_bit = testnlb & (LPASS8 | LLITOUT); 829: 830: /* If they have changed any tty settings, we have to keep up with them. */ 831: /* PWP: but only believe them if changes are made to cooked mode! */ 832: if (((testsgb.sg_flags != nb.sg_flags) || (testnlb != nlb)) && 833: ((testsgb.sg_flags != xb.sg_flags) || (testnlb != xlb)) && 834: !(testsgb.sg_flags & (RAW | CBREAK))) { 835: 836: nb.sg_flags = testsgb.sg_flags; 837: 838: /* 839: * re-test for some things here (like maybe the user typed "stty -tabs" 840: */ 841: if ((nb.sg_flags & XTABS) == XTABS) { /* check for no tabs mode */ 842: T_Tabs = 0; 843: } 844: else { 845: T_Tabs = CanWeTab(); 846: } 847: 848: nb.sg_flags &= ~(CBREAK | RAW); 849: nb.sg_flags |= (ECHO | CRMOD | ANYP); 850: if (T_Tabs) { /* order of &= and |= is important to XTABS */ 851: nb.sg_flags &= ~XTABS; 852: } 853: else { 854: nb.sg_flags |= XTABS; 855: } 856: 857: xb.sg_flags = testsgb.sg_flags; 858: if (T_Tabs) { 859: xb.sg_flags &= ~(RAW | ECHO | XTABS); 860: xb.sg_flags |= (CBREAK | CRMOD | ANYP); 861: } 862: else { 863: xb.sg_flags &= ~(RAW | ECHO); 864: xb.sg_flags |= (CBREAK | CRMOD | ANYP | XTABS); 865: } 866: 867: nlb = testnlb; 868: /* 869: * Bugfix: turn off output flushing. By: 870: * Justin Bur 871: * Universite de Montreal - IRO uunet!utai!musocs!iros1!justin 872: * Montreal (Qc) Canada H3C 3J7 <bur%iro.udem.cdn@ubc.csnet> 873: * Thanks! 874: */ 875: nlb &= ~(LPRTERA | LFLUSHO); 876: nlb |= (LCRTBS | LCRTERA | LCRTKIL); 877: 878: xlb = nlb; 879: } 880: 881: /* get and set the new local chars */ 882: if (ioctl(SHIN, TIOCGLTC, (ioctl_t) & testlc) < 0) 883: return (-1); 884: # ifdef TIOCGPAGE 885: if (ioctl(SHIN, TIOCGPAGE, (ioctl_t) & testpc) < 0) 886: return (-1); 887: (void) dosetkey((char *) &testpc.tps_statc, (char *) &npc.tps_statc); 888: (void) dosetkey((char *) &testpc.tps_pagec, (char *) &npc.tps_pagec); 889: (void) dosetkey((char *) &testpc.tps_pgoffc, (char *) &npc.tps_pgoffc); 890: # endif /* TIOCGPAGE */ 891: 892: (void) dosetkey((char *) &testlc.t_suspc, (char *) &nlc.t_suspc); 893: (void) dosetkey((char *) &testlc.t_dsuspc, (char *) &nlc.t_dsuspc); 894: if (dosetkey((char *) &testlc.t_flushc, (char *) &nlc.t_flushc)) 895: xlc.t_flushc = nlc.t_flushc; 896: (void) dosetkey((char *) &testlc.t_werasc, (char *) &nlc.t_werasc); 897: (void) dosetkey((char *) &testlc.t_rprntc, (char *) &nlc.t_rprntc); 898: (void) dosetkey((char *) &testlc.t_lnextc, (char *) &nlc.t_lnextc); 899: 900: if (ioctl(SHIN, TIOCSETN, (ioctl_t) & xb) < 0) 901: return (-1); 902: if (ioctl(SHIN, TIOCSETC, (ioctl_t) & xtc) < 0) 903: return (-1); 904: if (ioctl(SHIN, TIOCSLTC, (ioctl_t) & xlc) < 0) 905: return (-1); 906: # ifdef TIOCGPAGE 907: if (ioctl(SHIN, TIOCSPAGE, (ioctl_t) & xpc) < 0) 908: return (-1); 909: # endif /* TIOCGPAGE */ 910: if (ioctl(SHIN, TIOCLSET, (ioctl_t) & xlb) < 0) 911: return (-1); 912: # endif /* TERMIO || POSIX */ 913: Tty_raw_mode = 1; 914: flush(); /* flush any buffered output */ 915: return (0); 916: } 917: 918: int 919: Cookedmode() 920: { /* set tty in normal setup */ 921: sigret_t(*orig_intr) (); 922: 923: #ifdef _IBMR2 924: if (edit_discipline) { 925: if (ioctl(SHIN, TXSETLD, (ioctl_t) & tx_disc) < 0) 926: return (-1); 927: edit_discipline = 0; 928: } 929: #endif /* _IBMR2 */ 930: if (!Tty_raw_mode) 931: return (0); 932: 933: #ifdef BSDSIGS 934: orig_intr = signal(SIGINT, SIG_IGN); /* hold this for reseting tty */ 935: #else 936: orig_intr = sigset(SIGINT, SIG_IGN); /* hold this for reseting tty */ 937: #endif /* BSDSIGS */ 938: #ifndef POSIX 939: # ifdef TERMIO 940: if (ioctl(SHIN, TCSETAW, (ioctl_t) & nio) < 0) 941: return (-1); 942: # if defined(OREO) || defined(hpux) || defined(_IBMR2) 943: if (ioctl(SHIN, TIOCSLTC, (ioctl_t) & nlc) < 0) 944: return (-1); 945: # endif /* OREO || hpux || _IBMR2 */ 946: # else /* GSTTY */ /* for BSD... */ 947: if (ioctl(SHIN, TIOCSETN, (ioctl_t) & nb) < 0) 948: return (-1); 949: if (ioctl(SHIN, TIOCSETC, (ioctl_t) & ntc) < 0) 950: return (-1); 951: if (ioctl(SHIN, TIOCSLTC, (ioctl_t) & nlc) < 0) 952: return (-1); 953: # ifdef TIOCGPAGE 954: if (ioctl(SHIN, TIOCSPAGE, (ioctl_t) & npc) < 0) 955: return (-1); 956: # endif /* TIOCGPAGE */ 957: if (ioctl(SHIN, TIOCLSET, (ioctl_t) & nlb) < 0) 958: return (-1); 959: # endif /* TERMIO */ 960: #else /* POSIX */ 961: if (tcsetattr(SHIN, TCSADRAIN, &nio) < 0) 962: return (-1); 963: # if defined(OREO) || defined(hpux) || defined(_IBMR2) 964: if (ioctl(SHIN, TIOCSLTC, (ioctl_t) & nlc) < 0) 965: return (-1); 966: # endif /* OREO || hpux || _IBMR2 */ 967: #endif /* POSIX */ 968: Tty_raw_mode = 0; 969: #ifdef BSDSIGS 970: (void) signal(SIGINT, orig_intr); /* take these again */ 971: #else 972: (void) sigset(SIGINT, orig_intr); /* take these again */ 973: #endif /* BSDSIGS */ 974: return (0); 975: } 976: 977: void 978: ResetInLine() 979: { 980: Cursor = InputBuf; /* reset cursor */ 981: LastChar = InputBuf; 982: InputLim = &InputBuf[INBUFSIZ - 2]; 983: Mark = InputBuf; 984: MetaNext = 0; 985: Cur_KeyMap = CcKeyMap; 986: AltKeyMap = 0; 987: Hist_num = 0; 988: DoingArg = 0; 989: Argument = 1; 990: #ifdef notdef 991: LastKill = KillBuf; /* no kill buffer */ 992: #endif 993: LastCmd = F_UNASSIGNED; /* previous command executed */ 994: MacroLvl = -1; /* no currently active macros */ 995: } 996: 997: static Char *Input_Line = NULL; 998: int 999: Load_input_line() 1000: { 1001: long chrs = 0; 1002: 1003: if (Input_Line) 1004: xfree((ptr_t) Input_Line); 1005: Input_Line = NULL; 1006: 1007: if (Tty_raw_mode) 1008: return 0; 1009: 1010: #ifdef FIONREAD 1011: (void) ioctl(SHIN, FIONREAD, &chrs); 1012: if (chrs > 0) { 1013: char buf[BUFSIZ]; 1014: 1015: chrs = read(SHIN, buf, (size_t) min(chrs, BUFSIZ - 1)); 1016: if (chrs > 0) { 1017: buf[chrs] = NULL; 1018: Input_Line = Strsave(str2short(buf)); 1019: PushMacro(Input_Line); 1020: } 1021: } 1022: #endif 1023: return chrs > 0; 1024: } 1025: 1026: /* 1027: * Bugfix (in Swedish) by: 1028: * Johan Widen 1029: * SICS, PO Box 1263, S-163 13 SPANGA, SWEDEN 1030: * {mcvax,munnari,cernvax,diku,inria,prlb2,penet,ukc,unido}!enea!sics.se!jw 1031: * Internet: jw@sics.se 1032: * 1033: * (via Hans J Albertsson (thanks)) 1034: */ 1035: 1036: void 1037: QModeOn() 1038: { 1039: #ifndef POSIX 1040: # ifndef TERMIO 1041: struct sgttyb rawb; 1042: # else 1043: struct termio rawb; 1044: # endif /* TERMIO */ 1045: #else /* POSIX */ 1046: struct termios rawb; 1047: #endif /* POSIX */ 1048: 1049: if (MacroLvl >= 0) 1050: return; 1051: 1052: #if defined(TERMIO) || defined(POSIX) 1053: rawb = xio; 1054: rawb.c_lflag &= ~(ISIG | IEXTEN | PARENB); 1055: rawb.c_iflag &= ~(IXON | IXOFF); 1056: # ifndef POSIX 1057: if (ioctl(SHIN, TCSETAW, (ioctl_t) & rawb) < 0) 1058: return; 1059: # else /* POSIX */ 1060: if (tcsetattr(SHIN, TCSADRAIN, &rawb) < 0) 1061: return; 1062: # endif /* POSIX */ 1063: #else /* GSTTYB */ 1064: 1065: rawb = xb; 1066: rawb.sg_flags &= ~(CBREAK); 1067: rawb.sg_flags |= RAW; 1068: if (ioctl(SHIN, TIOCSETN, (ioctl_t) & rawb) < 0) 1069: return; 1070: #endif /* TERMIO || POSIX */ 1071: Tty_quote_mode = 1; 1072: return; 1073: } 1074: 1075: void 1076: QModeOff() 1077: { 1078: if (!Tty_quote_mode) 1079: return; 1080: Tty_quote_mode = 0; 1081: #if defined(TERMIO) || defined(POSIX) 1082: # ifndef POSIX 1083: if (ioctl(SHIN, TCSETAW, (ioctl_t) & xio) < 0) 1084: return; 1085: # else /* POSIX */ 1086: if (tcsetattr(SHIN, TCSADRAIN, &xio) < 0) 1087: return; 1088: # endif /* POSIX */ 1089: #else /* GSTTYB */ 1090: if (ioctl(SHIN, TIOCSETN, (ioctl_t) & xb) < 0) 1091: return; 1092: #endif /* !TERMIO && !POSIX */ 1093: return; 1094: }