-ttyinput(c, tp)
- register c;
- register struct tty *tp;
-{
- register int iflag = tp->t_iflag;
- register int lflag = tp->t_lflag;
- register u_char *cc = tp->t_cc;
- int i, err;
-
- /*
- * If input is pending take it first.
- */
- if (lflag&PENDIN)
- ttypend(tp);
- /*
- * Gather stats.
- */
-
- tk_nin++;
- if (lflag&ICANON) {
- tk_cancc++;
- tp->t_cancc++;
- } else {
- tk_rawcc++;
- tp->t_rawcc++;
- }
- /*
- * Handle exceptional conditions (break, parity, framing).
- */
- if (err = (c&TTY_ERRORMASK)) {
- c &= TTY_CHARMASK;
- if (err&TTY_FE && !c) { /* break */
- if (iflag&IGNBRK)
- goto endcase;
- else if (iflag&BRKINT && lflag&ISIG &&
- (cc[VINTR] != POSIX_V_DISABLE))
- c = cc[VINTR];
- else
- c = 0;
- } else if ((err&TTY_PE && iflag&INPCK) || err&TTY_FE) {
- if (iflag&IGNPAR)
- goto endcase;
- else if (iflag&PARMRK) {
- ttyinput(0377, tp);
- ttyinput(0, tp);
- } else
- c = 0;
- }
- }
- dprintf("<%o>\n", c);
-
- /*
- * In tandem mode, check high water mark.
- */
- if (iflag&IXOFF)
- ttyblock(tp);
-
- /*
- * In tandem mode, check high water mark.
- */
- if ((tp->t_state&TS_TYPEN) == 0 && (iflag&ISTRIP))
- c &= ~0x80;
-
- /*
- * Extensions to POSIX input modes which aren't controlled
- * by ICANON, ISIG, or IXON.
- */
- if (iflag&IEXTEN) {
- if (CCEQ(cc[VLNEXT],c) && (iflag&ISTRIP)) {
- if (lflag&ECHO)
- ttyout("^\b", tp); /*XXX - presumes too much */
- }
- /*
- * Signals.
- */
- if (lflag&ISIG) {
- if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
- if ((lflag&NOFLSH) == 0)
- ttyflush(tp, FREAD|FWRITE);
- ttyecho(c, tp);
- tp->t_lflag |= FLUSHO;
- }
- if (CCEQ(cc[VSUSP], c)) {
- if ((lflag&NOFLSH) == 0)
- ttyflush(tp, FREAD);
- ttyecho(c, tp);
- pgsignal(tp->t_pgrp, SIGTSTP, 1);
- goto endcase;
- }
- }
- if (iflag&IXON) {
- if (CCEQ(cc[VSTOP],c)) {
- if ((tp->t_state&TS_TTSTOP) == 0) {
- tp->t_state |= TS_TTSTOP;
- (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
- return;
- }
- if (!CCEQ(cc[VSTART], c))
- return;
- /*
- * if VSTART == VSTOP we toggle
- */
- goto endcase;
- }
- if (CCEQ(cc[VSTART], c))
- goto restartoutput;
- }
- c = unputc(&tp->t_rawq);
- } while (c != ' ' && c != '\t');
- (void) putc(c, &tp->t_rawq);
- goto endcase;
- }
- /*
- * reprint line (^R)
- */
- if (CCEQ(cc[VREPRINT], c)) {
- ttyretype(tp);
- goto endcase;
- }
- /*
- * Check for input buffer overflow
- */
- if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) {
- if (iflag&IMAXBEL) {
- if (tp->t_outq.c_cc < TTHIWAT(tp))
- (void) ttyoutput(CTRL('g'), tp);
- } else
- ttyflush(tp, FREAD | FWRITE);
- goto endcase;
- }
- /*
- * Put data char in q for user and
- * wakeup on seeing a line delimiter.
- */
- if (putc(c, &tp->t_rawq) >= 0) {
- if ((lflag&ICANON) == 0) {
- ttwakeup(tp);
- ttyecho(c, tp);
- goto endcase;
- }
- if (ttbreakc(c)) {
- tp->t_rocount = 0;
- catq(&tp->t_rawq, &tp->t_canq);
- ttwakeup(tp);
- } else if (tp->t_rocount++ == 0)
- tp->t_rocol = tp->t_col;
- if (CCEQ(cc[VQUOTE], c) && (iflag&ISTRIP))
- tp->t_state |= TS_QUOT; /* '\' escape */
- if (tp->t_state&TS_ERASE) {
- /*
- * end of prterase \.../
- */
- /*
- * end of prterase \.../
- */
- tp->t_state &= ~TS_ERASE;
- (void) ttyoutput('/', tp);
- }
- i = tp->t_col;
- ttyecho(c, tp);
- if (CCEQ(cc[VEOF], c) && lflag&ECHO) {
- /*
- * Place the cursor over the '^' of the ^D.
- */
- i = min(2, tp->t_col - i);
- while (i > 0) {
- (void) ttyoutput('\b', tp);
- i--;
- }
- }