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