tty.c 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455
  1. /* $OpenBSD: tty.c,v 1.122 2015/07/20 22:28:57 sf Exp $ */
  2. /* $NetBSD: tty.c,v 1.68.4.2 1996/06/06 16:04:52 thorpej Exp $ */
  3. /*-
  4. * Copyright (c) 1982, 1986, 1990, 1991, 1993
  5. * The Regents of the University of California. All rights reserved.
  6. * (c) UNIX System Laboratories, Inc.
  7. * All or some portions of this file are derived from material licensed
  8. * to the University of California by American Telephone and Telegraph
  9. * Co. or Unix System Laboratories, Inc. and are reproduced herein with
  10. * the permission of UNIX System Laboratories, Inc.
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions
  14. * are met:
  15. * 1. Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in the
  19. * documentation and/or other materials provided with the distribution.
  20. * 3. Neither the name of the University nor the names of its contributors
  21. * may be used to endorse or promote products derived from this software
  22. * without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34. * SUCH DAMAGE.
  35. *
  36. * @(#)tty.c 8.8 (Berkeley) 1/21/94
  37. */
  38. #include <sys/param.h>
  39. #include <sys/systm.h>
  40. #include <sys/ioctl.h>
  41. #include <sys/proc.h>
  42. #define TTYDEFCHARS
  43. #include <sys/tty.h>
  44. #undef TTYDEFCHARS
  45. #include <sys/file.h>
  46. #include <sys/conf.h>
  47. #include <sys/uio.h>
  48. #include <sys/kernel.h>
  49. #include <sys/vnode.h>
  50. #include <sys/lock.h>
  51. #include <sys/syslog.h>
  52. #include <sys/malloc.h>
  53. #include <sys/msgbuf.h>
  54. #include <sys/signalvar.h>
  55. #include <sys/resourcevar.h>
  56. #include <sys/sysctl.h>
  57. #include <sys/pool.h>
  58. #include <sys/poll.h>
  59. #include <sys/unistd.h>
  60. #include <sys/namei.h>
  61. #include <uvm/uvm_extern.h>
  62. #include <dev/cons.h>
  63. #include <dev/rndvar.h>
  64. #include "pty.h"
  65. static int ttnread(struct tty *);
  66. static void ttyblock(struct tty *);
  67. void ttyunblock(struct tty *);
  68. static void ttyecho(int, struct tty *);
  69. static void ttyrubo(struct tty *, int);
  70. void ttkqflush(struct klist *klist);
  71. int filt_ttyread(struct knote *kn, long hint);
  72. void filt_ttyrdetach(struct knote *kn);
  73. int filt_ttywrite(struct knote *kn, long hint);
  74. void filt_ttywdetach(struct knote *kn);
  75. void ttystats_init(struct itty **);
  76. /* Symbolic sleep message strings. */
  77. char ttclos[] = "ttycls";
  78. char ttopen[] = "ttyopn";
  79. char ttybg[] = "ttybg";
  80. char ttyin[] = "ttyin";
  81. char ttyout[] = "ttyout";
  82. /*
  83. * Table with character classes and parity. The 8th bit indicates parity,
  84. * the 7th bit indicates the character is an alphameric or underscore (for
  85. * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits
  86. * are 0 then the character needs no special processing on output; classes
  87. * other than 0 might be translated or (not currently) require delays.
  88. */
  89. #define E 0x00 /* Even parity. */
  90. #define O 0x80 /* Odd parity. */
  91. #define PARITY(c) (char_type[c] & O)
  92. #define ALPHA 0x40 /* Alpha or underscore. */
  93. #define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA)
  94. #define CCLASSMASK 0x3f
  95. #define CCLASS(c) (char_type[c] & CCLASSMASK)
  96. #define BS BACKSPACE
  97. #define CC CONTROL
  98. #define CR RETURN
  99. #define NA ORDINARY | ALPHA
  100. #define NL NEWLINE
  101. #define NO ORDINARY
  102. #define TB TAB
  103. #define VT VTAB
  104. u_char const char_type[] = {
  105. E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
  106. O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
  107. O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
  108. E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
  109. O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
  110. E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
  111. E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
  112. O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
  113. O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
  114. E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
  115. E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
  116. O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
  117. E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
  118. O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
  119. O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
  120. E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
  121. /*
  122. * Meta chars; should be settable per character set;
  123. * for now, treat them all as normal characters.
  124. */
  125. NA, NA, NA, NA, NA, NA, NA, NA,
  126. NA, NA, NA, NA, NA, NA, NA, NA,
  127. NA, NA, NA, NA, NA, NA, NA, NA,
  128. NA, NA, NA, NA, NA, NA, NA, NA,
  129. NA, NA, NA, NA, NA, NA, NA, NA,
  130. NA, NA, NA, NA, NA, NA, NA, NA,
  131. NA, NA, NA, NA, NA, NA, NA, NA,
  132. NA, NA, NA, NA, NA, NA, NA, NA,
  133. NA, NA, NA, NA, NA, NA, NA, NA,
  134. NA, NA, NA, NA, NA, NA, NA, NA,
  135. NA, NA, NA, NA, NA, NA, NA, NA,
  136. NA, NA, NA, NA, NA, NA, NA, NA,
  137. NA, NA, NA, NA, NA, NA, NA, NA,
  138. NA, NA, NA, NA, NA, NA, NA, NA,
  139. NA, NA, NA, NA, NA, NA, NA, NA,
  140. NA, NA, NA, NA, NA, NA, NA, NA,
  141. };
  142. #undef BS
  143. #undef CC
  144. #undef CR
  145. #undef NA
  146. #undef NL
  147. #undef NO
  148. #undef TB
  149. #undef VT
  150. #define islower(c) ((c) >= 'a' && (c) <= 'z')
  151. #define isupper(c) ((c) >= 'A' && (c) <= 'Z')
  152. #define tolower(c) ((c) - 'A' + 'a')
  153. #define toupper(c) ((c) - 'a' + 'A')
  154. struct ttylist_head ttylist; /* TAILQ_HEAD */
  155. int tty_count;
  156. int64_t tk_cancc, tk_nin, tk_nout, tk_rawcc;
  157. /*
  158. * Initial open of tty, or (re)entry to standard tty line discipline.
  159. */
  160. int
  161. ttyopen(dev_t device, struct tty *tp, struct proc *p)
  162. {
  163. int s;
  164. s = spltty();
  165. tp->t_dev = device;
  166. if (!ISSET(tp->t_state, TS_ISOPEN)) {
  167. SET(tp->t_state, TS_ISOPEN);
  168. memset(&tp->t_winsize, 0, sizeof(tp->t_winsize));
  169. tp->t_column = 0;
  170. }
  171. CLR(tp->t_state, TS_WOPEN);
  172. splx(s);
  173. return (0);
  174. }
  175. /*
  176. * Handle close() on a tty line: flush and set to initial state,
  177. * bumping generation number so that pending read/write calls
  178. * can detect recycling of the tty.
  179. */
  180. int
  181. ttyclose(struct tty *tp)
  182. {
  183. extern struct tty *constty; /* Temporary virtual console. */
  184. if (constty == tp)
  185. constty = NULL;
  186. ttyflush(tp, FREAD | FWRITE);
  187. tp->t_gen++;
  188. tp->t_pgrp = NULL;
  189. if (tp->t_session)
  190. SESSRELE(tp->t_session);
  191. tp->t_session = NULL;
  192. tp->t_state = 0;
  193. return (0);
  194. }
  195. #define FLUSHQ(q) { \
  196. if ((q)->c_cc) \
  197. ndflush(q, (q)->c_cc); \
  198. }
  199. /* Is 'c' a line delimiter ("break" character)? */
  200. #define TTBREAKC(c, lflag) \
  201. ((c) == '\n' || (((c) == cc[VEOF] || (c) == cc[VEOL] || \
  202. ((c) == cc[VEOL2] && (lflag & IEXTEN))) && (c) != _POSIX_VDISABLE))
  203. /*
  204. * Process input of a single character received on a tty.
  205. */
  206. int
  207. ttyinput(int c, struct tty *tp)
  208. {
  209. int iflag, lflag;
  210. u_char *cc;
  211. int i, error;
  212. int s;
  213. add_tty_randomness(tp->t_dev << 8 | c);
  214. /*
  215. * If receiver is not enabled, drop it.
  216. */
  217. if (!ISSET(tp->t_cflag, CREAD))
  218. return (0);
  219. /*
  220. * If input is pending take it first.
  221. */
  222. lflag = tp->t_lflag;
  223. s = spltty();
  224. if (ISSET(lflag, PENDIN))
  225. ttypend(tp);
  226. splx(s);
  227. /*
  228. * Gather stats.
  229. */
  230. if (ISSET(lflag, ICANON)) {
  231. ++tk_cancc;
  232. ++tp->t_cancc;
  233. } else {
  234. ++tk_rawcc;
  235. ++tp->t_rawcc;
  236. }
  237. ++tk_nin;
  238. /* Handle exceptional conditions (break, parity, framing). */
  239. cc = tp->t_cc;
  240. iflag = tp->t_iflag;
  241. if ((error = (ISSET(c, TTY_ERRORMASK))) != 0) {
  242. CLR(c, TTY_ERRORMASK);
  243. if (ISSET(error, TTY_FE) && !c) { /* Break. */
  244. if (ISSET(iflag, IGNBRK))
  245. return (0);
  246. ttyflush(tp, FREAD | FWRITE);
  247. if (ISSET(iflag, BRKINT)) {
  248. pgsignal(tp->t_pgrp, SIGINT, 1);
  249. goto endcase;
  250. }
  251. else if (ISSET(iflag, PARMRK))
  252. goto parmrk;
  253. } else if ((ISSET(error, TTY_PE) && ISSET(iflag, INPCK)) ||
  254. ISSET(error, TTY_FE)) {
  255. if (ISSET(iflag, IGNPAR))
  256. goto endcase;
  257. else if (ISSET(iflag, PARMRK)) {
  258. parmrk: (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
  259. if (ISSET(iflag, ISTRIP) || c != 0377)
  260. (void)putc(0 | TTY_QUOTE, &tp->t_rawq);
  261. (void)putc(c | TTY_QUOTE, &tp->t_rawq);
  262. goto endcase;
  263. } else
  264. c = 0;
  265. }
  266. }
  267. if (c == 0377 && !ISSET(iflag, ISTRIP) && ISSET(iflag, PARMRK))
  268. goto parmrk;
  269. /*
  270. * In tandem mode, check high water mark.
  271. */
  272. if (ISSET(iflag, IXOFF) || ISSET(tp->t_cflag, CHWFLOW))
  273. ttyblock(tp);
  274. if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
  275. CLR(c, 0x80);
  276. if (!ISSET(lflag, EXTPROC)) {
  277. /*
  278. * Check for literal nexting very first
  279. */
  280. if (ISSET(tp->t_state, TS_LNCH)) {
  281. SET(c, TTY_QUOTE);
  282. CLR(tp->t_state, TS_LNCH);
  283. }
  284. /*
  285. * Scan for special characters. This code
  286. * is really just a big case statement with
  287. * non-constant cases. The bottom of the
  288. * case statement is labeled ``endcase'', so goto
  289. * it after a case match, or similar.
  290. */
  291. /*
  292. * Control chars which aren't controlled
  293. * by ICANON, ISIG, or IXON.
  294. */
  295. if (ISSET(lflag, IEXTEN)) {
  296. if (CCEQ(cc[VLNEXT], c)) {
  297. if (ISSET(lflag, ECHO)) {
  298. if (ISSET(lflag, ECHOE)) {
  299. (void)ttyoutput('^', tp);
  300. (void)ttyoutput('\b', tp);
  301. } else
  302. ttyecho(c, tp);
  303. }
  304. SET(tp->t_state, TS_LNCH);
  305. goto endcase;
  306. }
  307. if (CCEQ(cc[VDISCARD], c)) {
  308. if (ISSET(lflag, FLUSHO))
  309. CLR(tp->t_lflag, FLUSHO);
  310. else {
  311. ttyflush(tp, FWRITE);
  312. ttyecho(c, tp);
  313. if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
  314. ttyretype(tp);
  315. SET(tp->t_lflag, FLUSHO);
  316. }
  317. goto startoutput;
  318. }
  319. }
  320. /*
  321. * Signals.
  322. */
  323. if (ISSET(lflag, ISIG)) {
  324. if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
  325. if (!ISSET(lflag, NOFLSH))
  326. ttyflush(tp, FREAD | FWRITE);
  327. ttyecho(c, tp);
  328. pgsignal(tp->t_pgrp,
  329. CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
  330. goto endcase;
  331. }
  332. if (CCEQ(cc[VSUSP], c)) {
  333. if (!ISSET(lflag, NOFLSH))
  334. ttyflush(tp, FREAD);
  335. ttyecho(c, tp);
  336. pgsignal(tp->t_pgrp, SIGTSTP, 1);
  337. goto endcase;
  338. }
  339. }
  340. /*
  341. * Handle start/stop characters.
  342. */
  343. if (ISSET(iflag, IXON)) {
  344. if (CCEQ(cc[VSTOP], c)) {
  345. if (!ISSET(tp->t_state, TS_TTSTOP)) {
  346. SET(tp->t_state, TS_TTSTOP);
  347. (*cdevsw[major(tp->t_dev)].d_stop)(tp,
  348. 0);
  349. return (0);
  350. }
  351. if (!CCEQ(cc[VSTART], c))
  352. return (0);
  353. /*
  354. * if VSTART == VSTOP then toggle
  355. */
  356. goto endcase;
  357. }
  358. if (CCEQ(cc[VSTART], c))
  359. goto restartoutput;
  360. }
  361. /*
  362. * IGNCR, ICRNL, & INLCR
  363. */
  364. if (c == '\r') {
  365. if (ISSET(iflag, IGNCR))
  366. goto endcase;
  367. else if (ISSET(iflag, ICRNL))
  368. c = '\n';
  369. } else if (c == '\n' && ISSET(iflag, INLCR))
  370. c = '\r';
  371. }
  372. if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
  373. /*
  374. * From here on down canonical mode character
  375. * processing takes place.
  376. */
  377. /*
  378. * upper case or specials with IUCLC and XCASE
  379. */
  380. if (ISSET(lflag, XCASE) && ISSET(iflag, IUCLC)) {
  381. if (ISSET(tp->t_state, TS_BKSL)) {
  382. CLR(tp->t_state, TS_BKSL);
  383. switch (c) {
  384. case '\'':
  385. c = '`';
  386. break;
  387. case '!':
  388. c = '|';
  389. break;
  390. case '^':
  391. c = '~';
  392. break;
  393. case '(':
  394. c = '{';
  395. break;
  396. case ')':
  397. c = '}';
  398. break;
  399. }
  400. }
  401. else if (c == '\\') {
  402. SET(tp->t_state, TS_BKSL);
  403. goto endcase;
  404. }
  405. else if (isupper(c))
  406. c = tolower(c);
  407. }
  408. else if (ISSET(iflag, IUCLC) && isupper(c))
  409. c = tolower(c);
  410. /*
  411. * erase (^H / ^?)
  412. */
  413. if (CCEQ(cc[VERASE], c)) {
  414. if (tp->t_rawq.c_cc)
  415. ttyrub(unputc(&tp->t_rawq), tp);
  416. goto endcase;
  417. }
  418. /*
  419. * kill (^U)
  420. */
  421. if (CCEQ(cc[VKILL], c)) {
  422. if (ISSET(lflag, ECHOKE) &&
  423. tp->t_rawq.c_cc == tp->t_rocount &&
  424. !ISSET(lflag, ECHOPRT))
  425. while (tp->t_rawq.c_cc)
  426. ttyrub(unputc(&tp->t_rawq), tp);
  427. else {
  428. ttyecho(c, tp);
  429. if (ISSET(lflag, ECHOK) ||
  430. ISSET(lflag, ECHOKE))
  431. ttyecho('\n', tp);
  432. FLUSHQ(&tp->t_rawq);
  433. tp->t_rocount = 0;
  434. }
  435. CLR(tp->t_state, TS_LOCAL);
  436. goto endcase;
  437. }
  438. /*
  439. * word erase (^W)
  440. */
  441. if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
  442. int alt = ISSET(lflag, ALTWERASE);
  443. int ctype;
  444. /*
  445. * erase whitespace
  446. */
  447. while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
  448. ttyrub(c, tp);
  449. if (c == -1)
  450. goto endcase;
  451. /*
  452. * erase last char of word and remember the
  453. * next chars type (for ALTWERASE)
  454. */
  455. ttyrub(c, tp);
  456. c = unputc(&tp->t_rawq);
  457. if (c == -1)
  458. goto endcase;
  459. if (c == ' ' || c == '\t') {
  460. (void)putc(c, &tp->t_rawq);
  461. goto endcase;
  462. }
  463. ctype = ISALPHA(c);
  464. /*
  465. * erase rest of word
  466. */
  467. do {
  468. ttyrub(c, tp);
  469. c = unputc(&tp->t_rawq);
  470. if (c == -1)
  471. goto endcase;
  472. } while (c != ' ' && c != '\t' &&
  473. (alt == 0 || ISALPHA(c) == ctype));
  474. (void)putc(c, &tp->t_rawq);
  475. goto endcase;
  476. }
  477. /*
  478. * reprint line (^R)
  479. */
  480. if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
  481. ttyretype(tp);
  482. goto endcase;
  483. }
  484. /*
  485. * ^T - kernel info and generate SIGINFO
  486. */
  487. if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
  488. if (ISSET(lflag, ISIG))
  489. pgsignal(tp->t_pgrp, SIGINFO, 1);
  490. if (!ISSET(lflag, NOKERNINFO))
  491. ttyinfo(tp);
  492. goto endcase;
  493. }
  494. }
  495. /*
  496. * Check for input buffer overflow
  497. */
  498. if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG(tp)) {
  499. if (ISSET(iflag, IMAXBEL)) {
  500. if (tp->t_outq.c_cc < tp->t_hiwat)
  501. (void)ttyoutput(CTRL('g'), tp);
  502. } else
  503. ttyflush(tp, FREAD | FWRITE);
  504. goto endcase;
  505. }
  506. /*
  507. * Put data char in q for user and
  508. * wakeup on seeing a line delimiter.
  509. */
  510. if (putc(c, &tp->t_rawq) >= 0) {
  511. if (!ISSET(lflag, ICANON)) {
  512. ttwakeup(tp);
  513. ttyecho(c, tp);
  514. goto endcase;
  515. }
  516. if (TTBREAKC(c, lflag)) {
  517. tp->t_rocount = 0;
  518. catq(&tp->t_rawq, &tp->t_canq);
  519. ttwakeup(tp);
  520. } else if (tp->t_rocount++ == 0)
  521. tp->t_rocol = tp->t_column;
  522. if (ISSET(tp->t_state, TS_ERASE)) {
  523. /*
  524. * end of prterase \.../
  525. */
  526. CLR(tp->t_state, TS_ERASE);
  527. (void)ttyoutput('/', tp);
  528. }
  529. i = tp->t_column;
  530. ttyecho(c, tp);
  531. if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
  532. /*
  533. * Place the cursor over the '^' of the ^D.
  534. */
  535. i = min(2, tp->t_column - i);
  536. while (i > 0) {
  537. (void)ttyoutput('\b', tp);
  538. i--;
  539. }
  540. }
  541. }
  542. endcase:
  543. /*
  544. * IXANY means allow any character to restart output.
  545. */
  546. if (ISSET(tp->t_state, TS_TTSTOP) &&
  547. !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP])
  548. return (0);
  549. restartoutput:
  550. CLR(tp->t_lflag, FLUSHO);
  551. CLR(tp->t_state, TS_TTSTOP);
  552. startoutput:
  553. return (ttstart(tp));
  554. }
  555. /*
  556. * Output a single character on a tty, doing output processing
  557. * as needed (expanding tabs, newline processing, etc.).
  558. * Returns < 0 if succeeds, otherwise returns char to resend.
  559. * Must be recursive.
  560. */
  561. int
  562. ttyoutput(int c, struct tty *tp)
  563. {
  564. long oflag;
  565. int col, notout, s, c2;
  566. oflag = tp->t_oflag;
  567. if (!ISSET(oflag, OPOST)) {
  568. tk_nout++;
  569. tp->t_outcc++;
  570. if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
  571. return (c);
  572. return (-1);
  573. }
  574. /*
  575. * Do tab expansion if OXTABS is set. Special case if we external
  576. * processing, we don't do the tab expansion because we'll probably
  577. * get it wrong. If tab expansion needs to be done, let it happen
  578. * externally.
  579. */
  580. CLR(c, ~TTY_CHARMASK);
  581. if (c == '\t' &&
  582. ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
  583. c = 8 - (tp->t_column & 7);
  584. if (ISSET(tp->t_lflag, FLUSHO)) {
  585. notout = 0;
  586. } else {
  587. s = spltty(); /* Don't interrupt tabs. */
  588. notout = b_to_q(" ", c, &tp->t_outq);
  589. c -= notout;
  590. tk_nout += c;
  591. tp->t_outcc += c;
  592. splx(s);
  593. }
  594. tp->t_column += c;
  595. return (notout ? '\t' : -1);
  596. }
  597. if (c == CEOT && ISSET(oflag, ONOEOT))
  598. return (-1);
  599. /*
  600. * Newline translation: if ONLCR is set,
  601. * translate newline into "\r\n". If OCRNL
  602. * is set, translate '\r' into '\n'.
  603. */
  604. if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
  605. tk_nout++;
  606. tp->t_outcc++;
  607. if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq))
  608. return (c);
  609. tp->t_column = 0;
  610. }
  611. else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
  612. c = '\n';
  613. if (ISSET(tp->t_oflag, OLCUC) && islower(c))
  614. c = toupper(c);
  615. else if (ISSET(tp->t_oflag, OLCUC) && ISSET(tp->t_lflag, XCASE)) {
  616. c2 = c;
  617. switch (c) {
  618. case '`':
  619. c2 = '\'';
  620. break;
  621. case '|':
  622. c2 = '!';
  623. break;
  624. case '~':
  625. c2 = '^';
  626. break;
  627. case '{':
  628. c2 = '(';
  629. break;
  630. case '}':
  631. c2 = ')';
  632. break;
  633. }
  634. if (c == '\\' || isupper(c) || c != c2) {
  635. tk_nout++;
  636. tp->t_outcc++;
  637. if (putc('\\', &tp->t_outq))
  638. return (c);
  639. c = c2;
  640. }
  641. }
  642. if (ISSET(tp->t_oflag, ONOCR) && c == '\r' && tp->t_column == 0)
  643. return (-1);
  644. tk_nout++;
  645. tp->t_outcc++;
  646. if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
  647. return (c);
  648. col = tp->t_column;
  649. switch (CCLASS(c)) {
  650. case BACKSPACE:
  651. if (col > 0)
  652. --col;
  653. break;
  654. case CONTROL:
  655. break;
  656. case NEWLINE:
  657. if (ISSET(tp->t_oflag, ONLRET) || ISSET(tp->t_oflag, OCRNL))
  658. col = 0;
  659. break;
  660. case RETURN:
  661. col = 0;
  662. break;
  663. case ORDINARY:
  664. ++col;
  665. break;
  666. case TAB:
  667. col = (col + 8) & ~7;
  668. break;
  669. }
  670. tp->t_column = col;
  671. return (-1);
  672. }
  673. /*
  674. * Ioctls for all tty devices. Called after line-discipline specific ioctl
  675. * has been called to do discipline-specific functions and/or reject any
  676. * of these ioctl commands.
  677. */
  678. /* ARGSUSED */
  679. int
  680. ttioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
  681. {
  682. extern struct tty *constty; /* Temporary virtual console. */
  683. extern int nlinesw;
  684. struct process *pr = p->p_p;
  685. int s, error;
  686. /* If the ioctl involves modification, hang if in the background. */
  687. switch (cmd) {
  688. case TIOCFLUSH:
  689. case TIOCDRAIN:
  690. case TIOCSBRK:
  691. case TIOCCBRK:
  692. case TIOCSETA:
  693. case TIOCSETD:
  694. case TIOCSETAF:
  695. case TIOCSETAW:
  696. #ifdef notdef
  697. case TIOCSPGRP:
  698. #endif
  699. case TIOCSTAT:
  700. case TIOCSTI:
  701. case TIOCSWINSZ:
  702. while (isbackground(pr, tp) &&
  703. (pr->ps_flags & PS_PPWAIT) == 0 &&
  704. (pr->ps_sigacts->ps_sigignore & sigmask(SIGTTOU)) == 0 &&
  705. (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
  706. if (pr->ps_pgrp->pg_jobc == 0)
  707. return (EIO);
  708. pgsignal(pr->ps_pgrp, SIGTTOU, 1);
  709. error = ttysleep(tp, &lbolt, TTOPRI | PCATCH,
  710. ttybg, 0);
  711. if (error)
  712. return (error);
  713. }
  714. break;
  715. }
  716. switch (cmd) { /* Process the ioctl. */
  717. case FIOASYNC: /* set/clear async i/o */
  718. s = spltty();
  719. if (*(int *)data)
  720. SET(tp->t_state, TS_ASYNC);
  721. else
  722. CLR(tp->t_state, TS_ASYNC);
  723. splx(s);
  724. break;
  725. case FIONBIO: /* set/clear non-blocking i/o */
  726. break; /* XXX: delete. */
  727. case FIONREAD: /* get # bytes to read */
  728. s = spltty();
  729. *(int *)data = ttnread(tp);
  730. splx(s);
  731. break;
  732. case TIOCEXCL: /* set exclusive use of tty */
  733. s = spltty();
  734. SET(tp->t_state, TS_XCLUDE);
  735. splx(s);
  736. break;
  737. case TIOCFLUSH: { /* flush buffers */
  738. int flags = *(int *)data;
  739. if (flags == 0)
  740. flags = FREAD | FWRITE;
  741. else
  742. flags &= FREAD | FWRITE;
  743. ttyflush(tp, flags);
  744. break;
  745. }
  746. case TIOCCONS: { /* become virtual console */
  747. if (*(int *)data) {
  748. struct nameidata nid;
  749. if (constty != NULL && constty != tp &&
  750. ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
  751. (TS_CARR_ON | TS_ISOPEN))
  752. return (EBUSY);
  753. /* ensure user can open the real console */
  754. NDINIT(&nid, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/console", p);
  755. error = namei(&nid);
  756. if (error)
  757. return (error);
  758. vn_lock(nid.ni_vp, LK_EXCLUSIVE | LK_RETRY, p);
  759. error = VOP_ACCESS(nid.ni_vp, VREAD, p->p_ucred, p);
  760. VOP_UNLOCK(nid.ni_vp, 0, p);
  761. vrele(nid.ni_vp);
  762. if (error)
  763. return (error);
  764. constty = tp;
  765. } else if (tp == constty)
  766. constty = NULL;
  767. break;
  768. }
  769. case TIOCDRAIN: /* wait till output drained */
  770. if ((error = ttywait(tp)) != 0)
  771. return (error);
  772. break;
  773. case TIOCGETA: { /* get termios struct */
  774. struct termios *t = (struct termios *)data;
  775. memcpy(t, &tp->t_termios, sizeof(struct termios));
  776. break;
  777. }
  778. case TIOCGETD: /* get line discipline */
  779. *(int *)data = tp->t_line;
  780. break;
  781. case TIOCGWINSZ: /* get window size */
  782. *(struct winsize *)data = tp->t_winsize;
  783. break;
  784. case TIOCGTSTAMP:
  785. s = spltty();
  786. *(struct timeval *)data = tp->t_tv;
  787. splx(s);
  788. break;
  789. case TIOCGPGRP: /* get pgrp of tty */
  790. if (!isctty(pr, tp) && suser(p, 0))
  791. return (ENOTTY);
  792. *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
  793. break;
  794. case TIOCGSID: /* get sid of tty */
  795. if (!isctty(pr, tp))
  796. return (ENOTTY);
  797. *(int *)data = tp->t_session->s_leader->ps_pid;
  798. break;
  799. #ifdef TIOCHPCL
  800. case TIOCHPCL: /* hang up on last close */
  801. s = spltty();
  802. SET(tp->t_cflag, HUPCL);
  803. splx(s);
  804. break;
  805. #endif
  806. case TIOCNXCL: /* reset exclusive use of tty */
  807. s = spltty();
  808. CLR(tp->t_state, TS_XCLUDE);
  809. splx(s);
  810. break;
  811. case TIOCOUTQ: /* output queue size */
  812. *(int *)data = tp->t_outq.c_cc;
  813. break;
  814. case TIOCSETA: /* set termios struct */
  815. case TIOCSETAW: /* drain output, set */
  816. case TIOCSETAF: { /* drn out, fls in, set */
  817. struct termios *t = (struct termios *)data;
  818. s = spltty();
  819. if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
  820. if ((error = ttywait(tp)) != 0) {
  821. splx(s);
  822. return (error);
  823. }
  824. if (cmd == TIOCSETAF)
  825. ttyflush(tp, FREAD);
  826. }
  827. if (!ISSET(t->c_cflag, CIGNORE)) {
  828. /*
  829. * Some minor validation is necessary.
  830. */
  831. if (t->c_ispeed < 0 || t->c_ospeed < 0) {
  832. splx(s);
  833. return (EINVAL);
  834. }
  835. /*
  836. * Set device hardware.
  837. */
  838. if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
  839. splx(s);
  840. return (error);
  841. } else {
  842. if (!ISSET(tp->t_state, TS_CARR_ON) &&
  843. ISSET(tp->t_cflag, CLOCAL) &&
  844. !ISSET(t->c_cflag, CLOCAL)) {
  845. CLR(tp->t_state, TS_ISOPEN);
  846. SET(tp->t_state, TS_WOPEN);
  847. ttwakeup(tp);
  848. }
  849. tp->t_cflag = t->c_cflag;
  850. tp->t_ispeed = t->c_ispeed;
  851. tp->t_ospeed = t->c_ospeed;
  852. if (t->c_ospeed == 0 && tp->t_session &&
  853. tp->t_session->s_leader)
  854. prsignal(tp->t_session->s_leader,
  855. SIGHUP);
  856. }
  857. ttsetwater(tp);
  858. }
  859. if (cmd != TIOCSETAF) {
  860. if (ISSET(t->c_lflag, ICANON) !=
  861. ISSET(tp->t_lflag, ICANON)) {
  862. if (ISSET(t->c_lflag, ICANON)) {
  863. SET(tp->t_lflag, PENDIN);
  864. ttwakeup(tp);
  865. } else {
  866. struct clist tq;
  867. catq(&tp->t_rawq, &tp->t_canq);
  868. tq = tp->t_rawq;
  869. tp->t_rawq = tp->t_canq;
  870. tp->t_canq = tq;
  871. CLR(tp->t_lflag, PENDIN);
  872. }
  873. }
  874. }
  875. tp->t_iflag = t->c_iflag;
  876. tp->t_oflag = t->c_oflag;
  877. /*
  878. * Make the EXTPROC bit read only.
  879. */
  880. if (ISSET(tp->t_lflag, EXTPROC))
  881. SET(t->c_lflag, EXTPROC);
  882. else
  883. CLR(t->c_lflag, EXTPROC);
  884. tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
  885. memcpy(tp->t_cc, t->c_cc, sizeof(t->c_cc));
  886. splx(s);
  887. break;
  888. }
  889. case TIOCSETD: { /* set line discipline */
  890. int t = *(int *)data;
  891. dev_t device = tp->t_dev;
  892. if ((u_int)t >= nlinesw)
  893. return (ENXIO);
  894. if (t != tp->t_line) {
  895. s = spltty();
  896. (*linesw[tp->t_line].l_close)(tp, flag, p);
  897. error = (*linesw[t].l_open)(device, tp, p);
  898. if (error) {
  899. (*linesw[tp->t_line].l_open)(device, tp, p);
  900. splx(s);
  901. return (error);
  902. }
  903. tp->t_line = t;
  904. splx(s);
  905. }
  906. break;
  907. }
  908. case TIOCSTART: /* start output, like ^Q */
  909. s = spltty();
  910. if (ISSET(tp->t_state, TS_TTSTOP) ||
  911. ISSET(tp->t_lflag, FLUSHO)) {
  912. CLR(tp->t_lflag, FLUSHO);
  913. CLR(tp->t_state, TS_TTSTOP);
  914. ttstart(tp);
  915. }
  916. splx(s);
  917. break;
  918. case TIOCSTI: /* simulate terminal input */
  919. if (p->p_ucred->cr_uid && (flag & FREAD) == 0)
  920. return (EPERM);
  921. if (p->p_ucred->cr_uid && !isctty(pr, tp))
  922. return (EACCES);
  923. (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
  924. break;
  925. case TIOCSTOP: /* stop output, like ^S */
  926. s = spltty();
  927. if (!ISSET(tp->t_state, TS_TTSTOP)) {
  928. SET(tp->t_state, TS_TTSTOP);
  929. (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
  930. }
  931. splx(s);
  932. break;
  933. case TIOCSCTTY: /* become controlling tty */
  934. /* Session ctty vnode pointer set in vnode layer. */
  935. if (!SESS_LEADER(pr) ||
  936. ((pr->ps_session->s_ttyvp || tp->t_session) &&
  937. (tp->t_session != pr->ps_session)))
  938. return (EPERM);
  939. if (tp->t_session)
  940. SESSRELE(tp->t_session);
  941. SESSHOLD(pr->ps_session);
  942. tp->t_session = pr->ps_session;
  943. tp->t_pgrp = pr->ps_pgrp;
  944. pr->ps_session->s_ttyp = tp;
  945. atomic_setbits_int(&pr->ps_flags, PS_CONTROLT);
  946. break;
  947. case TIOCSPGRP: { /* set pgrp of tty */
  948. struct pgrp *pgrp = pgfind(*(int *)data);
  949. if (!isctty(pr, tp))
  950. return (ENOTTY);
  951. else if (pgrp == NULL)
  952. return (EINVAL);
  953. else if (pgrp->pg_session != pr->ps_session)
  954. return (EPERM);
  955. tp->t_pgrp = pgrp;
  956. break;
  957. }
  958. case TIOCSTAT: /* get load avg stats */
  959. ttyinfo(tp);
  960. break;
  961. case TIOCSWINSZ: /* set window size */
  962. if (bcmp((caddr_t)&tp->t_winsize, data,
  963. sizeof (struct winsize))) {
  964. tp->t_winsize = *(struct winsize *)data;
  965. pgsignal(tp->t_pgrp, SIGWINCH, 1);
  966. }
  967. break;
  968. case TIOCSTSTAMP: {
  969. struct tstamps *ts = (struct tstamps *)data;
  970. s = spltty();
  971. CLR(tp->t_flags, TS_TSTAMPDCDSET);
  972. CLR(tp->t_flags, TS_TSTAMPCTSSET);
  973. CLR(tp->t_flags, TS_TSTAMPDCDCLR);
  974. CLR(tp->t_flags, TS_TSTAMPCTSCLR);
  975. if (ISSET(ts->ts_set, TIOCM_CAR))
  976. SET(tp->t_flags, TS_TSTAMPDCDSET);
  977. if (ISSET(ts->ts_set, TIOCM_CTS))
  978. SET(tp->t_flags, TS_TSTAMPCTSSET);
  979. if (ISSET(ts->ts_clr, TIOCM_CAR))
  980. SET(tp->t_flags, TS_TSTAMPDCDCLR);
  981. if (ISSET(ts->ts_clr, TIOCM_CTS))
  982. SET(tp->t_flags, TS_TSTAMPCTSCLR);
  983. splx(s);
  984. break;
  985. }
  986. default:
  987. return (-1);
  988. }
  989. return (0);
  990. }
  991. int
  992. ttpoll(dev_t device, int events, struct proc *p)
  993. {
  994. struct tty *tp;
  995. int revents, s;
  996. tp = (*cdevsw[major(device)].d_tty)(device);
  997. revents = 0;
  998. s = spltty();
  999. if (events & (POLLIN | POLLRDNORM)) {
  1000. if (ttnread(tp) > 0 || (!ISSET(tp->t_cflag, CLOCAL) &&
  1001. !ISSET(tp->t_state, TS_CARR_ON)))
  1002. revents |= events & (POLLIN | POLLRDNORM);
  1003. }
  1004. /* NOTE: POLLHUP and POLLOUT/POLLWRNORM are mutually exclusive */
  1005. if (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) {
  1006. revents |= POLLHUP;
  1007. } else if (events & (POLLOUT | POLLWRNORM)) {
  1008. if (tp->t_outq.c_cc <= tp->t_lowat)
  1009. revents |= events & (POLLOUT | POLLWRNORM);
  1010. }
  1011. if (revents == 0) {
  1012. if (events & (POLLIN | POLLRDNORM))
  1013. selrecord(p, &tp->t_rsel);
  1014. if (events & (POLLOUT | POLLWRNORM))
  1015. selrecord(p, &tp->t_wsel);
  1016. }
  1017. splx(s);
  1018. return (revents);
  1019. }
  1020. struct filterops ttyread_filtops =
  1021. { 1, NULL, filt_ttyrdetach, filt_ttyread };
  1022. struct filterops ttywrite_filtops =
  1023. { 1, NULL, filt_ttywdetach, filt_ttywrite };
  1024. int
  1025. ttkqfilter(dev_t dev, struct knote *kn)
  1026. {
  1027. struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev);
  1028. struct klist *klist;
  1029. int s;
  1030. switch (kn->kn_filter) {
  1031. case EVFILT_READ:
  1032. klist = &tp->t_rsel.si_note;
  1033. kn->kn_fop = &ttyread_filtops;
  1034. break;
  1035. case EVFILT_WRITE:
  1036. klist = &tp->t_wsel.si_note;
  1037. kn->kn_fop = &ttywrite_filtops;
  1038. break;
  1039. default:
  1040. return (EINVAL);
  1041. }
  1042. kn->kn_hook = (caddr_t)((u_long)dev);
  1043. s = spltty();
  1044. SLIST_INSERT_HEAD(klist, kn, kn_selnext);
  1045. splx(s);
  1046. return (0);
  1047. }
  1048. void
  1049. ttkqflush(struct klist *klist)
  1050. {
  1051. struct knote *kn, *kn1;
  1052. SLIST_FOREACH_SAFE(kn, klist, kn_selnext, kn1) {
  1053. SLIST_REMOVE(klist, kn, knote, kn_selnext);
  1054. kn->kn_hook = (caddr_t)((u_long)NODEV);
  1055. kn->kn_flags |= EV_EOF;
  1056. knote_activate(kn);
  1057. }
  1058. }
  1059. void
  1060. filt_ttyrdetach(struct knote *kn)
  1061. {
  1062. dev_t dev = (dev_t)((u_long)kn->kn_hook);
  1063. struct tty *tp;
  1064. int s;
  1065. if (dev == NODEV)
  1066. return;
  1067. tp = (*cdevsw[major(dev)].d_tty)(dev);
  1068. s = spltty();
  1069. SLIST_REMOVE(&tp->t_rsel.si_note, kn, knote, kn_selnext);
  1070. splx(s);
  1071. }
  1072. int
  1073. filt_ttyread(struct knote *kn, long hint)
  1074. {
  1075. dev_t dev = (dev_t)((u_long)kn->kn_hook);
  1076. struct tty *tp;
  1077. int s;
  1078. if (dev == NODEV) {
  1079. kn->kn_flags |= EV_EOF;
  1080. return (1);
  1081. }
  1082. tp = (*cdevsw[major(dev)].d_tty)(dev);
  1083. s = spltty();
  1084. kn->kn_data = ttnread(tp);
  1085. splx(s);
  1086. if (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) {
  1087. kn->kn_flags |= EV_EOF;
  1088. return (1);
  1089. }
  1090. return (kn->kn_data > 0);
  1091. }
  1092. void
  1093. filt_ttywdetach(struct knote *kn)
  1094. {
  1095. dev_t dev = (dev_t)((u_long)kn->kn_hook);
  1096. struct tty *tp;
  1097. int s;
  1098. if (dev == NODEV)
  1099. return;
  1100. tp = (*cdevsw[major(dev)].d_tty)(dev);
  1101. s = spltty();
  1102. SLIST_REMOVE(&tp->t_wsel.si_note, kn, knote, kn_selnext);
  1103. splx(s);
  1104. }
  1105. int
  1106. filt_ttywrite(struct knote *kn, long hint)
  1107. {
  1108. dev_t dev = (dev_t)((u_long)kn->kn_hook);
  1109. struct tty *tp;
  1110. int canwrite, s;
  1111. if (dev == NODEV) {
  1112. kn->kn_flags |= EV_EOF;
  1113. return (1);
  1114. }
  1115. tp = (*cdevsw[major(dev)].d_tty)(dev);
  1116. s = spltty();
  1117. kn->kn_data = tp->t_outq.c_cn - tp->t_outq.c_cc;
  1118. canwrite = (tp->t_outq.c_cc <= tp->t_lowat);
  1119. splx(s);
  1120. return (canwrite);
  1121. }
  1122. static int
  1123. ttnread(struct tty *tp)
  1124. {
  1125. int nread;
  1126. splassert(IPL_TTY);
  1127. if (ISSET(tp->t_lflag, PENDIN))
  1128. ttypend(tp);
  1129. nread = tp->t_canq.c_cc;
  1130. if (!ISSET(tp->t_lflag, ICANON)) {
  1131. nread += tp->t_rawq.c_cc;
  1132. if (nread < tp->t_cc[VMIN] && !tp->t_cc[VTIME])
  1133. nread = 0;
  1134. }
  1135. return (nread);
  1136. }
  1137. /*
  1138. * Wait for output to drain.
  1139. */
  1140. int
  1141. ttywait(struct tty *tp)
  1142. {
  1143. int error, s;
  1144. error = 0;
  1145. s = spltty();
  1146. while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
  1147. (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL)) &&
  1148. tp->t_oproc) {
  1149. (*tp->t_oproc)(tp);
  1150. if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
  1151. (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
  1152. && tp->t_oproc) {
  1153. SET(tp->t_state, TS_ASLEEP);
  1154. error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
  1155. if (error)
  1156. break;
  1157. } else
  1158. break;
  1159. }
  1160. splx(s);
  1161. return (error);
  1162. }
  1163. /*
  1164. * Flush if successfully wait.
  1165. */
  1166. int
  1167. ttywflush(struct tty *tp)
  1168. {
  1169. int error;
  1170. if ((error = ttywait(tp)) == 0)
  1171. ttyflush(tp, FREAD);
  1172. return (error);
  1173. }
  1174. /*
  1175. * Flush tty read and/or write queues, notifying anyone waiting.
  1176. */
  1177. void
  1178. ttyflush(struct tty *tp, int rw)
  1179. {
  1180. int s;
  1181. s = spltty();
  1182. if (rw & FREAD) {
  1183. FLUSHQ(&tp->t_canq);
  1184. FLUSHQ(&tp->t_rawq);
  1185. tp->t_rocount = 0;
  1186. tp->t_rocol = 0;
  1187. CLR(tp->t_state, TS_LOCAL);
  1188. ttyunblock(tp);
  1189. ttwakeup(tp);
  1190. }
  1191. if (rw & FWRITE) {
  1192. CLR(tp->t_state, TS_TTSTOP);
  1193. (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
  1194. FLUSHQ(&tp->t_outq);
  1195. wakeup((caddr_t)&tp->t_outq);
  1196. selwakeup(&tp->t_wsel);
  1197. }
  1198. splx(s);
  1199. }
  1200. /*
  1201. * Copy in the default termios characters.
  1202. */
  1203. void
  1204. ttychars(struct tty *tp)
  1205. {
  1206. memcpy(tp->t_cc, ttydefchars, sizeof(ttydefchars));
  1207. }
  1208. /*
  1209. * Send stop character on input overflow.
  1210. */
  1211. static void
  1212. ttyblock(struct tty *tp)
  1213. {
  1214. int total;
  1215. total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
  1216. if (tp->t_rawq.c_cc > TTYHOG(tp)) {
  1217. ttyflush(tp, FREAD | FWRITE);
  1218. CLR(tp->t_state, TS_TBLOCK);
  1219. }
  1220. /*
  1221. * Block further input iff: current input > threshold
  1222. * AND input is available to user program.
  1223. */
  1224. if ((total >= TTYHOG(tp) / 2 &&
  1225. !ISSET(tp->t_state, TS_TBLOCK) &&
  1226. !ISSET(tp->t_lflag, ICANON)) || tp->t_canq.c_cc > 0) {
  1227. if (ISSET(tp->t_iflag, IXOFF) &&
  1228. tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
  1229. putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
  1230. SET(tp->t_state, TS_TBLOCK);
  1231. ttstart(tp);
  1232. }
  1233. /* Try to block remote output via hardware flow control. */
  1234. if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
  1235. (*tp->t_hwiflow)(tp, 1) != 0)
  1236. SET(tp->t_state, TS_TBLOCK);
  1237. }
  1238. }
  1239. void
  1240. ttrstrt(void *tp_arg)
  1241. {
  1242. struct tty *tp;
  1243. int s;
  1244. #ifdef DIAGNOSTIC
  1245. if (tp_arg == NULL)
  1246. panic("ttrstrt");
  1247. #endif
  1248. tp = tp_arg;
  1249. s = spltty();
  1250. CLR(tp->t_state, TS_TIMEOUT);
  1251. ttstart(tp);
  1252. splx(s);
  1253. }
  1254. int
  1255. ttstart(struct tty *tp)
  1256. {
  1257. if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
  1258. (*tp->t_oproc)(tp);
  1259. return (0);
  1260. }
  1261. /*
  1262. * "close" a line discipline
  1263. */
  1264. int
  1265. ttylclose(struct tty *tp, int flag, struct proc *p)
  1266. {
  1267. if (flag & FNONBLOCK)
  1268. ttyflush(tp, FREAD | FWRITE);
  1269. else
  1270. ttywflush(tp);
  1271. return (0);
  1272. }
  1273. /*
  1274. * Handle modem control transition on a tty.
  1275. * Flag indicates new state of carrier.
  1276. * Returns 0 if the line should be turned off, otherwise 1.
  1277. */
  1278. int
  1279. ttymodem(struct tty *tp, int flag)
  1280. {
  1281. if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) {
  1282. /*
  1283. * MDMBUF: do flow control according to carrier flag
  1284. */
  1285. if (flag) {
  1286. CLR(tp->t_state, TS_TTSTOP);
  1287. ttstart(tp);
  1288. } else if (!ISSET(tp->t_state, TS_TTSTOP)) {
  1289. SET(tp->t_state, TS_TTSTOP);
  1290. (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
  1291. }
  1292. } else if (flag == 0) {
  1293. /*
  1294. * Lost carrier.
  1295. */
  1296. CLR(tp->t_state, TS_CARR_ON);
  1297. if (ISSET(tp->t_state, TS_ISOPEN) &&
  1298. !ISSET(tp->t_cflag, CLOCAL)) {
  1299. if (tp->t_session && tp->t_session->s_leader)
  1300. prsignal(tp->t_session->s_leader, SIGHUP);
  1301. ttyflush(tp, FREAD | FWRITE);
  1302. return (0);
  1303. }
  1304. } else {
  1305. /*
  1306. * Carrier now on.
  1307. */
  1308. SET(tp->t_state, TS_CARR_ON);
  1309. ttwakeup(tp);
  1310. }
  1311. return (1);
  1312. }
  1313. /*
  1314. * Default modem control routine (for other line disciplines).
  1315. * Return argument flag, to turn off device on carrier drop.
  1316. */
  1317. int
  1318. nullmodem(struct tty *tp, int flag)
  1319. {
  1320. if (flag)
  1321. SET(tp->t_state, TS_CARR_ON);
  1322. else {
  1323. CLR(tp->t_state, TS_CARR_ON);
  1324. if (ISSET(tp->t_state, TS_ISOPEN) &&
  1325. !ISSET(tp->t_cflag, CLOCAL)) {
  1326. if (tp->t_session && tp->t_session->s_leader)
  1327. prsignal(tp->t_session->s_leader, SIGHUP);
  1328. ttyflush(tp, FREAD | FWRITE);
  1329. return (0);
  1330. }
  1331. }
  1332. return (1);
  1333. }
  1334. /*
  1335. * Reinput pending characters after state switch
  1336. * call at spltty().
  1337. */
  1338. void
  1339. ttypend(struct tty *tp)
  1340. {
  1341. struct clist tq;
  1342. int c;
  1343. splassert(IPL_TTY);
  1344. CLR(tp->t_lflag, PENDIN);
  1345. SET(tp->t_state, TS_TYPEN);
  1346. tq = tp->t_rawq;
  1347. tp->t_rawq.c_cc = 0;
  1348. tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
  1349. while ((c = getc(&tq)) >= 0)
  1350. ttyinput(c, tp);
  1351. CLR(tp->t_state, TS_TYPEN);
  1352. }
  1353. void ttvtimeout(void *);
  1354. void
  1355. ttvtimeout(void *arg)
  1356. {
  1357. struct tty *tp = (struct tty *)arg;
  1358. wakeup(&tp->t_rawq);
  1359. }
  1360. /*
  1361. * Process a read call on a tty device.
  1362. */
  1363. int
  1364. ttread(struct tty *tp, struct uio *uio, int flag)
  1365. {
  1366. struct timeout *stime = NULL;
  1367. struct proc *p = curproc;
  1368. struct process *pr = p->p_p;
  1369. int s, first, error = 0;
  1370. u_char *cc = tp->t_cc;
  1371. struct clist *qp;
  1372. int last_cc = 0;
  1373. long lflag;
  1374. int c;
  1375. loop: lflag = tp->t_lflag;
  1376. s = spltty();
  1377. /*
  1378. * take pending input first
  1379. */
  1380. if (ISSET(lflag, PENDIN))
  1381. ttypend(tp);
  1382. splx(s);
  1383. /*
  1384. * Hang process if it's in the background.
  1385. */
  1386. if (isbackground(pr, tp)) {
  1387. if ((pr->ps_sigacts->ps_sigignore & sigmask(SIGTTIN)) ||
  1388. (p->p_sigmask & sigmask(SIGTTIN)) ||
  1389. pr->ps_flags & PS_PPWAIT || pr->ps_pgrp->pg_jobc == 0) {
  1390. error = EIO;
  1391. goto out;
  1392. }
  1393. pgsignal(pr->ps_pgrp, SIGTTIN, 1);
  1394. error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0);
  1395. if (error)
  1396. goto out;
  1397. goto loop;
  1398. }
  1399. s = spltty();
  1400. if (!ISSET(lflag, ICANON)) {
  1401. int m = cc[VMIN];
  1402. long t;
  1403. /*
  1404. * Note - since cc[VTIME] is a u_char, this won't overflow
  1405. * until we have 32-bit longs and a hz > 8388608.
  1406. * Hopefully this code and 32-bit longs are obsolete by then.
  1407. */
  1408. t = cc[VTIME] * hz / 10;
  1409. qp = &tp->t_rawq;
  1410. /*
  1411. * Check each of the four combinations.
  1412. * (m > 0 && t == 0) is the normal read case.
  1413. * It should be fairly efficient, so we check that and its
  1414. * companion case (m == 0 && t == 0) first.
  1415. */
  1416. if (t == 0) {
  1417. if (qp->c_cc < m)
  1418. goto sleep;
  1419. goto read;
  1420. }
  1421. if (m > 0) {
  1422. if (qp->c_cc <= 0)
  1423. goto sleep;
  1424. if (qp->c_cc >= m)
  1425. goto read;
  1426. if (stime == NULL) {
  1427. alloc_timer:
  1428. stime = malloc(sizeof(*stime), M_TEMP, M_WAITOK);
  1429. timeout_set(stime, ttvtimeout, tp);
  1430. timeout_add(stime, t);
  1431. } else if (qp->c_cc > last_cc) {
  1432. /* got a character, restart timer */
  1433. timeout_add(stime, t);
  1434. }
  1435. } else { /* m == 0 */
  1436. if (qp->c_cc > 0)
  1437. goto read;
  1438. if (stime == NULL) {
  1439. goto alloc_timer;
  1440. }
  1441. }
  1442. last_cc = qp->c_cc;
  1443. if (stime && !timeout_triggered(stime)) {
  1444. goto sleep;
  1445. }
  1446. } else if ((qp = &tp->t_canq)->c_cc <= 0) {
  1447. int carrier;
  1448. sleep:
  1449. /*
  1450. * If there is no input, sleep on rawq
  1451. * awaiting hardware receipt and notification.
  1452. * If we have data, we don't need to check for carrier.
  1453. */
  1454. carrier = ISSET(tp->t_state, TS_CARR_ON) ||
  1455. ISSET(tp->t_cflag, CLOCAL);
  1456. if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
  1457. splx(s);
  1458. error = 0;
  1459. goto out;
  1460. }
  1461. if (flag & IO_NDELAY) {
  1462. splx(s);
  1463. error = EWOULDBLOCK;
  1464. goto out;
  1465. }
  1466. error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
  1467. carrier ? ttyin : ttopen, 0);
  1468. splx(s);
  1469. if (stime && timeout_triggered(stime))
  1470. error = EWOULDBLOCK;
  1471. if (cc[VMIN] == 0 && error == EWOULDBLOCK) {
  1472. error = 0;
  1473. goto out;
  1474. }
  1475. if (error && error != EWOULDBLOCK)
  1476. goto out;
  1477. error = 0;
  1478. goto loop;
  1479. }
  1480. read:
  1481. splx(s);
  1482. /*
  1483. * Input present, check for input mapping and processing.
  1484. */
  1485. first = 1;
  1486. while ((c = getc(qp)) >= 0) {
  1487. /*
  1488. * delayed suspend (^Y)
  1489. */
  1490. if (CCEQ(cc[VDSUSP], c) &&
  1491. ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
  1492. pgsignal(tp->t_pgrp, SIGTSTP, 1);
  1493. if (first) {
  1494. error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
  1495. ttybg, 0);
  1496. if (error)
  1497. break;
  1498. goto loop;
  1499. }
  1500. break;
  1501. }
  1502. /*
  1503. * Interpret EOF only in canonical mode.
  1504. */
  1505. if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
  1506. break;
  1507. /*
  1508. * Give user character.
  1509. */
  1510. error = ureadc(c, uio);
  1511. if (error)
  1512. break;
  1513. if (uio->uio_resid == 0)
  1514. break;
  1515. /*
  1516. * In canonical mode check for a "break character"
  1517. * marking the end of a "line of input".
  1518. */
  1519. if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
  1520. break;
  1521. first = 0;
  1522. }
  1523. /*
  1524. * Look to unblock output now that (presumably)
  1525. * the input queue has gone down.
  1526. */
  1527. s = spltty();
  1528. if (tp->t_rawq.c_cc < TTYHOG(tp)/5)
  1529. ttyunblock(tp);
  1530. splx(s);
  1531. out:
  1532. if (stime) {
  1533. timeout_del(stime);
  1534. free(stime, M_TEMP, 0);
  1535. }
  1536. return (error);
  1537. }
  1538. /* Call at spltty */
  1539. void
  1540. ttyunblock(struct tty *tp)
  1541. {
  1542. u_char *cc = tp->t_cc;
  1543. splassert(IPL_TTY);
  1544. if (ISSET(tp->t_state, TS_TBLOCK)) {
  1545. if (ISSET(tp->t_iflag, IXOFF) &&
  1546. cc[VSTART] != _POSIX_VDISABLE &&
  1547. putc(cc[VSTART], &tp->t_outq) == 0) {
  1548. CLR(tp->t_state, TS_TBLOCK);
  1549. ttstart(tp);
  1550. }
  1551. /* Try to unblock remote output via hardware flow control. */
  1552. if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
  1553. (*tp->t_hwiflow)(tp, 0) != 0)
  1554. CLR(tp->t_state, TS_TBLOCK);
  1555. }
  1556. }
  1557. /*
  1558. * Check the output queue on tp for space for a kernel message (from uprintf
  1559. * or tprintf). Allow some space over the normal hiwater mark so we don't
  1560. * lose messages due to normal flow control, but don't let the tty run amok.
  1561. * Sleeps here are not interruptible, but we return prematurely if new signals
  1562. * arrive.
  1563. */
  1564. int
  1565. ttycheckoutq(struct tty *tp, int wait)
  1566. {
  1567. int hiwat, s, oldsig;
  1568. hiwat = tp->t_hiwat;
  1569. s = spltty();
  1570. oldsig = wait ? curproc->p_siglist : 0;
  1571. if (tp->t_outq.c_cc > hiwat + TTHIWATMINSPACE)
  1572. while (tp->t_outq.c_cc > hiwat) {
  1573. ttstart(tp);
  1574. if (wait == 0 || curproc->p_siglist != oldsig) {
  1575. splx(s);
  1576. return (0);
  1577. }
  1578. SET(tp->t_state, TS_ASLEEP);
  1579. tsleep(&tp->t_outq, PZERO - 1, "ttckoutq", hz);
  1580. }
  1581. splx(s);
  1582. return (1);
  1583. }
  1584. /*
  1585. * Process a write call on a tty device.
  1586. */
  1587. int
  1588. ttwrite(struct tty *tp, struct uio *uio, int flag)
  1589. {
  1590. u_char *cp = NULL;
  1591. int cc, ce, obufcc = 0;
  1592. struct proc *p;
  1593. struct process *pr;
  1594. int i, hiwat, error, s;
  1595. size_t cnt;
  1596. u_char obuf[OBUFSIZ];
  1597. hiwat = tp->t_hiwat;
  1598. cnt = uio->uio_resid;
  1599. error = 0;
  1600. cc = 0;
  1601. loop:
  1602. s = spltty();
  1603. if (!ISSET(tp->t_state, TS_CARR_ON) &&
  1604. !ISSET(tp->t_cflag, CLOCAL)) {
  1605. if (ISSET(tp->t_state, TS_ISOPEN)) {
  1606. splx(s);
  1607. error = EIO;
  1608. goto done;
  1609. } else if (flag & IO_NDELAY) {
  1610. splx(s);
  1611. error = EWOULDBLOCK;
  1612. goto out;
  1613. } else {
  1614. /* Sleep awaiting carrier. */
  1615. error = ttysleep(tp,
  1616. &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
  1617. splx(s);
  1618. if (error)
  1619. goto out;
  1620. goto loop;
  1621. }
  1622. }
  1623. splx(s);
  1624. /*
  1625. * Hang the process if it's in the background.
  1626. */
  1627. p = curproc;
  1628. pr = p->p_p;
  1629. if (isbackground(pr, tp) &&
  1630. ISSET(tp->t_lflag, TOSTOP) && (pr->ps_flags & PS_PPWAIT) == 0 &&
  1631. (pr->ps_sigacts->ps_sigignore & sigmask(SIGTTOU)) == 0 &&
  1632. (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
  1633. if (pr->ps_pgrp->pg_jobc == 0) {
  1634. error = EIO;
  1635. goto out;
  1636. }
  1637. pgsignal(pr->ps_pgrp, SIGTTOU, 1);
  1638. error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0);
  1639. if (error)
  1640. goto out;
  1641. goto loop;
  1642. }
  1643. /*
  1644. * Process the user's data in at most OBUFSIZ chunks. Perform any
  1645. * output translation. Keep track of high water mark, sleep on
  1646. * overflow awaiting device aid in acquiring new space.
  1647. */
  1648. while (uio->uio_resid > 0 || cc > 0) {
  1649. if (ISSET(tp->t_lflag, FLUSHO)) {
  1650. uio->uio_resid = 0;
  1651. goto done;
  1652. }
  1653. if (tp->t_outq.c_cc > hiwat)
  1654. goto ovhiwat;
  1655. /*
  1656. * Grab a hunk of data from the user, unless we have some
  1657. * leftover from last time.
  1658. */
  1659. if (cc == 0) {
  1660. cc = MIN(uio->uio_resid, OBUFSIZ);
  1661. cp = obuf;
  1662. error = uiomovei(cp, cc, uio);
  1663. if (error) {
  1664. cc = 0;
  1665. break;
  1666. }
  1667. if (cc > obufcc)
  1668. obufcc = cc;
  1669. /* duplicate /dev/console output into console buffer */
  1670. if (consbufp && cn_tab &&
  1671. cn_tab->cn_dev == tp->t_dev && tp->t_gen == 0) {
  1672. int i;
  1673. for (i = 0; i < cc; i++) {
  1674. char c = cp[i];
  1675. if (c != '\0' && c != '\r' && c != 0177)
  1676. msgbuf_putchar(consbufp, c);
  1677. }
  1678. }
  1679. }
  1680. /*
  1681. * If nothing fancy need be done, grab those characters we
  1682. * can handle without any of ttyoutput's processing and
  1683. * just transfer them to the output q. For those chars
  1684. * which require special processing (as indicated by the
  1685. * bits in char_type), call ttyoutput. After processing
  1686. * a hunk of data, look for FLUSHO so ^O's will take effect
  1687. * immediately.
  1688. */
  1689. while (cc > 0) {
  1690. if (!ISSET(tp->t_oflag, OPOST))
  1691. ce = cc;
  1692. else {
  1693. ce = cc - scanc((u_int)cc, cp, char_type,
  1694. CCLASSMASK);
  1695. /*
  1696. * If ce is zero, then we're processing
  1697. * a special character through ttyoutput.
  1698. */
  1699. if (ce == 0) {
  1700. tp->t_rocount = 0;
  1701. if (ttyoutput(*cp, tp) >= 0) {
  1702. /* out of space */
  1703. goto ovhiwat;
  1704. }
  1705. cp++;
  1706. cc--;
  1707. if (ISSET(tp->t_lflag, FLUSHO) ||
  1708. tp->t_outq.c_cc > hiwat)
  1709. goto ovhiwat;
  1710. continue;
  1711. }
  1712. }
  1713. /*
  1714. * A bunch of normal characters have been found.
  1715. * Transfer them en masse to the output queue and
  1716. * continue processing at the top of the loop.
  1717. * If there are any further characters in this
  1718. * <= OBUFSIZ chunk, the first should be a character
  1719. * requiring special handling by ttyoutput.
  1720. */
  1721. tp->t_rocount = 0;
  1722. i = b_to_q(cp, ce, &tp->t_outq);
  1723. ce -= i;
  1724. tp->t_column += ce;
  1725. cp += ce, cc -= ce, tk_nout += ce;
  1726. tp->t_outcc += ce;
  1727. if (i > 0) {
  1728. /* out of space */
  1729. goto ovhiwat;
  1730. }
  1731. if (ISSET(tp->t_lflag, FLUSHO) ||
  1732. tp->t_outq.c_cc > hiwat)
  1733. break;
  1734. }
  1735. ttstart(tp);
  1736. }
  1737. out:
  1738. /*
  1739. * If cc is nonzero, we leave the uio structure inconsistent, as the
  1740. * offset and iov pointers have moved forward, but it doesn't matter
  1741. * (the call will either return short or restart with a new uio).
  1742. */
  1743. uio->uio_resid += cc;
  1744. done:
  1745. if (obufcc)
  1746. explicit_bzero(obuf, obufcc);
  1747. return (error);
  1748. ovhiwat:
  1749. ttstart(tp);
  1750. s = spltty();
  1751. /*
  1752. * This can only occur if FLUSHO is set in t_lflag,
  1753. * or if ttstart/oproc is synchronous (or very fast).
  1754. */
  1755. if (tp->t_outq.c_cc <= hiwat) {
  1756. splx(s);
  1757. goto loop;
  1758. }
  1759. if (flag & IO_NDELAY) {
  1760. splx(s);
  1761. uio->uio_resid += cc;
  1762. if (obufcc)
  1763. explicit_bzero(obuf, obufcc);
  1764. return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
  1765. }
  1766. SET(tp->t_state, TS_ASLEEP);
  1767. error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
  1768. splx(s);
  1769. if (error)
  1770. goto out;
  1771. goto loop;
  1772. }
  1773. /*
  1774. * Rubout one character from the rawq of tp
  1775. * as cleanly as possible.
  1776. */
  1777. void
  1778. ttyrub(int c, struct tty *tp)
  1779. {
  1780. u_char *cp;
  1781. int savecol;
  1782. int tabc, s;
  1783. if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
  1784. return;
  1785. CLR(tp->t_lflag, FLUSHO);
  1786. if (ISSET(tp->t_lflag, ECHOE)) {
  1787. if (tp->t_rocount == 0) {
  1788. /*
  1789. * Screwed by ttwrite; retype
  1790. */
  1791. ttyretype(tp);
  1792. return;
  1793. }
  1794. if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
  1795. ttyrubo(tp, 2);
  1796. else {
  1797. CLR(c, ~TTY_CHARMASK);
  1798. switch (CCLASS(c)) {
  1799. case ORDINARY:
  1800. ttyrubo(tp, 1);
  1801. break;
  1802. case BACKSPACE:
  1803. case CONTROL:
  1804. case NEWLINE:
  1805. case RETURN:
  1806. case VTAB:
  1807. if (ISSET(tp->t_lflag, ECHOCTL))
  1808. ttyrubo(tp, 2);
  1809. break;
  1810. case TAB:
  1811. if (tp->t_rocount < tp->t_rawq.c_cc) {
  1812. ttyretype(tp);
  1813. return;
  1814. }
  1815. s = spltty();
  1816. savecol = tp->t_column;
  1817. SET(tp->t_state, TS_CNTTB);
  1818. SET(tp->t_lflag, FLUSHO);
  1819. tp->t_column = tp->t_rocol;
  1820. for (cp = firstc(&tp->t_rawq, &tabc); cp;
  1821. cp = nextc(&tp->t_rawq, cp, &tabc))
  1822. ttyecho(tabc, tp);
  1823. CLR(tp->t_lflag, FLUSHO);
  1824. CLR(tp->t_state, TS_CNTTB);
  1825. splx(s);
  1826. /* savecol will now be length of the tab. */
  1827. savecol -= tp->t_column;
  1828. tp->t_column += savecol;
  1829. if (savecol > 8)
  1830. savecol = 8; /* overflow screw */
  1831. while (--savecol >= 0)
  1832. (void)ttyoutput('\b', tp);
  1833. break;
  1834. default: /* XXX */
  1835. #define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
  1836. (void)printf(PANICSTR, c, CCLASS(c));
  1837. #ifdef notdef
  1838. panic(PANICSTR, c, CCLASS(c));
  1839. #endif
  1840. }
  1841. }
  1842. } else if (ISSET(tp->t_lflag, ECHOPRT)) {
  1843. if (!ISSET(tp->t_state, TS_ERASE)) {
  1844. SET(tp->t_state, TS_ERASE);
  1845. (void)ttyoutput('\\', tp);
  1846. }
  1847. ttyecho(c, tp);
  1848. } else
  1849. ttyecho(tp->t_cc[VERASE], tp);
  1850. --tp->t_rocount;
  1851. }
  1852. /*
  1853. * Back over cnt characters, erasing them.
  1854. */
  1855. static void
  1856. ttyrubo(struct tty *tp, int cnt)
  1857. {
  1858. while (cnt-- > 0) {
  1859. (void)ttyoutput('\b', tp);
  1860. (void)ttyoutput(' ', tp);
  1861. (void)ttyoutput('\b', tp);
  1862. }
  1863. }
  1864. /*
  1865. * ttyretype --
  1866. * Reprint the rawq line. Note, it is assumed that c_cc has already
  1867. * been checked.
  1868. */
  1869. void
  1870. ttyretype(struct tty *tp)
  1871. {
  1872. u_char *cp;
  1873. int s, c;
  1874. /* Echo the reprint character. */
  1875. if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
  1876. ttyecho(tp->t_cc[VREPRINT], tp);
  1877. (void)ttyoutput('\n', tp);
  1878. s = spltty();
  1879. for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
  1880. ttyecho(c, tp);
  1881. for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
  1882. ttyecho(c, tp);
  1883. CLR(tp->t_state, TS_ERASE);
  1884. splx(s);
  1885. tp->t_rocount = tp->t_rawq.c_cc;
  1886. tp->t_rocol = 0;
  1887. }
  1888. /*
  1889. * Echo a typed character to the terminal.
  1890. */
  1891. static void
  1892. ttyecho(int c, struct tty *tp)
  1893. {
  1894. if (!ISSET(tp->t_state, TS_CNTTB))
  1895. CLR(tp->t_lflag, FLUSHO);
  1896. if ((!ISSET(tp->t_lflag, ECHO) &&
  1897. (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) ||
  1898. ISSET(tp->t_lflag, EXTPROC))
  1899. return;
  1900. if (((ISSET(tp->t_lflag, ECHOCTL) &&
  1901. (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) ||
  1902. ISSET(c, TTY_CHARMASK) == 0177)) {
  1903. (void)ttyoutput('^', tp);
  1904. CLR(c, ~TTY_CHARMASK);
  1905. if (c == 0177)
  1906. c = '?';
  1907. else
  1908. c += 'A' - 1;
  1909. }
  1910. (void)ttyoutput(c, tp);
  1911. }
  1912. /*
  1913. * Wakeup any writers if necessary.
  1914. */
  1915. void
  1916. ttwakeupwr(struct tty *tp)
  1917. {
  1918. if (tp->t_outq.c_cc <= tp->t_lowat) {
  1919. if (ISSET(tp->t_state, TS_ASLEEP)) {
  1920. CLR(tp->t_state, TS_ASLEEP);
  1921. wakeup(&tp->t_outq);
  1922. }
  1923. selwakeup(&tp->t_wsel);
  1924. }
  1925. }
  1926. /*
  1927. * Wake up any readers on a tty.
  1928. */
  1929. void
  1930. ttwakeup(struct tty *tp)
  1931. {
  1932. selwakeup(&tp->t_rsel);
  1933. if (ISSET(tp->t_state, TS_ASYNC))
  1934. pgsignal(tp->t_pgrp, SIGIO, 1);
  1935. wakeup((caddr_t)&tp->t_rawq);
  1936. }
  1937. /*
  1938. * Look up a code for a specified speed in a conversion table;
  1939. * used by drivers to map software speed values to hardware parameters.
  1940. */
  1941. int
  1942. ttspeedtab(int speed, const struct speedtab *table)
  1943. {
  1944. for ( ; table->sp_speed != -1; table++)
  1945. if (table->sp_speed == speed)
  1946. return (table->sp_code);
  1947. return (-1);
  1948. }
  1949. /*
  1950. * Set tty hi and low water marks.
  1951. *
  1952. * Try to arrange the dynamics so there's about one second
  1953. * from hi to low water.
  1954. */
  1955. void
  1956. ttsetwater(struct tty *tp)
  1957. {
  1958. int cps, x;
  1959. #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
  1960. cps = tp->t_ospeed / 10;
  1961. tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
  1962. x += cps;
  1963. tp->t_hiwat = CLAMP(x, tp->t_outq.c_cn - TTHIWATMINSPACE, TTMINHIWAT);
  1964. #undef CLAMP
  1965. }
  1966. /*
  1967. * Get the total estcpu for a process, summing across threads.
  1968. * Returns true if at least one thread is runnable/running.
  1969. */
  1970. static int
  1971. process_sum(struct process *pr, fixpt_t *estcpup)
  1972. {
  1973. struct proc *p;
  1974. fixpt_t estcpu;
  1975. int ret;
  1976. ret = 0;
  1977. estcpu = 0;
  1978. TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
  1979. if (p->p_stat == SRUN || p->p_stat == SONPROC)
  1980. ret = 1;
  1981. estcpu += p->p_pctcpu;
  1982. }
  1983. *estcpup = estcpu;
  1984. return (ret);
  1985. }
  1986. /*
  1987. * Report on state of foreground process group.
  1988. */
  1989. void
  1990. ttyinfo(struct tty *tp)
  1991. {
  1992. struct process *pr, *pickpr;
  1993. struct proc *p, *pick;
  1994. struct timespec utime, stime;
  1995. int tmp;
  1996. if (ttycheckoutq(tp,0) == 0)
  1997. return;
  1998. /* Print load average. */
  1999. tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
  2000. ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
  2001. if (tp->t_session == NULL)
  2002. ttyprintf(tp, "not a controlling terminal\n");
  2003. else if (tp->t_pgrp == NULL)
  2004. ttyprintf(tp, "no foreground process group\n");
  2005. else if ((pr = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL)
  2006. empty: ttyprintf(tp, "empty foreground process group\n");
  2007. else {
  2008. const char *state;
  2009. fixpt_t pctcpu, pctcpu2;
  2010. int run, run2;
  2011. int calc_pctcpu;
  2012. long rss;
  2013. /*
  2014. * Pick the most active process:
  2015. * - prefer at least one running/runnable thread
  2016. * - prefer higher total pctcpu
  2017. * - prefer non-zombie
  2018. * Otherwise take the most recently added to this process group
  2019. */
  2020. pickpr = pr;
  2021. run = process_sum(pickpr, &pctcpu);
  2022. while ((pr = LIST_NEXT(pr, ps_pglist)) != NULL) {
  2023. run2 = process_sum(pr, &pctcpu2);
  2024. if (run) {
  2025. /*
  2026. * pick is running; is p running w/same or
  2027. * more cpu?
  2028. */
  2029. if (run2 && pctcpu2 >= pctcpu)
  2030. goto update_pickpr;
  2031. continue;
  2032. }
  2033. /* pick isn't running; is p running *or* w/more cpu? */
  2034. if (run2 || pctcpu2 > pctcpu)
  2035. goto update_pickpr;
  2036. /* if p has less cpu or is zombie, then it's worse */
  2037. if (pctcpu2 < pctcpu || (pr->ps_flags & PS_ZOMBIE))
  2038. continue;
  2039. update_pickpr:
  2040. pickpr = pr;
  2041. run = run2;
  2042. pctcpu = pctcpu2;
  2043. }
  2044. /* Calculate percentage cpu, resident set size. */
  2045. calc_pctcpu = (pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
  2046. rss = (pickpr->ps_flags & (PS_EMBRYO | PS_ZOMBIE)) ? 0 :
  2047. vm_resident_count(pickpr->ps_vmspace);
  2048. calctsru(&pickpr->ps_tu, &utime, &stime, NULL);
  2049. /* Round up and print user time. */
  2050. utime.tv_nsec += 5000000;
  2051. if (utime.tv_nsec >= 1000000000) {
  2052. utime.tv_sec += 1;
  2053. utime.tv_nsec -= 1000000000;
  2054. }
  2055. /* Round up and print system time. */
  2056. stime.tv_nsec += 5000000;
  2057. if (stime.tv_nsec >= 1000000000) {
  2058. stime.tv_sec += 1;
  2059. stime.tv_nsec -= 1000000000;
  2060. }
  2061. /*
  2062. * Find the most active thread:
  2063. * - prefer runnable
  2064. * - prefer higher pctcpu
  2065. * - prefer living
  2066. * Otherwise take the newest thread
  2067. */
  2068. pick = p = TAILQ_FIRST(&pickpr->ps_threads);
  2069. if (p == NULL)
  2070. goto empty;
  2071. run = p->p_stat == SRUN || p->p_stat == SONPROC;
  2072. pctcpu = p->p_pctcpu;
  2073. while ((p = TAILQ_NEXT(p, p_thr_link)) != NULL) {
  2074. run2 = p->p_stat == SRUN || p->p_stat == SONPROC;
  2075. pctcpu2 = p->p_pctcpu;
  2076. if (run) {
  2077. /*
  2078. * pick is running; is p running w/same or
  2079. * more cpu?
  2080. */
  2081. if (run2 && pctcpu2 >= pctcpu)
  2082. goto update_pick;
  2083. continue;
  2084. }
  2085. /* pick isn't running; is p running *or* w/more cpu? */
  2086. if (run2 || pctcpu2 > pctcpu)
  2087. goto update_pick;
  2088. /* if p has less cpu or is exiting, then it's worse */
  2089. if (pctcpu2 < pctcpu || p->p_flag & P_WEXIT)
  2090. continue;
  2091. update_pick:
  2092. pick = p;
  2093. run = run2;
  2094. pctcpu = p->p_pctcpu;
  2095. }
  2096. state = pick->p_stat == SONPROC ? "running" :
  2097. pick->p_stat == SRUN ? "runnable" :
  2098. pick->p_wmesg ? pick->p_wmesg : "iowait";
  2099. ttyprintf(tp,
  2100. " cmd: %s %d [%s] %lld.%02ldu %lld.%02lds %d%% %ldk\n",
  2101. pick->p_comm, pickpr->ps_pid, state,
  2102. (long long)utime.tv_sec, utime.tv_nsec / 10000000,
  2103. (long long)stime.tv_sec, stime.tv_nsec / 10000000,
  2104. calc_pctcpu / 100, rss);
  2105. }
  2106. tp->t_rocount = 0; /* so pending input will be retyped if BS */
  2107. }
  2108. /*
  2109. * Output char to tty; console putchar style.
  2110. */
  2111. int
  2112. tputchar(int c, struct tty *tp)
  2113. {
  2114. int s;
  2115. s = spltty();
  2116. if (ISSET(tp->t_state, TS_ISOPEN) == 0 ||
  2117. !(ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))) {
  2118. splx(s);
  2119. return (-1);
  2120. }
  2121. if (c == '\n')
  2122. (void)ttyoutput('\r', tp);
  2123. (void)ttyoutput(c, tp);
  2124. ttstart(tp);
  2125. splx(s);
  2126. return (0);
  2127. }
  2128. /*
  2129. * Sleep on chan, returning ERESTART if tty changed while we napped and
  2130. * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep. If
  2131. * the tty is revoked, restarting a pending call will redo validation done
  2132. * at the start of the call.
  2133. */
  2134. int
  2135. ttysleep(struct tty *tp, void *chan, int pri, char *wmesg, int timo)
  2136. {
  2137. int error;
  2138. short gen;
  2139. gen = tp->t_gen;
  2140. if ((error = tsleep(chan, pri, wmesg, timo)) != 0)
  2141. return (error);
  2142. return (tp->t_gen == gen ? 0 : ERESTART);
  2143. }
  2144. /*
  2145. * Initialise the global tty list.
  2146. */
  2147. void
  2148. tty_init(void)
  2149. {
  2150. TAILQ_INIT(&ttylist);
  2151. tty_count = 0;
  2152. }
  2153. /*
  2154. * Allocate a tty structure and its associated buffers, and attach it to the
  2155. * tty list.
  2156. */
  2157. struct tty *
  2158. ttymalloc(int baud)
  2159. {
  2160. struct tty *tp;
  2161. tp = malloc(sizeof(struct tty), M_TTYS, M_WAITOK|M_ZERO);
  2162. if (baud <= 115200)
  2163. tp->t_qlen = 1024;
  2164. else
  2165. tp->t_qlen = 8192;
  2166. clalloc(&tp->t_rawq, tp->t_qlen, 1);
  2167. clalloc(&tp->t_canq, tp->t_qlen, 1);
  2168. /* output queue doesn't need quoting */
  2169. clalloc(&tp->t_outq, tp->t_qlen, 0);
  2170. TAILQ_INSERT_TAIL(&ttylist, tp, tty_link);
  2171. ++tty_count;
  2172. timeout_set(&tp->t_rstrt_to, ttrstrt, tp);
  2173. return(tp);
  2174. }
  2175. /*
  2176. * Free a tty structure and its buffers, after removing it from the tty list.
  2177. */
  2178. void
  2179. ttyfree(struct tty *tp)
  2180. {
  2181. --tty_count;
  2182. #ifdef DIAGNOSTIC
  2183. if (tty_count < 0)
  2184. panic("ttyfree: tty_count < 0");
  2185. #endif
  2186. TAILQ_REMOVE(&ttylist, tp, tty_link);
  2187. ttkqflush(&tp->t_rsel.si_note);
  2188. ttkqflush(&tp->t_wsel.si_note);
  2189. clfree(&tp->t_rawq);
  2190. clfree(&tp->t_canq);
  2191. clfree(&tp->t_outq);
  2192. free(tp, M_TTYS, 0);
  2193. }
  2194. void
  2195. ttystats_init(struct itty **ttystats)
  2196. {
  2197. struct itty *itp;
  2198. struct tty *tp;
  2199. *ttystats = mallocarray(tty_count, sizeof(struct itty),
  2200. M_SYSCTL, M_WAITOK|M_ZERO);
  2201. for (tp = TAILQ_FIRST(&ttylist), itp = *ttystats; tp;
  2202. tp = TAILQ_NEXT(tp, tty_link), itp++) {
  2203. itp->t_dev = tp->t_dev;
  2204. itp->t_rawq_c_cc = tp->t_rawq.c_cc;
  2205. itp->t_canq_c_cc = tp->t_canq.c_cc;
  2206. itp->t_outq_c_cc = tp->t_outq.c_cc;
  2207. itp->t_hiwat = tp->t_hiwat;
  2208. itp->t_lowat = tp->t_lowat;
  2209. itp->t_column = tp->t_column;
  2210. itp->t_state = tp->t_state;
  2211. itp->t_session = tp->t_session;
  2212. if (tp->t_pgrp)
  2213. itp->t_pgrp_pg_id = tp->t_pgrp->pg_id;
  2214. else
  2215. itp->t_pgrp_pg_id = 0;
  2216. itp->t_line = tp->t_line;
  2217. }
  2218. }
  2219. /*
  2220. * Return tty-related information.
  2221. */
  2222. int
  2223. sysctl_tty(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
  2224. size_t newlen)
  2225. {
  2226. int err;
  2227. if (namelen != 1)
  2228. return (ENOTDIR);
  2229. switch (name[0]) {
  2230. case KERN_TTY_TKNIN:
  2231. return (sysctl_rdquad(oldp, oldlenp, newp, tk_nin));
  2232. case KERN_TTY_TKNOUT:
  2233. return (sysctl_rdquad(oldp, oldlenp, newp, tk_nout));
  2234. case KERN_TTY_TKRAWCC:
  2235. return (sysctl_rdquad(oldp, oldlenp, newp, tk_rawcc));
  2236. case KERN_TTY_TKCANCC:
  2237. return (sysctl_rdquad(oldp, oldlenp, newp, tk_cancc));
  2238. case KERN_TTY_INFO:
  2239. {
  2240. struct itty *ttystats;
  2241. ttystats_init(&ttystats);
  2242. err = sysctl_rdstruct(oldp, oldlenp, newp, ttystats,
  2243. tty_count * sizeof(struct itty));
  2244. free(ttystats, M_SYSCTL, 0);
  2245. return (err);
  2246. }
  2247. default:
  2248. #if NPTY > 0
  2249. return (sysctl_pty(name, namelen, oldp, oldlenp, newp, newlen));
  2250. #else
  2251. return (EOPNOTSUPP);
  2252. #endif
  2253. }
  2254. /* NOTREACHED */
  2255. }
  2256. void
  2257. ttytstamp(struct tty *tp, int octs, int ncts, int odcd, int ndcd)
  2258. {
  2259. int doit = 0;
  2260. if (ncts ^ octs)
  2261. doit |= ncts ? ISSET(tp->t_flags, TS_TSTAMPCTSSET) :
  2262. ISSET(tp->t_flags, TS_TSTAMPCTSCLR);
  2263. if (ndcd ^ odcd)
  2264. doit |= ndcd ? ISSET(tp->t_flags, TS_TSTAMPDCDSET) :
  2265. ISSET(tp->t_flags, TS_TSTAMPDCDCLR);
  2266. if (doit)
  2267. microtime(&tp->t_tv);
  2268. }