Esempio n. 1
0
int
ptsread(dev_t dev, struct uio *uio, int flag)
{
	struct proc *p = curproc;
	struct process *pr = p->p_p;
	struct pt_softc *pti = pt_softc[minor(dev)];
	struct tty *tp = pti->pt_tty;
	int error = 0;

again:
	if (pti->pt_flags & PF_REMOTE) {
		while (isbackground(pr, tp)) {
			if ((p->p_sigacts->ps_sigignore & sigmask(SIGTTIN)) ||
			    (p->p_sigmask & sigmask(SIGTTIN)) ||
			    pr->ps_pgrp->pg_jobc == 0 ||
			    pr->ps_flags & PS_PPWAIT)
				return (EIO);
			pgsignal(pr->ps_pgrp, SIGTTIN, 1);
			error = ttysleep(tp, &lbolt,
			    TTIPRI | PCATCH, ttybg, 0);
			if (error)
				return (error);
		}
		if (tp->t_canq.c_cc == 0) {
			if (flag & IO_NDELAY)
				return (EWOULDBLOCK);
			error = ttysleep(tp, &tp->t_canq,
			    TTIPRI | PCATCH, ttyin, 0);
			if (error)
				return (error);
			goto again;
		}
		while (tp->t_canq.c_cc > 1 && uio->uio_resid > 0)
			if (ureadc(getc(&tp->t_canq), uio) < 0) {
				error = EFAULT;
				break;
			}
		if (tp->t_canq.c_cc == 1)
			(void) getc(&tp->t_canq);
		if (tp->t_canq.c_cc)
			return (error);
	} else
		if (tp->t_oproc)
			error = (*linesw[tp->t_line].l_read)(tp, uio, flag);
	ptcwakeup(tp, FWRITE);
	return (error);
}
Esempio n. 2
0
/*ARGSUSED*/
int
ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	struct pt_softc *pti = pt_softc[minor(dev)];
	struct tty *tp = pti->pt_tty;
	u_char *cc = tp->t_cc;
	int stop, error;

	/*
	 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
	 * ttywflush(tp) will hang if there are characters in the outq.
	 */
	if (cmd == TIOCEXT) {
		/*
		 * When the EXTPROC bit is being toggled, we need
		 * to send an TIOCPKT_IOCTL if the packet driver
		 * is turned on.
		 */
		if (*(int *)data) {
			if (pti->pt_flags & PF_PKT) {
				pti->pt_send |= TIOCPKT_IOCTL;
				ptcwakeup(tp, FREAD);
			}
			tp->t_lflag |= EXTPROC;
		} else {
			if ((tp->t_lflag & EXTPROC) &&
			    (pti->pt_flags & PF_PKT)) {
				pti->pt_send |= TIOCPKT_IOCTL;
				ptcwakeup(tp, FREAD);
			}
			tp->t_lflag &= ~EXTPROC;
		}
		return(0);
	} else if (cdevsw[major(dev)].d_open == ptcopen)
		switch (cmd) {

		case TIOCGPGRP:
#ifdef COMPAT_SUNOS
		    {
			/*
			 * I'm not sure about SunOS TIOCGPGRP semantics
			 * on PTYs, but it's something like this:
			 */
			extern struct emul emul_sunos;
			if (p->p_emul == &emul_sunos) {
				if (tp->t_pgrp == 0)
					return (EIO);
				*(int *)data = tp->t_pgrp->pg_id;
				return (0);
			}
		    }
#endif
			/*
			 * We avoid calling ttioctl on the controller since,
			 * in that case, tp must be the controlling terminal.
			 */
			*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
			return (0);

		case TIOCPKT:
			if (*(int *)data) {
				if (pti->pt_flags & PF_UCNTL)
					return (EINVAL);
				pti->pt_flags |= PF_PKT;
			} else
				pti->pt_flags &= ~PF_PKT;
			return (0);

		case TIOCUCNTL:
			if (*(int *)data) {
				if (pti->pt_flags & PF_PKT)
					return (EINVAL);
				pti->pt_flags |= PF_UCNTL;
			} else
				pti->pt_flags &= ~PF_UCNTL;
			return (0);

		case TIOCREMOTE:
			if (*(int *)data)
				pti->pt_flags |= PF_REMOTE;
			else
				pti->pt_flags &= ~PF_REMOTE;
			ttyflush(tp, FREAD|FWRITE);
			return (0);

#ifdef COMPAT_OLDTTY
		case TIOCSETP:
		case TIOCSETN:
#endif
		case TIOCSETD:
		case TIOCSETA:
		case TIOCSETAW:
		case TIOCSETAF:
			ndflush(&tp->t_outq, tp->t_outq.c_cc);
			break;

		case TIOCSIG:
			if (*(unsigned int *)data >= NSIG ||
			    *(unsigned int *)data == 0)
				return(EINVAL);
			if ((tp->t_lflag&NOFLSH) == 0)
				ttyflush(tp, FREAD|FWRITE);
			pgsignal(tp->t_pgrp, *(unsigned int *)data, 1);
			if ((*(unsigned int *)data == SIGINFO) &&
			    ((tp->t_lflag&NOKERNINFO) == 0))
				ttyinfo(tp);
			return(0);
		}
	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
	if (error < 0)
		 error = ttioctl(tp, cmd, data, flag, p);
	if (error < 0) {
		if (pti->pt_flags & PF_UCNTL &&
		    (cmd & ~0xff) == UIOCCMD(0)) {
			if (cmd & 0xff) {
				pti->pt_ucntl = (u_char)cmd;
				ptcwakeup(tp, FREAD);
			}
			return (0);
		}
		error = ENOTTY;
	}
	/*
	 * If external processing and packet mode send ioctl packet.
	 */
	if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
		switch (cmd) {
		case TIOCSETA:
		case TIOCSETAW:
		case TIOCSETAF:
#ifdef COMPAT_OLDTTY
		case TIOCSETP:
		case TIOCSETN:
		case TIOCSETC:
		case TIOCSLTC:
		case TIOCLBIS:
		case TIOCLBIC:
		case TIOCLSET:
#endif
			pti->pt_send |= TIOCPKT_IOCTL;
			ptcwakeup(tp, FREAD);
		default:
			break;
		}
	}
	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s')) &&
	    CCEQ(cc[VSTART], CTRL('q'));
	if (pti->pt_flags & PF_NOSTOP) {
		if (stop) {
			pti->pt_send &= ~TIOCPKT_NOSTOP;
			pti->pt_send |= TIOCPKT_DOSTOP;
			pti->pt_flags &= ~PF_NOSTOP;
			ptcwakeup(tp, FREAD);
		}
	} else {
		if (!stop) {
			pti->pt_send &= ~TIOCPKT_DOSTOP;
			pti->pt_send |= TIOCPKT_NOSTOP;
			pti->pt_flags |= PF_NOSTOP;
			ptcwakeup(tp, FREAD);
		}
	}
	return (error);
}
int
sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
                  int fontsize, int fontwidth)
{
#ifndef SC_PIXEL_MODE
    return ENODEV;
#else
    video_info_t info;
    u_char *font;
    int prev_ysize;
    int error;
    int s;

    if (vidd_get_info(scp->sc->adp, scp->mode, &info))
        return ENODEV;		/* this shouldn't happen */

    /* adjust argument values */
    if (fontsize <= 0)
        fontsize = info.vi_cheight;
    if (fontsize < 14) {
        fontsize = 8;
#ifndef SC_NO_FONT_LOADING
        if (!(scp->sc->fonts_loaded & FONT_8))
            return EINVAL;
        font = scp->sc->font_8;
#else
        font = NULL;
#endif
    } else if (fontsize >= 16) {
        fontsize = 16;
#ifndef SC_NO_FONT_LOADING
        if (!(scp->sc->fonts_loaded & FONT_16))
            return EINVAL;
        font = scp->sc->font_16;
#else
        font = NULL;
#endif
    } else {
        fontsize = 14;
#ifndef SC_NO_FONT_LOADING
        if (!(scp->sc->fonts_loaded & FONT_14))
            return EINVAL;
        font = scp->sc->font_14;
#else
        font = NULL;
#endif
    }
    if (xsize <= 0)
        xsize = info.vi_width/8;
    if (ysize <= 0)
        ysize = info.vi_height/fontsize;

    if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
        return EINVAL;

    /*
     * We currently support the following graphic modes:
     *
     * - 4 bpp planar modes whose memory size does not exceed 64K
     * - 15, 16, 24 and 32 bpp linear modes
     */

    if (info.vi_mem_model == V_INFO_MM_PLANAR) {
        if (info.vi_planes != 4)
            return ENODEV;

        /*
         * A memory size >64K requires bank switching to access the entire
         * screen. XXX
         */

        if (info.vi_width * info.vi_height / 8 > info.vi_window_size)
            return ENODEV;
    } else if (info.vi_mem_model == V_INFO_MM_DIRECT) {
        if (!(info.vi_flags & V_INFO_LINEAR) &&
                (info.vi_depth != 15) && (info.vi_depth != 16) &&
                (info.vi_depth != 24) && (info.vi_depth != 32))
            return ENODEV;
    } else
        return ENODEV;

    /* stop screen saver, etc */
    s = spltty();
    if ((error = sc_clean_up(scp))) {
        splx(s);
        return error;
    }

    if (sc_render_match(scp, scp->sc->adp->va_name, PIXEL_MODE) == NULL) {
        splx(s);
        return ENODEV;
    }

#if 0
    if (scp->tsw)
        (*scp->tsw->te_term)(scp, scp->ts);
    scp->tsw = NULL;
    scp->ts = NULL;
#endif

    /* set up scp */
#ifndef SC_NO_HISTORY
    if (scp->history != NULL)
        sc_hist_save(scp);
#endif
    prev_ysize = scp->ysize;
    scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
    scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE);
    scp->xsize = xsize;
    scp->ysize = ysize;
    scp->xoff = (scp->xpixel/8 - xsize)/2;
    scp->yoff = (scp->ypixel/fontsize - ysize)/2;
    scp->font = font;
    scp->font_size = fontsize;
    scp->font_width = fontwidth;

    /* allocate buffers */
    sc_alloc_scr_buffer(scp, TRUE, TRUE);
    sc_init_emulator(scp, NULL);
#ifndef SC_NO_CUTPASTE
    sc_alloc_cut_buffer(scp, FALSE);
#endif
#ifndef SC_NO_HISTORY
    sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE);
#endif
    splx(s);

    if (scp == scp->sc->cur_scp) {
        sc_set_border(scp, scp->border);
        sc_set_cursor_image(scp);
    }

    scp->status &= ~UNKNOWN_MODE;

    if (tp == NULL)
        return 0;
    if (tp->t_winsize.ws_col != scp->xsize
            || tp->t_winsize.ws_row != scp->ysize) {
        tp->t_winsize.ws_col = scp->xsize;
        tp->t_winsize.ws_row = scp->ysize;
        if (tp->t_pgrp != NULL) {
            PGRP_LOCK(tp->t_pgrp);
            pgsignal(tp->t_pgrp, SIGWINCH, 1);
            PGRP_UNLOCK(tp->t_pgrp);
        }
    }

    return 0;
#endif /* SC_PIXEL_MODE */
}
Esempio n. 4
0
int
sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, 
		  int fontsize, int fontwidth)
{
#ifndef SC_PIXEL_MODE
    return ENODEV;
#else
    video_info_t info;
    ksiginfo_t ksi;
    u_char *font;
    int prev_ysize;
    int error;
    int s;

    if (vidd_get_info(scp->sc->adp, scp->mode, &info))
	return ENODEV;		/* this shouldn't happen */

    /* adjust argument values */
    if (fontsize <= 0)
	fontsize = info.vi_cheight;
    if (fontsize < 14)
	fontsize = 8;
    else if (fontsize >= 16)
	fontsize = 16;
    else
	fontsize = 14;
#ifndef SC_NO_FONT_LOADING
    switch (fontsize) {
    case 8:
	if ((scp->sc->fonts_loaded & FONT_8) == 0)
	    return (EINVAL);
	font = scp->sc->font_8;
	break;
    case 14:
	if ((scp->sc->fonts_loaded & FONT_14) == 0)
	    return (EINVAL);
	font = scp->sc->font_14;
	break;
    case 16:
	if ((scp->sc->fonts_loaded & FONT_16) == 0)
	    return (EINVAL);
	font = scp->sc->font_16;
	break;
    }
#else
    font = NULL;
#endif
    if (xsize <= 0)
	xsize = info.vi_width/8;
    if (ysize <= 0)
	ysize = info.vi_height/fontsize;

    if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
	return EINVAL;

    if (!sc_support_pixel_mode(&info))
	return ENODEV;

    /* stop screen saver, etc */
    s = spltty();
    if ((error = sc_clean_up(scp))) {
	splx(s);
	return error;
    }

    if (sc_render_match(scp, scp->sc->adp->va_name, PIXEL_MODE) == NULL) {
	splx(s);
	return ENODEV;
    }

#if 0
    if (scp->tsw)
	(*scp->tsw->te_term)(scp, scp->ts);
    scp->tsw = NULL;
    scp->ts = NULL;
#endif

    /* set up scp */
#ifndef SC_NO_HISTORY
    if (scp->history != NULL)
	sc_hist_save(scp);
#endif
    prev_ysize = scp->ysize;
    scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
    scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE);
    scp->xsize = xsize;
    scp->ysize = ysize;
    scp->xoff = (scp->xpixel/8 - xsize)/2;
    scp->yoff = (scp->ypixel/fontsize - ysize)/2;
    scp->font = font;
    scp->font_size = fontsize;
    scp->font_width = fontwidth;

    /* allocate buffers */
    sc_alloc_scr_buffer(scp, TRUE, TRUE);
    sc_init_emulator(scp, NULL);
#ifndef SC_NO_CUTPASTE
    sc_alloc_cut_buffer(scp, FALSE);
#endif
#ifndef SC_NO_HISTORY
    sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE);
#endif
    splx(s);

    if (scp == scp->sc->cur_scp) {
	sc_set_border(scp, scp->border);
	sc_set_cursor_image(scp);
    }

    scp->status &= ~UNKNOWN_MODE;

    if (tp == NULL)
	return 0;
    if (tp->t_winsize.ws_col != scp->xsize
	|| tp->t_winsize.ws_row != scp->ysize) {
	tp->t_winsize.ws_col = scp->xsize;
	tp->t_winsize.ws_row = scp->ysize;
	if (tp->t_pgrp != NULL) {
	    ksiginfo_init(&ksi);
	    ksi.ksi_signo = SIGWINCH;
	    ksi.ksi_code = SI_KERNEL;
	    PGRP_LOCK(tp->t_pgrp);
	    pgsignal(tp->t_pgrp, SIGWINCH, 1, &ksi);
	    PGRP_UNLOCK(tp->t_pgrp);
	}
    }

    return 0;
#endif /* SC_PIXEL_MODE */
}
Esempio n. 5
0
static	int
ptsread(struct dev_read_args *ap)
{
	cdev_t dev = ap->a_head.a_dev;
	struct proc *p = curproc;
	struct tty *tp = dev->si_tty;
	struct pt_ioctl *pti = dev->si_drv1;
	struct lwp *lp;

	int error = 0;

	lp = curthread->td_lwp;

	lwkt_gettoken(&tty_token);
again:
	if (pti->pt_flags & PF_REMOTE) {
		while (isbackground(p, tp)) {
			if (SIGISMEMBER(p->p_sigignore, SIGTTIN) ||
			    SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
			    p->p_pgrp->pg_jobc == 0 ||
			    (p->p_flags & P_PPWAIT)) {
				lwkt_reltoken(&tty_token);
				return (EIO);
			}
			pgsignal(p->p_pgrp, SIGTTIN, 1);
			error = ttysleep(tp, &lbolt, PCATCH, "ptsbg", 0);
			if (error) {
				lwkt_reltoken(&tty_token);
				return (error);
			}
		}
		if (tp->t_canq.c_cc == 0) {
			if (ap->a_ioflag & IO_NDELAY) {
				lwkt_reltoken(&tty_token);
				return (EWOULDBLOCK);
			}
			error = ttysleep(tp, TSA_PTS_READ(tp), PCATCH,
					 "ptsin", 0);
			if (error) {
				lwkt_reltoken(&tty_token);
				return (error);
			}
			goto again;
		}
		while (tp->t_canq.c_cc > 1 && ap->a_uio->uio_resid > 0)
			if (ureadc(clist_getc(&tp->t_canq), ap->a_uio) < 0) {
				error = EFAULT;
				break;
			}
		if (tp->t_canq.c_cc == 1)
			clist_getc(&tp->t_canq);
		if (tp->t_canq.c_cc) {
			lwkt_reltoken(&tty_token);
			return (error);
		}
	} else
		if (tp->t_oproc)
			error = (*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag);
	ptcwakeup(tp, FWRITE);
	lwkt_reltoken(&tty_token);
	return (error);
}
Esempio n. 6
0
/*ARGSUSED*/
static	int
ptyioctl(struct dev_ioctl_args *ap)
{
	cdev_t dev = ap->a_head.a_dev;
	struct tty *tp = dev->si_tty;
	struct pt_ioctl *pti = dev->si_drv1;
	u_char *cc = tp->t_cc;
	int stop, error;

	lwkt_gettoken(&tty_token);
	if (dev_dflags(dev) & D_MASTER) {
		switch (ap->a_cmd) {

		case TIOCGPGRP:
			/*
			 * We avoid calling ttioctl on the controller since,
			 * in that case, tp must be the controlling terminal.
			 */
			*(int *)ap->a_data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
			lwkt_reltoken(&tty_token);
			return (0);

		case TIOCPKT:
			if (*(int *)ap->a_data) {
				if (pti->pt_flags & PF_UCNTL) {
					lwkt_reltoken(&tty_token);
					return (EINVAL);
				}
				pti->pt_flags |= PF_PKT;
			} else {
				pti->pt_flags &= ~PF_PKT;
			}
			lwkt_reltoken(&tty_token);
			return (0);

		case TIOCUCNTL:
			if (*(int *)ap->a_data) {
				if (pti->pt_flags & PF_PKT) {
					lwkt_reltoken(&tty_token);
					return (EINVAL);
				}
				pti->pt_flags |= PF_UCNTL;
			} else {
				pti->pt_flags &= ~PF_UCNTL;
			}
			lwkt_reltoken(&tty_token);
			return (0);

		case TIOCREMOTE:
			if (*(int *)ap->a_data)
				pti->pt_flags |= PF_REMOTE;
			else
				pti->pt_flags &= ~PF_REMOTE;
			ttyflush(tp, FREAD|FWRITE);
			lwkt_reltoken(&tty_token);
			return (0);

#ifdef UNIX98_PTYS
		case TIOCISPTMASTER:
			if ((pti->pt_flags & PF_UNIX98) &&
			    (pti->devc == dev)) {
				lwkt_reltoken(&tty_token);
				return (0);
			} else {
				lwkt_reltoken(&tty_token);
				return (EINVAL);
			}
		}
#endif

		/*
		 * The rest of the ioctls shouldn't be called until 
		 * the slave is open.
		 */
		if ((tp->t_state & TS_ISOPEN) == 0) {
			lwkt_reltoken(&tty_token);
			return (EAGAIN);
		}

		switch (ap->a_cmd) {
#ifdef COMPAT_43
		case TIOCSETP:
		case TIOCSETN:
#endif
		case TIOCSETD:
		case TIOCSETA:
		case TIOCSETAW:
		case TIOCSETAF:
			/*
			 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
			 * ttywflush(tp) will hang if there are characters in
			 * the outq.
			 */
			ndflush(&tp->t_outq, tp->t_outq.c_cc);
			break;

		case TIOCSIG:
			if (*(unsigned int *)ap->a_data >= NSIG ||
			    *(unsigned int *)ap->a_data == 0) {
				lwkt_reltoken(&tty_token);
				return(EINVAL);
			}
			if ((tp->t_lflag&NOFLSH) == 0)
				ttyflush(tp, FREAD|FWRITE);
			pgsignal(tp->t_pgrp, *(unsigned int *)ap->a_data, 1);
			if ((*(unsigned int *)ap->a_data == SIGINFO) &&
			    ((tp->t_lflag&NOKERNINFO) == 0))
				ttyinfo(tp);
			lwkt_reltoken(&tty_token);
			return(0);
		}
	}
	if (ap->a_cmd == TIOCEXT) {
		/*
		 * When the EXTPROC bit is being toggled, we need
		 * to send an TIOCPKT_IOCTL if the packet driver
		 * is turned on.
		 */
		if (*(int *)ap->a_data) {
			if (pti->pt_flags & PF_PKT) {
				pti->pt_send |= TIOCPKT_IOCTL;
				ptcwakeup(tp, FREAD);
			}
			tp->t_lflag |= EXTPROC;
		} else {
			if ((tp->t_lflag & EXTPROC) &&
			    (pti->pt_flags & PF_PKT)) {
				pti->pt_send |= TIOCPKT_IOCTL;
				ptcwakeup(tp, FREAD);
			}
			tp->t_lflag &= ~EXTPROC;
		}
		lwkt_reltoken(&tty_token);
		return(0);
	}
	error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data,
					      ap->a_fflag, ap->a_cred);
	if (error == ENOIOCTL)
		 error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
	if (error == ENOIOCTL) {
		if (pti->pt_flags & PF_UCNTL &&
		    (ap->a_cmd & ~0xff) == UIOCCMD(0)) {
			if (ap->a_cmd & 0xff) {
				pti->pt_ucntl = (u_char)ap->a_cmd;
				ptcwakeup(tp, FREAD);
			}
			lwkt_reltoken(&tty_token);
			return (0);
		}
		error = ENOTTY;
	}
	/*
	 * If external processing and packet mode send ioctl packet.
	 */
	if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
		switch(ap->a_cmd) {
		case TIOCSETA:
		case TIOCSETAW:
		case TIOCSETAF:
#ifdef COMPAT_43
		case TIOCSETP:
		case TIOCSETN:
#endif
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
		case TIOCSETC:
		case TIOCSLTC:
		case TIOCLBIS:
		case TIOCLBIC:
		case TIOCLSET:
#endif
			pti->pt_send |= TIOCPKT_IOCTL;
			ptcwakeup(tp, FREAD);
		default:
			break;
		}
	}
	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
		&& CCEQ(cc[VSTART], CTRL('q'));
	if (pti->pt_flags & PF_NOSTOP) {
		if (stop) {
			pti->pt_send &= ~TIOCPKT_NOSTOP;
			pti->pt_send |= TIOCPKT_DOSTOP;
			pti->pt_flags &= ~PF_NOSTOP;
			ptcwakeup(tp, FREAD);
		}
	} else {
		if (!stop) {
			pti->pt_send &= ~TIOCPKT_DOSTOP;
			pti->pt_send |= TIOCPKT_NOSTOP;
			pti->pt_flags |= PF_NOSTOP;
			ptcwakeup(tp, FREAD);
		}
	}
	lwkt_reltoken(&tty_token);
	return (error);
}
Esempio n. 7
0
/*
 * Process an input character, with input processing
 * return -1, if queue full.
 */
int ttinput(int c, TTY tp)
{
	USHORT lflag = tp->t_lflag;
	char far *cc = tp->t_cc;
	CQ rq = &tp->inq;
	int nocan = ISCLR(lflag,ICANON);
	int ret = 0;

	/* only 8 or 7 bits */
	c &= (tp->t_iflag & ISTRIP ? 0x7f : 0xff);

	/* filter out CR LF sequences, store as LF only */
	if (c==0x0d)
	{
	  if (ISSET(tp->t_iflag, IGNCR))       // Ignore CR on input
	  {
		  BSET(tp->state,ST_CRSEEN);
		  return 0;
		}
		else if (ISSET(tp->t_iflag, ICRNL))  // Translate CR -> NR on input
		  c = 0x0a;
	}
	else if (c != 0x0a && ISSET(tp->state,ST_CRSEEN))
	{
		/* out of band CR, ok */
		BCLR(tp->state,ST_CRSEEN);
		if (putc(0x0d,rq) < 0)
		  return -1;
		if (nocan)
		  ret = ttecho(0x0d, tp);
	}
	else if ( c == 0x0a && ISSET(tp->t_iflag, INLCR))
	{
	  BCLR(tp->state, ST_CRSEEN);
	  c = 0x0d;
	}
	else if (ISCLR(lflag,EXTPROC))
	{
		BCLR(tp->state,ST_CRSEEN);

		/* internal processing */
		if (ISSET(lflag,ISIG))
		{
			if (CCEQ(cc[VINTR],c) /*|| CCEQ(cc[VQUIT],c)*/)
			{
				if (ISCLR(lflag,NOFLSH))
					ttflush(tp,3);
				ttecho(c,tp);
				pgsignal(tp->pgrp, SIGINT);
				goto endproc;
			}
		}
	}
	else
	  /* else was an LF or no CRSEEN */
		BCLR(tp->state,ST_CRSEEN);

	if (ret >= 0)
	{
		/* regular char or CR/LF: put in queue */
		if (putc(c,rq) >= 0)
		{
			if (nocan)
			  ret = ttecho(c,tp);
		}
	}
endproc:
	/* reaches here if something has been processed */
	ttstart(tp);
	return ret;
}