Exemple #1
0
int tty_ioctl(uint8_t minor, uint16_t request, char *data)
{				/* Data in User Space */
	if (!minor)
		minor = udata.u_ptab->p_tty;
	if (minor < 1 || minor > NUM_DEV_TTY + 1) {
		udata.u_error = ENODEV;
		return -1;
	}
	if (deadflag[minor]) {
	        udata.u_error = ENXIO;
	        return -1;
        }
	switch (request) {
	case TCGETS:
		uput(&ttydata[minor], data, sizeof(struct termios));
		break;
	case TCSETSW:
		/* We don't have an output queue really so for now drop
		   through */
	case TCSETS:
	case TCSETSF:
		uget(data, &ttydata[minor], sizeof(struct termios));
		if (request == TCSETSF)
			clrq(&ttyinq[minor]);
                tty_setup(minor);
		break;
	case TIOCINQ:
		uput(&ttyinq[minor].q_count, data, 2);
		break;
	case TIOCFLUSH:
		clrq(&ttyinq[minor]);
		break;
        case TIOCHANGUP:
                tty_hangup(minor);
                return 0;
	default:
		udata.u_error = ENOTTY;
		return (-1);
	}
	return (0);
}
Exemple #2
0
int tty_inproc(uint8_t minor, unsigned char c)
{
	unsigned char oc;
	struct termios *td;
	struct s_queue *q = &ttyinq[minor];
	int canon;
	uint16_t pgrp = tty_pgrp[minor];
	uint8_t wr;

	td = &ttydata[minor];
	canon = td->c_lflag & ICANON;

	if (td->c_iflag & ISTRIP)
		c &= 0x7f;	/* Strip off parity */
	if (canon && !c)
		return 1;	/* Simply quit if Null character */

#ifdef CONFIG_IDUMP
	if (c == 0x1a)		/* ^Z */
		idump();	/*   (For debugging) */
#endif
#ifdef CONFIG_MONITOR
	if (c == 0x01)		/* ^A */
		trap_monitor();
#endif

	if (c == '\r' && (td->c_iflag & ICRNL))
		c = '\n';
	if (c == '\n' && (td->c_iflag & INLCR))
		c = '\r';

	if (td->c_lflag & ISIG) {
		if (c == td->c_cc[VINTR]) {	/* ^C */
			sgrpsig(pgrp, SIGINT);
			clrq(q);
			stopflag[minor] = flshflag[minor] = false;
			return 1;
		} else if (c == td->c_cc[VQUIT]) {	/* ^\ */
			sgrpsig(pgrp, SIGQUIT);
			clrq(q);
			stopflag[minor] = flshflag[minor] = false;
			return 1;
		}
	}
	if (c == td->c_cc[VDISCARD]) {	/* ^O */
		flshflag[minor] = !flshflag[minor];
		return 1;
	}
	if (td->c_iflag & IXON) {
		if (c == td->c_cc[VSTOP]) {	/* ^S */
			stopflag[minor] = true;
			return 1;
		}
		if (c == td->c_cc[VSTART]) {	/* ^Q */
			stopflag[minor] = false;
			wakeup(&stopflag[minor]);
			return 1;
		}
	}
	if (canon) {
		if (c == td->c_cc[VERASE]) {
			if (uninsq(q, &oc)) {
				if (oc == '\n' || oc == td->c_cc[VEOL])
					insq(q, oc);	/* Don't erase past nl */
				else if (td->c_lflag & ECHOE)
					tty_erase(minor);
				return 1;
			} else if (c == td->c_cc[VKILL]) {
				while (uninsq(q, &oc)) {
					if (oc == '\n'
					    || oc == td->c_cc[VEOL]) {
						insq(q, oc);	/* Don't erase past nl */
						break;
					}
					if (td->c_lflag & ECHOK)
						tty_erase(minor);
				}
				return 1;
			}
		}
	}

	/* All modes come here */
	if (c == '\n') {
		if ((td->c_oflag & OPOST | ONLCR) == OPOST | ONLCR)
			tty_echo(minor, '\r');
	}

	wr = insq(q, c);
	if (wr)
		tty_echo(minor, c);
	else if (minor < PTY_OFFSET)
		tty_putc_wait(minor, '\007');	/* Beep if no more room */

	if (!canon || c == td->c_cc[VEOL] || c == '\n'
	    || c == td->c_cc[VEOF])
		wakeup(q);
	return wr;
}
Exemple #3
0
/* This routine processes a character in response to an interrupt.  It
 * adds the character to the tty input queue, echoing and processing
 * backspace and carriage return.  If the queue contains a full line,
 * it wakes up anything waiting on it.  If it is totally full, it beeps
 * at the user.
 * UZI180 - This routine is called from the raw Hardware read routine,
 * either interrupt or polled, to process the input character.  HFB
 */
int tty_inproc(uint8_t minor, unsigned char c)
{
	unsigned char oc;
	int canon;
	uint8_t wr;
	struct tty *t = &ttydata[minor];
	struct s_queue *q = &ttyinq[minor];

	canon = t->termios.c_lflag & ICANON;

	if (t->termios.c_iflag & ISTRIP)
		c &= 0x7f;	/* Strip off parity */
	if (canon && !c)
		return 1;	/* Simply quit if Null character */

#ifdef CONFIG_IDUMP
	if (c == 0x1a)		/* ^Z */
		idump();	/*   (For debugging) */
#endif
#ifdef CONFIG_MONITOR
	if (c == 0x01)		/* ^A */
		trap_monitor();
#endif

	if (c == '\r' && (t->termios.c_iflag & ICRNL))
		c = '\n';
	if (c == '\n' && (t->termios.c_iflag & INLCR))
		c = '\r';

	if (t->termios.c_lflag & ISIG) {
		if (c == t->termios.c_cc[VINTR]) {	/* ^C */
		        wr = SIGINT;
			goto sigout;
		} else if (c == t->termios.c_cc[VQUIT]) {	/* ^\ */
		        wr = SIGQUIT;
sigout:
			sgrpsig(t->pgrp, wr);
			clrq(q);
			t->flag &= ~(TTYF_STOP | TTYF_DISCARD);
			return 1;
		}
	}
	if (c == t->termios.c_cc[VDISCARD]) {	/* ^O */
	        t->flag ^= TTYF_DISCARD;
		return 1;
	}
	if (t->termios.c_iflag & IXON) {
		if (c == t->termios.c_cc[VSTOP]) {	/* ^S */
		        t->flag |= TTYF_STOP;
			return 1;
		}
		if (c == t->termios.c_cc[VSTART]) {	/* ^Q */
		        t->flag &= ~TTYF_STOP;
			wakeup(&t->flag);
			return 1;
		}
	}
	if (canon) {
		if (c == t->termios.c_cc[VERASE]) {
		        wr = ECHOE;
		        goto eraseout;
		} else if (c == t->termios.c_cc[VKILL]) {
		        wr = ECHOK;
		        goto eraseout;
		}
	}

	/* All modes come here */
	if (c == '\n') {
		if ((t->termios.c_oflag & (OPOST | ONLCR)) == (OPOST | ONLCR))
			tty_echo(minor, '\r');
	}

	wr = insq(q, c);
	if (wr)
		tty_echo(minor, c);
	else
		tty_putc(minor, '\007');	/* Beep if no more room */

	if (!canon || c == t->termios.c_cc[VEOL] || c == '\n'
	    || c == t->termios.c_cc[VEOF])
		wakeup(q);
	return wr;

eraseout:
	while (uninsq(q, &oc)) {
		if (oc == '\n' || oc == t->termios.c_cc[VEOL]) {
			insq(q, oc);	/* Don't erase past nl */
			break;
		}
		if (t->termios.c_lflag & wr)
			tty_erase(minor);
                if (wr == ECHOE)
                        break;
	}
	return 1;
}
Exemple #4
0
int tty_ioctl(uint8_t minor, uarg_t request, char *data)
{				/* Data in User Space */
        struct tty *t;
	if (minor > NUM_DEV_TTY + 1) {
		udata.u_error = ENODEV;
		return -1;
	}
        t = &ttydata[minor];
	if (t->flag & TTYF_DEAD) {
	        udata.u_error = ENXIO;
	        return -1;
        }
        jobcontrol_in(minor, t);
	switch (request) {
	case TCGETS:
		return uput(&t->termios, data, sizeof(struct termios));
		break;
	case TCSETSF:
		clrq(&ttyinq[minor]);
		/* Fall through for now */
	case TCSETSW:
		/* We don't have an output queue really so for now drop
		   through */
	case TCSETS:
		if (uget(data, &t->termios, sizeof(struct termios)) == -1)
		        return -1;
                tty_setup(minor);
		break;
	case TIOCINQ:
		return uput(&ttyinq[minor].q_count, data, 2);
	case TIOCFLUSH:
		clrq(&ttyinq[minor]);
		break;
        case TIOCHANGUP:
                tty_hangup(minor);
                return 0;
	case TIOCOSTOP:
		t->flag |= TTYF_STOP;
		break;
	case TIOCOSTART:
		t->flag &= ~TTYF_STOP;
		break;
        case TIOCGWINSZ:
                return uput(&t->winsize, data, sizeof(struct winsize));
        case TIOCSWINSZ:
                if (uget(&t->winsize, data, sizeof(struct winsize)))
                        return -1;
                sgrpsig(t->pgrp, SIGWINCH);
                return 0;
        case TIOCGPGRP:
                return uputw(t->pgrp, data);
#ifdef CONFIG_LEVEL_2
        case TIOCSPGRP:
                /* Only applicable via controlling terminal */
                if (minor != udata.u_ptab->p_tty) {
                        udata.u_error = ENOTTY;
                        return -1;
                }
                return tcsetpgrp(t, data);
#endif
	default:
		udata.u_error = ENOTTY;
		return -1;
	}
	return 0;
}