Beispiel #1
0
/*
 * Put the chars in the from queue on the end of the to queue.
 */
static void tty_catq(struct tty_queue *from, struct tty_queue *to)
{
  int c;

  while ((c = tty_getc(from)) != -1)
    tty_putc(c, to);
}
Beispiel #2
0
/*
 * Get command from the client.
 * return  < 0: error
 * return >= 0: size of buffer
 */
int get_nntp(char *buf, int max)
{
    int	    c, len;

    len = 0;
    memset(buf, 0, sizeof(buf));
    while (TRUE) {
	c = tty_getc(180);
	if (c <= 0) {
	    if (c == -2) {
		/*
		 * Timeout
		 */
		send_nntp("400 Service discontinued, timeout");
	    }
	    Syslog('+', "Receiver status %s", ttystat[- c]);
	    return c;
	}
	if ((c == '\r') || (c == '\n')) {
	    rcvdbytes += (len + 1);
	    return len;
	}
	else {
	    buf[len] = c;
	    len++;
	    buf[len] = '\0';
	}
	if (len >= max) {
	    WriteError("Input buffer full");
	    return len;
	}
    }

    return 0;	    /* Not reached */
}
Beispiel #3
0
/*
 * Start TTY output operation.
 */
static void
serial_start(struct tty *tp)
{
	struct serial_softc *sc = device_private(tp->t_dev);
	struct serial_port *port = sc->port;
	int c;

	while ((c = tty_getc(&tp->t_outq)) >= 0)
		sc->ops->xmt_char(port, c);
}
Beispiel #4
0
/*
 * Flush tty read and/or write queues, notifying anyone waiting.
 */
static void tty_flush(struct tty *tp, int rw)
{

  DPRINTF(TTYDB_CORE, ("tty_flush rw=%d\n", rw));

  if (rw & FREAD) {
    while (tty_getc(&tp->t_canq) != -1)
      continue;

    while (tty_getc(&tp->t_rawq) != -1)
      continue;

    sem_post(&tp->t_input);
  }

  if (rw & FWRITE) {
    tp->t_state &= ~TS_TTSTOP;
    tty_start(tp);
  }
}
Beispiel #5
0
/*
 * Process a read call on a tty device.
 */
int tty_read(struct tty *tp, struct uio *uio, size_t *size)
{
  unsigned char *cc;
  struct tty_queue *qp;
  int rc, tmp;
  u_char c;
  tcflag_t lflag;

  DPRINTF(TTYDB_CORE, ("tty_read\n"));

  lflag = tp->t_lflag;
  cc = tp->t_cc;
  qp = (lflag & ICANON) ? &tp->t_canq : &tp->t_rawq;

  size_t total = 0;
  for (int i = 0; i < uio->iovcnt; ++i) {
    /* If there is no input, wait it */
    while (ttyq_empty(qp)) {
      rc = sem_wait(&tp->t_input);
      if ((rc != 0 && errno == EINTR) || tp->t_state & TS_ISIG) {
        tp->t_state &= ~TS_ISIG;
        return -EINTR;
      }
    }

    size_t count = 0;
    char *buf = uio->iov[i].iov_base;
    size_t nbyte = uio->iov[i].iov_len;
    while (count < nbyte) {
      if ((tmp = tty_getc(qp)) == -1)
        break;

      c = (u_char)tmp;
      if (c == cc[VEOF] && (lflag & ICANON))
        break;

      ++count;
      if (copyout(&c, buf, 1))
        return -EFAULT;

      if ((lflag & ICANON) && (c == '\n' || c == cc[VEOL]))
        break;

      ++buf;
    }

    total += count;
  }

  *size = total;
  return 0;
}
Beispiel #6
0
//
// Read characters into a buffer, terminated by a '\n' character
// Note: the '\n' character is not stored
//
int
tty_getline(int chan, char *buf)
{
    char c;
    int len = 0;

    while (((c = tty_getc(chan)) != '\n') && (c != '\r')) {
        tty_putc(chan, c);
        *buf++ = c;
        len++;
    }
    *buf = '\0';
    return len;
}
Beispiel #7
0
int tty_expect(char *what,int timeout)
{
	time_t t1;
	int to=timeout,got=0,p=0,ch;
	calling=0;
	while(!got&&to>0) {
		t1=t_start();
		ch=tty_getc(to);
		if(ch<0)return ch;
		to-=t_time(t1);
		if(ch==what[p])p++;
		    else p=0;
		if(!what[p])got=1;
	}
	return got?OK:TIMEOUT;
}
Beispiel #8
0
int tty_gets(char *what,size_t n,int timeout)
{
	time_t t1;
	int to=timeout,p=0,ch=0;
	*what=0;
	while(to>0&&p<n-1&&ch!='\r'&&ch!='\n') {
		t1=t_start();
		ch=tty_getc(to);
		if(NOTTO(ch))return ch;
		to-=t_time(t1);
		if(ch>=0)what[p++]=ch;
	}
	what[p>0?--p:0]=0;
	if(p>0)DEBUG(('M',1,"<< %s",what));
	if(ch=='\r'||ch=='\n') {
		DEBUG(('M',5,"tty_gets: completed"));
		return OK;
	} else if(to<=0) {
		DEBUG(('M',3,"tty_gets: timed out"));
	} else DEBUG(('M',3,"tty_gets: line too long"));
	return TIMEOUT;
}
Beispiel #9
0
int
get_key(char *buf, size_t size, size_t *nread)
{
	static struct {
		union {
			const char *s;
			char c;
		} input;
		size_t length;
		int key;
	} keys[] = {
		{ { (char *)8 },		1,	DEL },
		{ { (char *)10 },		1,	ENTER },
		{ { (char *)127 },		1,	DEL },
		{ { (char *)CTRL('A') },	1,	CTRL_A },
		{ { (char *)CTRL('B') },	1,	LEFT },
		{ { (char *)CTRL('D') },	1,	CTRL_D },
		{ { (char *)CTRL('E') },	1,	CTRL_E },
		{ { (char *)CTRL('F') },	1,	RIGHT },
		{ { (char *)CTRL('K') },	1,	CTRL_K },
		{ { (char *)CTRL('N') },	1,	DOWN },
		{ { (char *)CTRL('P') },	1,	UP },
		{ { (char *)CTRL('U') },	1,	CTRL_U },
		{ { (char *)CTRL('W') },	1,	CTRL_W },
		{ { "\033\n" },			2,	ALT_ENTER },
		{ { "\033[A" },			3,	UP },
		{ { "\033OA" },			3,	UP },
		{ { "\033[B" },			3,	DOWN },
		{ { "\033OB" },			3,	DOWN },
		{ { "\033[C" },			3,	RIGHT },
		{ { "\033OC" },			3,	RIGHT },
		{ { "\033[D" },			3,	LEFT },
		{ { "\033OD" },			3,	LEFT },
		{ { NULL },			0,	0 },
	};
	const char	*input;
	int		 i;

	*nread = 0;
getc:
	buf[(*nread)++] = tty_getc();
	size--;
	for (i = 0; keys[i].input.s; i++) {
		input = keys[i].length > 1 ? keys[i].input.s : &keys[i].input.c;
		if (*nread > keys[i].length || strncmp(buf, input, *nread))
			continue;

		if (*nread == keys[i].length)
			return keys[i].key;

		/* Partial match found, continue reading. */
		if (size > 0)
			goto getc;
	}

	if (*nread > 1 && buf[0] == '\033' && (buf[1] == '[' || buf[1] == 'O'))
		/*
		 * A escape sequence which is not a supported key is being read.
		 * Ensure the whole sequence is read.
		 */
		while ((buf[*nread - 1] < '@' || buf[*nread - 1] > '~')
		    && size-- > 0)
			buf[(*nread)++] = tty_getc();

	if (!isu8start(buf[0]))
		return UNKNOWN;

	/*
	 * Ensure a whole Unicode character is read. The number of MSBs in the
	 * first octet of a Unicode character is equal to the number of octets
	 * the character consists of, followed by a zero. Therefore, as long as
	 * the MSB is not zero there is still bytes left to read.
	 */
	while (((buf[0] << *nread) & 0x80) == 0x80 && size-- > 0)
		buf[(*nread)++] = tty_getc();

	return UNKNOWN;
}