tty.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182
  1. /* $NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $ */
  2. /*-
  3. * Copyright (c) 1992, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * This code is derived from software contributed to Berkeley by
  7. * Christos Zoulas of Cornell University.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. All advertising materials mentioning features or use of this software
  18. * must display the following acknowledgement:
  19. * This product includes software developed by the University of
  20. * California, Berkeley and its contributors.
  21. * 4. Neither the name of the University nor the names of its contributors
  22. * may be used to endorse or promote products derived from this software
  23. * without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35. * SUCH DAMAGE.
  36. */
  37. #include "config.h"
  38. #if !defined(lint) && !defined(SCCSID)
  39. #if 0
  40. static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
  41. #else
  42. __RCSID("$NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $");
  43. #endif
  44. #endif /* not lint && not SCCSID */
  45. /*
  46. * tty.c: tty interface stuff
  47. */
  48. #include "tty.h"
  49. #include "el.h"
  50. typedef struct ttymodes_t {
  51. const char *m_name;
  52. u_int m_value;
  53. int m_type;
  54. } ttymodes_t;
  55. typedef struct ttymap_t {
  56. int nch, och; /* Internal and termio rep of chars */
  57. el_action_t bind[3]; /* emacs, vi, and vi-cmd */
  58. } ttymap_t;
  59. private const ttyperm_t ttyperm = {
  60. {
  61. {"iflag:", ICRNL, (INLCR | IGNCR)},
  62. {"oflag:", (OPOST | ONLCR), ONLRET},
  63. {"cflag:", 0, 0},
  64. {"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN),
  65. (NOFLSH | ECHONL | EXTPROC | FLUSHO)},
  66. {"chars:", 0, 0},
  67. },
  68. {
  69. {"iflag:", (INLCR | ICRNL), IGNCR},
  70. {"oflag:", (OPOST | ONLCR), ONLRET},
  71. {"cflag:", 0, 0},
  72. {"lflag:", ISIG,
  73. (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)},
  74. {"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) |
  75. C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) |
  76. C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0}
  77. },
  78. {
  79. {"iflag:", 0, IXON | IXOFF | INLCR | ICRNL},
  80. {"oflag:", 0, 0},
  81. {"cflag:", 0, 0},
  82. {"lflag:", 0, ISIG | IEXTEN},
  83. {"chars:", 0, 0},
  84. }
  85. };
  86. private const ttychar_t ttychar = {
  87. {
  88. CINTR, CQUIT, CERASE, CKILL,
  89. CEOF, CEOL, CEOL2, CSWTCH,
  90. CDSWTCH, CERASE2, CSTART, CSTOP,
  91. CWERASE, CSUSP, CDSUSP, CREPRINT,
  92. CDISCARD, CLNEXT, CSTATUS, CPAGE,
  93. CPGOFF, CKILL2, CBRK, CMIN,
  94. CTIME
  95. },
  96. {
  97. CINTR, CQUIT, CERASE, CKILL,
  98. _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
  99. _POSIX_VDISABLE, CERASE2, CSTART, CSTOP,
  100. _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE,
  101. CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE,
  102. _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1,
  103. 0
  104. },
  105. {
  106. 0, 0, 0, 0,
  107. 0, 0, 0, 0,
  108. 0, 0, 0, 0,
  109. 0, 0, 0, 0,
  110. 0, 0, 0, 0,
  111. 0, 0, 0, 0,
  112. 0
  113. }
  114. };
  115. private const ttymap_t tty_map[] = {
  116. #ifdef VERASE
  117. {C_ERASE, VERASE,
  118. {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
  119. #endif /* VERASE */
  120. #ifdef VERASE2
  121. {C_ERASE2, VERASE2,
  122. {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
  123. #endif /* VERASE2 */
  124. #ifdef VKILL
  125. {C_KILL, VKILL,
  126. {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
  127. #endif /* VKILL */
  128. #ifdef VKILL2
  129. {C_KILL2, VKILL2,
  130. {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}},
  131. #endif /* VKILL2 */
  132. #ifdef VEOF
  133. {C_EOF, VEOF,
  134. {EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}},
  135. #endif /* VEOF */
  136. #ifdef VWERASE
  137. {C_WERASE, VWERASE,
  138. {ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}},
  139. #endif /* VWERASE */
  140. #ifdef VREPRINT
  141. {C_REPRINT, VREPRINT,
  142. {ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}},
  143. #endif /* VREPRINT */
  144. #ifdef VLNEXT
  145. {C_LNEXT, VLNEXT,
  146. {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
  147. #endif /* VLNEXT */
  148. {-1, -1,
  149. {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
  150. };
  151. private const ttymodes_t ttymodes[] = {
  152. #ifdef IGNBRK
  153. {"ignbrk", IGNBRK, MD_INP},
  154. #endif /* IGNBRK */
  155. #ifdef BRKINT
  156. {"brkint", BRKINT, MD_INP},
  157. #endif /* BRKINT */
  158. #ifdef IGNPAR
  159. {"ignpar", IGNPAR, MD_INP},
  160. #endif /* IGNPAR */
  161. #ifdef PARMRK
  162. {"parmrk", PARMRK, MD_INP},
  163. #endif /* PARMRK */
  164. #ifdef INPCK
  165. {"inpck", INPCK, MD_INP},
  166. #endif /* INPCK */
  167. #ifdef ISTRIP
  168. {"istrip", ISTRIP, MD_INP},
  169. #endif /* ISTRIP */
  170. #ifdef INLCR
  171. {"inlcr", INLCR, MD_INP},
  172. #endif /* INLCR */
  173. #ifdef IGNCR
  174. {"igncr", IGNCR, MD_INP},
  175. #endif /* IGNCR */
  176. #ifdef ICRNL
  177. {"icrnl", ICRNL, MD_INP},
  178. #endif /* ICRNL */
  179. #ifdef IUCLC
  180. {"iuclc", IUCLC, MD_INP},
  181. #endif /* IUCLC */
  182. #ifdef IXON
  183. {"ixon", IXON, MD_INP},
  184. #endif /* IXON */
  185. #ifdef IXANY
  186. {"ixany", IXANY, MD_INP},
  187. #endif /* IXANY */
  188. #ifdef IXOFF
  189. {"ixoff", IXOFF, MD_INP},
  190. #endif /* IXOFF */
  191. #ifdef IMAXBEL
  192. {"imaxbel", IMAXBEL, MD_INP},
  193. #endif /* IMAXBEL */
  194. #ifdef OPOST
  195. {"opost", OPOST, MD_OUT},
  196. #endif /* OPOST */
  197. #ifdef OLCUC
  198. {"olcuc", OLCUC, MD_OUT},
  199. #endif /* OLCUC */
  200. #ifdef ONLCR
  201. {"onlcr", ONLCR, MD_OUT},
  202. #endif /* ONLCR */
  203. #ifdef OCRNL
  204. {"ocrnl", OCRNL, MD_OUT},
  205. #endif /* OCRNL */
  206. #ifdef ONOCR
  207. {"onocr", ONOCR, MD_OUT},
  208. #endif /* ONOCR */
  209. #ifdef ONOEOT
  210. {"onoeot", ONOEOT, MD_OUT},
  211. #endif /* ONOEOT */
  212. #ifdef ONLRET
  213. {"onlret", ONLRET, MD_OUT},
  214. #endif /* ONLRET */
  215. #ifdef OFILL
  216. {"ofill", OFILL, MD_OUT},
  217. #endif /* OFILL */
  218. #ifdef OFDEL
  219. {"ofdel", OFDEL, MD_OUT},
  220. #endif /* OFDEL */
  221. #ifdef NLDLY
  222. {"nldly", NLDLY, MD_OUT},
  223. #endif /* NLDLY */
  224. #ifdef CRDLY
  225. {"crdly", CRDLY, MD_OUT},
  226. #endif /* CRDLY */
  227. #ifdef TABDLY
  228. {"tabdly", TABDLY, MD_OUT},
  229. #endif /* TABDLY */
  230. #ifdef XTABS
  231. {"xtabs", XTABS, MD_OUT},
  232. #endif /* XTABS */
  233. #ifdef BSDLY
  234. {"bsdly", BSDLY, MD_OUT},
  235. #endif /* BSDLY */
  236. #ifdef VTDLY
  237. {"vtdly", VTDLY, MD_OUT},
  238. #endif /* VTDLY */
  239. #ifdef FFDLY
  240. {"ffdly", FFDLY, MD_OUT},
  241. #endif /* FFDLY */
  242. #ifdef PAGEOUT
  243. {"pageout", PAGEOUT, MD_OUT},
  244. #endif /* PAGEOUT */
  245. #ifdef WRAP
  246. {"wrap", WRAP, MD_OUT},
  247. #endif /* WRAP */
  248. #ifdef CIGNORE
  249. {"cignore", CIGNORE, MD_CTL},
  250. #endif /* CBAUD */
  251. #ifdef CBAUD
  252. {"cbaud", CBAUD, MD_CTL},
  253. #endif /* CBAUD */
  254. #ifdef CSTOPB
  255. {"cstopb", CSTOPB, MD_CTL},
  256. #endif /* CSTOPB */
  257. #ifdef CREAD
  258. {"cread", CREAD, MD_CTL},
  259. #endif /* CREAD */
  260. #ifdef PARENB
  261. {"parenb", PARENB, MD_CTL},
  262. #endif /* PARENB */
  263. #ifdef PARODD
  264. {"parodd", PARODD, MD_CTL},
  265. #endif /* PARODD */
  266. #ifdef HUPCL
  267. {"hupcl", HUPCL, MD_CTL},
  268. #endif /* HUPCL */
  269. #ifdef CLOCAL
  270. {"clocal", CLOCAL, MD_CTL},
  271. #endif /* CLOCAL */
  272. #ifdef LOBLK
  273. {"loblk", LOBLK, MD_CTL},
  274. #endif /* LOBLK */
  275. #ifdef CIBAUD
  276. {"cibaud", CIBAUD, MD_CTL},
  277. #endif /* CIBAUD */
  278. #ifdef CRTSCTS
  279. #ifdef CCTS_OFLOW
  280. {"ccts_oflow", CCTS_OFLOW, MD_CTL},
  281. #else
  282. {"crtscts", CRTSCTS, MD_CTL},
  283. #endif /* CCTS_OFLOW */
  284. #endif /* CRTSCTS */
  285. #ifdef CRTS_IFLOW
  286. {"crts_iflow", CRTS_IFLOW, MD_CTL},
  287. #endif /* CRTS_IFLOW */
  288. #ifdef CDTRCTS
  289. {"cdtrcts", CDTRCTS, MD_CTL},
  290. #endif /* CDTRCTS */
  291. #ifdef MDMBUF
  292. {"mdmbuf", MDMBUF, MD_CTL},
  293. #endif /* MDMBUF */
  294. #ifdef RCV1EN
  295. {"rcv1en", RCV1EN, MD_CTL},
  296. #endif /* RCV1EN */
  297. #ifdef XMT1EN
  298. {"xmt1en", XMT1EN, MD_CTL},
  299. #endif /* XMT1EN */
  300. #ifdef ISIG
  301. {"isig", ISIG, MD_LIN},
  302. #endif /* ISIG */
  303. #ifdef ICANON
  304. {"icanon", ICANON, MD_LIN},
  305. #endif /* ICANON */
  306. #ifdef XCASE
  307. {"xcase", XCASE, MD_LIN},
  308. #endif /* XCASE */
  309. #ifdef ECHO
  310. {"echo", ECHO, MD_LIN},
  311. #endif /* ECHO */
  312. #ifdef ECHOE
  313. {"echoe", ECHOE, MD_LIN},
  314. #endif /* ECHOE */
  315. #ifdef ECHOK
  316. {"echok", ECHOK, MD_LIN},
  317. #endif /* ECHOK */
  318. #ifdef ECHONL
  319. {"echonl", ECHONL, MD_LIN},
  320. #endif /* ECHONL */
  321. #ifdef NOFLSH
  322. {"noflsh", NOFLSH, MD_LIN},
  323. #endif /* NOFLSH */
  324. #ifdef TOSTOP
  325. {"tostop", TOSTOP, MD_LIN},
  326. #endif /* TOSTOP */
  327. #ifdef ECHOCTL
  328. {"echoctl", ECHOCTL, MD_LIN},
  329. #endif /* ECHOCTL */
  330. #ifdef ECHOPRT
  331. {"echoprt", ECHOPRT, MD_LIN},
  332. #endif /* ECHOPRT */
  333. #ifdef ECHOKE
  334. {"echoke", ECHOKE, MD_LIN},
  335. #endif /* ECHOKE */
  336. #ifdef DEFECHO
  337. {"defecho", DEFECHO, MD_LIN},
  338. #endif /* DEFECHO */
  339. #ifdef FLUSHO
  340. {"flusho", FLUSHO, MD_LIN},
  341. #endif /* FLUSHO */
  342. #ifdef PENDIN
  343. {"pendin", PENDIN, MD_LIN},
  344. #endif /* PENDIN */
  345. #ifdef IEXTEN
  346. {"iexten", IEXTEN, MD_LIN},
  347. #endif /* IEXTEN */
  348. #ifdef NOKERNINFO
  349. {"nokerninfo", NOKERNINFO, MD_LIN},
  350. #endif /* NOKERNINFO */
  351. #ifdef ALTWERASE
  352. {"altwerase", ALTWERASE, MD_LIN},
  353. #endif /* ALTWERASE */
  354. #ifdef EXTPROC
  355. {"extproc", EXTPROC, MD_LIN},
  356. #endif /* EXTPROC */
  357. #if defined(VINTR)
  358. {"intr", C_SH(C_INTR), MD_CHAR},
  359. #endif /* VINTR */
  360. #if defined(VQUIT)
  361. {"quit", C_SH(C_QUIT), MD_CHAR},
  362. #endif /* VQUIT */
  363. #if defined(VERASE)
  364. {"erase", C_SH(C_ERASE), MD_CHAR},
  365. #endif /* VERASE */
  366. #if defined(VKILL)
  367. {"kill", C_SH(C_KILL), MD_CHAR},
  368. #endif /* VKILL */
  369. #if defined(VEOF)
  370. {"eof", C_SH(C_EOF), MD_CHAR},
  371. #endif /* VEOF */
  372. #if defined(VEOL)
  373. {"eol", C_SH(C_EOL), MD_CHAR},
  374. #endif /* VEOL */
  375. #if defined(VEOL2)
  376. {"eol2", C_SH(C_EOL2), MD_CHAR},
  377. #endif /* VEOL2 */
  378. #if defined(VSWTCH)
  379. {"swtch", C_SH(C_SWTCH), MD_CHAR},
  380. #endif /* VSWTCH */
  381. #if defined(VDSWTCH)
  382. {"dswtch", C_SH(C_DSWTCH), MD_CHAR},
  383. #endif /* VDSWTCH */
  384. #if defined(VERASE2)
  385. {"erase2", C_SH(C_ERASE2), MD_CHAR},
  386. #endif /* VERASE2 */
  387. #if defined(VSTART)
  388. {"start", C_SH(C_START), MD_CHAR},
  389. #endif /* VSTART */
  390. #if defined(VSTOP)
  391. {"stop", C_SH(C_STOP), MD_CHAR},
  392. #endif /* VSTOP */
  393. #if defined(VWERASE)
  394. {"werase", C_SH(C_WERASE), MD_CHAR},
  395. #endif /* VWERASE */
  396. #if defined(VSUSP)
  397. {"susp", C_SH(C_SUSP), MD_CHAR},
  398. #endif /* VSUSP */
  399. #if defined(VDSUSP)
  400. {"dsusp", C_SH(C_DSUSP), MD_CHAR},
  401. #endif /* VDSUSP */
  402. #if defined(VREPRINT)
  403. {"reprint", C_SH(C_REPRINT), MD_CHAR},
  404. #endif /* VREPRINT */
  405. #if defined(VDISCARD)
  406. {"discard", C_SH(C_DISCARD), MD_CHAR},
  407. #endif /* VDISCARD */
  408. #if defined(VLNEXT)
  409. {"lnext", C_SH(C_LNEXT), MD_CHAR},
  410. #endif /* VLNEXT */
  411. #if defined(VSTATUS)
  412. {"status", C_SH(C_STATUS), MD_CHAR},
  413. #endif /* VSTATUS */
  414. #if defined(VPAGE)
  415. {"page", C_SH(C_PAGE), MD_CHAR},
  416. #endif /* VPAGE */
  417. #if defined(VPGOFF)
  418. {"pgoff", C_SH(C_PGOFF), MD_CHAR},
  419. #endif /* VPGOFF */
  420. #if defined(VKILL2)
  421. {"kill2", C_SH(C_KILL2), MD_CHAR},
  422. #endif /* VKILL2 */
  423. #if defined(VBRK)
  424. {"brk", C_SH(C_BRK), MD_CHAR},
  425. #endif /* VBRK */
  426. #if defined(VMIN)
  427. {"min", C_SH(C_MIN), MD_CHAR},
  428. #endif /* VMIN */
  429. #if defined(VTIME)
  430. {"time", C_SH(C_TIME), MD_CHAR},
  431. #endif /* VTIME */
  432. {NULL, 0, -1},
  433. };
  434. #define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
  435. #define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
  436. #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
  437. #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
  438. #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
  439. private void tty__getchar(struct termios *, unsigned char *);
  440. private void tty__setchar(struct termios *, unsigned char *);
  441. private speed_t tty__getspeed(struct termios *);
  442. private int tty_setup(EditLine *);
  443. #define t_qu t_ts
  444. /* tty_setup():
  445. * Get the tty parameters and initialize the editing state
  446. */
  447. private int
  448. tty_setup(EditLine *el)
  449. {
  450. int rst = 1;
  451. if (el->el_flags & EDIT_DISABLED)
  452. return (0);
  453. if (tty_getty(el, &el->el_tty.t_ed) == -1) {
  454. #ifdef DEBUG_TTY
  455. (void) fprintf(el->el_errfile,
  456. "tty_setup: tty_getty: %s\n", strerror(errno));
  457. #endif /* DEBUG_TTY */
  458. return (-1);
  459. }
  460. el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
  461. el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
  462. el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
  463. el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
  464. el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
  465. el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
  466. el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
  467. el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
  468. el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
  469. el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
  470. el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
  471. el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
  472. /*
  473. * Reset the tty chars to reasonable defaults
  474. * If they are disabled, then enable them.
  475. */
  476. if (rst) {
  477. if (tty__cooked_mode(&el->el_tty.t_ts)) {
  478. tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
  479. /*
  480. * Don't affect CMIN and CTIME for the editor mode
  481. */
  482. for (rst = 0; rst < C_NCC - 2; rst++)
  483. if (el->el_tty.t_c[TS_IO][rst] !=
  484. el->el_tty.t_vdisable
  485. && el->el_tty.t_c[ED_IO][rst] !=
  486. el->el_tty.t_vdisable)
  487. el->el_tty.t_c[ED_IO][rst] =
  488. el->el_tty.t_c[TS_IO][rst];
  489. for (rst = 0; rst < C_NCC; rst++)
  490. if (el->el_tty.t_c[TS_IO][rst] !=
  491. el->el_tty.t_vdisable)
  492. el->el_tty.t_c[EX_IO][rst] =
  493. el->el_tty.t_c[TS_IO][rst];
  494. }
  495. tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
  496. if (tty_setty(el, &el->el_tty.t_ex) == -1) {
  497. #ifdef DEBUG_TTY
  498. (void) fprintf(el->el_errfile,
  499. "tty_setup: tty_setty: %s\n",
  500. strerror(errno));
  501. #endif /* DEBUG_TTY */
  502. return (-1);
  503. }
  504. } else
  505. tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
  506. el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
  507. el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
  508. el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
  509. el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
  510. el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
  511. el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
  512. el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
  513. el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
  514. tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
  515. tty_bind_char(el, 1);
  516. return (0);
  517. }
  518. protected int
  519. tty_init(EditLine *el)
  520. {
  521. el->el_tty.t_mode = EX_IO;
  522. el->el_tty.t_vdisable = _POSIX_VDISABLE;
  523. (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
  524. (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
  525. return (tty_setup(el));
  526. }
  527. /* tty_end():
  528. * Restore the tty to its original settings
  529. */
  530. protected void
  531. /*ARGSUSED*/
  532. tty_end(EditLine *el)
  533. {
  534. /* XXX: Maybe reset to an initial state? */
  535. }
  536. /* tty__getspeed():
  537. * Get the tty speed
  538. */
  539. private speed_t
  540. tty__getspeed(struct termios *td)
  541. {
  542. speed_t spd;
  543. if ((spd = cfgetispeed(td)) == 0)
  544. spd = cfgetospeed(td);
  545. return (spd);
  546. }
  547. /* tty__getchar():
  548. * Get the tty characters
  549. */
  550. private void
  551. tty__getchar(struct termios *td, unsigned char *s)
  552. {
  553. #ifdef VINTR
  554. s[C_INTR] = td->c_cc[VINTR];
  555. #endif /* VINTR */
  556. #ifdef VQUIT
  557. s[C_QUIT] = td->c_cc[VQUIT];
  558. #endif /* VQUIT */
  559. #ifdef VERASE
  560. s[C_ERASE] = td->c_cc[VERASE];
  561. #endif /* VERASE */
  562. #ifdef VKILL
  563. s[C_KILL] = td->c_cc[VKILL];
  564. #endif /* VKILL */
  565. #ifdef VEOF
  566. s[C_EOF] = td->c_cc[VEOF];
  567. #endif /* VEOF */
  568. #ifdef VEOL
  569. s[C_EOL] = td->c_cc[VEOL];
  570. #endif /* VEOL */
  571. #ifdef VEOL2
  572. s[C_EOL2] = td->c_cc[VEOL2];
  573. #endif /* VEOL2 */
  574. #ifdef VSWTCH
  575. s[C_SWTCH] = td->c_cc[VSWTCH];
  576. #endif /* VSWTCH */
  577. #ifdef VDSWTCH
  578. s[C_DSWTCH] = td->c_cc[VDSWTCH];
  579. #endif /* VDSWTCH */
  580. #ifdef VERASE2
  581. s[C_ERASE2] = td->c_cc[VERASE2];
  582. #endif /* VERASE2 */
  583. #ifdef VSTART
  584. s[C_START] = td->c_cc[VSTART];
  585. #endif /* VSTART */
  586. #ifdef VSTOP
  587. s[C_STOP] = td->c_cc[VSTOP];
  588. #endif /* VSTOP */
  589. #ifdef VWERASE
  590. s[C_WERASE] = td->c_cc[VWERASE];
  591. #endif /* VWERASE */
  592. #ifdef VSUSP
  593. s[C_SUSP] = td->c_cc[VSUSP];
  594. #endif /* VSUSP */
  595. #ifdef VDSUSP
  596. s[C_DSUSP] = td->c_cc[VDSUSP];
  597. #endif /* VDSUSP */
  598. #ifdef VREPRINT
  599. s[C_REPRINT] = td->c_cc[VREPRINT];
  600. #endif /* VREPRINT */
  601. #ifdef VDISCARD
  602. s[C_DISCARD] = td->c_cc[VDISCARD];
  603. #endif /* VDISCARD */
  604. #ifdef VLNEXT
  605. s[C_LNEXT] = td->c_cc[VLNEXT];
  606. #endif /* VLNEXT */
  607. #ifdef VSTATUS
  608. s[C_STATUS] = td->c_cc[VSTATUS];
  609. #endif /* VSTATUS */
  610. #ifdef VPAGE
  611. s[C_PAGE] = td->c_cc[VPAGE];
  612. #endif /* VPAGE */
  613. #ifdef VPGOFF
  614. s[C_PGOFF] = td->c_cc[VPGOFF];
  615. #endif /* VPGOFF */
  616. #ifdef VKILL2
  617. s[C_KILL2] = td->c_cc[VKILL2];
  618. #endif /* KILL2 */
  619. #ifdef VMIN
  620. s[C_MIN] = td->c_cc[VMIN];
  621. #endif /* VMIN */
  622. #ifdef VTIME
  623. s[C_TIME] = td->c_cc[VTIME];
  624. #endif /* VTIME */
  625. } /* tty__getchar */
  626. /* tty__setchar():
  627. * Set the tty characters
  628. */
  629. private void
  630. tty__setchar(struct termios *td, unsigned char *s)
  631. {
  632. #ifdef VINTR
  633. td->c_cc[VINTR] = s[C_INTR];
  634. #endif /* VINTR */
  635. #ifdef VQUIT
  636. td->c_cc[VQUIT] = s[C_QUIT];
  637. #endif /* VQUIT */
  638. #ifdef VERASE
  639. td->c_cc[VERASE] = s[C_ERASE];
  640. #endif /* VERASE */
  641. #ifdef VKILL
  642. td->c_cc[VKILL] = s[C_KILL];
  643. #endif /* VKILL */
  644. #ifdef VEOF
  645. td->c_cc[VEOF] = s[C_EOF];
  646. #endif /* VEOF */
  647. #ifdef VEOL
  648. td->c_cc[VEOL] = s[C_EOL];
  649. #endif /* VEOL */
  650. #ifdef VEOL2
  651. td->c_cc[VEOL2] = s[C_EOL2];
  652. #endif /* VEOL2 */
  653. #ifdef VSWTCH
  654. td->c_cc[VSWTCH] = s[C_SWTCH];
  655. #endif /* VSWTCH */
  656. #ifdef VDSWTCH
  657. td->c_cc[VDSWTCH] = s[C_DSWTCH];
  658. #endif /* VDSWTCH */
  659. #ifdef VERASE2
  660. td->c_cc[VERASE2] = s[C_ERASE2];
  661. #endif /* VERASE2 */
  662. #ifdef VSTART
  663. td->c_cc[VSTART] = s[C_START];
  664. #endif /* VSTART */
  665. #ifdef VSTOP
  666. td->c_cc[VSTOP] = s[C_STOP];
  667. #endif /* VSTOP */
  668. #ifdef VWERASE
  669. td->c_cc[VWERASE] = s[C_WERASE];
  670. #endif /* VWERASE */
  671. #ifdef VSUSP
  672. td->c_cc[VSUSP] = s[C_SUSP];
  673. #endif /* VSUSP */
  674. #ifdef VDSUSP
  675. td->c_cc[VDSUSP] = s[C_DSUSP];
  676. #endif /* VDSUSP */
  677. #ifdef VREPRINT
  678. td->c_cc[VREPRINT] = s[C_REPRINT];
  679. #endif /* VREPRINT */
  680. #ifdef VDISCARD
  681. td->c_cc[VDISCARD] = s[C_DISCARD];
  682. #endif /* VDISCARD */
  683. #ifdef VLNEXT
  684. td->c_cc[VLNEXT] = s[C_LNEXT];
  685. #endif /* VLNEXT */
  686. #ifdef VSTATUS
  687. td->c_cc[VSTATUS] = s[C_STATUS];
  688. #endif /* VSTATUS */
  689. #ifdef VPAGE
  690. td->c_cc[VPAGE] = s[C_PAGE];
  691. #endif /* VPAGE */
  692. #ifdef VPGOFF
  693. td->c_cc[VPGOFF] = s[C_PGOFF];
  694. #endif /* VPGOFF */
  695. #ifdef VKILL2
  696. td->c_cc[VKILL2] = s[C_KILL2];
  697. #endif /* VKILL2 */
  698. #ifdef VMIN
  699. td->c_cc[VMIN] = s[C_MIN];
  700. #endif /* VMIN */
  701. #ifdef VTIME
  702. td->c_cc[VTIME] = s[C_TIME];
  703. #endif /* VTIME */
  704. } /* tty__setchar */
  705. /* tty_bind_char():
  706. * Rebind the editline functions
  707. */
  708. protected void
  709. tty_bind_char(EditLine *el, int force)
  710. {
  711. unsigned char *t_n = el->el_tty.t_c[ED_IO];
  712. unsigned char *t_o = el->el_tty.t_ed.c_cc;
  713. unsigned char new[2], old[2];
  714. const ttymap_t *tp;
  715. el_action_t *map, *alt;
  716. const el_action_t *dmap, *dalt;
  717. new[1] = old[1] = '\0';
  718. map = el->el_map.key;
  719. alt = el->el_map.alt;
  720. if (el->el_map.type == MAP_VI) {
  721. dmap = el->el_map.vii;
  722. dalt = el->el_map.vic;
  723. } else {
  724. dmap = el->el_map.emacs;
  725. dalt = NULL;
  726. }
  727. for (tp = tty_map; tp->nch != -1; tp++) {
  728. new[0] = t_n[tp->nch];
  729. old[0] = t_o[tp->och];
  730. if (new[0] == old[0] && !force)
  731. continue;
  732. /* Put the old default binding back, and set the new binding */
  733. key_clear(el, map, (char *)old);
  734. map[old[0]] = dmap[old[0]];
  735. key_clear(el, map, (char *)new);
  736. /* MAP_VI == 1, MAP_EMACS == 0... */
  737. map[new[0]] = tp->bind[el->el_map.type];
  738. if (dalt) {
  739. key_clear(el, alt, (char *)old);
  740. alt[old[0]] = dalt[old[0]];
  741. key_clear(el, alt, (char *)new);
  742. alt[new[0]] = tp->bind[el->el_map.type + 1];
  743. }
  744. }
  745. }
  746. /* tty_rawmode():
  747. * Set terminal into 1 character at a time mode.
  748. */
  749. protected int
  750. tty_rawmode(EditLine *el)
  751. {
  752. if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
  753. return (0);
  754. if (el->el_flags & EDIT_DISABLED)
  755. return (0);
  756. if (tty_getty(el, &el->el_tty.t_ts) == -1) {
  757. #ifdef DEBUG_TTY
  758. (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n",
  759. strerror(errno));
  760. #endif /* DEBUG_TTY */
  761. return (-1);
  762. }
  763. /*
  764. * We always keep up with the eight bit setting and the speed of the
  765. * tty. But only we only believe changes that are made to cooked mode!
  766. */
  767. el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
  768. el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
  769. if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed ||
  770. tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) {
  771. (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed);
  772. (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed);
  773. (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed);
  774. (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
  775. }
  776. if (tty__cooked_mode(&el->el_tty.t_ts)) {
  777. if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
  778. el->el_tty.t_ex.c_cflag =
  779. el->el_tty.t_ts.c_cflag;
  780. el->el_tty.t_ex.c_cflag &=
  781. ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
  782. el->el_tty.t_ex.c_cflag |=
  783. el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
  784. el->el_tty.t_ed.c_cflag =
  785. el->el_tty.t_ts.c_cflag;
  786. el->el_tty.t_ed.c_cflag &=
  787. ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
  788. el->el_tty.t_ed.c_cflag |=
  789. el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
  790. }
  791. if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
  792. (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
  793. el->el_tty.t_ex.c_lflag =
  794. el->el_tty.t_ts.c_lflag;
  795. el->el_tty.t_ex.c_lflag &=
  796. ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
  797. el->el_tty.t_ex.c_lflag |=
  798. el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
  799. el->el_tty.t_ed.c_lflag =
  800. el->el_tty.t_ts.c_lflag;
  801. el->el_tty.t_ed.c_lflag &=
  802. ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
  803. el->el_tty.t_ed.c_lflag |=
  804. el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
  805. }
  806. if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
  807. (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
  808. el->el_tty.t_ex.c_iflag =
  809. el->el_tty.t_ts.c_iflag;
  810. el->el_tty.t_ex.c_iflag &=
  811. ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
  812. el->el_tty.t_ex.c_iflag |=
  813. el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
  814. el->el_tty.t_ed.c_iflag =
  815. el->el_tty.t_ts.c_iflag;
  816. el->el_tty.t_ed.c_iflag &=
  817. ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
  818. el->el_tty.t_ed.c_iflag |=
  819. el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
  820. }
  821. if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
  822. (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
  823. el->el_tty.t_ex.c_oflag =
  824. el->el_tty.t_ts.c_oflag;
  825. el->el_tty.t_ex.c_oflag &=
  826. ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
  827. el->el_tty.t_ex.c_oflag |=
  828. el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
  829. el->el_tty.t_ed.c_oflag =
  830. el->el_tty.t_ts.c_oflag;
  831. el->el_tty.t_ed.c_oflag &=
  832. ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
  833. el->el_tty.t_ed.c_oflag |=
  834. el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
  835. }
  836. if (tty__gettabs(&el->el_tty.t_ex) == 0)
  837. el->el_tty.t_tabs = 0;
  838. else
  839. el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
  840. {
  841. int i;
  842. tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
  843. /*
  844. * Check if the user made any changes.
  845. * If he did, then propagate the changes to the
  846. * edit and execute data structures.
  847. */
  848. for (i = 0; i < C_NCC; i++)
  849. if (el->el_tty.t_c[TS_IO][i] !=
  850. el->el_tty.t_c[EX_IO][i])
  851. break;
  852. if (i != C_NCC) {
  853. /*
  854. * Propagate changes only to the unprotected
  855. * chars that have been modified just now.
  856. */
  857. for (i = 0; i < C_NCC; i++) {
  858. if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
  859. && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
  860. el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
  861. if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i))
  862. el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
  863. }
  864. tty_bind_char(el, 0);
  865. tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
  866. for (i = 0; i < C_NCC; i++) {
  867. if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
  868. && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
  869. el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
  870. if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i))
  871. el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
  872. }
  873. tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
  874. }
  875. }
  876. }
  877. if (tty_setty(el, &el->el_tty.t_ed) == -1) {
  878. #ifdef DEBUG_TTY
  879. (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
  880. strerror(errno));
  881. #endif /* DEBUG_TTY */
  882. return (-1);
  883. }
  884. el->el_tty.t_mode = ED_IO;
  885. return (0);
  886. }
  887. /* tty_cookedmode():
  888. * Set the tty back to normal mode
  889. */
  890. protected int
  891. tty_cookedmode(EditLine *el)
  892. { /* set tty in normal setup */
  893. if (el->el_tty.t_mode == EX_IO)
  894. return (0);
  895. if (el->el_flags & EDIT_DISABLED)
  896. return (0);
  897. if (tty_setty(el, &el->el_tty.t_ex) == -1) {
  898. #ifdef DEBUG_TTY
  899. (void) fprintf(el->el_errfile,
  900. "tty_cookedmode: tty_setty: %s\n",
  901. strerror(errno));
  902. #endif /* DEBUG_TTY */
  903. return (-1);
  904. }
  905. el->el_tty.t_mode = EX_IO;
  906. return (0);
  907. }
  908. /* tty_quotemode():
  909. * Turn on quote mode
  910. */
  911. protected int
  912. tty_quotemode(EditLine *el)
  913. {
  914. if (el->el_tty.t_mode == QU_IO)
  915. return (0);
  916. el->el_tty.t_qu = el->el_tty.t_ed;
  917. el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask;
  918. el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask;
  919. el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask;
  920. el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask;
  921. el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask;
  922. el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask;
  923. el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
  924. el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
  925. if (tty_setty(el, &el->el_tty.t_qu) == -1) {
  926. #ifdef DEBUG_TTY
  927. (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
  928. strerror(errno));
  929. #endif /* DEBUG_TTY */
  930. return (-1);
  931. }
  932. el->el_tty.t_mode = QU_IO;
  933. return (0);
  934. }
  935. /* tty_noquotemode():
  936. * Turn off quote mode
  937. */
  938. protected int
  939. tty_noquotemode(EditLine *el)
  940. {
  941. if (el->el_tty.t_mode != QU_IO)
  942. return (0);
  943. if (tty_setty(el, &el->el_tty.t_ed) == -1) {
  944. #ifdef DEBUG_TTY
  945. (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
  946. strerror(errno));
  947. #endif /* DEBUG_TTY */
  948. return (-1);
  949. }
  950. el->el_tty.t_mode = ED_IO;
  951. return (0);
  952. }
  953. /* tty_stty():
  954. * Stty builtin
  955. */
  956. protected int
  957. /*ARGSUSED*/
  958. tty_stty(EditLine *el, int argc, const char **argv)
  959. {
  960. const ttymodes_t *m;
  961. char x;
  962. int aflag = 0;
  963. const char *s, *d;
  964. const char *name;
  965. int z = EX_IO;
  966. if (argv == NULL)
  967. return (-1);
  968. name = *argv++;
  969. while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
  970. switch (argv[0][1]) {
  971. case 'a':
  972. aflag++;
  973. argv++;
  974. break;
  975. case 'd':
  976. argv++;
  977. z = ED_IO;
  978. break;
  979. case 'x':
  980. argv++;
  981. z = EX_IO;
  982. break;
  983. case 'q':
  984. argv++;
  985. z = QU_IO;
  986. break;
  987. default:
  988. (void) fprintf(el->el_errfile,
  989. "%s: Unknown switch `%c'.\n",
  990. name, argv[0][1]);
  991. return (-1);
  992. }
  993. if (!argv || !*argv) {
  994. int i = -1;
  995. int len = 0, st = 0, cu;
  996. for (m = ttymodes; m->m_name; m++) {
  997. if (m->m_type != i) {
  998. (void) fprintf(el->el_outfile, "%s%s",
  999. i != -1 ? "\n" : "",
  1000. el->el_tty.t_t[z][m->m_type].t_name);
  1001. i = m->m_type;
  1002. st = len =
  1003. strlen(el->el_tty.t_t[z][m->m_type].t_name);
  1004. }
  1005. x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
  1006. ? '+' : '\0';
  1007. x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
  1008. ? '-' : x;
  1009. if (x != '\0' || aflag) {
  1010. cu = strlen(m->m_name) + (x != '\0') + 1;
  1011. if (len + cu >= el->el_term.t_size.h) {
  1012. (void) fprintf(el->el_outfile, "\n%*s",
  1013. st, "");
  1014. len = st + cu;
  1015. } else
  1016. len += cu;
  1017. if (x != '\0')
  1018. (void) fprintf(el->el_outfile, "%c%s ",
  1019. x, m->m_name);
  1020. else
  1021. (void) fprintf(el->el_outfile, "%s ",
  1022. m->m_name);
  1023. }
  1024. }
  1025. (void) fprintf(el->el_outfile, "\n");
  1026. return (0);
  1027. }
  1028. while (argv && (s = *argv++)) {
  1029. switch (*s) {
  1030. case '+':
  1031. case '-':
  1032. x = *s++;
  1033. break;
  1034. default:
  1035. x = '\0';
  1036. break;
  1037. }
  1038. d = s;
  1039. for (m = ttymodes; m->m_name; m++)
  1040. if (strcmp(m->m_name, d) == 0)
  1041. break;
  1042. if (!m->m_name) {
  1043. (void) fprintf(el->el_errfile,
  1044. "%s: Invalid argument `%s'.\n", name, d);
  1045. return (-1);
  1046. }
  1047. switch (x) {
  1048. case '+':
  1049. el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
  1050. el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
  1051. break;
  1052. case '-':
  1053. el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
  1054. el->el_tty.t_t[z][m->m_type].t_clrmask |= m->m_value;
  1055. break;
  1056. default:
  1057. el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value;
  1058. el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value;
  1059. break;
  1060. }
  1061. }
  1062. return (0);
  1063. }
  1064. #ifdef notyet
  1065. /* tty_printchar():
  1066. * DEbugging routine to print the tty characters
  1067. */
  1068. private void
  1069. tty_printchar(EditLine *el, unsigned char *s)
  1070. {
  1071. ttyperm_t *m;
  1072. int i;
  1073. for (i = 0; i < C_NCC; i++) {
  1074. for (m = el->el_tty.t_t; m->m_name; m++)
  1075. if (m->m_type == MD_CHAR && C_SH(i) == m->m_value)
  1076. break;
  1077. if (m->m_name)
  1078. (void) fprintf(el->el_errfile, "%s ^%c ",
  1079. m->m_name, s[i] + 'A' - 1);
  1080. if (i % 5 == 0)
  1081. (void) fprintf(el->el_errfile, "\n");
  1082. }
  1083. (void) fprintf(el->el_errfile, "\n");
  1084. }
  1085. #endif /* notyet */