386BSD 0.0 development
[unix-history] / usr / src / sys.386bsd / kern / tty.c
CommitLineData
707530a2
WJ
1/*-
2 * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
3 * Copyright (c) 1991 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)tty.c 7.44 (Berkeley) 5/28/91
35 */
36static char rcsid[] = "$Header: /usr/bill/working/sys/kern/RCS/tty.c,v 1.3 92/01/21 21:31:11 william Exp $";
37
38#include "param.h"
39#include "systm.h"
40#include "ioctl.h"
41#define TTYDEFCHARS
42#include "tty.h"
43#undef TTYDEFCHARS
44#include "proc.h"
45#include "file.h"
46#include "conf.h"
47#include "dkstat.h"
48#include "uio.h"
49#include "kernel.h"
50#include "vnode.h"
51#include "syslog.h"
52
53#include "vm/vm.h"
54
55static int proc_compare __P((struct proc *p1, struct proc *p2));
56
57/* symbolic sleep message strings */
58char ttyin[] = "ttyin";
59char ttyout[] = "ttyout";
60char ttopen[] = "ttyopn";
61char ttclos[] = "ttycls";
62char ttybg[] = "ttybg";
63char ttybuf[] = "ttybuf";
64
65/*
66 * Table giving parity for characters and indicating
67 * character classes to tty driver. The 8th bit
68 * indicates parity, the 7th bit indicates the character
69 * is an alphameric or underscore (for ALTWERASE), and the
70 * low 6 bits indicate delay type. If the low 6 bits are 0
71 * then the character needs no special processing on output;
72 * classes other than 0 might be translated or (not currently)
73 * require delays.
74 */
75#define PARITY(c) (partab[c] & 0x80)
76#define ISALPHA(c) (partab[(c)&TTY_CHARMASK] & 0x40)
77#define CCLASSMASK 0x3f
78#define CCLASS(c) (partab[c] & CCLASSMASK)
79
80#define E 0x00 /* even parity */
81#define O 0x80 /* odd parity */
82#define ALPHA 0x40 /* alpha or underscore */
83
84#define NO ORDINARY
85#define NA ORDINARY|ALPHA
86#define CC CONTROL
87#define BS BACKSPACE
88#define NL NEWLINE
89#define TB TAB
90#define VT VTAB
91#define CR RETURN
92
93char partab[] = {
94 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
95 O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
96 O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
97 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
98 O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
99 E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
100 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
101 O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
102 O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
103 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
104 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
105 O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
106 E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
107 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
108 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
109 E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
110 /*
111 * "meta" chars; should be settable per charset.
112 * For now, treat all as normal characters.
113 */
114 NA, NA, NA, NA, NA, NA, NA, NA,
115 NA, NA, NA, NA, NA, NA, NA, NA,
116 NA, NA, NA, NA, NA, NA, NA, NA,
117 NA, NA, NA, NA, NA, NA, NA, NA,
118 NA, NA, NA, NA, NA, NA, NA, NA,
119 NA, NA, NA, NA, NA, NA, NA, NA,
120 NA, NA, NA, NA, NA, NA, NA, NA,
121 NA, NA, NA, NA, NA, NA, NA, NA,
122 NA, NA, NA, NA, NA, NA, NA, NA,
123 NA, NA, NA, NA, NA, NA, NA, NA,
124 NA, NA, NA, NA, NA, NA, NA, NA,
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};
131#undef NO
132#undef NA
133#undef CC
134#undef BS
135#undef NL
136#undef TB
137#undef VT
138#undef CR
139
140extern struct tty *constty; /* temporary virtual console */
141
142/*
143 * Is 'c' a line delimiter ("break" character)?
144 */
145#define ttbreakc(c) ((c) == '\n' || ((c) == cc[VEOF] || \
146 (c) == cc[VEOL] || (c) == cc[VEOL2]) && (c) != _POSIX_VDISABLE)
147
148ttychars(tp)
149 struct tty *tp;
150{
151
152 bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
153}
154
155/*
156 * Flush tty after output has drained.
157 */
158ttywflush(tp)
159 struct tty *tp;
160{
161 int error;
162
163 if ((error = ttywait(tp)) == 0)
164 ttyflush(tp, FREAD);
165 return (error);
166}
167
168/*
169 * Wait for output to drain.
170 */
171ttywait(tp)
172 register struct tty *tp;
173{
174 int error = 0, s = spltty();
175
176 while ((RB_LEN(&tp->t_out) || tp->t_state&TS_BUSY) &&
177 (tp->t_state&TS_CARR_ON || tp->t_cflag&CLOCAL) &&
178 tp->t_oproc) {
179 (*tp->t_oproc)(tp);
180 tp->t_state |= TS_ASLEEP;
181 if (error = ttysleep(tp, (caddr_t)&tp->t_out,
182 TTOPRI | PCATCH, ttyout, 0))
183 break;
184 }
185 splx(s);
186 return (error);
187}
188
189#define flushq(qq) { \
190 register struct ringb *r = qq; \
191 r->rb_hd = r->rb_tl; \
192}
193
194/*
195 * Flush TTY read and/or write queues,
196 * notifying anyone waiting.
197 */
198ttyflush(tp, rw)
199 register struct tty *tp;
200{
201 register s;
202
203 s = spltty();
204 if (rw & FREAD) {
205 flushq(&tp->t_can);
206 flushq(&tp->t_raw);
207 tp->t_rocount = 0;
208 tp->t_rocol = 0;
209 tp->t_state &= ~TS_LOCAL;
210 ttwakeup(tp);
211 }
212 if (rw & FWRITE) {
213 tp->t_state &= ~TS_TTSTOP;
214 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
215 flushq(&tp->t_out);
216 wakeup((caddr_t)&tp->t_out);
217 if (tp->t_wsel) {
218 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
219 tp->t_wsel = 0;
220 tp->t_state &= ~TS_WCOLL;
221 }
222 }
223 splx(s);
224}
225
226/*
227 * Send stop character on input overflow.
228 */
229ttyblock(tp)
230 register struct tty *tp;
231{
232 register x;
233 int rawcc, cancc;
234
235 rawcc = RB_LEN(&tp->t_raw);
236 cancc = RB_LEN(&tp->t_can);
237 x = rawcc + cancc;
238 if (rawcc > TTYHOG) {
239 ttyflush(tp, FREAD|FWRITE);
240 tp->t_state &= ~TS_TBLOCK;
241 }
242 /*
243 * Block further input iff:
244 * Current input > threshold AND input is available to user program
245 */
246 if (x >= TTYHOG/2 && (tp->t_state & TS_TBLOCK) == 0 &&
247 ((tp->t_lflag&ICANON) == 0) || (cancc > 0) &&
248 tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
249 if (putc(tp->t_cc[VSTOP], &tp->t_out) == 0) {
250 tp->t_state |= TS_TBLOCK;
251 ttstart(tp);
252 }
253 }
254}
255
256ttstart(tp)
257 struct tty *tp;
258{
259
260 if (tp->t_oproc) /* kludge for pty */
261 (*tp->t_oproc)(tp);
262}
263
264ttrstrt(tp) /* XXX */
265 struct tty *tp;
266{
267
268#ifdef DIAGNOSTIC
269 if (tp == 0)
270 panic("ttrstrt");
271#endif
272 tp->t_state &= ~TS_TIMEOUT;
273 ttstart(tp);
274}
275
276
277/*
278 * Common code for ioctls on tty devices.
279 * Called after line-discipline-specific ioctl
280 * has been called to do discipline-specific functions
281 * and/or reject any of these ioctl commands.
282 */
283/*ARGSUSED*/
284ttioctl(tp, com, data, flag)
285 register struct tty *tp;
286 caddr_t data;
287{
288 register struct proc *p = curproc; /* XXX */
289 extern int nldisp;
290 int s, error;
291
292 /*
293 * If the ioctl involves modification,
294 * hang if in the background.
295 */
296 switch (com) {
297
298 case TIOCSETD:
299 case TIOCFLUSH:
300 /*case TIOCSPGRP:*/
301 case TIOCSTI:
302 case TIOCSWINSZ:
303 case TIOCSETA:
304 case TIOCSETAW:
305 case TIOCSETAF:
306#ifdef COMPAT_43
307 case TIOCSETP:
308 case TIOCSETN:
309 case TIOCSETC:
310 case TIOCSLTC:
311 case TIOCLBIS:
312 case TIOCLBIC:
313 case TIOCLSET:
314 case OTIOCSETD:
315#endif
316 while (isbackground(curproc, tp) &&
317 p->p_pgrp->pg_jobc && (p->p_flag&SPPWAIT) == 0 &&
318 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
319 (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
320 pgsignal(p->p_pgrp, SIGTTOU, 1);
321 if (error = ttysleep(tp, (caddr_t)&lbolt,
322 TTOPRI | PCATCH, ttybg, 0))
323 return (error);
324 }
325 break;
326 }
327
328 /*
329 * Process the ioctl.
330 */
331 switch (com) {
332
333 /* get discipline number */
334 case TIOCGETD:
335 *(int *)data = tp->t_line;
336 break;
337
338 /* set line discipline */
339 case TIOCSETD: {
340 register int t = *(int *)data;
341 dev_t dev = tp->t_dev;
342
343 if ((unsigned)t >= nldisp)
344 return (ENXIO);
345 if (t != tp->t_line) {
346 s = spltty();
347 (*linesw[tp->t_line].l_close)(tp, flag);
348 error = (*linesw[t].l_open)(dev, tp);
349 if (error) {
350 (void)(*linesw[tp->t_line].l_open)(dev, tp);
351 splx(s);
352 return (error);
353 }
354 tp->t_line = t;
355 splx(s);
356 }
357 break;
358 }
359
360 /* prevent more opens on channel */
361 case TIOCEXCL:
362 tp->t_state |= TS_XCLUDE;
363 break;
364
365 case TIOCNXCL:
366 tp->t_state &= ~TS_XCLUDE;
367 break;
368
369 case TIOCHPCL:
370 tp->t_cflag |= HUPCL;
371 break;
372
373 case TIOCFLUSH: {
374 register int flags = *(int *)data;
375
376 if (flags == 0)
377 flags = FREAD|FWRITE;
378 else
379 flags &= FREAD|FWRITE;
380 ttyflush(tp, flags);
381 break;
382 }
383
384 case FIOASYNC:
385 if (*(int *)data)
386 tp->t_state |= TS_ASYNC;
387 else
388 tp->t_state &= ~TS_ASYNC;
389 break;
390
391 case FIONBIO:
392 break; /* XXX remove */
393
394 /* return number of characters immediately available */
395 case FIONREAD:
396 *(off_t *)data = ttnread(tp);
397 break;
398
399 case TIOCOUTQ:
400 *(int *)data = RB_LEN(&tp->t_out);
401 break;
402
403 case TIOCSTOP:
404 s = spltty();
405 if ((tp->t_state&TS_TTSTOP) == 0) {
406 tp->t_state |= TS_TTSTOP;
407 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
408 }
409 splx(s);
410 break;
411
412 case TIOCSTART:
413 s = spltty();
414 if ((tp->t_state&TS_TTSTOP) || (tp->t_lflag&FLUSHO)) {
415 tp->t_state &= ~TS_TTSTOP;
416 tp->t_lflag &= ~FLUSHO;
417 ttstart(tp);
418 }
419 splx(s);
420 break;
421
422 /*
423 * Simulate typing of a character at the terminal.
424 */
425 case TIOCSTI:
426 if (p->p_ucred->cr_uid && (flag & FREAD) == 0)
427 return (EPERM);
428 if (p->p_ucred->cr_uid && !isctty(p, tp))
429 return (EACCES);
430 (*linesw[tp->t_line].l_rint)(*(char *)data, tp);
431 break;
432
433 case TIOCGETA: {
434 struct termios *t = (struct termios *)data;
435
436 bcopy(&tp->t_termios, t, sizeof(struct termios));
437 break;
438 }
439
440 case TIOCSETA:
441 case TIOCSETAW:
442 case TIOCSETAF: {
443 register struct termios *t = (struct termios *)data;
444
445 s = spltty();
446 if (com == TIOCSETAW || com == TIOCSETAF) {
447 if (error = ttywait(tp)) {
448 splx(s);
449 return (error);
450 }
451 if (com == TIOCSETAF)
452 ttyflush(tp, FREAD);
453 }
454 if ((t->c_cflag&CIGNORE) == 0) {
455 /*
456 * set device hardware
457 */
458 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
459 splx(s);
460 return (error);
461 } else {
462 if ((tp->t_state&TS_CARR_ON) == 0 &&
463 (tp->t_cflag&CLOCAL) &&
464 (t->c_cflag&CLOCAL) == 0) {
465 tp->t_state &= ~TS_ISOPEN;
466 tp->t_state |= TS_WOPEN;
467 ttwakeup(tp);
468 }
469 tp->t_cflag = t->c_cflag;
470 tp->t_ispeed = t->c_ispeed;
471 tp->t_ospeed = t->c_ospeed;
472 }
473 ttsetwater(tp);
474 }
475 if (com != TIOCSETAF) {
476 if ((t->c_lflag&ICANON) != (tp->t_lflag&ICANON))
477 if (t->c_lflag&ICANON) {
478 tp->t_lflag |= PENDIN;
479 ttwakeup(tp);
480 }
481 else {
482 struct ringb tb;
483
484 catb(&tp->t_raw, &tp->t_can);
485 tb = tp->t_raw;
486 tp->t_raw = tp->t_can;
487 tp->t_can = tb;
488 }
489 }
490 tp->t_iflag = t->c_iflag;
491 tp->t_oflag = t->c_oflag;
492 /*
493 * Make the EXTPROC bit read only.
494 */
495 if (tp->t_lflag&EXTPROC)
496 t->c_lflag |= EXTPROC;
497 else
498 t->c_lflag &= ~EXTPROC;
499 tp->t_lflag = t->c_lflag;
500 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
501 splx(s);
502 break;
503 }
504
505 /*
506 * Set controlling terminal.
507 * Session ctty vnode pointer set in vnode layer.
508 */
509 case TIOCSCTTY:
510 if (!SESS_LEADER(p) ||
511 (p->p_session->s_ttyvp || tp->t_session) &&
512 (tp->t_session != p->p_session))
513 return (EPERM);
514 tp->t_session = p->p_session;
515 tp->t_pgrp = p->p_pgrp;
516 p->p_session->s_ttyp = tp;
517 p->p_flag |= SCTTY;
518 break;
519
520 /*
521 * Set terminal process group.
522 */
523 case TIOCSPGRP: {
524 register struct pgrp *pgrp = pgfind(*(int *)data);
525
526 if (!isctty(p, tp))
527 return (ENOTTY);
528 else if (pgrp == NULL || pgrp->pg_session != p->p_session)
529 return (EPERM);
530 tp->t_pgrp = pgrp;
531 break;
532 }
533
534 case TIOCGPGRP:
535 if (!isctty(p, tp))
536 return (ENOTTY);
537 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
538 break;
539
540 case TIOCSWINSZ:
541 if (bcmp((caddr_t)&tp->t_winsize, data,
542 sizeof (struct winsize))) {
543 tp->t_winsize = *(struct winsize *)data;
544 pgsignal(tp->t_pgrp, SIGWINCH, 1);
545 }
546 break;
547
548 case TIOCGWINSZ:
549 *(struct winsize *)data = tp->t_winsize;
550 break;
551
552 case TIOCCONS:
553 if (*(int *)data) {
554 if (constty && constty != tp &&
555 (constty->t_state & (TS_CARR_ON|TS_ISOPEN)) ==
556 (TS_CARR_ON|TS_ISOPEN))
557 return (EBUSY);
558#ifndef UCONSOLE
559 if (error = suser(p->p_ucred, &p->p_acflag))
560 return (error);
561#endif
562 constty = tp;
563 } else if (tp == constty)
564 constty = NULL;
565 break;
566
567 case TIOCDRAIN:
568 if (error = ttywait(tp))
569 return (error);
570 break;
571
572 default:
573#ifdef COMPAT_43
574 return (ttcompat(tp, com, data, flag));
575#else
576 return (-1);
577#endif
578 }
579 return (0);
580}
581
582ttnread(tp)
583 struct tty *tp;
584{
585 int nread = 0;
586
587 if (tp->t_lflag & PENDIN)
588 ttypend(tp);
589 nread = RB_LEN(&tp->t_can);
590 if ((tp->t_lflag & ICANON) == 0)
591 nread += RB_LEN(&tp->t_raw);
592 return (nread);
593}
594
595ttselect(dev, rw)
596 dev_t dev;
597 int rw;
598{
599 register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
600 int nread;
601 int s = spltty();
602
603 switch (rw) {
604
605 case FREAD:
606 nread = ttnread(tp);
607 if (nread > 0 ||
608 ((tp->t_cflag&CLOCAL) == 0 && (tp->t_state&TS_CARR_ON) == 0))
609 goto win;
610 if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
611 tp->t_state |= TS_RCOLL;
612 else
613 tp->t_rsel = curproc;
614 break;
615
616 case FWRITE:
617 if (RB_LEN(&tp->t_out) <= tp->t_lowat)
618 goto win;
619 if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait)
620 tp->t_state |= TS_WCOLL;
621 else
622 tp->t_wsel = curproc;
623 break;
624 }
625 splx(s);
626 return (0);
627win:
628 splx(s);
629 return (1);
630}
631
632/*
633 * Initial open of tty, or (re)entry to standard tty line discipline.
634 */
635ttyopen(dev, tp)
636 dev_t dev;
637 register struct tty *tp;
638{
639
640 tp->t_dev = dev;
641
642 tp->t_state &= ~TS_WOPEN;
643 if ((tp->t_state & TS_ISOPEN) == 0) {
644 tp->t_state |= TS_ISOPEN;
645 initrb(&tp->t_raw);
646 initrb(&tp->t_can);
647 initrb(&tp->t_out);
648 bzero((caddr_t)&tp->t_winsize, sizeof(tp->t_winsize));
649 }
650 return (0);
651}
652
653/*
654 * "close" a line discipline
655 */
656ttylclose(tp, flag)
657 struct tty *tp;
658 int flag;
659{
660
661 if (flag&IO_NDELAY)
662 ttyflush(tp, FREAD|FWRITE);
663 else
664 ttywflush(tp);
665}
666
667/*
668 * Handle close() on a tty line: flush and set to initial state,
669 * bumping generation number so that pending read/write calls
670 * can detect recycling of the tty.
671 */
672ttyclose(tp)
673 register struct tty *tp;
674{
675 if (constty == tp)
676 constty = NULL;
677 ttyflush(tp, FREAD|FWRITE);
678 tp->t_session = NULL;
679 tp->t_pgrp = NULL;
680 tp->t_state = 0;
681 tp->t_gen++;
682 return (0);
683}
684
685/*
686 * Handle modem control transition on a tty.
687 * Flag indicates new state of carrier.
688 * Returns 0 if the line should be turned off, otherwise 1.
689 */
690ttymodem(tp, flag)
691 register struct tty *tp;
692{
693
694 if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_lflag&MDMBUF)) {
695 /*
696 * MDMBUF: do flow control according to carrier flag
697 */
698 if (flag) {
699 tp->t_state &= ~TS_TTSTOP;
700 ttstart(tp);
701 } else if ((tp->t_state&TS_TTSTOP) == 0) {
702 tp->t_state |= TS_TTSTOP;
703 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
704 }
705 } else if (flag == 0) {
706 /*
707 * Lost carrier.
708 */
709 tp->t_state &= ~TS_CARR_ON;
710 if (tp->t_state&TS_ISOPEN && (tp->t_cflag&CLOCAL) == 0) {
711 if (tp->t_session && tp->t_session->s_leader)
712 psignal(tp->t_session->s_leader, SIGHUP);
713 ttyflush(tp, FREAD|FWRITE);
714 return (0);
715 }
716 } else {
717 /*
718 * Carrier now on.
719 */
720 tp->t_state |= TS_CARR_ON;
721 ttwakeup(tp);
722 }
723 return (1);
724}
725
726/*
727 * Default modem control routine (for other line disciplines).
728 * Return argument flag, to turn off device on carrier drop.
729 */
730nullmodem(tp, flag)
731 register struct tty *tp;
732 int flag;
733{
734
735 if (flag)
736 tp->t_state |= TS_CARR_ON;
737 else {
738 tp->t_state &= ~TS_CARR_ON;
739 if ((tp->t_cflag&CLOCAL) == 0) {
740 if (tp->t_session && tp->t_session->s_leader)
741 psignal(tp->t_session->s_leader, SIGHUP);
742 return (0);
743 }
744 }
745 return (1);
746}
747
748/*
749 * reinput pending characters after state switch
750 * call at spltty().
751 */
752ttypend(tp)
753 register struct tty *tp;
754{
755 struct ringb tb;
756 register c;
757
758 tp->t_lflag &= ~PENDIN;
759 tp->t_state |= TS_TYPEN;
760 tb = tp->t_raw;
761 tp->t_raw.rb_hd = tp->t_raw.rb_tl = tp->t_raw.rb_buf;
762 while ((c = getc(&tb)) >= 0)
763 ttyinput(c, tp);
764 tp->t_state &= ~TS_TYPEN;
765}
766
767/*
768 * Process input of a single character received on a tty.
769 */
770ttyinput(c, tp)
771 register c;
772 register struct tty *tp;
773{
774 register int iflag = tp->t_iflag;
775 register int lflag = tp->t_lflag;
776 register u_char *cc = tp->t_cc;
777 int i, err;
778
779 /*
780 * If input is pending take it first.
781 */
782 if (lflag&PENDIN)
783 ttypend(tp);
784 /*
785 * Gather stats.
786 */
787 tk_nin++;
788 if (lflag&ICANON) {
789 tk_cancc++;
790 tp->t_cancc++;
791 } else {
792 tk_rawcc++;
793 tp->t_rawcc++;
794 }
795 /*
796 * Handle exceptional conditions (break, parity, framing).
797 */
798 if (err = (c&TTY_ERRORMASK)) {
799 c &= ~TTY_ERRORMASK;
800 if (err&TTY_FE && !c) { /* break */
801 if (iflag&IGNBRK)
802 goto endcase;
803 else if (iflag&BRKINT && lflag&ISIG &&
804 (cc[VINTR] != _POSIX_VDISABLE))
805 c = cc[VINTR];
806 else if (iflag&PARMRK)
807 goto parmrk;
808 } else if ((err&TTY_PE && iflag&INPCK) || err&TTY_FE) {
809 if (iflag&IGNPAR)
810 goto endcase;
811 else if (iflag&PARMRK) {
812parmrk:
813 putc(0377|TTY_QUOTE, &tp->t_raw);
814 putc(0|TTY_QUOTE, &tp->t_raw);
815 putc(c|TTY_QUOTE, &tp->t_raw);
816 goto endcase;
817 } else
818 c = 0;
819 }
820 }
821 /*
822 * In tandem mode, check high water mark.
823 */
824 if (iflag&IXOFF)
825 ttyblock(tp);
826 if ((tp->t_state&TS_TYPEN) == 0 && (iflag&ISTRIP))
827 c &= ~0x80;
828 if ((tp->t_lflag&EXTPROC) == 0) {
829 /*
830 * Check for literal nexting very first
831 */
832 if (tp->t_state&TS_LNCH) {
833 c |= TTY_QUOTE;
834 tp->t_state &= ~TS_LNCH;
835 }
836 /*
837 * Scan for special characters. This code
838 * is really just a big case statement with
839 * non-constant cases. The bottom of the
840 * case statement is labeled ``endcase'', so goto
841 * it after a case match, or similar.
842 */
843
844 /*
845 * Control chars which aren't controlled
846 * by ICANON, ISIG, or IXON.
847 */
848 if (lflag&IEXTEN) {
849 if (CCEQ(cc[VLNEXT], c)) {
850 if (lflag&ECHO) {
851 if (lflag&ECHOE)
852 ttyoutstr("^\b", tp);
853 else
854 ttyecho(c, tp);
855 }
856 tp->t_state |= TS_LNCH;
857 goto endcase;
858 }
859 if (CCEQ(cc[VDISCARD], c)) {
860 if (lflag&FLUSHO)
861 tp->t_lflag &= ~FLUSHO;
862 else {
863 ttyflush(tp, FWRITE);
864 ttyecho(c, tp);
865 if (RB_LEN(&tp->t_raw) + RB_LEN(&tp->t_can))
866 ttyretype(tp);
867 tp->t_lflag |= FLUSHO;
868 }
869 goto startoutput;
870 }
871 }
872 /*
873 * Signals.
874 */
875 if (lflag&ISIG) {
876 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
877 if ((lflag&NOFLSH) == 0)
878 ttyflush(tp, FREAD|FWRITE);
879 ttyecho(c, tp);
880 pgsignal(tp->t_pgrp,
881 CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
882 goto endcase;
883 }
884 if (CCEQ(cc[VSUSP], c)) {
885 if ((lflag&NOFLSH) == 0)
886 ttyflush(tp, FREAD);
887 ttyecho(c, tp);
888 pgsignal(tp->t_pgrp, SIGTSTP, 1);
889 goto endcase;
890 }
891 }
892 /*
893 * Handle start/stop characters.
894 */
895 if (iflag&IXON) {
896 if (CCEQ(cc[VSTOP], c)) {
897 if ((tp->t_state&TS_TTSTOP) == 0) {
898 tp->t_state |= TS_TTSTOP;
899 (*cdevsw[major(tp->t_dev)].d_stop)(tp,
900 0);
901 return;
902 }
903 if (!CCEQ(cc[VSTART], c))
904 return;
905 /*
906 * if VSTART == VSTOP then toggle
907 */
908 goto endcase;
909 }
910 if (CCEQ(cc[VSTART], c))
911 goto restartoutput;
912 }
913 /*
914 * IGNCR, ICRNL, & INLCR
915 */
916 if (c == '\r') {
917 if (iflag&IGNCR)
918 goto endcase;
919 else if (iflag&ICRNL)
920 c = '\n';
921 } else if (c == '\n' && iflag&INLCR)
922 c = '\r';
923 }
924 if ((tp->t_lflag&EXTPROC) == 0 && lflag&ICANON) {
925 /*
926 * From here on down canonical mode character
927 * processing takes place.
928 */
929 /*
930 * erase (^H / ^?)
931 */
932 if (CCEQ(cc[VERASE], c)) {
933 if (RB_LEN(&tp->t_raw))
934 ttyrub(unputc(&tp->t_raw), tp);
935 goto endcase;
936 }
937 /*
938 * kill (^U)
939 */
940 if (CCEQ(cc[VKILL], c)) {
941 if (lflag&ECHOKE && RB_LEN(&tp->t_raw) == tp->t_rocount &&
942 (lflag&ECHOPRT) == 0) {
943 while (RB_LEN(&tp->t_raw))
944 ttyrub(unputc(&tp->t_raw), tp);
945 } else {
946 ttyecho(c, tp);
947 if (lflag&ECHOK || lflag&ECHOKE)
948 ttyecho('\n', tp);
949 while (getc(&tp->t_raw) > 0)
950 ;
951 tp->t_rocount = 0;
952 }
953 tp->t_state &= ~TS_LOCAL;
954 goto endcase;
955 }
956 /*
957 * word erase (^W)
958 */
959 if (CCEQ(cc[VWERASE], c)) {
960 int ctype;
961 int alt = lflag&ALTWERASE;
962
963 /*
964 * erase whitespace
965 */
966 while ((c = unputc(&tp->t_raw)) == ' ' || c == '\t')
967 ttyrub(c, tp);
968 if (c == -1)
969 goto endcase;
970 /*
971 * erase last char of word and remember the
972 * next chars type (for ALTWERASE)
973 */
974 ttyrub(c, tp);
975 c = unputc(&tp->t_raw);
976 if (c == -1)
977 goto endcase;
978 ctype = ISALPHA(c);
979 /*
980 * erase rest of word
981 */
982 do {
983 ttyrub(c, tp);
984 c = unputc(&tp->t_raw);
985 if (c == -1)
986 goto endcase;
987 } while (c != ' ' && c != '\t' &&
988 (alt == 0 || ISALPHA(c) == ctype));
989 (void) putc(c, &tp->t_raw);
990 goto endcase;
991 }
992 /*
993 * reprint line (^R)
994 */
995 if (CCEQ(cc[VREPRINT], c)) {
996 ttyretype(tp);
997 goto endcase;
998 }
999 /*
1000 * ^T - kernel info and generate SIGINFO
1001 */
1002 if (CCEQ(cc[VSTATUS], c)) {
1003 pgsignal(tp->t_pgrp, SIGINFO, 1);
1004 if ((lflag&NOKERNINFO) == 0)
1005 ttyinfo(tp);
1006 goto endcase;
1007 }
1008 }
1009 /*
1010 * Check for input buffer overflow
1011 */
1012 if (RB_LEN(&tp->t_raw)+RB_LEN(&tp->t_can) >= TTYHOG) {
1013 if (iflag&IMAXBEL) {
1014 if (RB_LEN(&tp->t_out) < tp->t_hiwat)
1015 (void) ttyoutput(CTRL('g'), tp);
1016 } else
1017 ttyflush(tp, FREAD | FWRITE);
1018 goto endcase;
1019 }
1020 /*
1021 * Put data char in q for user and
1022 * wakeup on seeing a line delimiter.
1023 */
1024 if (putc(c, &tp->t_raw) >= 0) {
1025 if ((lflag&ICANON) == 0) {
1026 ttwakeup(tp);
1027 ttyecho(c, tp);
1028 goto endcase;
1029 }
1030 if (ttbreakc(c)) {
1031 tp->t_rocount = 0;
1032 catb(&tp->t_raw, &tp->t_can);
1033 ttwakeup(tp);
1034 } else if (tp->t_rocount++ == 0)
1035 tp->t_rocol = tp->t_col;
1036 if (tp->t_state&TS_ERASE) {
1037 /*
1038 * end of prterase \.../
1039 */
1040 tp->t_state &= ~TS_ERASE;
1041 (void) ttyoutput('/', tp);
1042 }
1043 i = tp->t_col;
1044 ttyecho(c, tp);
1045 if (CCEQ(cc[VEOF], c) && lflag&ECHO) {
1046 /*
1047 * Place the cursor over the '^' of the ^D.
1048 */
1049 i = MIN(2, tp->t_col - i);
1050 while (i > 0) {
1051 (void) ttyoutput('\b', tp);
1052 i--;
1053 }
1054 }
1055 }
1056endcase:
1057 /*
1058 * IXANY means allow any character to restart output.
1059 */
1060 if ((tp->t_state&TS_TTSTOP) && (iflag&IXANY) == 0 &&
1061 cc[VSTART] != cc[VSTOP])
1062 return;
1063restartoutput:
1064 tp->t_state &= ~TS_TTSTOP;
1065 tp->t_lflag &= ~FLUSHO;
1066startoutput:
1067 ttstart(tp);
1068}
1069
1070/*
1071 * Output a single character on a tty, doing output processing
1072 * as needed (expanding tabs, newline processing, etc.).
1073 * Returns < 0 if putc succeeds, otherwise returns char to resend.
1074 * Must be recursive.
1075 */
1076ttyoutput(c, tp)
1077 register c;
1078 register struct tty *tp;
1079{
1080 register int col;
1081 register long oflag = tp->t_oflag;
1082
1083 if ((oflag&OPOST) == 0) {
1084 if (tp->t_lflag&FLUSHO)
1085 return (-1);
1086 if (putc(c, &tp->t_out))
1087 return (c);
1088 tk_nout++;
1089 tp->t_outcc++;
1090 return (-1);
1091 }
1092 c &= TTY_CHARMASK;
1093 /*
1094 * Do tab expansion if OXTABS is set.
1095 * Special case if we have external processing, we don't
1096 * do the tab expansion because we'll probably get it
1097 * wrong. If tab expansion needs to be done, let it
1098 * happen externally.
1099 */
1100 if (c == '\t' && oflag&OXTABS && (tp->t_lflag&EXTPROC) == 0) {
1101 register int s;
1102
1103 c = 8 - (tp->t_col&7);
1104 if ((tp->t_lflag&FLUSHO) == 0) {
1105 int i;
1106
1107 s = spltty(); /* don't interrupt tabs */
1108#ifdef was
1109 c -= b_to_q(" ", c, &tp->t_outq);
1110#else
1111 i = min (c, RB_CONTIGPUT(&tp->t_out));
1112 bcopy(" ", tp->t_out.rb_tl, i);
1113 tp->t_out.rb_tl =
1114 RB_ROLLOVER(&tp->t_out, tp->t_out.rb_tl+i);
1115 i = min (c-i, RB_CONTIGPUT(&tp->t_out));
1116
1117 /* off end and still have space? */
1118 if (i) {
1119 bcopy(" ", tp->t_out.rb_tl, i);
1120 tp->t_out.rb_tl =
1121 RB_ROLLOVER(&tp->t_out, tp->t_out.rb_tl+i);
1122 }
1123#endif
1124 tk_nout += c;
1125 tp->t_outcc += c;
1126 splx(s);
1127 }
1128 tp->t_col += c;
1129 return (c ? -1 : '\t');
1130 }
1131 if (c == CEOT && oflag&ONOEOT)
1132 return (-1);
1133 tk_nout++;
1134 tp->t_outcc++;
1135 /*
1136 * Newline translation: if ONLCR is set,
1137 * translate newline into "\r\n".
1138 */
1139 if (c == '\n' && (tp->t_oflag&ONLCR) && ttyoutput('\r', tp) >= 0)
1140 return (c);
1141 if ((tp->t_lflag&FLUSHO) == 0 && putc(c, &tp->t_out))
1142 return (c);
1143
1144 col = tp->t_col;
1145 switch (CCLASS(c)) {
1146
1147 case ORDINARY:
1148 col++;
1149
1150 case CONTROL:
1151 break;
1152
1153 case BACKSPACE:
1154 if (col > 0)
1155 col--;
1156 break;
1157
1158 case NEWLINE:
1159 col = 0;
1160 break;
1161
1162 case TAB:
1163 col = (col + 8) &~ 0x7;
1164 break;
1165
1166 case RETURN:
1167 col = 0;
1168 }
1169 tp->t_col = col;
1170 return (-1);
1171}
1172
1173/*
1174 * Process a read call on a tty device.
1175 */
1176ttread(tp, uio, flag)
1177 register struct tty *tp;
1178 struct uio *uio;
1179{
1180 register struct ringb *qp;
1181 register int c;
1182 register long lflag;
1183 register u_char *cc = tp->t_cc;
1184 register struct proc *p = curproc;
1185 int s, first, error = 0;
1186
1187loop:
1188 lflag = tp->t_lflag;
1189 s = spltty();
1190 /*
1191 * take pending input first
1192 */
1193 if (lflag&PENDIN)
1194 ttypend(tp);
1195 splx(s);
1196
1197 /*
1198 * Hang process if it's in the background.
1199 */
1200 if (isbackground(p, tp)) {
1201 if ((p->p_sigignore & sigmask(SIGTTIN)) ||
1202 (p->p_sigmask & sigmask(SIGTTIN)) ||
1203 p->p_flag&SPPWAIT || p->p_pgrp->pg_jobc == 0)
1204 return (EIO);
1205 pgsignal(p->p_pgrp, SIGTTIN, 1);
1206 if (error = ttysleep(tp, (caddr_t)&lbolt, TTIPRI | PCATCH,
1207 ttybg, 0))
1208 return (error);
1209 goto loop;
1210 }
1211
1212 /*
1213 * If canonical, use the canonical queue,
1214 * else use the raw queue.
1215 */
1216 qp = lflag&ICANON ? &tp->t_can : &tp->t_raw;
1217
1218 /*
1219 * If there is no input, sleep on rawq
1220 * awaiting hardware receipt and notification.
1221 * If we have data, we don't need to check for carrier.
1222 */
1223 s = spltty();
1224 if (RB_LEN(qp) <= 0) {
1225 int carrier;
1226
1227 carrier = (tp->t_state&TS_CARR_ON) || (tp->t_cflag&CLOCAL);
1228 if (!carrier && tp->t_state&TS_ISOPEN) {
1229 splx(s);
1230 return (0); /* EOF */
1231 }
1232 if (flag & IO_NDELAY) {
1233 splx(s);
1234 return (EWOULDBLOCK);
1235 }
1236 error = ttysleep(tp, (caddr_t)&tp->t_raw, TTIPRI | PCATCH,
1237 carrier ? ttyin : ttopen, 0);
1238 splx(s);
1239 if (error)
1240 return (error);
1241 goto loop;
1242 }
1243 splx(s);
1244
1245 /*
1246 * Input present, check for input mapping and processing.
1247 */
1248 first = 1;
1249 while ((c = getc(qp)) >= 0) {
1250 /*
1251 * delayed suspend (^Y)
1252 */
1253 if (CCEQ(cc[VDSUSP], c) && lflag&ISIG) {
1254 pgsignal(tp->t_pgrp, SIGTSTP, 1);
1255 if (first) {
1256 if (error = ttysleep(tp, (caddr_t)&lbolt,
1257 TTIPRI | PCATCH, ttybg, 0))
1258 break;
1259 goto loop;
1260 }
1261 break;
1262 }
1263 /*
1264 * Interpret EOF only in canonical mode.
1265 */
1266 if (CCEQ(cc[VEOF], c) && lflag&ICANON)
1267 break;
1268 /*
1269 * Give user character.
1270 */
1271 error = ureadc(c, uio);
1272 if (error)
1273 break;
1274 if (uio->uio_resid == 0)
1275 break;
1276 /*
1277 * In canonical mode check for a "break character"
1278 * marking the end of a "line of input".
1279 */
1280 if (lflag&ICANON && ttbreakc(c))
1281 break;
1282 first = 0;
1283 }
1284 /*
1285 * Look to unblock output now that (presumably)
1286 * the input queue has gone down.
1287 */
1288 if (tp->t_state&TS_TBLOCK && RB_LEN(&tp->t_raw) < TTYHOG/5) {
1289 if (cc[VSTART] != _POSIX_VDISABLE &&
1290 putc(cc[VSTART], &tp->t_out) == 0) {
1291 tp->t_state &= ~TS_TBLOCK;
1292 ttstart(tp);
1293 }
1294 }
1295 return (error);
1296}
1297
1298/*
1299 * Check the output queue on tp for space for a kernel message
1300 * (from uprintf/tprintf). Allow some space over the normal
1301 * hiwater mark so we don't lose messages due to normal flow
1302 * control, but don't let the tty run amok.
1303 * Sleeps here are not interruptible, but we return prematurely
1304 * if new signals come in.
1305 */
1306ttycheckoutq(tp, wait)
1307 register struct tty *tp;
1308 int wait;
1309{
1310 int hiwat, s, oldsig;
1311 extern int wakeup();
1312
1313 hiwat = tp->t_hiwat;
1314 s = spltty();
1315 oldsig = curproc->p_sig;
1316 if (RB_LEN(&tp->t_out) > hiwat + 200)
1317 while (RB_LEN(&tp->t_out) > hiwat) {
1318 ttstart(tp);
1319 if (wait == 0 || curproc->p_sig != oldsig) {
1320 splx(s);
1321 return (0);
1322 }
1323 timeout(wakeup, (caddr_t)&tp->t_out, hz);
1324 tp->t_state |= TS_ASLEEP;
1325 sleep((caddr_t)&tp->t_out, PZERO - 1);
1326 }
1327 splx(s);
1328 return (1);
1329}
1330
1331/*
1332 * Process a write call on a tty device.
1333 */
1334ttwrite(tp, uio, flag)
1335 register struct tty *tp;
1336 register struct uio *uio;
1337{
1338 register char *cp;
1339 register int cc = 0, ce;
1340 register struct proc *p = curproc;
1341 int i, hiwat, cnt, error, s;
1342 char obuf[OBUFSIZ];
1343
1344 hiwat = tp->t_hiwat;
1345 cnt = uio->uio_resid;
1346 error = 0;
1347loop:
1348 s = spltty();
1349 if ((tp->t_state&TS_CARR_ON) == 0 && (tp->t_cflag&CLOCAL) == 0) {
1350 if (tp->t_state&TS_ISOPEN) {
1351 splx(s);
1352 return (EIO);
1353 } else if (flag & IO_NDELAY) {
1354 splx(s);
1355 error = EWOULDBLOCK;
1356 goto out;
1357 } else {
1358 /*
1359 * sleep awaiting carrier
1360 */
1361 error = ttysleep(tp, (caddr_t)&tp->t_raw,
1362 TTIPRI | PCATCH,ttopen, 0);
1363 splx(s);
1364 if (error)
1365 goto out;
1366 goto loop;
1367 }
1368 }
1369 splx(s);
1370 /*
1371 * Hang the process if it's in the background.
1372 */
1373 if (isbackground(p, tp) &&
1374 tp->t_lflag&TOSTOP && (p->p_flag&SPPWAIT) == 0 &&
1375 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
1376 (p->p_sigmask & sigmask(SIGTTOU)) == 0 &&
1377 p->p_pgrp->pg_jobc) {
1378 pgsignal(p->p_pgrp, SIGTTOU, 1);
1379 if (error = ttysleep(tp, (caddr_t)&lbolt, TTIPRI | PCATCH,
1380 ttybg, 0))
1381 goto out;
1382 goto loop;
1383 }
1384 /*
1385 * Process the user's data in at most OBUFSIZ
1386 * chunks. Perform any output translation.
1387 * Keep track of high water mark, sleep on overflow
1388 * awaiting device aid in acquiring new space.
1389 */
1390 while (uio->uio_resid > 0 || cc > 0) {
1391 if (tp->t_lflag&FLUSHO) {
1392 uio->uio_resid = 0;
1393 return (0);
1394 }
1395 if (RB_LEN(&tp->t_out) > hiwat)
1396 goto ovhiwat;
1397 /*
1398 * Grab a hunk of data from the user,
1399 * unless we have some leftover from last time.
1400 */
1401 if (cc == 0) {
1402 cc = min(uio->uio_resid, OBUFSIZ);
1403 cp = obuf;
1404 error = uiomove(cp, cc, uio);
1405 if (error) {
1406 cc = 0;
1407 break;
1408 }
1409 }
1410 /*
1411 * If nothing fancy need be done, grab those characters we
1412 * can handle without any of ttyoutput's processing and
1413 * just transfer them to the output q. For those chars
1414 * which require special processing (as indicated by the
1415 * bits in partab), call ttyoutput. After processing
1416 * a hunk of data, look for FLUSHO so ^O's will take effect
1417 * immediately.
1418 */
1419 while (cc > 0) {
1420 if ((tp->t_oflag&OPOST) == 0)
1421 ce = cc;
1422 else {
1423 ce = cc - scanc((unsigned)cc, (u_char *)cp,
1424 (u_char *)partab, CCLASSMASK);
1425 /*
1426 * If ce is zero, then we're processing
1427 * a special character through ttyoutput.
1428 */
1429 if (ce == 0) {
1430 tp->t_rocount = 0;
1431 if (ttyoutput(*cp, tp) >= 0) {
1432 /* no c-lists, wait a bit */
1433 ttstart(tp);
1434 if (error = ttysleep(tp,
1435 (caddr_t)&lbolt,
1436 TTOPRI | PCATCH, ttybuf, 0))
1437 break;
1438 goto loop;
1439 }
1440 cp++, cc--;
1441 if ((tp->t_lflag&FLUSHO) ||
1442 RB_LEN(&tp->t_out) > hiwat)
1443 goto ovhiwat;
1444 continue;
1445 }
1446 }
1447 /*
1448 * A bunch of normal characters have been found,
1449 * transfer them en masse to the output queue and
1450 * continue processing at the top of the loop.
1451 * If there are any further characters in this
1452 * <= OBUFSIZ chunk, the first should be a character
1453 * requiring special handling by ttyoutput.
1454 */
1455 tp->t_rocount = 0;
1456#ifdef was
1457 i = b_to_q(cp, ce, &tp->t_outq);
1458#else
1459 i = min (ce, RB_CONTIGPUT(&tp->t_out));
1460 bcopy(cp, tp->t_out.rb_tl, i);
1461 tp->t_out.rb_tl = RB_ROLLOVER(&tp->t_out, tp->t_out.rb_tl+i);
1462 i = ce - i;
1463#endif
1464 ce -= i;
1465 tp->t_col += ce;
1466 cp += ce, cc -= ce, tk_nout += ce;
1467 tp->t_outcc += ce;
1468 if (i > 0) {
1469 /* out of space, wait a bit */
1470 ttstart(tp);
1471 if (error = ttysleep(tp, (caddr_t)&lbolt,
1472 TTOPRI | PCATCH, ttybuf, 0))
1473 break;
1474 goto loop;
1475 }
1476 if (tp->t_lflag&FLUSHO || RB_LEN(&tp->t_out) > hiwat)
1477 break;
1478 }
1479 ttstart(tp);
1480 }
1481out:
1482 /*
1483 * If cc is nonzero, we leave the uio structure inconsistent,
1484 * as the offset and iov pointers have moved forward,
1485 * but it doesn't matter (the call will either return short
1486 * or restart with a new uio).
1487 */
1488 uio->uio_resid += cc;
1489 return (error);
1490
1491ovhiwat:
1492 ttstart(tp);
1493 s = spltty();
1494 /*
1495 * This can only occur if FLUSHO is set in t_lflag,
1496 * or if ttstart/oproc is synchronous (or very fast).
1497 */
1498 if (RB_LEN(&tp->t_out) <= hiwat) {
1499 splx(s);
1500 goto loop;
1501 }
1502 if (flag & IO_NDELAY) {
1503 splx(s);
1504 uio->uio_resid += cc;
1505 if (uio->uio_resid == cnt)
1506 return (EWOULDBLOCK);
1507 return (0);
1508 }
1509 tp->t_state |= TS_ASLEEP;
1510 error = ttysleep(tp, (caddr_t)&tp->t_out, TTOPRI | PCATCH, ttyout, 0);
1511 splx(s);
1512 if (error)
1513 goto out;
1514 goto loop;
1515}
1516
1517/*
1518 * Rubout one character from the rawq of tp
1519 * as cleanly as possible.
1520 */
1521ttyrub(c, tp)
1522 register c;
1523 register struct tty *tp;
1524{
1525 char *cp;
1526 register int savecol;
1527 int s;
1528
1529 if ((tp->t_lflag&ECHO) == 0 || (tp->t_lflag&EXTPROC))
1530 return;
1531 tp->t_lflag &= ~FLUSHO;
1532 if (tp->t_lflag&ECHOE) {
1533 if (tp->t_rocount == 0) {
1534 /*
1535 * Screwed by ttwrite; retype
1536 */
1537 ttyretype(tp);
1538 return;
1539 }
1540 if (c == ('\t'|TTY_QUOTE) || c == ('\n'|TTY_QUOTE))
1541 ttyrubo(tp, 2);
1542 else switch (CCLASS(c &= TTY_CHARMASK)) {
1543
1544 case ORDINARY:
1545 ttyrubo(tp, 1);
1546 break;
1547
1548 case VTAB:
1549 case BACKSPACE:
1550 case CONTROL:
1551 case RETURN:
1552 case NEWLINE:
1553 if (tp->t_lflag&ECHOCTL)
1554 ttyrubo(tp, 2);
1555 break;
1556
1557 case TAB: {
1558 int c;
1559
1560 if (tp->t_rocount < RB_LEN(&tp->t_raw)) {
1561 ttyretype(tp);
1562 return;
1563 }
1564 s = spltty();
1565 savecol = tp->t_col;
1566 tp->t_state |= TS_CNTTB;
1567 tp->t_lflag |= FLUSHO;
1568 tp->t_col = tp->t_rocol;
1569 cp = tp->t_raw.rb_hd;
1570 for (c = nextc(&tp->t_raw, &cp); c ;
1571 c = nextc(&tp->t_raw, cp))
1572 ttyecho(c, tp);
1573 tp->t_lflag &= ~FLUSHO;
1574 tp->t_state &= ~TS_CNTTB;
1575 splx(s);
1576 /*
1577 * savecol will now be length of the tab
1578 */
1579 savecol -= tp->t_col;
1580 tp->t_col += savecol;
1581 if (savecol > 8)
1582 savecol = 8; /* overflow screw */
1583 while (--savecol >= 0)
1584 (void) ttyoutput('\b', tp);
1585 break;
1586 }
1587
1588 default:
1589 /* XXX */
1590 printf("ttyrub: would panic c = %d, val = %d\n",
1591 c, CCLASS(c));
1592 /*panic("ttyrub");*/
1593 }
1594 } else if (tp->t_lflag&ECHOPRT) {
1595 if ((tp->t_state&TS_ERASE) == 0) {
1596 (void) ttyoutput('\\', tp);
1597 tp->t_state |= TS_ERASE;
1598 }
1599 ttyecho(c, tp);
1600 } else
1601 ttyecho(tp->t_cc[VERASE], tp);
1602 tp->t_rocount--;
1603}
1604
1605/*
1606 * Crt back over cnt chars perhaps
1607 * erasing them.
1608 */
1609ttyrubo(tp, cnt)
1610 register struct tty *tp;
1611 int cnt;
1612{
1613
1614 while (--cnt >= 0)
1615 ttyoutstr("\b \b", tp);
1616}
1617
1618/*
1619 * Reprint the rawq line.
1620 * We assume c_cc has already been checked.
1621 */
1622ttyretype(tp)
1623 register struct tty *tp;
1624{
1625 char *cp;
1626 int s, c;
1627
1628 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
1629 ttyecho(tp->t_cc[VREPRINT], tp);
1630 (void) ttyoutput('\n', tp);
1631
1632 s = spltty();
1633 cp = tp->t_can.rb_hd;
1634 for (c = nextc(&tp->t_can, &cp); c ; c = nextc(&tp->t_can, cp))
1635 ttyecho(c, tp);
1636 cp = tp->t_raw.rb_hd;
1637 for (c = nextc(&tp->t_raw, &cp); c ; c = nextc(&tp->t_raw, cp))
1638 ttyecho(c, tp);
1639 tp->t_state &= ~TS_ERASE;
1640 splx(s);
1641
1642 tp->t_rocount = RB_LEN(&tp->t_raw);
1643 tp->t_rocol = 0;
1644}
1645
1646/*
1647 * Echo a typed character to the terminal.
1648 */
1649ttyecho(c, tp)
1650 register c;
1651 register struct tty *tp;
1652{
1653 if ((tp->t_state&TS_CNTTB) == 0)
1654 tp->t_lflag &= ~FLUSHO;
1655 if (((tp->t_lflag&ECHO) == 0 &&
1656 ((tp->t_lflag&ECHONL) == 0 || c == '\n')) || (tp->t_lflag&EXTPROC))
1657 return;
1658 if (tp->t_lflag&ECHOCTL) {
1659 if ((c&TTY_CHARMASK) <= 037 && c != '\t' && c != '\n' ||
1660 c == 0177) {
1661 (void) ttyoutput('^', tp);
1662 c &= TTY_CHARMASK;
1663 if (c == 0177)
1664 c = '?';
1665 else
1666 c += 'A' - 1;
1667 }
1668 }
1669 (void) ttyoutput(c, tp);
1670}
1671
1672/*
1673 * send string cp to tp
1674 */
1675ttyoutstr(cp, tp)
1676 register char *cp;
1677 register struct tty *tp;
1678{
1679 register char c;
1680
1681 while (c = *cp++)
1682 (void) ttyoutput(c, tp);
1683}
1684
1685/*
1686 * Wake up any readers on a tty.
1687 */
1688ttwakeup(tp)
1689 register struct tty *tp;
1690{
1691
1692 if (tp->t_rsel) {
1693 selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);
1694 tp->t_state &= ~TS_RCOLL;
1695 tp->t_rsel = 0;
1696 }
1697 if (tp->t_state & TS_ASYNC)
1698 pgsignal(tp->t_pgrp, SIGIO, 1);
1699 wakeup((caddr_t)&tp->t_raw);
1700}
1701
1702/*
1703 * Look up a code for a specified speed in a conversion table;
1704 * used by drivers to map software speed values to hardware parameters.
1705 */
1706ttspeedtab(speed, table)
1707 register struct speedtab *table;
1708{
1709
1710 for ( ; table->sp_speed != -1; table++)
1711 if (table->sp_speed == speed)
1712 return (table->sp_code);
1713 return (-1);
1714}
1715
1716/*
1717 * set tty hi and low water marks
1718 *
1719 * Try to arrange the dynamics so there's about one second
1720 * from hi to low water.
1721 *
1722 */
1723ttsetwater(tp)
1724 struct tty *tp;
1725{
1726 register cps = tp->t_ospeed / 10;
1727 register x;
1728
1729#define clamp(x, h, l) ((x)>h ? h : ((x)<l) ? l : (x))
1730 tp->t_lowat = x = clamp(cps/2, TTMAXLOWAT, TTMINLOWAT);
1731 x += cps;
1732 x = clamp(x, TTMAXHIWAT, TTMINHIWAT);
1733 tp->t_hiwat = roundup(x, CBSIZE);
1734#undef clamp
1735}
1736
1737/*
1738 * Report on state of foreground process group.
1739 */
1740ttyinfo(tp)
1741 register struct tty *tp;
1742{
1743 register struct proc *p, *pick;
1744 struct timeval utime, stime;
1745 int tmp;
1746
1747 if (ttycheckoutq(tp,0) == 0)
1748 return;
1749
1750 /* Print load average. */
1751 tmp = (averunnable[0] * 100 + FSCALE / 2) >> FSHIFT;
1752 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
1753
1754 if (tp->t_session == NULL)
1755 ttyprintf(tp, "not a controlling terminal\n");
1756 else if (tp->t_pgrp == NULL)
1757 ttyprintf(tp, "no foreground process group\n");
1758 else if ((p = tp->t_pgrp->pg_mem) == NULL)
1759 ttyprintf(tp, "empty foreground process group\n");
1760 else {
1761 /* Pick interesting process. */
1762 for (pick = NULL; p != NULL; p = p->p_pgrpnxt)
1763 if (proc_compare(pick, p))
1764 pick = p;
1765
1766 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
1767 pick->p_stat == SRUN ? "running" :
1768 pick->p_wmesg ? pick->p_wmesg : "iowait");
1769
1770 /*
1771 * Lock out clock if process is running; get user/system
1772 * cpu time.
1773 */
1774 if (curproc == pick)
1775 tmp = splclock();
1776 utime = pick->p_utime;
1777 stime = pick->p_stime;
1778 if (curproc == pick)
1779 splx(tmp);
1780
1781 /* Print user time. */
1782 ttyprintf(tp, "%d.%02du ",
1783 utime.tv_sec, (utime.tv_usec + 5000) / 10000);
1784
1785 /* Print system time. */
1786 ttyprintf(tp, "%d.%02ds ",
1787 stime.tv_sec, (stime.tv_usec + 5000) / 10000);
1788
1789#define pgtok(a) (((a) * NBPG) / 1024)
1790 /* Print percentage cpu, resident set size. */
1791 tmp = pick->p_pctcpu * 10000 + FSCALE / 2 >> FSHIFT;
1792 ttyprintf(tp, "%d%% %dk\n",
1793 tmp / 100, pgtok(pick->p_vmspace->vm_rssize));
1794 }
1795 tp->t_rocount = 0; /* so pending input will be retyped if BS */
1796}
1797
1798/*
1799 * Returns 1 if p2 is "better" than p1
1800 *
1801 * The algorithm for picking the "interesting" process is thus:
1802 *
1803 * 1) (Only foreground processes are eligable - implied)
1804 * 2) Runnable processes are favored over anything
1805 * else. The runner with the highest cpu
1806 * utilization is picked (p_cpu). Ties are
1807 * broken by picking the highest pid.
1808 * 3 Next, the sleeper with the shortest sleep
1809 * time is favored. With ties, we pick out
1810 * just "short-term" sleepers (SSINTR == 0).
1811 * Further ties are broken by picking the highest
1812 * pid.
1813 *
1814 */
1815#define isrun(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
1816#define TESTAB(a, b) ((a)<<1 | (b))
1817#define ONLYA 2
1818#define ONLYB 1
1819#define BOTH 3
1820
1821static int
1822proc_compare(p1, p2)
1823 register struct proc *p1, *p2;
1824{
1825
1826 if (p1 == NULL)
1827 return (1);
1828 /*
1829 * see if at least one of them is runnable
1830 */
1831 switch (TESTAB(isrun(p1), isrun(p2))) {
1832 case ONLYA:
1833 return (0);
1834 case ONLYB:
1835 return (1);
1836 case BOTH:
1837 /*
1838 * tie - favor one with highest recent cpu utilization
1839 */
1840 if (p2->p_cpu > p1->p_cpu)
1841 return (1);
1842 if (p1->p_cpu > p2->p_cpu)
1843 return (0);
1844 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1845 }
1846 /*
1847 * weed out zombies
1848 */
1849 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
1850 case ONLYA:
1851 return (1);
1852 case ONLYB:
1853 return (0);
1854 case BOTH:
1855 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1856 }
1857 /*
1858 * pick the one with the smallest sleep time
1859 */
1860 if (p2->p_slptime > p1->p_slptime)
1861 return (0);
1862 if (p1->p_slptime > p2->p_slptime)
1863 return (1);
1864 /*
1865 * favor one sleeping in a non-interruptible sleep
1866 */
1867 if (p1->p_flag&SSINTR && (p2->p_flag&SSINTR) == 0)
1868 return (1);
1869 if (p2->p_flag&SSINTR && (p1->p_flag&SSINTR) == 0)
1870 return (0);
1871 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1872}
1873
1874/*
1875 * Output char to tty; console putchar style.
1876 */
1877tputchar(c, tp)
1878 int c;
1879 struct tty *tp;
1880{
1881 register s = spltty();
1882
1883 if ((tp->t_state & (TS_CARR_ON|TS_ISOPEN)) == (TS_CARR_ON|TS_ISOPEN)) {
1884 if (c == '\n')
1885 (void) ttyoutput('\r', tp);
1886 (void) ttyoutput(c, tp);
1887 ttstart(tp);
1888 splx(s);
1889 return (0);
1890 }
1891 splx(s);
1892 return (-1);
1893}
1894
1895/*
1896 * Sleep on chan, returning ERESTART if tty changed
1897 * while we napped and returning any errors (e.g. EINTR/ETIMEDOUT)
1898 * reported by tsleep. If the tty is revoked, restarting a pending
1899 * call will redo validation done at the start of the call.
1900 */
1901ttysleep(tp, chan, pri, wmesg, timo)
1902 struct tty *tp;
1903 caddr_t chan;
1904 int pri;
1905 char *wmesg;
1906 int timo;
1907{
1908 int error;
1909 short gen = tp->t_gen;
1910
1911 if (error = tsleep(chan, pri, wmesg, timo))
1912 return (error);
1913 if (tp->t_gen != gen)
1914 return (ERESTART);
1915 return (0);
1916}