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