/contrib/tcsh/ed.term.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 1141 lines · 1021 code · 64 blank · 56 comment · 131 complexity · 0557706028600e5853c82f3c1f9ae76e MD5 · raw file

  1. /* $Header: /p/tcsh/cvsroot/tcsh/ed.term.c,v 1.38 2011/02/25 23:58:34 christos Exp $ */
  2. /*
  3. * ed.term.c: Low level terminal interface
  4. */
  5. /*-
  6. * Copyright (c) 1980, 1991 The Regents of the University of California.
  7. * All rights reserved.
  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. Neither the name of the University nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. */
  33. #include "sh.h"
  34. #ifndef WINNT_NATIVE
  35. RCSID("$tcsh: ed.term.c,v 1.38 2011/02/25 23:58:34 christos Exp $")
  36. #include <assert.h>
  37. #include "ed.h"
  38. int didsetty = 0;
  39. ttyperm_t ttylist = {
  40. {
  41. #if defined(POSIX) || defined(TERMIO)
  42. { "iflag:", ICRNL, (INLCR|IGNCR) },
  43. { "oflag:", (OPOST|ONLCR), ONLRET },
  44. { "cflag:", 0, 0 },
  45. { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN),
  46. (NOFLSH|ECHONL|EXTPROC|FLUSHO|IDEFAULT) },
  47. #else /* GSTTY */
  48. { "nrmal:", (ECHO|CRMOD|ANYP), (CBREAK|RAW|LCASE|VTDELAY|ALLDELAY) },
  49. { "local:", (LCRTBS|LCRTERA|LCRTKIL), (LPRTERA|LFLUSHO) },
  50. #endif /* POSIX || TERMIO */
  51. { "chars:", 0, 0 },
  52. },
  53. {
  54. #if defined(POSIX) || defined(TERMIO)
  55. { "iflag:", (INLCR|ICRNL), IGNCR },
  56. { "oflag:", (OPOST|ONLCR), ONLRET },
  57. { "cflag:", 0, 0 },
  58. { "lflag:", ISIG,
  59. (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO|
  60. IDEFAULT) },
  61. #else /* GSTTY */
  62. { "nrmal:", (CBREAK|CRMOD|ANYP), (RAW|ECHO|LCASE|VTDELAY|ALLDELAY) },
  63. { "local:", (LCRTBS|LCRTERA|LCRTKIL), (LPRTERA|LFLUSHO) },
  64. #endif /* POSIX || TERMIO */
  65. { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)|
  66. C_SH(C_WERASE)|C_SH(C_REPRINT)|C_SH(C_SUSP)|C_SH(C_DSUSP)|
  67. C_SH(C_EOF)|C_SH(C_EOL)|C_SH(C_DISCARD)|C_SH(C_PGOFF)|
  68. C_SH(C_KILL2)|C_SH(C_PAGE)|C_SH(C_STATUS)|C_SH(C_LNEXT)),
  69. 0 }
  70. },
  71. {
  72. #if defined(POSIX) || defined(TERMIO)
  73. { "iflag:", 0, IXON | IXOFF },
  74. { "oflag:", 0, 0 },
  75. { "cflag:", 0, 0 },
  76. { "lflag:", 0, ISIG | IEXTEN },
  77. #else /* GSTTY */
  78. { "nrmal:", RAW, CBREAK },
  79. { "local:", 0, 0 },
  80. #endif /* POSIX || TERMIO */
  81. { "chars:", 0, 0 },
  82. }
  83. };
  84. static const struct tcshmodes {
  85. const char *m_name;
  86. #ifdef SOLARIS2
  87. unsigned long m_value;
  88. #else /* !SOLARIS2 */
  89. int m_value;
  90. #endif /* SOLARIS2 */
  91. int m_type;
  92. } modelist[] = {
  93. #if defined(POSIX) || defined(TERMIO)
  94. # ifdef IGNBRK
  95. { "ignbrk", IGNBRK, M_INPUT },
  96. # endif /* IGNBRK */
  97. # ifdef BRKINT
  98. { "brkint", BRKINT, M_INPUT },
  99. # endif /* BRKINT */
  100. # ifdef IGNPAR
  101. { "ignpar", IGNPAR, M_INPUT },
  102. # endif /* IGNPAR */
  103. # ifdef PARMRK
  104. { "parmrk", PARMRK, M_INPUT },
  105. # endif /* PARMRK */
  106. # ifdef INPCK
  107. { "inpck", INPCK, M_INPUT },
  108. # endif /* INPCK */
  109. # ifdef ISTRIP
  110. { "istrip", ISTRIP, M_INPUT },
  111. # endif /* ISTRIP */
  112. # ifdef INLCR
  113. { "inlcr", INLCR, M_INPUT },
  114. # endif /* INLCR */
  115. # ifdef IGNCR
  116. { "igncr", IGNCR, M_INPUT },
  117. # endif /* IGNCR */
  118. # ifdef ICRNL
  119. { "icrnl", ICRNL, M_INPUT },
  120. # endif /* ICRNL */
  121. # ifdef IUCLC
  122. { "iuclc", IUCLC, M_INPUT },
  123. # endif /* IUCLC */
  124. # ifdef IXON
  125. { "ixon", IXON, M_INPUT },
  126. # endif /* IXON */
  127. # ifdef IXANY
  128. { "ixany", IXANY, M_INPUT },
  129. # endif /* IXANY */
  130. # ifdef IXOFF
  131. { "ixoff", IXOFF, M_INPUT },
  132. # endif /* IXOFF */
  133. # ifdef IMAXBEL
  134. { "imaxbel",IMAXBEL,M_INPUT },
  135. # endif /* IMAXBEL */
  136. # ifdef IDELETE
  137. { "idelete",IDELETE,M_INPUT },
  138. # endif /* IDELETE */
  139. # ifdef OPOST
  140. { "opost", OPOST, M_OUTPUT },
  141. # endif /* OPOST */
  142. # ifdef OLCUC
  143. { "olcuc", OLCUC, M_OUTPUT },
  144. # endif /* OLCUC */
  145. # ifdef ONLCR
  146. { "onlcr", ONLCR, M_OUTPUT },
  147. # endif /* ONLCR */
  148. # ifdef OCRNL
  149. { "ocrnl", OCRNL, M_OUTPUT },
  150. # endif /* OCRNL */
  151. # ifdef ONOCR
  152. { "onocr", ONOCR, M_OUTPUT },
  153. # endif /* ONOCR */
  154. # ifdef ONOEOT
  155. { "onoeot", ONOEOT, M_OUTPUT },
  156. # endif /* ONOEOT */
  157. # ifdef ONLRET
  158. { "onlret", ONLRET, M_OUTPUT },
  159. # endif /* ONLRET */
  160. # ifdef OFILL
  161. { "ofill", OFILL, M_OUTPUT },
  162. # endif /* OFILL */
  163. # ifdef OFDEL
  164. { "ofdel", OFDEL, M_OUTPUT },
  165. # endif /* OFDEL */
  166. # ifdef NLDLY
  167. { "nldly", NLDLY, M_OUTPUT },
  168. # endif /* NLDLY */
  169. # ifdef CRDLY
  170. { "crdly", CRDLY, M_OUTPUT },
  171. # endif /* CRDLY */
  172. # ifdef TABDLY
  173. { "tabdly", TABDLY, M_OUTPUT },
  174. # endif /* TABDLY */
  175. # ifdef XTABS
  176. { "xtabs", XTABS, M_OUTPUT },
  177. # endif /* XTABS */
  178. # ifdef BSDLY
  179. { "bsdly", BSDLY, M_OUTPUT },
  180. # endif /* BSDLY */
  181. # ifdef VTDLY
  182. { "vtdly", VTDLY, M_OUTPUT },
  183. # endif /* VTDLY */
  184. # ifdef FFDLY
  185. { "ffdly", FFDLY, M_OUTPUT },
  186. # endif /* FFDLY */
  187. # ifdef PAGEOUT
  188. { "pageout",PAGEOUT,M_OUTPUT },
  189. # endif /* PAGEOUT */
  190. # ifdef WRAP
  191. { "wrap", WRAP, M_OUTPUT },
  192. # endif /* WRAP */
  193. # ifdef CIGNORE
  194. { "cignore",CIGNORE,M_CONTROL },
  195. # endif /* CBAUD */
  196. # ifdef CBAUD
  197. { "cbaud", CBAUD, M_CONTROL },
  198. # endif /* CBAUD */
  199. # ifdef CSTOPB
  200. { "cstopb", CSTOPB, M_CONTROL },
  201. # endif /* CSTOPB */
  202. # ifdef CREAD
  203. { "cread", CREAD, M_CONTROL },
  204. # endif /* CREAD */
  205. # ifdef PARENB
  206. { "parenb", PARENB, M_CONTROL },
  207. # endif /* PARENB */
  208. # ifdef PARODD
  209. { "parodd", PARODD, M_CONTROL },
  210. # endif /* PARODD */
  211. # ifdef HUPCL
  212. { "hupcl", HUPCL, M_CONTROL },
  213. # endif /* HUPCL */
  214. # ifdef CLOCAL
  215. { "clocal", CLOCAL, M_CONTROL },
  216. # endif /* CLOCAL */
  217. # ifdef LOBLK
  218. { "loblk", LOBLK, M_CONTROL },
  219. # endif /* LOBLK */
  220. # ifdef CIBAUD
  221. { "cibaud", CIBAUD, M_CONTROL },
  222. # endif /* CIBAUD */
  223. # ifdef CRTSCTS
  224. # ifdef CCTS_OFLOW
  225. { "ccts_oflow",CCTS_OFLOW,M_CONTROL },
  226. # else
  227. { "crtscts",CRTSCTS,M_CONTROL },
  228. # endif /* CCTS_OFLOW */
  229. # endif /* CRTSCTS */
  230. # ifdef CRTS_IFLOW
  231. { "crts_iflow",CRTS_IFLOW,M_CONTROL },
  232. # endif /* CRTS_IFLOW */
  233. # ifdef MDMBUF
  234. { "mdmbuf", MDMBUF, M_CONTROL },
  235. # endif /* MDMBUF */
  236. # ifdef RCV1EN
  237. { "rcv1en", RCV1EN, M_CONTROL },
  238. # endif /* RCV1EN */
  239. # ifdef XMT1EN
  240. { "xmt1en", XMT1EN, M_CONTROL },
  241. # endif /* XMT1EN */
  242. # ifdef ISIG
  243. { "isig", ISIG, M_LINED },
  244. # endif /* ISIG */
  245. # ifdef ICANON
  246. { "icanon", ICANON, M_LINED },
  247. # endif /* ICANON */
  248. # ifdef XCASE
  249. { "xcase", XCASE, M_LINED },
  250. # endif /* XCASE */
  251. # ifdef ECHO
  252. { "echo", ECHO, M_LINED },
  253. # endif /* ECHO */
  254. # ifdef ECHOE
  255. { "echoe", ECHOE, M_LINED },
  256. # endif /* ECHOE */
  257. # ifdef ECHOK
  258. { "echok", ECHOK, M_LINED },
  259. # endif /* ECHOK */
  260. # ifdef ECHONL
  261. { "echonl", ECHONL, M_LINED },
  262. # endif /* ECHONL */
  263. # ifdef NOFLSH
  264. { "noflsh", NOFLSH, M_LINED },
  265. # endif /* NOFLSH */
  266. # ifdef TOSTOP
  267. { "tostop", TOSTOP, M_LINED },
  268. # endif /* TOSTOP */
  269. # ifdef ECHOCTL
  270. { "echoctl",ECHOCTL,M_LINED },
  271. # endif /* ECHOCTL */
  272. # ifdef ECHOPRT
  273. { "echoprt",ECHOPRT,M_LINED },
  274. # endif /* ECHOPRT */
  275. # ifdef ECHOKE
  276. { "echoke", ECHOKE, M_LINED },
  277. # endif /* ECHOKE */
  278. # ifdef DEFECHO
  279. { "defecho",DEFECHO,M_LINED },
  280. # endif /* DEFECHO */
  281. # ifdef FLUSHO
  282. { "flusho", FLUSHO, M_LINED },
  283. # endif /* FLUSHO */
  284. # ifdef PENDIN
  285. { "pendin", PENDIN, M_LINED },
  286. # endif /* PENDIN */
  287. # ifdef IEXTEN
  288. { "iexten", IEXTEN, M_LINED },
  289. # endif /* IEXTEN */
  290. # ifdef NOKERNINFO
  291. { "nokerninfo",NOKERNINFO,M_LINED },
  292. # endif /* NOKERNINFO */
  293. # ifdef ALTWERASE
  294. { "altwerase",ALTWERASE,M_LINED },
  295. # endif /* ALTWERASE */
  296. # ifdef EXTPROC
  297. { "extproc",EXTPROC,M_LINED },
  298. # endif /* EXTPROC */
  299. # ifdef IDEFAULT
  300. { "idefault",IDEFAULT,M_LINED },
  301. # endif /* IDEFAULT */
  302. #else /* GSTTY */
  303. # ifdef TANDEM
  304. { "tandem", TANDEM, M_CONTROL },
  305. # endif /* TANDEM */
  306. # ifdef CBREAK
  307. { "cbreak", CBREAK, M_CONTROL },
  308. # endif /* CBREAK */
  309. # ifdef LCASE
  310. { "lcase", LCASE, M_CONTROL },
  311. # endif /* LCASE */
  312. # ifdef ECHO
  313. { "echo", ECHO, M_CONTROL },
  314. # endif /* ECHO */
  315. # ifdef CRMOD
  316. { "crmod", CRMOD, M_CONTROL },
  317. # endif /* CRMOD */
  318. # ifdef RAW
  319. { "raw", RAW, M_CONTROL },
  320. # endif /* RAW */
  321. # ifdef ODDP
  322. { "oddp", ODDP, M_CONTROL },
  323. # endif /* ODDP */
  324. # ifdef EVENP
  325. { "evenp", EVENP, M_CONTROL },
  326. # endif /* EVENP */
  327. # ifdef ANYP
  328. { "anyp", ANYP, M_CONTROL },
  329. # endif /* ANYP */
  330. # ifdef NLDELAY
  331. { "nldelay",NLDELAY,M_CONTROL },
  332. # endif /* NLDELAY */
  333. # ifdef TBDELAY
  334. { "tbdelay",TBDELAY,M_CONTROL },
  335. # endif /* TBDELAY */
  336. # ifdef XTABS
  337. { "xtabs", XTABS, M_CONTROL },
  338. # endif /* XTABS */
  339. # ifdef CRDELAY
  340. { "crdelay",CRDELAY,M_CONTROL },
  341. # endif /* CRDELAY */
  342. # ifdef VTDELAY
  343. { "vtdelay",VTDELAY,M_CONTROL },
  344. # endif /* VTDELAY */
  345. # ifdef BSDELAY
  346. { "bsdelay",BSDELAY,M_CONTROL },
  347. # endif /* BSDELAY */
  348. # ifdef CRTBS
  349. { "crtbs", CRTBS, M_CONTROL },
  350. # endif /* CRTBS */
  351. # ifdef PRTERA
  352. { "prtera", PRTERA, M_CONTROL },
  353. # endif /* PRTERA */
  354. # ifdef CRTERA
  355. { "crtera", CRTERA, M_CONTROL },
  356. # endif /* CRTERA */
  357. # ifdef TILDE
  358. { "tilde", TILDE, M_CONTROL },
  359. # endif /* TILDE */
  360. # ifdef MDMBUF
  361. { "mdmbuf", MDMBUF, M_CONTROL },
  362. # endif /* MDMBUF */
  363. # ifdef LITOUT
  364. { "litout", LITOUT, M_CONTROL },
  365. # endif /* LITOUT */
  366. # ifdef TOSTOP
  367. { "tostop", TOSTOP, M_CONTROL },
  368. # endif /* TOSTOP */
  369. # ifdef FLUSHO
  370. { "flusho", FLUSHO, M_CONTROL },
  371. # endif /* FLUSHO */
  372. # ifdef NOHANG
  373. { "nohang", NOHANG, M_CONTROL },
  374. # endif /* NOHANG */
  375. # ifdef L001000
  376. { "l001000",L001000,M_CONTROL },
  377. # endif /* L001000 */
  378. # ifdef CRTKIL
  379. { "crtkil", CRTKIL, M_CONTROL },
  380. # endif /* CRTKIL */
  381. # ifdef PASS8
  382. { "pass8", PASS8, M_CONTROL },
  383. # endif /* PASS8 */
  384. # ifdef CTLECH
  385. { "ctlech", CTLECH, M_CONTROL },
  386. # endif /* CTLECH */
  387. # ifdef PENDIN
  388. { "pendin", PENDIN, M_CONTROL },
  389. # endif /* PENDIN */
  390. # ifdef DECCTQ
  391. { "decctq", DECCTQ, M_CONTROL },
  392. # endif /* DECCTQ */
  393. # ifdef NOFLSH
  394. { "noflsh", NOFLSH, M_CONTROL },
  395. # endif /* NOFLSH */
  396. # ifdef LCRTBS
  397. { "lcrtbs", LCRTBS, M_LOCAL },
  398. # endif /* LCRTBS */
  399. # ifdef LPRTERA
  400. { "lprtera",LPRTERA,M_LOCAL },
  401. # endif /* LPRTERA */
  402. # ifdef LCRTERA
  403. { "lcrtera",LCRTERA,M_LOCAL },
  404. # endif /* LCRTERA */
  405. # ifdef LTILDE
  406. { "ltilde", LTILDE, M_LOCAL },
  407. # endif /* LTILDE */
  408. # ifdef LMDMBUF
  409. { "lmdmbuf",LMDMBUF,M_LOCAL },
  410. # endif /* LMDMBUF */
  411. # ifdef LLITOUT
  412. { "llitout",LLITOUT,M_LOCAL },
  413. # endif /* LLITOUT */
  414. # ifdef LTOSTOP
  415. { "ltostop",LTOSTOP,M_LOCAL },
  416. # endif /* LTOSTOP */
  417. # ifdef LFLUSHO
  418. { "lflusho",LFLUSHO,M_LOCAL },
  419. # endif /* LFLUSHO */
  420. # ifdef LNOHANG
  421. { "lnohang",LNOHANG,M_LOCAL },
  422. # endif /* LNOHANG */
  423. # ifdef LCRTKIL
  424. { "lcrtkil",LCRTKIL,M_LOCAL },
  425. # endif /* LCRTKIL */
  426. # ifdef LPASS8
  427. { "lpass8", LPASS8, M_LOCAL },
  428. # endif /* LPASS8 */
  429. # ifdef LCTLECH
  430. { "lctlech",LCTLECH,M_LOCAL },
  431. # endif /* LCTLECH */
  432. # ifdef LPENDIN
  433. { "lpendin",LPENDIN,M_LOCAL },
  434. # endif /* LPENDIN */
  435. # ifdef LDECCTQ
  436. { "ldecctq",LDECCTQ,M_LOCAL },
  437. # endif /* LDECCTQ */
  438. # ifdef LNOFLSH
  439. { "lnoflsh",LNOFLSH,M_LOCAL },
  440. # endif /* LNOFLSH */
  441. #endif /* POSIX || TERMIO */
  442. # if defined(VINTR) || defined(TIOCGETC)
  443. { "intr", C_SH(C_INTR), M_CHAR },
  444. # endif /* VINTR */
  445. # if defined(VQUIT) || defined(TIOCGETC)
  446. { "quit", C_SH(C_QUIT), M_CHAR },
  447. # endif /* VQUIT */
  448. # if defined(VERASE) || defined(TIOCGETP)
  449. { "erase", C_SH(C_ERASE), M_CHAR },
  450. # endif /* VERASE */
  451. # if defined(VKILL) || defined(TIOCGETP)
  452. { "kill", C_SH(C_KILL), M_CHAR },
  453. # endif /* VKILL */
  454. # if defined(VEOF) || defined(TIOCGETC)
  455. { "eof", C_SH(C_EOF), M_CHAR },
  456. # endif /* VEOF */
  457. # if defined(VEOL)
  458. { "eol", C_SH(C_EOL), M_CHAR },
  459. # endif /* VEOL */
  460. # if defined(VEOL2)
  461. { "eol2", C_SH(C_EOL2), M_CHAR },
  462. # endif /* VEOL2 */
  463. # if defined(VSWTCH)
  464. { "swtch", C_SH(C_SWTCH), M_CHAR },
  465. # endif /* VSWTCH */
  466. # if defined(VDSWTCH)
  467. { "dswtch", C_SH(C_DSWTCH), M_CHAR },
  468. # endif /* VDSWTCH */
  469. # if defined(VERASE2)
  470. { "erase2", C_SH(C_ERASE2), M_CHAR },
  471. # endif /* VERASE2 */
  472. # if defined(VSTART) || defined(TIOCGETC)
  473. { "start", C_SH(C_START), M_CHAR },
  474. # endif /* VSTART */
  475. # if defined(VSTOP) || defined(TIOCGETC)
  476. { "stop", C_SH(C_STOP), M_CHAR },
  477. # endif /* VSTOP */
  478. # if defined(VWERASE) || defined(TIOCGLTC)
  479. { "werase", C_SH(C_WERASE), M_CHAR },
  480. # endif /* VWERASE */
  481. # if defined(VSUSP) || defined(TIOCGLTC)
  482. { "susp", C_SH(C_SUSP), M_CHAR },
  483. # endif /* VSUSP */
  484. # if defined(VDSUSP) || defined(TIOCGLTC)
  485. { "dsusp", C_SH(C_DSUSP), M_CHAR },
  486. # endif /* VDSUSP */
  487. # if defined(VREPRINT) || defined(TIOCGLTC)
  488. { "reprint", C_SH(C_REPRINT),M_CHAR },
  489. # endif /* WREPRINT */
  490. # if defined(VDISCARD) || defined(TIOCGLTC)
  491. { "discard", C_SH(C_DISCARD),M_CHAR },
  492. # endif /* VDISCARD */
  493. # if defined(VLNEXT) || defined(TIOCGLTC)
  494. { "lnext", C_SH(C_LNEXT), M_CHAR },
  495. # endif /* VLNEXT */
  496. # if defined(VSTATUS) || defined(TIOCGPAGE)
  497. { "status", C_SH(C_STATUS), M_CHAR },
  498. # endif /* VSTATUS */
  499. # if defined(VPAGE) || defined(TIOCGPAGE)
  500. { "page", C_SH(C_PAGE), M_CHAR },
  501. # endif /* VPAGE */
  502. # if defined(VPGOFF) || defined(TIOCGPAGE)
  503. { "pgoff", C_SH(C_PGOFF), M_CHAR },
  504. # endif /* VPGOFF */
  505. # if defined(VKILL2)
  506. { "kill2", C_SH(C_KILL2), M_CHAR },
  507. # endif /* VKILL2 */
  508. # if defined(VBRK) || defined(TIOCGETC)
  509. { "brk", C_SH(C_BRK), M_CHAR },
  510. # endif /* VBRK */
  511. # if defined(VMIN)
  512. { "min", C_SH(C_MIN), M_CHAR },
  513. # endif /* VMIN */
  514. # if defined(VTIME)
  515. { "time", C_SH(C_TIME), M_CHAR },
  516. # endif /* VTIME */
  517. { NULL, 0, -1 },
  518. };
  519. /*
  520. * If EAGAIN and/or EWOULDBLOCK are defined, we can't just return -1 in all
  521. * situations where ioctl() does.
  522. *
  523. * On AIX 4.1.5 (and presumably some other versions and OSes), as you
  524. * perform the manual test suite in the README, if you 'bg' vi immediately
  525. * after suspending it, all is well, but if you wait a few seconds,
  526. * usually ioctl() will return -1, which previously caused tty_setty() to
  527. * return -1, causing Rawmode() to return -1, causing Inputl() to return
  528. * 0, causing bgetc() to return -1, causing readc() to set doneinp to 1,
  529. * causing process() to break out of the main loop, causing tcsh to exit
  530. * prematurely.
  531. *
  532. * If ioctl()'s errno is EAGAIN/EWOULDBLOCK ("Resource temporarily
  533. * unavailable"), apparently the tty is being messed with by the OS and we
  534. * need to try again. In my testing, ioctl() was never called more than
  535. * twice in a row.
  536. *
  537. * -- Dan Harkless <dan@wave.eng.uci.edu>
  538. *
  539. * So, I retry all ioctl's in case others happen to fail too (christos)
  540. */
  541. #if defined(EAGAIN) && defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
  542. # define OKERROR(e) (((e) == EAGAIN) || ((e) == EWOULDBLOCK) || ((e) == EINTR))
  543. #elif defined(EAGAIN)
  544. # define OKERROR(e) (((e) == EAGAIN) || ((e) == EINTR))
  545. #elif defined(EWOULDBLOCK)
  546. # define OKERROR(e) (((e) == EWOULDBLOCK) || ((e) == EINTR))
  547. #else
  548. # define OKERROR(e) ((e) == EINTR)
  549. #endif
  550. #ifdef __NetBSD__
  551. #define KLUDGE (errno == ENOTTY && count < 10)
  552. #else
  553. #define KLUDGE 0
  554. #endif
  555. /* Retry a system call */
  556. #define RETRY(x) \
  557. do { \
  558. int count; \
  559. \
  560. for (count = 0;; count++) \
  561. if ((x) == -1) { \
  562. if (OKERROR(errno) || KLUDGE) \
  563. continue; \
  564. else \
  565. return -1; \
  566. } \
  567. else \
  568. break; \
  569. } while (0)
  570. /*ARGSUSED*/
  571. void
  572. dosetty(Char **v, struct command *t)
  573. {
  574. const struct tcshmodes *m;
  575. char x, *d, *cmdname;
  576. int aflag = 0;
  577. Char *s;
  578. int z = EX_IO;
  579. USE(t);
  580. cmdname = strsave(short2str(*v++));
  581. cleanup_push(cmdname, xfree);
  582. setname(cmdname);
  583. while (v && *v && v[0][0] == '-' && v[0][2] == '\0')
  584. switch (v[0][1]) {
  585. case 'a':
  586. aflag++;
  587. v++;
  588. break;
  589. case 'd':
  590. v++;
  591. z = ED_IO;
  592. break;
  593. case 'x':
  594. v++;
  595. z = EX_IO;
  596. break;
  597. case 'q':
  598. v++;
  599. z = QU_IO;
  600. break;
  601. default:
  602. stderror(ERR_NAME | ERR_SYSTEM, short2str(v[0]),
  603. CGETS(8, 1, "Unknown switch"));
  604. break;
  605. }
  606. didsetty = 1;
  607. if (!v || !*v) {
  608. int i = -1;
  609. int len = 0, st = 0, cu;
  610. for (m = modelist; m->m_name; m++) {
  611. if (m->m_type != i) {
  612. xprintf("%s%s", i != -1 ? "\n" : "",
  613. ttylist[z][m->m_type].t_name);
  614. i = m->m_type;
  615. st = len = strlen(ttylist[z][m->m_type].t_name);
  616. }
  617. assert(i != -1);
  618. x = (ttylist[z][i].t_setmask & m->m_value) ? '+' : '\0';
  619. x = (ttylist[z][i].t_clrmask & m->m_value) ? '-' : x;
  620. if (x != '\0' || aflag) {
  621. cu = strlen(m->m_name) + (x != '\0') + 1;
  622. if (len + cu >= TermH) {
  623. xprintf("\n%*s", st, "");
  624. len = st + cu;
  625. }
  626. else
  627. len += cu;
  628. if (x != '\0')
  629. xprintf("%c%s ", x, m->m_name);
  630. else
  631. xprintf("%s ", m->m_name);
  632. }
  633. }
  634. xputchar('\n');
  635. cleanup_until(cmdname);
  636. return;
  637. }
  638. while (v && (s = *v++)) {
  639. switch (*s) {
  640. case '+':
  641. case '-':
  642. x = *s++;
  643. break;
  644. default:
  645. x = '\0';
  646. break;
  647. }
  648. d = short2str(s);
  649. for (m = modelist; m->m_name; m++)
  650. if (strcmp(m->m_name, d) == 0)
  651. break;
  652. if (!m->m_name)
  653. stderror(ERR_NAME | ERR_SYSTEM, d, CGETS(8, 2, "Invalid argument"));
  654. switch (x) {
  655. case '+':
  656. ttylist[z][m->m_type].t_setmask |= m->m_value;
  657. ttylist[z][m->m_type].t_clrmask &= ~m->m_value;
  658. break;
  659. case '-':
  660. ttylist[z][m->m_type].t_setmask &= ~m->m_value;
  661. ttylist[z][m->m_type].t_clrmask |= m->m_value;
  662. break;
  663. default:
  664. ttylist[z][m->m_type].t_setmask &= ~m->m_value;
  665. ttylist[z][m->m_type].t_clrmask &= ~m->m_value;
  666. break;
  667. }
  668. }
  669. cleanup_until(cmdname);
  670. } /* end dosetty */
  671. int
  672. tty_getty(int fd, ttydata_t *td)
  673. {
  674. #ifdef POSIX
  675. RETRY(tcgetattr(fd, &td->d_t));
  676. #else /* TERMIO || GSTTY */
  677. # ifdef TERMIO
  678. RETRY(ioctl(fd, TCGETA, (ioctl_t) &td->d_t));
  679. # else /* GSTTY */
  680. # ifdef TIOCGETP
  681. RETRY(ioctl(fd, TIOCGETP, (ioctl_t) &td->d_t));
  682. # endif /* TIOCGETP */
  683. # ifdef TIOCGETC
  684. RETRY(ioctl(fd, TIOCGETC, (ioctl_t) &td->d_tc));
  685. # endif /* TIOCGETC */
  686. # ifdef TIOCGPAGE
  687. RETRY(ioctl(fd, TIOCGPAGE, (ioctl_t) &td->d_pc));
  688. # endif /* TIOCGPAGE */
  689. # ifdef TIOCLGET
  690. RETRY(ioctl(fd, TIOCLGET, (ioctl_t) &td->d_lb));
  691. # endif /* TIOCLGET */
  692. # endif /* TERMIO */
  693. #endif /* POSIX */
  694. #ifdef TIOCGLTC
  695. RETRY(ioctl(fd, TIOCGLTC, (ioctl_t) &td->d_ltc));
  696. #endif /* TIOCGLTC */
  697. return 0;
  698. }
  699. int
  700. tty_setty(int fd, ttydata_t *td)
  701. {
  702. #ifdef POSIX
  703. RETRY(xtcsetattr(fd, TCSADRAIN, &td->d_t));
  704. #else
  705. # ifdef TERMIO
  706. RETRY(ioctl(fd, TCSETAW, (ioctl_t) &td->d_t));
  707. # else
  708. # ifdef TIOCSETN
  709. RETRY(ioctl(fd, TIOCSETN, (ioctl_t) &td->d_t));
  710. # endif /* TIOCSETN */
  711. # ifdef TIOCGETC
  712. RETRY(ioctl(fd, TIOCSETC, (ioctl_t) &td->d_tc));
  713. # endif /* TIOCGETC */
  714. # ifdef TIOCGPAGE
  715. RETRY(ioctl(fd, TIOCSPAGE, (ioctl_t) &td->d_pc));
  716. # endif /* TIOCGPAGE */
  717. # ifdef TIOCLGET
  718. RETRY(ioctl(fd, TIOCLSET, (ioctl_t) &td->d_lb));
  719. # endif /* TIOCLGET */
  720. # endif /* TERMIO */
  721. #endif /* POSIX */
  722. #ifdef TIOCGLTC
  723. RETRY(ioctl(fd, TIOCSLTC, (ioctl_t) &td->d_ltc));
  724. #endif /* TIOCGLTC */
  725. return 0;
  726. }
  727. void
  728. tty_getchar(ttydata_t *td, unsigned char *s)
  729. {
  730. #ifdef TIOCGLTC
  731. {
  732. struct ltchars *n = &td->d_ltc;
  733. s[C_SUSP] = n->t_suspc;
  734. s[C_DSUSP] = n->t_dsuspc;
  735. s[C_REPRINT] = n->t_rprntc;
  736. s[C_DISCARD] = n->t_flushc;
  737. s[C_WERASE] = n->t_werasc;
  738. s[C_LNEXT] = n->t_lnextc;
  739. }
  740. #endif /* TIOCGLTC */
  741. #if defined(POSIX) || defined(TERMIO)
  742. {
  743. # ifdef POSIX
  744. struct termios *n = &td->d_t;
  745. # else
  746. struct termio *n = &td->d_t;
  747. # endif /* POSIX */
  748. # ifdef VINTR
  749. s[C_INTR] = n->c_cc[VINTR];
  750. # endif /* VINTR */
  751. # ifdef VQUIT
  752. s[C_QUIT] = n->c_cc[VQUIT];
  753. # endif /* VQUIT */
  754. # ifdef VERASE
  755. s[C_ERASE] = n->c_cc[VERASE];
  756. # endif /* VERASE */
  757. # ifdef VKILL
  758. s[C_KILL] = n->c_cc[VKILL];
  759. # endif /* VKILL */
  760. # ifdef VEOF
  761. s[C_EOF] = n->c_cc[VEOF];
  762. # endif /* VEOF */
  763. # ifdef VEOL
  764. s[C_EOL] = n->c_cc[VEOL];
  765. # endif /* VEOL */
  766. # ifdef VEOL2
  767. s[C_EOL2] = n->c_cc[VEOL2];
  768. # endif /* VEOL2 */
  769. # ifdef VSWTCH
  770. s[C_SWTCH] = n->c_cc[VSWTCH];
  771. # endif /* VSWTCH */
  772. # ifdef VDSWTCH
  773. s[C_DSWTCH] = n->c_cc[VDSWTCH];
  774. # endif /* VDSWTCH */
  775. # ifdef VERASE2
  776. s[C_ERASE2] = n->c_cc[VERASE2];
  777. # endif /* VERASE2 */
  778. # ifdef VSTART
  779. s[C_START] = n->c_cc[VSTART];
  780. # endif /* VSTART */
  781. # ifdef VSTOP
  782. s[C_STOP] = n->c_cc[VSTOP];
  783. # endif /* VSTOP */
  784. # ifdef VWERASE
  785. s[C_WERASE] = n->c_cc[VWERASE];
  786. # endif /* VWERASE */
  787. # ifdef VSUSP
  788. s[C_SUSP] = n->c_cc[VSUSP];
  789. # endif /* VSUSP */
  790. # ifdef VDSUSP
  791. s[C_DSUSP] = n->c_cc[VDSUSP];
  792. # endif /* VDSUSP */
  793. # ifdef VREPRINT
  794. s[C_REPRINT] = n->c_cc[VREPRINT];
  795. # endif /* WREPRINT */
  796. # ifdef VDISCARD
  797. s[C_DISCARD] = n->c_cc[VDISCARD];
  798. # endif /* VDISCARD */
  799. # ifdef VLNEXT
  800. s[C_LNEXT] = n->c_cc[VLNEXT];
  801. # endif /* VLNEXT */
  802. # ifdef VSTATUS
  803. s[C_STATUS] = n->c_cc[VSTATUS];
  804. # endif /* VSTATUS */
  805. # ifdef VPAGE
  806. s[C_PAGE] = n->c_cc[VPAGE];
  807. # endif /* VPAGE */
  808. # ifdef VPGOFF
  809. s[C_PGOFF] = n->c_cc[VPGOFF];
  810. # endif /* VPGOFF */
  811. # ifdef VKILL2
  812. s[C_KILL2] = n->c_cc[VKILL2];
  813. # endif /* KILL2 */
  814. # ifdef VMIN
  815. s[C_MIN] = n->c_cc[VMIN];
  816. # endif /* VMIN */
  817. # ifdef VTIME
  818. s[C_TIME] = n->c_cc[VTIME];
  819. # endif /* VTIME */
  820. }
  821. #else /* SGTTY */
  822. # ifdef TIOCGPAGE
  823. {
  824. struct ttypagestat *n = &td->d_pc;
  825. s[C_STATUS] = n->tps_statc;
  826. s[C_PAGE] = n->tps_pagec;
  827. s[C_PGOFF] = n->tps_pgoffc;
  828. }
  829. # endif /* TIOCGPAGE */
  830. # ifdef TIOCGETC
  831. {
  832. struct tchars *n = &td->d_tc;
  833. s[C_INTR] = n->t_intrc;
  834. s[C_QUIT] = n->t_quitc;
  835. s[C_START] = n->t_startc;
  836. s[C_STOP] = n->t_stopc;
  837. s[C_EOF] = n->t_eofc;
  838. s[C_BRK] = n->t_brkc;
  839. }
  840. # endif /* TIOCGETC */
  841. # ifdef TIOCGETP
  842. {
  843. struct sgttyb *n = &td->d_t;
  844. s[C_ERASE] = n->sg_erase;
  845. s[C_KILL] = n->sg_kill;
  846. }
  847. # endif /* TIOCGETP */
  848. #endif /* !POSIX || TERMIO */
  849. } /* tty_getchar */
  850. void
  851. tty_setchar(ttydata_t *td, unsigned char *s)
  852. {
  853. #ifdef TIOCGLTC
  854. {
  855. struct ltchars *n = &td->d_ltc;
  856. n->t_suspc = s[C_SUSP];
  857. n->t_dsuspc = s[C_DSUSP];
  858. n->t_rprntc = s[C_REPRINT];
  859. n->t_flushc = s[C_DISCARD];
  860. n->t_werasc = s[C_WERASE];
  861. n->t_lnextc = s[C_LNEXT];
  862. }
  863. #endif /* TIOCGLTC */
  864. #if defined(POSIX) || defined(TERMIO)
  865. {
  866. # ifdef POSIX
  867. struct termios *n = &td->d_t;
  868. # else
  869. struct termio *n = &td->d_t;
  870. # endif /* POSIX */
  871. # ifdef VINTR
  872. n->c_cc[VINTR] = s[C_INTR];
  873. # endif /* VINTR */
  874. # ifdef VQUIT
  875. n->c_cc[VQUIT] = s[C_QUIT];
  876. # endif /* VQUIT */
  877. # ifdef VERASE
  878. n->c_cc[VERASE] = s[C_ERASE];
  879. # endif /* VERASE */
  880. # ifdef VKILL
  881. n->c_cc[VKILL] = s[C_KILL];
  882. # endif /* VKILL */
  883. # ifdef VEOF
  884. n->c_cc[VEOF] = s[C_EOF];
  885. # endif /* VEOF */
  886. # ifdef VEOL
  887. n->c_cc[VEOL] = s[C_EOL];
  888. # endif /* VEOL */
  889. # ifdef VEOL2
  890. n->c_cc[VEOL2] = s[C_EOL2];
  891. # endif /* VEOL2 */
  892. # ifdef VSWTCH
  893. n->c_cc[VSWTCH] = s[C_SWTCH];
  894. # endif /* VSWTCH */
  895. # ifdef VDSWTCH
  896. n->c_cc[VDSWTCH] = s[C_DSWTCH];
  897. # endif /* VDSWTCH */
  898. # ifdef VERASE2
  899. n->c_cc[VERASE2] = s[C_ERASE2];
  900. # endif /* VERASE2 */
  901. # ifdef VSTART
  902. n->c_cc[VSTART] = s[C_START];
  903. # endif /* VSTART */
  904. # ifdef VSTOP
  905. n->c_cc[VSTOP] = s[C_STOP];
  906. # endif /* VSTOP */
  907. # ifdef VWERASE
  908. n->c_cc[VWERASE] = s[C_WERASE];
  909. # endif /* VWERASE */
  910. # ifdef VSUSP
  911. n->c_cc[VSUSP] = s[C_SUSP];
  912. # endif /* VSUSP */
  913. # ifdef VDSUSP
  914. n->c_cc[VDSUSP] = s[C_DSUSP];
  915. # endif /* VDSUSP */
  916. # ifdef VREPRINT
  917. n->c_cc[VREPRINT] = s[C_REPRINT];
  918. # endif /* WREPRINT */
  919. # ifdef VDISCARD
  920. n->c_cc[VDISCARD] = s[C_DISCARD];
  921. # endif /* VDISCARD */
  922. # ifdef VLNEXT
  923. n->c_cc[VLNEXT] = s[C_LNEXT];
  924. # endif /* VLNEXT */
  925. # ifdef VSTATUS
  926. n->c_cc[VSTATUS] = s[C_STATUS];
  927. # endif /* VSTATUS */
  928. # ifdef VPAGE
  929. n->c_cc[VPAGE] = s[C_PAGE];
  930. # endif /* VPAGE */
  931. # ifdef VPGOFF
  932. n->c_cc[VPGOFF] = s[C_PGOFF];
  933. # endif /* VPGOFF */
  934. # ifdef VKILL2
  935. n->c_cc[VKILL2] = s[C_KILL2];
  936. # endif /* VKILL2 */
  937. # ifdef VMIN
  938. n->c_cc[VMIN] = s[C_MIN];
  939. # endif /* VMIN */
  940. # ifdef VTIME
  941. n->c_cc[VTIME] = s[C_TIME];
  942. # endif /* VTIME */
  943. }
  944. #else /* GSTTY */
  945. # ifdef TIOCGPAGE
  946. {
  947. struct ttypagestat *n = &td->d_pc;
  948. n->tps_length = 0;
  949. n->tps_lpos = 0;
  950. n->tps_statc = s[C_STATUS];
  951. n->tps_pagec = s[C_PAGE];
  952. n->tps_pgoffc = s[C_PGOFF];
  953. n->tps_flag = 0;
  954. }
  955. # endif /* TIOCGPAGE */
  956. # ifdef TIOCGETC
  957. {
  958. struct tchars *n = &td->d_tc;
  959. n->t_intrc = s[C_INTR];
  960. n->t_quitc = s[C_QUIT];
  961. n->t_startc = s[C_START];
  962. n->t_stopc = s[C_STOP];
  963. n->t_eofc = s[C_EOF];
  964. n->t_brkc = s[C_BRK];
  965. }
  966. # endif /* TIOCGETC */
  967. # ifdef TIOCGETP
  968. {
  969. struct sgttyb *n = &td->d_t;
  970. n->sg_erase = s[C_ERASE];
  971. n->sg_kill = s[C_KILL];
  972. }
  973. # endif /* TIOCGETP */
  974. #endif /* !POSIX || TERMIO */
  975. } /* tty_setchar */
  976. speed_t
  977. tty_getspeed(ttydata_t *td)
  978. {
  979. speed_t spd;
  980. #ifdef POSIX
  981. if ((spd = cfgetispeed(&td->d_t)) == 0)
  982. spd = cfgetospeed(&td->d_t);
  983. #else /* ! POSIX */
  984. # ifdef TERMIO
  985. # ifdef CBAUD
  986. spd = td->d_t.c_cflag & CBAUD;
  987. # else
  988. spd = 0;
  989. # endif
  990. # else /* SGTTY */
  991. spd = td->d_t.sg_ispeed;
  992. # endif /* TERMIO */
  993. #endif /* POSIX */
  994. return spd;
  995. } /* end tty_getspeed */
  996. int
  997. tty_gettabs(ttydata_t *td)
  998. {
  999. #if defined(POSIX) || defined(TERMIO)
  1000. return ((td->d_t.c_oflag & TAB3) == TAB3) ? 0 : 1;
  1001. #else /* SGTTY */
  1002. return (td->d_t.sg_flags & XTABS) == XTABS ? 0 : 1;
  1003. #endif /* POSIX || TERMIO */
  1004. } /* end tty_gettabs */
  1005. int
  1006. tty_geteightbit(ttydata_t *td)
  1007. {
  1008. #if defined(POSIX) || defined(TERMIO)
  1009. return (td->d_t.c_cflag & CSIZE) == CS8;
  1010. #else /* SGTTY */
  1011. return td->d_lb & (LPASS8 | LLITOUT);
  1012. #endif /* POSIX || TERMIO */
  1013. } /* end tty_geteightbit */
  1014. int
  1015. tty_cooked_mode(ttydata_t *td)
  1016. {
  1017. #if defined(POSIX) || defined(TERMIO)
  1018. return (td->d_t.c_lflag & ICANON);
  1019. #else /* SGTTY */
  1020. return !(td->d_t.sg_flags & (RAW | CBREAK));
  1021. #endif /* POSIX || TERMIO */
  1022. } /* end tty_cooked_mode */
  1023. #ifdef _IBMR2
  1024. void
  1025. tty_setdisc(int fd, int dis)
  1026. {
  1027. static int edit_discipline = 0;
  1028. static union txname tx_disc;
  1029. extern char strPOSIX[];
  1030. switch (dis) {
  1031. case EX_IO:
  1032. if (edit_discipline) {
  1033. if (ioctl(fd, TXSETLD, (ioctl_t) & tx_disc) == -1)
  1034. return;
  1035. edit_discipline = 0;
  1036. }
  1037. return;
  1038. case ED_IO:
  1039. tx_disc.tx_which = 0;
  1040. if (ioctl(fd, TXGETLD, (ioctl_t) & tx_disc) == -1)
  1041. return;
  1042. if (strcmp(tx_disc.tx_name, strPOSIX) != 0) {
  1043. edit_discipline = 1;
  1044. if (ioctl(fd, TXSETLD, (ioctl_t) strPOSIX) == -1)
  1045. return;
  1046. }
  1047. return;
  1048. default:
  1049. return;
  1050. }
  1051. } /* end tty_setdisc */
  1052. #endif /* _IBMR2 */
  1053. #ifdef DEBUG_TTY
  1054. static void
  1055. tty_printchar(unsigned char *s)
  1056. {
  1057. struct tcshmodes *m;
  1058. int i;
  1059. for (i = 0; i < C_NCC; i++) {
  1060. for (m = modelist; m->m_name; m++)
  1061. if (m->m_type == M_CHAR && C_SH(i) == m->m_value)
  1062. break;
  1063. if (m->m_name)
  1064. xprintf("%s ^%c ", m->m_name, s[i] + 'A' - 1);
  1065. if (i % 5 == 0)
  1066. xputchar('\n');
  1067. }
  1068. xputchar('\n');
  1069. }
  1070. #endif /* DEBUG_TTY */
  1071. #else /* WINNT_NATIVE */
  1072. int
  1073. tty_cooked_mode(void *td)
  1074. {
  1075. return do_nt_check_cooked_mode();
  1076. }
  1077. #endif /* !WINNT_NATIVE */