tty.cxx

Go to the documentation of this file.
00001 // @(#)root/editline:$Id: tty.cxx 36313 2010-10-12 12:40:20Z axel $
00002 // Author: Mary-Louise Gill, 2009
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 /*      $NetBSD: tty.c,v 1.15 2001/05/17 01:02:17 christos Exp $        */
00013 
00014 /*-
00015  * Copyright (c) 1992, 1993
00016  *      The Regents of the University of California.  All rights reserved.
00017  *
00018  * This code is derived from software contributed to Berkeley by
00019  * Christos Zoulas of Cornell University.
00020  *
00021  * Redistribution and use in source and binary forms, with or without
00022  * modification, are permitted provided that the following conditions
00023  * are met:
00024  * 1. Redistributions of source code must retain the above copyright
00025  *    notice, this list of conditions and the following disclaimer.
00026  * 2. Redistributions in binary form must reproduce the above copyright
00027  *    notice, this list of conditions and the following disclaimer in the
00028  *    documentation and/or other materials provided with the distribution.
00029  * 3. Neither the name of the University nor the names of its contributors
00030  *    may be used to endorse or promote products derived from this software
00031  *    without specific prior written permission.
00032  *
00033  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00034  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00035  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00036  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00037  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00038  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00039  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00040  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00041  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00042  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00043  * SUCH DAMAGE.
00044  */
00045 
00046 #include "compat.h"
00047 
00048 /*
00049  * tty.c: tty interface stuff
00050  */
00051 #include "sys.h"
00052 #include "tty.h"
00053 #include "el.h"
00054 #include "errno.h"
00055 #include "stdio.h"
00056 
00057 
00058 struct TTYModes_t {
00059    const char* fName;
00060    u_int fValue;
00061    int fType;
00062 };
00063 
00064 struct TTYMap_t {
00065    int fNCh;                /* Internal rep of chars */
00066    int fOCh;                /* Termio rep of chars */
00067    ElAction_t fBind[3];     /* emacs, vi, and vi-cmd */
00068 };
00069 
00070 
00071 el_private const TTYPerm_t ttyperm = {
00072    {
00073       { "iflag:", ICRNL, (INLCR | IGNCR) },
00074       { "oflag:", (OPOST | ONLCR), ONLRET },
00075       { "cflag:", 0, 0 },
00076       { "lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN),
00077         (NOFLSH | ECHONL | EXTPROC | FLUSHO) },
00078       { "chars:", 0, 0 },
00079    },
00080    {
00081       { "iflag:", (INLCR | ICRNL), IGNCR },
00082       { "oflag:", (OPOST | ONLCR), ONLRET },
00083       { "cflag:", 0, 0 },
00084       { "lflag:", ISIG,
00085         (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO) },
00086       { "chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) |
00087                    C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) |
00088                    C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0 }
00089    },
00090    {
00091       { "iflag:", 0, IXON | IXOFF | INLCR | ICRNL },
00092       { "oflag:", 0, 0 },
00093       { "cflag:", 0, 0 },
00094       { "lflag:", 0, ISIG | IEXTEN },
00095       { "chars:", 0, 0 },
00096    }
00097 };
00098 
00099 el_private const TTYChar_t ttychar = {
00100    {
00101       CINTR, CQUIT, CERASE, CKILL,
00102       CEOF, CEOL, CEOL2, CSWTCH,
00103       CDSWTCH, CERASE2, CSTART, CSTOP,
00104       CWERASE, CSUSP, CDSUSP, CREPRINT,
00105       CDISCARD, CLNEXT, CSTATUS, CPAGE,
00106       CPGOFF, CKILL2, CBRK, CMIN,
00107       CTIME
00108    },
00109    {
00110       CINTR, CQUIT, CERASE, CKILL,
00111       _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
00112       _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
00113       _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
00114       CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
00115       _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
00116       0
00117    },
00118    {
00119       0, 0, 0, 0,
00120       0, 0, 0, 0,
00121       0, 0, 0, 0,
00122       0, 0, 0, 0,
00123       0, 0, 0, 0,
00124       0, 0, 0, 0,
00125       0
00126    }
00127 };
00128 
00129 el_private const TTYMap_t tty_map[] = {
00130 #ifdef VERASE
00131    { C_ERASE, VERASE,
00132      { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
00133 #endif /* VERASE */
00134 #ifdef VERASE2
00135    { C_ERASE2, VERASE2,
00136      { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } },
00137 #endif /* VERASE2 */
00138 #ifdef VKILL
00139    { C_KILL, VKILL,
00140      { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
00141 #endif /* VKILL */
00142 #ifdef VKILL2
00143    { C_KILL2, VKILL2,
00144      { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } },
00145 #endif /* VKILL2 */
00146 #ifdef VEOF
00147    { C_EOF, VEOF,
00148      { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } },
00149 #endif /* VEOF */
00150 #ifdef VWERASE
00151    { C_WERASE, VWERASE,
00152      { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } },
00153 #endif /* VWERASE */
00154 #ifdef VREPRINT
00155    { C_REPRINT, VREPRINT,
00156      { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } },
00157 #endif /* VREPRINT */
00158 #ifdef VLNEXT
00159    { C_LNEXT, VLNEXT,
00160      { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } },
00161 #endif /* VLNEXT */
00162    { -1, -1,
00163      { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } }
00164 };
00165 
00166 el_private const TTYModes_t ttymodes[] = {
00167 #ifdef  IGNBRK
00168    { "ignbrk", IGNBRK, MD_INP },
00169 #endif /* IGNBRK */
00170 #ifdef  BRKINT
00171    { "brkint", BRKINT, MD_INP },
00172 #endif /* BRKINT */
00173 #ifdef  IGNPAR
00174    { "ignpar", IGNPAR, MD_INP },
00175 #endif /* IGNPAR */
00176 #ifdef  PARMRK
00177    { "parmrk", PARMRK, MD_INP },
00178 #endif /* PARMRK */
00179 #ifdef  INPCK
00180    { "inpck", INPCK, MD_INP },
00181 #endif /* INPCK */
00182 #ifdef  ISTRIP
00183    { "istrip", ISTRIP, MD_INP },
00184 #endif /* ISTRIP */
00185 #ifdef  INLCR
00186    { "inlcr", INLCR, MD_INP },
00187 #endif /* INLCR */
00188 #ifdef  IGNCR
00189    { "igncr", IGNCR, MD_INP },
00190 #endif /* IGNCR */
00191 #ifdef  ICRNL
00192    { "icrnl", ICRNL, MD_INP },
00193 #endif /* ICRNL */
00194 #ifdef  IUCLC
00195    { "iuclc", IUCLC, MD_INP },
00196 #endif /* IUCLC */
00197 #ifdef  IXON
00198    { "ixon", IXON, MD_INP },
00199 #endif /* IXON */
00200 #ifdef  IXANY
00201    { "ixany", IXANY, MD_INP },
00202 #endif /* IXANY */
00203 #ifdef  IXOFF
00204    { "ixoff", IXOFF, MD_INP },
00205 #endif /* IXOFF */
00206 #ifdef  IMAXBEL
00207    { "imaxbel", IMAXBEL, MD_INP },
00208 #endif /* IMAXBEL */
00209 
00210 #ifdef  OPOST
00211    { "opost", OPOST, MD_OUT },
00212 #endif /* OPOST */
00213 #ifdef  OLCUC
00214    { "olcuc", OLCUC, MD_OUT },
00215 #endif /* OLCUC */
00216 #ifdef  ONLCR
00217    { "onlcr", ONLCR, MD_OUT },
00218 #endif /* ONLCR */
00219 #ifdef  OCRNL
00220    { "ocrnl", OCRNL, MD_OUT },
00221 #endif /* OCRNL */
00222 #ifdef  ONOCR
00223    { "onocr", ONOCR, MD_OUT },
00224 #endif /* ONOCR */
00225 #ifdef ONOEOT
00226    { "onoeot", ONOEOT, MD_OUT },
00227 #endif /* ONOEOT */
00228 #ifdef  ONLRET
00229    { "onlret", ONLRET, MD_OUT },
00230 #endif /* ONLRET */
00231 #ifdef  OFILL
00232    { "ofill", OFILL, MD_OUT },
00233 #endif /* OFILL */
00234 #ifdef  OFDEL
00235    { "ofdel", OFDEL, MD_OUT },
00236 #endif /* OFDEL */
00237 #ifdef  NLDLY
00238    { "nldly", NLDLY, MD_OUT },
00239 #endif /* NLDLY */
00240 #ifdef  CRDLY
00241    { "crdly", CRDLY, MD_OUT },
00242 #endif /* CRDLY */
00243 #ifdef  TABDLY
00244    { "tabdly", TABDLY, MD_OUT },
00245 #endif /* TABDLY */
00246 #ifdef  XTABS
00247    { "xtabs", XTABS, MD_OUT },
00248 #endif /* XTABS */
00249 #ifdef  BSDLY
00250    { "bsdly", BSDLY, MD_OUT },
00251 #endif /* BSDLY */
00252 #ifdef  VTDLY
00253    { "vtdly", VTDLY, MD_OUT },
00254 #endif /* VTDLY */
00255 #ifdef  FFDLY
00256    { "ffdly", FFDLY, MD_OUT },
00257 #endif /* FFDLY */
00258 #ifdef  PAGEOUT
00259    { "pageout", PAGEOUT, MD_OUT },
00260 #endif /* PAGEOUT */
00261 #ifdef  WRAP
00262    { "wrap", WRAP, MD_OUT },
00263 #endif /* WRAP */
00264 
00265 #ifdef  CIGNORE
00266    { "cignore", CIGNORE, MD_CTL },
00267 #endif /* CBAUD */
00268 #ifdef  CBAUD
00269    { "cbaud", CBAUD, MD_CTL },
00270 #endif /* CBAUD */
00271 #ifdef  CSTOPB
00272    { "cstopb", CSTOPB, MD_CTL },
00273 #endif /* CSTOPB */
00274 #ifdef  CREAD
00275    { "cread", CREAD, MD_CTL },
00276 #endif /* CREAD */
00277 #ifdef  PARENB
00278    { "parenb", PARENB, MD_CTL },
00279 #endif /* PARENB */
00280 #ifdef  PARODD
00281    { "parodd", PARODD, MD_CTL },
00282 #endif /* PARODD */
00283 #ifdef  HUPCL
00284    { "hupcl", HUPCL, MD_CTL },
00285 #endif /* HUPCL */
00286 #ifdef  CLOCAL
00287    { "clocal", CLOCAL, MD_CTL },
00288 #endif /* CLOCAL */
00289 #ifdef  LOBLK
00290    { "loblk", LOBLK, MD_CTL },
00291 #endif /* LOBLK */
00292 #ifdef  CIBAUD
00293    { "cibaud", CIBAUD, MD_CTL },
00294 #endif /* CIBAUD */
00295 #ifdef CRTSCTS
00296 # ifdef CCTS_OFLOW
00297    { "ccts_oflow", CCTS_OFLOW, MD_CTL },
00298 # else
00299    { "crtscts", CRTSCTS, MD_CTL },
00300 # endif /* CCTS_OFLOW */
00301 #endif /* CRTSCTS */
00302 #ifdef CRTS_IFLOW
00303    { "crts_iflow", CRTS_IFLOW, MD_CTL },
00304 #endif /* CRTS_IFLOW */
00305 #ifdef CDTRCTS
00306    { "cdtrcts", CDTRCTS, MD_CTL },
00307 #endif /* CDTRCTS */
00308 #ifdef MDMBUF
00309    { "mdmbuf", MDMBUF, MD_CTL },
00310 #endif /* MDMBUF */
00311 #ifdef RCV1EN
00312    { "rcv1en", RCV1EN, MD_CTL },
00313 #endif /* RCV1EN */
00314 #ifdef XMT1EN
00315    { "xmt1en", XMT1EN, MD_CTL },
00316 #endif /* XMT1EN */
00317 
00318 #ifdef  ISIG
00319    { "isig", ISIG, MD_LIN },
00320 #endif /* ISIG */
00321 #ifdef  ICANON
00322    { "icanon", ICANON, MD_LIN },
00323 #endif /* ICANON */
00324 #ifdef  XCASE
00325    { "xcase", XCASE, MD_LIN },
00326 #endif /* XCASE */
00327 #ifdef  ECHO
00328    { "echo", ECHO, MD_LIN },
00329 #endif /* ECHO */
00330 #ifdef  ECHOE
00331    { "echoe", ECHOE, MD_LIN },
00332 #endif /* ECHOE */
00333 #ifdef  ECHOK
00334    { "echok", ECHOK, MD_LIN },
00335 #endif /* ECHOK */
00336 #ifdef  ECHONL
00337    { "echonl", ECHONL, MD_LIN },
00338 #endif /* ECHONL */
00339 #ifdef  NOFLSH
00340    { "noflsh", NOFLSH, MD_LIN },
00341 #endif /* NOFLSH */
00342 #ifdef  TOSTOP
00343    { "tostop", TOSTOP, MD_LIN },
00344 #endif /* TOSTOP */
00345 #ifdef  ECHOCTL
00346    { "echoctl", ECHOCTL, MD_LIN },
00347 #endif /* ECHOCTL */
00348 #ifdef  ECHOPRT
00349    { "echoprt", ECHOPRT, MD_LIN },
00350 #endif /* ECHOPRT */
00351 #ifdef  ECHOKE
00352    { "echoke", ECHOKE, MD_LIN },
00353 #endif /* ECHOKE */
00354 #ifdef  DEFECHO
00355    { "defecho", DEFECHO, MD_LIN },
00356 #endif /* DEFECHO */
00357 #ifdef  FLUSHO
00358    { "flusho", FLUSHO, MD_LIN },
00359 #endif /* FLUSHO */
00360 #ifdef  PENDIN
00361    { "pendin", PENDIN, MD_LIN },
00362 #endif /* PENDIN */
00363 #ifdef  IEXTEN
00364    { "iexten", IEXTEN, MD_LIN },
00365 #endif /* IEXTEN */
00366 #ifdef  NOKERNINFO
00367    { "nokerninfo", NOKERNINFO, MD_LIN },
00368 #endif /* NOKERNINFO */
00369 #ifdef  ALTWERASE
00370    { "altwerase", ALTWERASE, MD_LIN },
00371 #endif /* ALTWERASE */
00372 #ifdef  EXTPROC
00373    { "extproc", EXTPROC, MD_LIN },
00374 #endif /* EXTPROC */
00375 
00376 #if defined(VINTR)
00377    { "intr", C_SH(C_INTR), MD_CHAR },
00378 #endif /* VINTR */
00379 #if defined(VQUIT)
00380    { "quit", C_SH(C_QUIT), MD_CHAR },
00381 #endif /* VQUIT */
00382 #if defined(VERASE)
00383    { "erase", C_SH(C_ERASE), MD_CHAR },
00384 #endif /* VERASE */
00385 #if defined(VKILL)
00386    { "kill", C_SH(C_KILL), MD_CHAR },
00387 #endif /* VKILL */
00388 #if defined(VEOF)
00389    { "eof", C_SH(C_EOF), MD_CHAR },
00390 #endif /* VEOF */
00391 #if defined(VEOL)
00392    { "eol", C_SH(C_EOL), MD_CHAR },
00393 #endif /* VEOL */
00394 #if defined(VEOL2)
00395    { "eol2", C_SH(C_EOL2), MD_CHAR },
00396 #endif /* VEOL2 */
00397 #if defined(VSWTCH)
00398    { "swtch", C_SH(C_SWTCH), MD_CHAR },
00399 #endif /* VSWTCH */
00400 #if defined(VDSWTCH)
00401    { "dswtch", C_SH(C_DSWTCH), MD_CHAR },
00402 #endif /* VDSWTCH */
00403 #if defined(VERASE2)
00404    { "erase2", C_SH(C_ERASE2), MD_CHAR },
00405 #endif /* VERASE2 */
00406 #if defined(VSTART)
00407    { "start", C_SH(C_START), MD_CHAR },
00408 #endif /* VSTART */
00409 #if defined(VSTOP)
00410    { "stop", C_SH(C_STOP), MD_CHAR },
00411 #endif /* VSTOP */
00412 #if defined(VWERASE)
00413    { "werase", C_SH(C_WERASE), MD_CHAR },
00414 #endif /* VWERASE */
00415 #if defined(VSUSP)
00416    { "susp", C_SH(C_SUSP), MD_CHAR },
00417 #endif /* VSUSP */
00418 #if defined(VDSUSP)
00419    { "dsusp", C_SH(C_DSUSP), MD_CHAR },
00420 #endif /* VDSUSP */
00421 #if defined(VREPRINT)
00422    { "reprint", C_SH(C_REPRINT), MD_CHAR },
00423 #endif /* VREPRINT */
00424 #if defined(VDISCARD)
00425    { "discard", C_SH(C_DISCARD), MD_CHAR },
00426 #endif /* VDISCARD */
00427 #if defined(VLNEXT)
00428    { "lnext", C_SH(C_LNEXT), MD_CHAR },
00429 #endif /* VLNEXT */
00430 #if defined(VSTATUS)
00431    { "status", C_SH(C_STATUS), MD_CHAR },
00432 #endif /* VSTATUS */
00433 #if defined(VPAGE)
00434    { "page", C_SH(C_PAGE), MD_CHAR },
00435 #endif /* VPAGE */
00436 #if defined(VPGOFF)
00437    { "pgoff", C_SH(C_PGOFF), MD_CHAR },
00438 #endif /* VPGOFF */
00439 #if defined(VKILL2)
00440    { "kill2", C_SH(C_KILL2), MD_CHAR },
00441 #endif /* VKILL2 */
00442 #if defined(VBRK)
00443    { "brk", C_SH(C_BRK), MD_CHAR },
00444 #endif /* VBRK */
00445 #if defined(VMIN)
00446    { "min", C_SH(C_MIN), MD_CHAR },
00447 #endif /* VMIN */
00448 #if defined(VTIME)
00449    { "time", C_SH(C_TIME), MD_CHAR },
00450 #endif /* VTIME */
00451    { NULL, 0, -1 },
00452 };
00453 
00454 
00455 #define tty_getty(el, td) tcgetattr((el)->fInFD, (td))
00456 #define tty_setty(el, td) tcsetattr((el)->fInFD, TCSADRAIN, (td))
00457 
00458 #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
00459 #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
00460 #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
00461 
00462 el_private void tty__getchar(struct termios*, unsigned char*);
00463 el_private void tty__setchar(struct termios*, unsigned char*);
00464 el_private speed_t tty__getspeed(struct termios*);
00465 el_private int tty_setup(EditLine_t*);
00466 
00467 #define t_qu t_ts
00468 
00469 /* tty_canoutput():
00470  *   Indicate whether we are connected or not to the tty.
00471  *   In particular returns false if the process is in the background.
00472  */
00473 int
00474 tty_can_output(void)
00475 {
00476    return (getpgrp() == tcgetpgrp(STDOUT_FILENO));
00477 }
00478 
00479 bool tty_need_to_run_setup = false;
00480 
00481 /* tty_setup():
00482  *      Get the tty parameters and initialize the editing state
00483  */
00484 el_private int
00485 tty_setup(EditLine_t* el) {
00486    int rst = 1;
00487    if (!tty_can_output()) {
00488       tty_need_to_run_setup = true;
00489       return 0;
00490    }
00491    tty_need_to_run_setup = false;
00492 
00493    /*
00494    if (el->fFlags & EDIT_DISABLED) {
00495       return 0;
00496    }
00497    */
00498 
00499    if (tty_getty(el, &el->fTTY.t_ed) == -1) {
00500 #ifdef DEBUG_TTY
00501          (void) fprintf(el->fErrFile,
00502                         "tty_setup: tty_getty: %s\n", strerror(errno));
00503 #endif /* DEBUG_TTY */
00504       return -1;
00505    }
00506    el->fTTY.t_ts = el->fTTY.t_ex = el->fTTY.t_ed;
00507 
00508    el->fTTY.t_speed = tty__getspeed(&el->fTTY.t_ex);
00509    el->fTTY.t_tabs = tty__gettabs(&el->fTTY.t_ex);
00510    el->fTTY.t_eight = tty__geteightbit(&el->fTTY.t_ex);
00511 
00512    el->fTTY.t_ex.c_iflag &= ~el->fTTY.t_t[EX_IO][MD_INP].t_clrmask;
00513    el->fTTY.t_ex.c_iflag |= el->fTTY.t_t[EX_IO][MD_INP].t_setmask;
00514 
00515    el->fTTY.t_ex.c_oflag &= ~el->fTTY.t_t[EX_IO][MD_OUT].t_clrmask;
00516    el->fTTY.t_ex.c_oflag |= el->fTTY.t_t[EX_IO][MD_OUT].t_setmask;
00517 
00518    el->fTTY.t_ex.c_cflag &= ~el->fTTY.t_t[EX_IO][MD_CTL].t_clrmask;
00519    el->fTTY.t_ex.c_cflag |= el->fTTY.t_t[EX_IO][MD_CTL].t_setmask;
00520 
00521    el->fTTY.t_ex.c_lflag &= ~el->fTTY.t_t[EX_IO][MD_LIN].t_clrmask;
00522    el->fTTY.t_ex.c_lflag |= el->fTTY.t_t[EX_IO][MD_LIN].t_setmask;
00523 
00524    /*
00525     * Reset the tty chars to reasonable defaults
00526     * If they are disabled, then enable them.
00527     */
00528    if (rst) {
00529       if (tty__cooked_mode(&el->fTTY.t_ts)) {
00530          tty__getchar(&el->fTTY.t_ts, el->fTTY.t_c[TS_IO]);
00531 
00532          /*
00533           * Don't affect CMIN and CTIME for the editor mode
00534           */
00535          for (rst = 0; rst < C_NCC - 2; rst++) {
00536             if (el->fTTY.t_c[TS_IO][rst] !=
00537                 el->fTTY.t_vdisable
00538                 && el->fTTY.t_c[ED_IO][rst] !=
00539                 el->fTTY.t_vdisable) {
00540                el->fTTY.t_c[ED_IO][rst] =
00541                   el->fTTY.t_c[TS_IO][rst];
00542             }
00543          }
00544 
00545          for (rst = 0; rst < C_NCC; rst++) {
00546             if (el->fTTY.t_c[TS_IO][rst] !=
00547                 el->fTTY.t_vdisable) {
00548                el->fTTY.t_c[EX_IO][rst] =
00549                   el->fTTY.t_c[TS_IO][rst];
00550             }
00551          }
00552       }
00553       tty__setchar(&el->fTTY.t_ex, el->fTTY.t_c[EX_IO]);
00554 
00555       if (tty_setty(el, &el->fTTY.t_ex) == -1) {
00556 #ifdef DEBUG_TTY
00557             (void) fprintf(el->fErrFile,
00558                            "tty_setup: tty_setty: %s\n",
00559                            strerror(errno));
00560 #endif /* DEBUG_TTY */
00561          return -1;
00562       }
00563    } else {
00564       // This cannot be reached as rst is set to 1 above.
00565       // coverity[dead_error_line]
00566       tty__setchar(&el->fTTY.t_ex, el->fTTY.t_c[EX_IO]);
00567    }
00568 
00569    el->fTTY.t_ed.c_iflag &= ~el->fTTY.t_t[ED_IO][MD_INP].t_clrmask;
00570    el->fTTY.t_ed.c_iflag |= el->fTTY.t_t[ED_IO][MD_INP].t_setmask;
00571 
00572    el->fTTY.t_ed.c_oflag &= ~el->fTTY.t_t[ED_IO][MD_OUT].t_clrmask;
00573    el->fTTY.t_ed.c_oflag |= el->fTTY.t_t[ED_IO][MD_OUT].t_setmask;
00574 
00575    el->fTTY.t_ed.c_cflag &= ~el->fTTY.t_t[ED_IO][MD_CTL].t_clrmask;
00576    el->fTTY.t_ed.c_cflag |= el->fTTY.t_t[ED_IO][MD_CTL].t_setmask;
00577 
00578    el->fTTY.t_ed.c_lflag &= ~el->fTTY.t_t[ED_IO][MD_LIN].t_clrmask;
00579    el->fTTY.t_ed.c_lflag |= el->fTTY.t_t[ED_IO][MD_LIN].t_setmask;
00580 
00581    tty__setchar(&el->fTTY.t_ed, el->fTTY.t_c[ED_IO]);
00582    tty_bind_char(el, 1);
00583 
00584    el_set(el, EL_EDITMODE, 1);
00585    return 0;
00586 } // tty_setup
00587 
00588 
00589 el_protected int
00590 tty_init(EditLine_t* el) {
00591    el->fTTY.t_mode = EX_IO;
00592    el->fTTY.t_vdisable = _POSIX_VDISABLE;
00593    (void) memcpy(el->fTTY.t_t, ttyperm, sizeof(TTYPerm_t));
00594    (void) memcpy(el->fTTY.t_c, ttychar, sizeof(TTYChar_t));
00595    return tty_setup(el);
00596 }
00597 
00598 
00599 /* tty_end():
00600  *      Restore the tty to its original settings
00601  */
00602 el_protected void
00603 /*ARGSUSED*/
00604 tty_end(EditLine_t* /*el*/) {
00605    /* XXX: Maybe reset to an initial state? */
00606 }
00607 
00608 
00609 /* tty__getspeed():
00610  *      Get the tty speed
00611  */
00612 el_private speed_t
00613 tty__getspeed(struct termios* td) {
00614    speed_t spd;
00615 
00616    if ((spd = cfgetispeed(td)) == 0) {
00617       spd = cfgetospeed(td);
00618    }
00619    return spd;
00620 }
00621 
00622 
00623 /* tty__getchar():
00624  *      Get the tty characters
00625  */
00626 el_private void
00627 tty__getchar(struct termios* td, unsigned char* s) {
00628 #ifdef VINTR
00629    s[C_INTR] = td->c_cc[VINTR];
00630 #endif /* VINTR */
00631 #ifdef VQUIT
00632    s[C_QUIT] = td->c_cc[VQUIT];
00633 #endif /* VQUIT */
00634 #ifdef VERASE
00635    s[C_ERASE] = td->c_cc[VERASE];
00636 #endif /* VERASE */
00637 #ifdef VKILL
00638    s[C_KILL] = td->c_cc[VKILL];
00639 #endif /* VKILL */
00640 #ifdef VEOF
00641    s[C_EOF] = td->c_cc[VEOF];
00642 #endif /* VEOF */
00643 #ifdef VEOL
00644    s[C_EOL] = td->c_cc[VEOL];
00645 #endif /* VEOL */
00646 #ifdef VEOL2
00647    s[C_EOL2] = td->c_cc[VEOL2];
00648 #endif /* VEOL2 */
00649 #ifdef VSWTCH
00650    s[C_SWTCH] = td->c_cc[VSWTCH];
00651 #endif /* VSWTCH */
00652 #ifdef VDSWTCH
00653    s[C_DSWTCH] = td->c_cc[VDSWTCH];
00654 #endif /* VDSWTCH */
00655 #ifdef VERASE2
00656    s[C_ERASE2] = td->c_cc[VERASE2];
00657 #endif /* VERASE2 */
00658 #ifdef VSTART
00659    s[C_START] = td->c_cc[VSTART];
00660 #endif /* VSTART */
00661 #ifdef VSTOP
00662    s[C_STOP] = td->c_cc[VSTOP];
00663 #endif /* VSTOP */
00664 #ifdef VWERASE
00665    s[C_WERASE] = td->c_cc[VWERASE];
00666 #endif /* VWERASE */
00667 #ifdef VSUSP
00668    s[C_SUSP] = td->c_cc[VSUSP];
00669 #endif /* VSUSP */
00670 #ifdef VDSUSP
00671    s[C_DSUSP] = td->c_cc[VDSUSP];
00672 #endif /* VDSUSP */
00673 #ifdef VREPRINT
00674    s[C_REPRINT] = td->c_cc[VREPRINT];
00675 #endif /* VREPRINT */
00676 #ifdef VDISCARD
00677    s[C_DISCARD] = td->c_cc[VDISCARD];
00678 #endif /* VDISCARD */
00679 #ifdef VLNEXT
00680    s[C_LNEXT] = td->c_cc[VLNEXT];
00681 #endif /* VLNEXT */
00682 #ifdef VSTATUS
00683    s[C_STATUS] = td->c_cc[VSTATUS];
00684 #endif /* VSTATUS */
00685 #ifdef VPAGE
00686    s[C_PAGE] = td->c_cc[VPAGE];
00687 #endif /* VPAGE */
00688 #ifdef VPGOFF
00689    s[C_PGOFF] = td->c_cc[VPGOFF];
00690 #endif /* VPGOFF */
00691 #ifdef VKILL2
00692    s[C_KILL2] = td->c_cc[VKILL2];
00693 #endif /* KILL2 */
00694 #ifdef VMIN
00695    s[C_MIN] = td->c_cc[VMIN];
00696 #endif /* VMIN */
00697 #ifdef VTIME
00698    s[C_TIME] = td->c_cc[VTIME];
00699 #endif /* VTIME */
00700 }                               /* tty__getchar */
00701 
00702 
00703 /* tty__setchar():
00704  *      Set the tty characters
00705  */
00706 el_private void
00707 tty__setchar(struct termios* td, unsigned char* s) {
00708 #ifdef VINTR
00709    td->c_cc[VINTR] = s[C_INTR];
00710 #endif /* VINTR */
00711 #ifdef VQUIT
00712    td->c_cc[VQUIT] = s[C_QUIT];
00713 #endif /* VQUIT */
00714 #ifdef VERASE
00715    td->c_cc[VERASE] = s[C_ERASE];
00716 #endif /* VERASE */
00717 #ifdef VKILL
00718    td->c_cc[VKILL] = s[C_KILL];
00719 #endif /* VKILL */
00720 #ifdef VEOF
00721    td->c_cc[VEOF] = s[C_EOF];
00722 #endif /* VEOF */
00723 #ifdef VEOL
00724    td->c_cc[VEOL] = s[C_EOL];
00725 #endif /* VEOL */
00726 #ifdef VEOL2
00727    td->c_cc[VEOL2] = s[C_EOL2];
00728 #endif /* VEOL2 */
00729 #ifdef VSWTCH
00730    td->c_cc[VSWTCH] = s[C_SWTCH];
00731 #endif /* VSWTCH */
00732 #ifdef VDSWTCH
00733    td->c_cc[VDSWTCH] = s[C_DSWTCH];
00734 #endif /* VDSWTCH */
00735 #ifdef VERASE2
00736    td->c_cc[VERASE2] = s[C_ERASE2];
00737 #endif /* VERASE2 */
00738 #ifdef VSTART
00739    td->c_cc[VSTART] = s[C_START];
00740 #endif /* VSTART */
00741 #ifdef VSTOP
00742    td->c_cc[VSTOP] = s[C_STOP];
00743 #endif /* VSTOP */
00744 #ifdef VWERASE
00745    td->c_cc[VWERASE] = s[C_WERASE];
00746 #endif /* VWERASE */
00747 #ifdef VSUSP
00748    td->c_cc[VSUSP] = s[C_SUSP];
00749 #endif /* VSUSP */
00750 #ifdef VDSUSP
00751    td->c_cc[VDSUSP] = s[C_DSUSP];
00752 #endif /* VDSUSP */
00753 #ifdef VREPRINT
00754    td->c_cc[VREPRINT] = s[C_REPRINT];
00755 #endif /* VREPRINT */
00756 #ifdef VDISCARD
00757    td->c_cc[VDISCARD] = s[C_DISCARD];
00758 #endif /* VDISCARD */
00759 #ifdef VLNEXT
00760    td->c_cc[VLNEXT] = s[C_LNEXT];
00761 #endif /* VLNEXT */
00762 #ifdef VSTATUS
00763    td->c_cc[VSTATUS] = s[C_STATUS];
00764 #endif /* VSTATUS */
00765 #ifdef VPAGE
00766    td->c_cc[VPAGE] = s[C_PAGE];
00767 #endif /* VPAGE */
00768 #ifdef VPGOFF
00769    td->c_cc[VPGOFF] = s[C_PGOFF];
00770 #endif /* VPGOFF */
00771 #ifdef VKILL2
00772    td->c_cc[VKILL2] = s[C_KILL2];
00773 #endif /* VKILL2 */
00774 #ifdef VMIN
00775    td->c_cc[VMIN] = s[C_MIN];
00776 #endif /* VMIN */
00777 #ifdef VTIME
00778    td->c_cc[VTIME] = s[C_TIME];
00779 #endif /* VTIME */
00780 }                               /* tty__setchar */
00781 
00782 
00783 /* tty_bind_char():
00784  *      Rebind the SEditLine_t functions
00785  */
00786 el_protected void
00787 tty_bind_char(EditLine_t* el, int force) {
00788    unsigned char* t_n = el->fTTY.t_c[ED_IO];
00789    unsigned char* t_o = el->fTTY.t_ed.c_cc;
00790    unsigned char newp[2], old[2];
00791    const TTYMap_t* tp;
00792    ElAction_t* map, * alt;
00793    const ElAction_t* dmap, * dalt;
00794    newp[1] = old[1] = '\0';
00795 
00796    map = el->fMap.fKey;
00797    alt = el->fMap.fAlt;
00798 
00799    if (el->fMap.fType == MAP_VI) {
00800       dmap = el->fMap.fVii;
00801       dalt = el->fMap.fVic;
00802    } else {
00803       dmap = el->fMap.fEmacs;
00804       dalt = NULL;
00805    }
00806 
00807    for (tp = tty_map; tp->fNCh != -1; tp++) {
00808       newp[0] = t_n[tp->fNCh];
00809       old[0] = t_o[tp->fOCh];
00810 
00811       if (newp[0] == old[0] && !force) {
00812          continue;
00813       }
00814       /* Put the old default binding back, and set the new binding */
00815       key_clear(el, map, (char*) old);
00816       map[old[0]] = dmap[old[0]];
00817       key_clear(el, map, (char*) newp);
00818       /* MAP_VI == 1, MAP_EMACS == 0... */
00819       map[newp[0]] = tp->fBind[el->fMap.fType];
00820 
00821       if (dalt) {
00822          key_clear(el, alt, (char*) old);
00823          alt[old[0]] = dalt[old[0]];
00824          key_clear(el, alt, (char*) newp);
00825          alt[newp[0]] = tp->fBind[el->fMap.fType + 1];
00826       }
00827    }
00828 } // tty_bind_char
00829 
00830 
00831 /* tty_rawmode():
00832  *      Set terminal into 1 character at a time mode.
00833  */
00834 el_protected int
00835 tty_rawmode(EditLine_t* el) {
00836    if (tty_need_to_run_setup) {
00837       tty_setup(el);
00838       if (tty_need_to_run_setup)
00839          return 0;
00840    }
00841 
00842    if (el->fTTY.t_mode == ED_IO || el->fTTY.t_mode == QU_IO) {
00843       return 0;
00844    }
00845 
00846    if (el->fFlags & EDIT_DISABLED) {
00847       return 0;
00848    }
00849 
00850    if (tty_getty(el, &el->fTTY.t_ts) == -1) {
00851 #ifdef DEBUG_TTY
00852          (void) fprintf(el->fErrFile, "tty_rawmode: tty_getty: %s\n",
00853                         strerror(errno));
00854 #endif /* DEBUG_TTY */
00855       return -1;
00856    }
00857 
00858    /*
00859     * We always keep up with the eight bit setting and the speed of the
00860     * tty. But only we only believe changes that are made to cooked mode!
00861     */
00862    el->fTTY.t_eight = tty__geteightbit(&el->fTTY.t_ts);
00863    el->fTTY.t_speed = tty__getspeed(&el->fTTY.t_ts);
00864 
00865    if (tty__getspeed(&el->fTTY.t_ex) != el->fTTY.t_speed ||
00866        tty__getspeed(&el->fTTY.t_ed) != el->fTTY.t_speed) {
00867       (void) cfsetispeed(&el->fTTY.t_ex, el->fTTY.t_speed);
00868       (void) cfsetospeed(&el->fTTY.t_ex, el->fTTY.t_speed);
00869       (void) cfsetispeed(&el->fTTY.t_ed, el->fTTY.t_speed);
00870       (void) cfsetospeed(&el->fTTY.t_ed, el->fTTY.t_speed);
00871    }
00872 
00873    if (tty__cooked_mode(&el->fTTY.t_ts)) {
00874       if (el->fTTY.t_ts.c_cflag != el->fTTY.t_ex.c_cflag) {
00875          el->fTTY.t_ex.c_cflag =
00876             el->fTTY.t_ts.c_cflag;
00877          el->fTTY.t_ex.c_cflag &=
00878             ~el->fTTY.t_t[EX_IO][MD_CTL].t_clrmask;
00879          el->fTTY.t_ex.c_cflag |=
00880             el->fTTY.t_t[EX_IO][MD_CTL].t_setmask;
00881 
00882          el->fTTY.t_ed.c_cflag =
00883             el->fTTY.t_ts.c_cflag;
00884          el->fTTY.t_ed.c_cflag &=
00885             ~el->fTTY.t_t[ED_IO][MD_CTL].t_clrmask;
00886          el->fTTY.t_ed.c_cflag |=
00887             el->fTTY.t_t[ED_IO][MD_CTL].t_setmask;
00888       }
00889 
00890       if ((el->fTTY.t_ts.c_lflag != el->fTTY.t_ex.c_lflag) &&
00891           (el->fTTY.t_ts.c_lflag != el->fTTY.t_ed.c_lflag)) {
00892          el->fTTY.t_ex.c_lflag =
00893             el->fTTY.t_ts.c_lflag;
00894          el->fTTY.t_ex.c_lflag &=
00895             ~el->fTTY.t_t[EX_IO][MD_LIN].t_clrmask;
00896          el->fTTY.t_ex.c_lflag |=
00897             el->fTTY.t_t[EX_IO][MD_LIN].t_setmask;
00898 
00899          el->fTTY.t_ed.c_lflag =
00900             el->fTTY.t_ts.c_lflag;
00901          el->fTTY.t_ed.c_lflag &=
00902             ~el->fTTY.t_t[ED_IO][MD_LIN].t_clrmask;
00903          el->fTTY.t_ed.c_lflag |=
00904             el->fTTY.t_t[ED_IO][MD_LIN].t_setmask;
00905       }
00906 
00907       if ((el->fTTY.t_ts.c_iflag != el->fTTY.t_ex.c_iflag) &&
00908           (el->fTTY.t_ts.c_iflag != el->fTTY.t_ed.c_iflag)) {
00909          el->fTTY.t_ex.c_iflag =
00910             el->fTTY.t_ts.c_iflag;
00911          el->fTTY.t_ex.c_iflag &=
00912             ~el->fTTY.t_t[EX_IO][MD_INP].t_clrmask;
00913          el->fTTY.t_ex.c_iflag |=
00914             el->fTTY.t_t[EX_IO][MD_INP].t_setmask;
00915 
00916          el->fTTY.t_ed.c_iflag =
00917             el->fTTY.t_ts.c_iflag;
00918          el->fTTY.t_ed.c_iflag &=
00919             ~el->fTTY.t_t[ED_IO][MD_INP].t_clrmask;
00920          el->fTTY.t_ed.c_iflag |=
00921             el->fTTY.t_t[ED_IO][MD_INP].t_setmask;
00922       }
00923 
00924       if ((el->fTTY.t_ts.c_oflag != el->fTTY.t_ex.c_oflag) &&
00925           (el->fTTY.t_ts.c_oflag != el->fTTY.t_ed.c_oflag)) {
00926          el->fTTY.t_ex.c_oflag =
00927             el->fTTY.t_ts.c_oflag;
00928          el->fTTY.t_ex.c_oflag &=
00929             ~el->fTTY.t_t[EX_IO][MD_OUT].t_clrmask;
00930          el->fTTY.t_ex.c_oflag |=
00931             el->fTTY.t_t[EX_IO][MD_OUT].t_setmask;
00932 
00933          el->fTTY.t_ed.c_oflag =
00934             el->fTTY.t_ts.c_oflag;
00935          el->fTTY.t_ed.c_oflag &=
00936             ~el->fTTY.t_t[ED_IO][MD_OUT].t_clrmask;
00937          el->fTTY.t_ed.c_oflag |=
00938             el->fTTY.t_t[ED_IO][MD_OUT].t_setmask;
00939       }
00940 
00941       if (tty__gettabs(&el->fTTY.t_ex) == 0) {
00942          el->fTTY.t_tabs = 0;
00943       } else {
00944          el->fTTY.t_tabs = EL_CAN_TAB ? 1 : 0;
00945       }
00946 
00947       {
00948          int i;
00949 
00950          tty__getchar(&el->fTTY.t_ts, el->fTTY.t_c[TS_IO]);
00951 
00952          /*
00953           * Check if the user made any changes.
00954           * If he did, then propagate the changes to the
00955           * edit and execute data structures.
00956           */
00957          for (i = 0; i < C_NCC; i++) {
00958             if (el->fTTY.t_c[TS_IO][i] !=
00959                 el->fTTY.t_c[EX_IO][i]) {
00960                break;
00961             }
00962          }
00963 
00964          if (i != C_NCC) {
00965             /*
00966              * Propagate changes only to the unprotected
00967              * chars that have been modified just now.
00968              */
00969             for (i = 0; i < C_NCC; i++) {
00970                if (!((el->fTTY.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
00971                    && (el->fTTY.t_c[TS_IO][i] != el->fTTY.t_c[EX_IO][i])) {
00972                   el->fTTY.t_c[ED_IO][i] = el->fTTY.t_c[TS_IO][i];
00973                }
00974 
00975                if (el->fTTY.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i)) {
00976                   el->fTTY.t_c[ED_IO][i] = el->fTTY.t_vdisable;
00977                }
00978             }
00979             tty_bind_char(el, 0);
00980             tty__setchar(&el->fTTY.t_ed, el->fTTY.t_c[ED_IO]);
00981 
00982             for (i = 0; i < C_NCC; i++) {
00983                if (!((el->fTTY.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
00984                    && (el->fTTY.t_c[TS_IO][i] != el->fTTY.t_c[EX_IO][i])) {
00985                   el->fTTY.t_c[EX_IO][i] = el->fTTY.t_c[TS_IO][i];
00986                }
00987 
00988                if (el->fTTY.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i)) {
00989                   el->fTTY.t_c[EX_IO][i] = el->fTTY.t_vdisable;
00990                }
00991             }
00992             tty__setchar(&el->fTTY.t_ex, el->fTTY.t_c[EX_IO]);
00993          }
00994       }
00995    }
00996 
00997    if (tty_setty(el, &el->fTTY.t_ed) == -1) {
00998 #ifdef DEBUG_TTY
00999          (void) fprintf(el->fErrFile, "tty_rawmode: tty_setty: %s\n",
01000                         strerror(errno));
01001 #endif /* DEBUG_TTY */
01002       return -1;
01003    }
01004    el->fTTY.t_mode = ED_IO;
01005    return 0;
01006 } // tty_rawmode
01007 
01008 
01009 /* tty_cookedmode():
01010  *      Set the tty back to normal mode
01011  */
01012 el_protected int
01013 tty_cookedmode(EditLine_t* el) {  /* set tty in normal setup */
01014    if (tty_need_to_run_setup) {
01015       tty_setup(el);
01016       if (tty_need_to_run_setup)
01017          return 0;
01018    }
01019 
01020    if (el->fTTY.t_mode == EX_IO) {
01021       return 0;
01022    }
01023 
01024    if (el->fFlags & EDIT_DISABLED) {
01025       return 0;
01026    }
01027 
01028    if (tty_setty(el, &el->fTTY.t_ex) == -1) {
01029 #ifdef DEBUG_TTY
01030          (void) fprintf(el->fErrFile,
01031                         "tty_cookedmode: tty_setty: %s\n",
01032                         strerror(errno));
01033 #endif /* DEBUG_TTY */
01034       return -1;
01035    }
01036    el->fTTY.t_mode = EX_IO;
01037    return 0;
01038 } // tty_cookedmode
01039 
01040 
01041 /* tty_quotemode():
01042  *      Turn on quote mode
01043  */
01044 el_protected int
01045 tty_quotemode(EditLine_t* el) {
01046    if (tty_need_to_run_setup) {
01047       tty_setup(el);
01048       if (tty_need_to_run_setup)
01049          return 0;
01050    }
01051 
01052    if (el->fTTY.t_mode == QU_IO) {
01053       return 0;
01054    }
01055 
01056    el->fTTY.t_qu = el->fTTY.t_ed;
01057 
01058    el->fTTY.t_qu.c_iflag &= ~el->fTTY.t_t[QU_IO][MD_INP].t_clrmask;
01059    el->fTTY.t_qu.c_iflag |= el->fTTY.t_t[QU_IO][MD_INP].t_setmask;
01060 
01061    el->fTTY.t_qu.c_oflag &= ~el->fTTY.t_t[QU_IO][MD_OUT].t_clrmask;
01062    el->fTTY.t_qu.c_oflag |= el->fTTY.t_t[QU_IO][MD_OUT].t_setmask;
01063 
01064    el->fTTY.t_qu.c_cflag &= ~el->fTTY.t_t[QU_IO][MD_CTL].t_clrmask;
01065    el->fTTY.t_qu.c_cflag |= el->fTTY.t_t[QU_IO][MD_CTL].t_setmask;
01066 
01067    el->fTTY.t_qu.c_lflag &= ~el->fTTY.t_t[QU_IO][MD_LIN].t_clrmask;
01068    el->fTTY.t_qu.c_lflag |= el->fTTY.t_t[QU_IO][MD_LIN].t_setmask;
01069 
01070    if (tty_setty(el, &el->fTTY.t_qu) == -1) {
01071 #ifdef DEBUG_TTY
01072          (void) fprintf(el->fErrFile, "QuoteModeOn: tty_setty: %s\n",
01073                         strerror(errno));
01074 #endif /* DEBUG_TTY */
01075       return -1;
01076    }
01077    el->fTTY.t_mode = QU_IO;
01078    return 0;
01079 } // tty_quotemode
01080 
01081 
01082 /* tty_noquotemode():
01083  *      Turn off quote mode
01084  */
01085 el_protected int
01086 tty_noquotemode(EditLine_t* el) {
01087    if (tty_need_to_run_setup) {
01088       tty_setup(el);
01089       if (tty_need_to_run_setup)
01090          return 0;
01091    }
01092 
01093    if (el->fTTY.t_mode != QU_IO) {
01094       return 0;
01095    }
01096 
01097    if (tty_setty(el, &el->fTTY.t_ed) == -1) {
01098 #ifdef DEBUG_TTY
01099          (void) fprintf(el->fErrFile, "QuoteModeOff: tty_setty: %s\n",
01100                         strerror(errno));
01101 #endif /* DEBUG_TTY */
01102       return -1;
01103    }
01104    el->fTTY.t_mode = ED_IO;
01105    return 0;
01106 }
01107 
01108 
01109 /* tty_stty():
01110  *      Stty builtin
01111  */
01112 el_protected int
01113 /*ARGSUSED*/
01114 tty_stty(EditLine_t* el, int /*argc*/, const char** cargv) {
01115    char** argv = (char**) cargv;
01116 
01117    /** ^^^^ HUGE KLUDGE
01118        This func doesn't really modify argv, but does do
01119        pointer arithmatic on it.
01120        ----- stephan@s11n.net 28 Nov 2004
01121     */
01122    const TTYModes_t* m;
01123    char x, * d;
01124    int aflag = 0;
01125    char* s;
01126    char* name;
01127    int z = EX_IO;
01128 
01129    if (argv == NULL) {
01130       return -1;
01131    }
01132    name = *argv++;
01133 
01134    while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
01135       switch (argv[0][1]) {
01136       case 'a':
01137          aflag++;
01138          argv++;
01139          break;
01140       case 'd':
01141          argv++;
01142          z = ED_IO;
01143          break;
01144       case 'x':
01145          argv++;
01146          z = EX_IO;
01147          break;
01148       case 'q':
01149          argv++;
01150          z = QU_IO;
01151          break;
01152       default:
01153          (void) fprintf(el->fErrFile,
01154                         "%s: Unknown switch `%c'.\n",
01155                         name, argv[0][1]);
01156          return -1;
01157       }
01158 
01159    if (!argv || !*argv) {
01160       int i = -1;
01161       int len = 0, st = 0, cu;
01162 
01163       for (m = ttymodes; m->fName; m++) {
01164          if (m->fType != i) {
01165             (void) fprintf(el->fOutFile, "%s%s",
01166                            i != -1 ? "\n" : "",
01167                            el->fTTY.t_t[z][m->fType].t_name);
01168             i = m->fType;
01169             st = len =
01170                     strlen(el->fTTY.t_t[z][m->fType].t_name);
01171          }
01172          x = (el->fTTY.t_t[z][i].t_setmask & m->fValue)
01173              ? '+' : '\0';
01174          x = (el->fTTY.t_t[z][i].t_clrmask & m->fValue)
01175              ? '-' : x;
01176 
01177          if (x != '\0' || aflag) {
01178             cu = strlen(m->fName) + (x != '\0') + 1;
01179 
01180             if (len + cu >= el->fTerm.fSize.fH) {
01181                (void) fprintf(el->fOutFile, "\n%*s",
01182                               st, "");
01183                len = st + cu;
01184             } else {
01185                len += cu;
01186             }
01187 
01188             if (x != '\0') {
01189                (void) fprintf(el->fOutFile, "%c%s ",
01190                               x, m->fName);
01191             } else {
01192                (void) fprintf(el->fOutFile, "%s ",
01193                               m->fName);
01194             }
01195          }
01196       }
01197       (void) fprintf(el->fOutFile, "\n");
01198       return 0;
01199    }
01200 
01201    while (argv && (s = *argv++)) {
01202       switch (*s) {
01203       case '+':
01204       case '-':
01205          x = *s++;
01206          break;
01207       default:
01208          x = '\0';
01209          break;
01210       }
01211       d = s;
01212 
01213       for (m = ttymodes; m->fName; m++) {
01214          if (strcmp(m->fName, d) == 0) {
01215             break;
01216          }
01217       }
01218 
01219       if (!m->fName) {
01220          (void) fprintf(el->fErrFile,
01221                         "%s: Invalid argument `%s'.\n", name, d);
01222          return -1;
01223       }
01224 
01225       switch (x) {
01226       case '+':
01227          el->fTTY.t_t[z][m->fType].t_setmask |= m->fValue;
01228          el->fTTY.t_t[z][m->fType].t_clrmask &= ~m->fValue;
01229          break;
01230       case '-':
01231          el->fTTY.t_t[z][m->fType].t_setmask &= ~m->fValue;
01232          el->fTTY.t_t[z][m->fType].t_clrmask |= m->fValue;
01233          break;
01234       default:
01235          el->fTTY.t_t[z][m->fType].t_setmask &= ~m->fValue;
01236          el->fTTY.t_t[z][m->fType].t_clrmask &= ~m->fValue;
01237          break;
01238       }
01239    }
01240    return 0;
01241 } // tty_stty
01242 
01243 
01244 #ifdef notyet
01245 
01246 /* tty_printchar():
01247  *      DEbugging routine to print the tty characters
01248  */
01249 el_private void
01250 tty_printchar(EditLine_t* el, unsigned char* s) {
01251    TTYPerm_t* m;
01252    int i;
01253 
01254    for (i = 0; i < C_NCC; i++) {
01255       for (m = el->fTTY.t_t; m->fName; m++) {
01256          if (m->fType == MD_CHAR && C_SH(i) == m->fValue) {
01257             break;
01258          }
01259       }
01260 
01261       if (m->fName) {
01262          (void) fprintf(el->fErrFile, "%s ^%c ",
01263                         m->fName, s[i] + 'A' - 1);
01264       }
01265 
01266       if (i % 5 == 0) {
01267          (void) fprintf(el->fErrFile, "\n");
01268       }
01269    }
01270    (void) fprintf(el->fErrFile, "\n");
01271 } // tty_printchar
01272 
01273 
01274 #endif /* notyet */

Generated on Tue Jul 5 14:11:39 2011 for ROOT_528-00b_version by  doxygen 1.5.1