コード例 #1
0
ファイル: rlogin.c プロジェクト: JabirTech/Source
static void
stop(char cmdc)
{
	mode(0);
	(void)signal(SIGCHLD, SIG_IGN);
	(void)kill(CCEQ(deftty.c_cc[VSUSP], cmdc) ? 0 : getpid(), SIGTSTP);
	(void)signal(SIGCHLD, catch_child);
	mode(1);
	sigwinch(0);			/* check for size changes */
}
コード例 #2
0
ファイル: rlogin.c プロジェクト: JabirTech/Source
/*
 * writer: write to remote: 0 -> line.
 * ~.				terminate
 * ~^Z				suspend rlogin process.
 * ~<delayed-suspend char>	suspend rlogin process, but leave reader alone.
 */
static void
writer(void)
{
	int bol, local, n;
	char c;

	bol = 1;			/* beginning of line */
	local = 0;
	for (;;) {
		n = read(STDIN_FILENO, &c, 1);
		if (n <= 0) {
			if (n < 0 && errno == EINTR)
				continue;
			break;
		}
		/*
		 * If we're at the beginning of the line and recognize a
		 * command character, then we echo locally.  Otherwise,
		 * characters are echo'd remotely.  If the command character
		 * is doubled, this acts as a force and local echo is
		 * suppressed.
		 */
		if (bol) {
			bol = 0;
			if (!noescape && c == escapechar) {
				local = 1;
				continue;
			}
		} else if (local) {
			local = 0;
			if (c == '.' || CCEQ(deftty.c_cc[VEOF], c)) {
				echo(c);
				break;
			}
			if (CCEQ(deftty.c_cc[VSUSP], c) ||
			    CCEQ(deftty.c_cc[VDSUSP], c)) {
				bol = 1;
				echo(c);
				stop(c);
				continue;
			}
			if (c != escapechar)
				(void)write(rem, &escapechar, 1);
		}

		if (write(rem, &c, 1) == 0) {
			msg("line gone");
			break;
		}
		bol = CCEQ(deftty.c_cc[VKILL], c) ||
		    CCEQ(deftty.c_cc[VEOF], c) ||
		    CCEQ(deftty.c_cc[VINTR], c) ||
		    CCEQ(deftty.c_cc[VSUSP], c) ||
		    c == '\r' || c == '\n';
	}
}
コード例 #3
0
ファイル: ttypty.c プロジェクト: OS2World/DRV-PPtP
/*
 * Process read
 */
void ttread(RP rp, TTY tp, char far* bp, int nb)
{
	USHORT lflag = tp->t_lflag;
	CQ qp = &tp->inq;
	int cnt = 0;
	int eof = 1;	
	int c;

	/* read chars from queue */
	while (nb != 0)
	{
		c = getc(qp,NOPEEK);
		if (c < 0)
		  break;

		/* simplified ICANON processing */
		if (ISSET(lflag,ICANON))
		{
			if (CCEQ(tp->t_cc[VEOF],c))
			{
				eof = 1;
				break;
			}
		}
		bp[cnt++] = (char)c;
		nb--;
		eof = 0;
		if (ISSET(lflag,ICANON) && CCEQ(tp->t_cc[VEOL],c))
			break;
	}
	RWCNT(rp) = cnt;
	if (ISSET(lflag,ICANON) && eof)
		handle_eof(rp, tp, bp);

	return;
}
コード例 #4
0
ファイル: ttypty.c プロジェクト: OS2World/DRV-PPtP
/*
 * Perform OPOST processing, queue character into outq,
 * return -1 if outq full
 */
int ttoutput(int c, TTY tp)
{
	CQ qp = &tp->outq;
	USHORT oflag = tp->t_oflag;

	if (ISSET(oflag, OPOST))
	{
		/* OPOST: do tab expansion */
		if (c==TAB && ISSET(oflag,OXTABS) && ISCLR(tp->t_lflag,EXTPROC))
		{
			for (c = 8-(tp->ocol & 7); c>0; c--)
				if (putc(' ',qp) < 0)
					break;
			tp->ocol += 8-(tp->ocol & 7)-c;
			return c ? -1 : TAB;
		}
		
		if (CCEQ(tp->t_cc[VEOF],c) && ISSET(oflag,ONOEOT))
			return c;
			
		if (c == LF && ISSET(oflag,ONLCR))
		{
			tp->ocol = 0;
			if (putc(CR,qp) < 0) return -1;
			return putc(LF,qp) < 0 ? -1 : c;
		}
		
		if (c == CR && ISSET(oflag,OCRNL))
		{
			tp->ocol = 0;
			return putc(LF,qp) < 0 ? -1 : c;
		}
		
		if (c >= 'a' && c <= 'z' && ISSET(oflag,OLCUC))
			c -= ('a'-'A');
	}

	if (putc(c,qp) < 0)
		return -1;
	tp->ocol++;
	return c;
}
コード例 #5
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);
}
コード例 #6
0
ファイル: munge.c プロジェクト: GNUHurdTR/hurd
/* Place newly input character C on the input queue.  If all remaining
   pending input characters should be dropped, return 1; else return
   0.  */
int
input_character (int c)
{
  int lflag = termstate.c_lflag;
  int iflag = termstate.c_iflag;
  int cflag = termstate.c_cflag;
  cc_t *cc = termstate.c_cc;
  struct queue **qp = (lflag & ICANON) ? &rawq : &inputq;
  int flush = 0;

  /* Handle parity errors */
  if ((iflag & INPCK)
      && ((cflag & PARODD) ? checkoddpar (c) : checkevenpar (c)))
    {
      if (iflag & IGNPAR)
	goto alldone;
      else if (iflag & PARMRK)
	{
	  enqueue_quote (qp, CHAR_USER_QUOTE);
	  enqueue_quote (qp, '\0');
	  enqueue_quote (qp, c);
	  goto alldone;
	}
      else
	c = 0;
    }

  /* Check to see if we should send IXOFF */
  if ((iflag & IXOFF)
      && !qavail (*qp)
      && (cc[VSTOP] != _POSIX_VDISABLE))
    {
      poutput (cc[VSTOP]);
      termflags |= SENT_VSTOP;
    }

  /* Character mutations */
  if (!(iflag & ISTRIP) && (iflag & PARMRK) && (c == CHAR_USER_QUOTE))
    enqueue_quote (qp, CHAR_USER_QUOTE); /* cause doubling */

  if (iflag & ISTRIP)
    c &= 0x7f;

  /* Handle LNEXT right away */
  if (!external_processing && (termflags & LAST_LNEXT))
    {
      enqueue_quote (qp, c);
      echo_char (c, 0, 1);
      termflags &= ~LAST_LNEXT;
      goto alldone;
    }

  /* Mutate ILCASE */
  if (!external_processing && (iflag & ILCASE) && isalpha(c))
    {
      if (termflags & LAST_SLASH)
	erase_1 (0);	/* remove the slash from input */
      else
	c = isupper(c) ? tolower (c) : c;
    }

  /* IEXTEN control chars */
  if (!external_processing && (lflag & IEXTEN))
    {
      if (CCEQ (cc[VLNEXT], c))
	{
	  if (lflag & ECHO)
	    {
	      poutput ('^');
	      poutput ('\b');
	    }
	  termflags |= LAST_LNEXT;
	  goto alldone;
	}

      if (CCEQ (cc[VDISCARD], c))
	{
	  if (termflags & FLUSH_OUTPUT)
	    termflags &= ~FLUSH_OUTPUT;
	  else
	    {
	      drop_output ();
	      poutput (cc[VDISCARD]);
	      termflags |= FLUSH_OUTPUT;
	    }
	  goto alldone;
	}
    }

  /* Signals */
  if (!external_processing && (lflag & ISIG))
    {
      if (CCEQ (cc[VINTR], c) || CCEQ (cc[VQUIT], c))
	{
	  if (!(lflag & NOFLSH))
	    {
	      drop_output ();
	      clear_queue (inputq);
	      clear_queue (rawq);
	      flush = 1;
	    }
	  echo_char (c, 0, 0);
	  echo_qsize = 0;
	  echo_pstart = output_psize;
	  send_signal (CCEQ (cc[VINTR], c) ? SIGINT : SIGQUIT);
	  goto alldone;
	}

      if (CCEQ (cc[VSUSP], c))
	{
	  if (!(lflag & NOFLSH))
	    {
	      flush = 1;
	      clear_queue (inputq);
	      clear_queue (rawq);
	    }
	  echo_char (c, 0, 0);
	  echo_qsize = 0;
	  echo_pstart = output_psize;
	  send_signal (SIGTSTP);
	  goto alldone;
	}
    }

  /* IXON */
  if (!external_processing && (iflag & IXON))
    {
      if (CCEQ (cc[VSTOP], c))
	{
	  if (CCEQ(cc[VSTART], c) && (termflags & USER_OUTPUT_SUSP))
	    /* Toggle if VSTART == VSTOP.  Alldone code always turns
	       off USER_OUTPUT_SUSP. */
	    goto alldone;

	  termflags |= USER_OUTPUT_SUSP;
	  (*bottom->suspend_physical_output) ();
	  return flush;
	}
      if (CCEQ (cc[VSTART], c))
	goto alldone;
    }

  if (!external_processing)
    {
      /* Newline and carriage-return frobbing */
      if (c == '\r')
	{
	  if (iflag & ICRNL)
	    c = '\n';
	  else if (iflag & IGNCR)
	    goto alldone;
	}
      else if ((c == '\n') && (iflag & INLCR))
	c = '\r';

    }

  /* Canonical mode processing */
  if (!external_processing && (lflag & ICANON))
    {
      if (CCEQ (cc[VERASE], c))
	{
	  if (qsize(rawq))
	    erase_1 (c);
	  if (!(termflags & LAST_SLASH)
	      || !(lflag & IEXTEN))
	    goto alldone;
	}

      if (CCEQ (cc[VKILL], c))
	{
	  if (!(termflags & LAST_SLASH)
	      || !(lflag & IEXTEN))
	    {
	      if ((lflag & ECHOKE) && !(lflag & ECHOPRT)
		  && (echo_qsize == qsize (rawq)))
		{
		  while (output_psize > echo_pstart)
		    write_erase_sequence ();
		}
	      else
		{
		  echo_char (c, 0, 0);
		  if ((lflag & ECHOK) || (lflag & ECHOKE))
		    echo_char ('\n', 0, 0);
		}
	      clear_queue (rawq);
	      echo_qsize = 0;
	      echo_pstart = output_psize;
	      termflags &= ~(LAST_SLASH|LAST_LNEXT|INSIDE_HDERASE);
	      goto alldone;
	    }
	  else
	    erase_1 (0);	/* remove \ */
	}

      if (CCEQ (cc[VWERASE], c))
	{
	  /* If we are not going to echo the erase, then
	     echo a WERASE character right now.  (If we
	     passed it to erase_1; it would echo it multiple
	     times.) */
	  if (!(lflag & (ECHOPRT|ECHOE)))
	    echo_char (cc[VWERASE], 0, 1);

	  /* Erase whitespace */
	  while (qsize (rawq) && isblank (unquote_char (rawq->ce[-1])))
	    erase_1 (0);

	  /* Erase word. */
	  if (lflag & ALTWERASE)
	    /* For ALTWERASE, we erase back to the first blank */
	    while (qsize (rawq) && !isblank (unquote_char (rawq->ce[-1])))
	      erase_1 (0);
	  else
	    /* For regular WERASE, we erase back to the first nonalpha/_ */
	    while (qsize (rawq) && !isblank (unquote_char (rawq->ce[-1]))
		   && (isalnum (unquote_char (rawq->ce[-1]))
		       || (unquote_char (rawq->ce[-1]) != '_')))
	      erase_1 (0);

	  goto alldone;
	}

      if (CCEQ (cc[VREPRINT], c) && (lflag & IEXTEN))
	{
	  reprint_line ();
	  goto alldone;
	}

      if (CCEQ (cc[VSTATUS], c) && (lflag & ISIG) && (lflag & IEXTEN))
	{
	  send_signal (SIGINFO);
	  goto alldone;
	}
    }

  /* Now we have a character intended as input.  See if it will fit. */
  if (!qavail (*qp))
    {
      if (iflag & IMAXBEL)
	poutput ('\a');
      else
	{
	  /* Drop everything */
	  drop_output ();
	  clear_queue (inputq);
	  clear_queue (rawq);
	  echo_pstart = 0;
	  echo_qsize = 0;
	  flush = 1;
	}
      goto alldone;
    }

  /* Echo */
  echo_char (c, 0, 0);
  if (CCEQ (cc[VEOF], c) && (lflag & ECHO))
    {
      /* Special bizarre echo processing for VEOF character. */
      int n;
      n = echo_double (c, 0) ? 2 : output_width (c, output_psize);
      while (n--)
	poutput ('\b');
    }

  /* Put character on input queue */
  enqueue (qp, c);

  /* Check for break characters in canonical input processing */
  if (lflag & ICANON)
    {
      if (CCEQ (cc[VEOL], c)
	  || CCEQ (cc[VEOL2], c)
	  || CCEQ (cc[VEOF], c)
	  || c == '\n')
	/* Make input available */
	while (qsize (rawq))
	  enqueue (&inputq, dequeue (rawq));
    }

alldone:
  /* Restart output */
  if ((iflag & IXANY) || (CCEQ (cc[VSTART], c)))
    termflags &= ~USER_OUTPUT_SUSP;
  (*bottom->start_output) ();

  return flush;
}
コード例 #7
0
ファイル: tty_pty.c プロジェクト: Gwenio/DragonFlyBSD
/*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);
}
コード例 #8
0
ファイル: CanonRead.c プロジェクト: andreiw/UefiToolsPkg
/** Read a line from the input file in canonical mode.
    Perform echoing and input processing as directed by the termios flags.

    @param[in]    filp      A pointer to a file descriptor structure.

    @return     The number of characters in the input buffer, or -1 if there
                was an error.
**/
ssize_t
IIO_CanonRead (
  struct __filedes *filp
  )
{
  cIIO             *This;
  cFIFO            *InBuf;
  struct termios   *Termio;
  struct __filedes *fpOut;
  ssize_t           NumRead;
  wint_t            InChar;
  tcflag_t          IFlag;
  tcflag_t          LFlag;
  BOOLEAN           EchoIsOK;
  BOOLEAN           Activate;
  BOOLEAN           FirstRead;
  int               OutMode;
  UINTN             MaxColumn;
  UINTN             MaxRow;

  NumRead   = MAX_INPUT;    // Workaround "potentially uninitialized" warning
  EchoIsOK  = FALSE;
  FirstRead = TRUE;
  This      = filp->devdata;
  Termio    = &This->Termio;
  InBuf     = This->InBuf;

  // Get a copy of the flags we are going to use
  IFlag = Termio->c_iflag;
  LFlag = Termio->c_lflag;

  /* Determine what the current screen size is. Also validates the output device. */
  OutMode = IIO_GetOutputSize(STDOUT_FILENO, &MaxColumn, &MaxRow);
  if(OutMode >= 0) {
    /*  Set the maximum screen dimensions. */
    This->MaxColumn = MaxColumn;
    This->MaxRow    = MaxRow;

    /*  Record where the cursor is at the beginning of this Input operation.
        The currently set stdout device is used to determine this.  If there is
        no stdout, or stdout is not an interactive device, nothing is recorded.
    */
    if (IIO_GetCursorPosition(STDOUT_FILENO, &This->InitialXY.Column, &This->InitialXY.Row) >= 0) {
      This->CurrentXY.Column  = This->InitialXY.Column;
      This->CurrentXY.Row     = This->InitialXY.Row;
      EchoIsOK  = TRUE;   // Can only echo to stdout
    }
  }

  // For now, we only echo to stdout.
  fpOut = &gMD->fdarray[STDOUT_FILENO];

  //  Input and process characters until BufferSize is exhausted.
  do {
    ssize_t CharRead;

    CharRead = IIO_GetInChar(filp, FirstRead, &InChar);
    if (CharRead <= 0) {
      /*
       * Error or EOF.
       */
      NumRead = CharRead;
      break;
    }
    FirstRead = FALSE;
    Activate  = TRUE;
    if(InChar == CHAR_CARRIAGE_RETURN) {
      if((IFlag & IGNCR) != 0) {
        continue;   // Restart the do loop, discarding the CR
      }
      else if((IFlag & ICRNL) != 0) {
        InChar = L'\n';
      }
    }
    else if(InChar == CHAR_LINEFEED) {
      if((IFlag & INLCR) != 0) {
        InChar = L'\r';
      }
    }
    else if(CCEQ(Termio->c_cc[VQUIT], InChar) ||
            CCEQ(Termio->c_cc[VINTR], InChar)) {
      /*
       * This is currently broken/not-implemented,
       * but it is assumed that in ICANON mode,
       * Ctrl-C/Ctrl-\ are expected to do *something*.
       *
       * On LFLag & ISIG != 0, this should raise the
       * signal before returning EINTR.
       */
      if((LFlag & ISIG) != 0) {
        errno = EINTR;
      } else {
        /*
         * Whatever it takes to make I/O fail.
         */
        errno = EIO;
      }
      return -1;
    }
    else if(CCEQ(Termio->c_cc[VEOF], InChar)) {
      /*
       * Seen EOT.
       */
      InChar = IIO_ECHO_DISCARD;
    }
    else if(CCEQ(Termio->c_cc[VEOL], InChar)) {
      EchoIsOK = FALSE;   // Buffer, but don't echo this character
    }
    else if(CCEQ(Termio->c_cc[VERASE], InChar)) {
      InChar = IIO_ECHO_ERASE;
      Activate = FALSE;
    }
    else if(CCEQ(Termio->c_cc[VKILL], InChar)) {
      InChar = IIO_ECHO_KILL;
      Activate = FALSE;
    }
    else {
      if((InChar < TtySpecKeyMin) || (InChar >= TtyFunKeyMax)) {
        Activate = FALSE;
      }
    }
    /** The Echo function is responsible for:
          * Adding the character to the input buffer, if appropriate.
          * Removing characters from the input buffer for ERASE and KILL processing.
          * Visually removing characters from the screen if ECHOE is set.
          * Ensuring one can not backspace beyond the beginning of the input text.
          * Sending final echo strings to output.
    **/
    (void)This->Echo(fpOut, (wchar_t)InChar, EchoIsOK);
    NumRead = InBuf->Count(InBuf, AsElements);
  } while((NumRead < MAX_INPUT) &&
          (Activate == FALSE));

  return (ssize_t)NumRead;
}
コード例 #9
0
ファイル: ttypty.c プロジェクト: OS2World/DRV-PPtP
/*
 * 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;
}