/*
- * testtty.c:
+ * tty.c:
*
* Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
* All rights reserved.
/*
* $Log$
- * Revision 1.1 2008/02/07 01:02:52 james
+ * Revision 1.10 2008/02/15 23:52:12 james
* *** empty log message ***
*
- * Revision 1.3 2008/02/06 17:53:28 james
+ * Revision 1.9 2008/02/15 03:32:07 james
* *** empty log message ***
*
- * Revision 1.2 2008/02/04 02:05:06 james
+ * Revision 1.8 2008/02/14 10:36:18 james
* *** empty log message ***
*
- * Revision 1.1 2008/02/04 01:32:39 james
+ * Revision 1.7 2008/02/14 10:34:30 james
+ * *** empty log message ***
+ *
+ * Revision 1.6 2008/02/13 16:59:34 james
+ * *** empty log message ***
+ *
+ * Revision 1.5 2008/02/13 16:57:29 james
+ * *** empty log message ***
+ *
+ * Revision 1.4 2008/02/12 22:36:46 james
+ * *** empty log message ***
+ *
+ * Revision 1.3 2008/02/09 15:47:28 james
* *** empty log message ***
*
*/
+
#include "project.h"
-static void
-set_nonblocking (int fd)
+static int
+speed_t_to_baud (speed_t s)
{
- long arg;
- arg = fcntl (fd, F_GETFL, arg);
- arg |= O_NONBLOCK;
- fcntl (fd, F_SETFL, arg);
-}
+ switch (s)
+ {
+#ifdef B0
+ case B0:
+ return 0;
+#endif
+#ifdef B50
+ case B50:
+ return 50;
+#endif
+#ifdef B75
+ case B75:
+ return 75;
+#endif
+#ifdef B110
+ case B110:
+ return 110;
+#endif
+#ifdef B134
+ case B134:
+ return 134;
+#endif
+#ifdef B150
+ case B150:
+ return 150;
+#endif
+#ifdef B200
+ case B200:
+ return 200;
+#endif
+#ifdef B300
+ case B300:
+ return 300;
+#endif
+#ifdef B600
+ case B600:
+ return 600;
+#endif
+#ifdef B1200
+ case B1200:
+ return 1200;
+#endif
+#ifdef B1800
+ case B1800:
+ return 1800;
+#endif
+#ifdef B2400
+ case B2400:
+ return 2400;
+#endif
+#ifdef B4800
+ case B4800:
+ return 4800;
+#endif
+#ifdef B9600
+ case B9600:
+ return 9600;
+#endif
+#ifdef B19200
+ case B19200:
+ return 19200;
+#endif
+#ifdef B38400
+ case B38400:
+ return 38400;
+#endif
+#ifdef B57600
+ case B57600:
+ return 57600;
+#endif
+#ifdef B115200
+ case B115200:
+ return 115200;
+#endif
+#ifdef B230400
+ case B230400:
+ return 230400;
+#endif
+ }
-static void
-set_blocking (int fd)
-{
- long arg;
- arg = fcntl (fd, F_GETFL, arg);
- arg &= ~O_NONBLOCK;
- fcntl (fd, F_SETFL, arg);
+ return -1;
}
-static void
-default_termios (struct termios *termios)
+static speed_t
+baud_to_speed_t (int baud)
{
-
- memset (termios, 0, sizeof (termios));
-
- termios->c_iflag = ICRNL | IXON;
- termios->c_oflag = OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0;
- termios->c_lflag =
- ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE;
-
- termios->c_cc[VINTR] = 003;
- termios->c_cc[VQUIT] = 034;
- termios->c_cc[VERASE] = 0177;
- termios->c_cc[VKILL] = 025;
- termios->c_cc[VEOF] = 004;
- termios->c_cc[VEOL] = 0;
- termios->c_cc[VEOL2] = 0;
- termios->c_cc[VSTART] = 021;
- termios->c_cc[VSTOP] = 023;
- termios->c_cc[VSUSP] = 032;
- termios->c_cc[VLNEXT] = 026;
- termios->c_cc[VWERASE] = 027;
- termios->c_cc[VREPRINT] = 022;
- termios->c_cc[VDISCARD] = 017;
-
- termios->c_cflag = CS8 | CREAD | CLOCAL;
-
- cfsetispeed (termios, B9600);
- cfsetospeed (termios, B9600);
+ switch (baud)
+ {
+#ifdef B0
+ case 0:
+ return B0;
+#endif
+#ifdef B50
+ case 50:
+ return B50;
+#endif
+#ifdef B75
+ case 75:
+ return B75;
+#endif
+#ifdef B110
+ case 110:
+ return B110;
+#endif
+#ifdef B134
+ case 134:
+ return B134;
+#endif
+#ifdef B150
+ case 150:
+ return B150;
+#endif
+#ifdef B200
+ case 200:
+ return B200;
+#endif
+#ifdef B300
+ case 300:
+ return B300;
+#endif
+#ifdef B600
+ case 600:
+ return B600;
+#endif
+#ifdef B1200
+ case 1200:
+ return B1200;
+#endif
+#ifdef B1800
+ case 1800:
+ return B1800;
+#endif
+#ifdef B2400
+ case 2400:
+ return B2400;
+#endif
+#ifdef B4800
+ case 4800:
+ return B4800;
+#endif
+#ifdef B9600
+ case 9600:
+ return B9600;
+#endif
+#ifdef B19200
+ case 19200:
+ return B19200;
+#endif
+#ifdef B38400
+ case 38400:
+ return B38400;
+#endif
+#ifdef B57600
+ case 57600:
+ return B57600;
+#endif
+#ifdef B115200
+ case 115200:
+ return B115200;
+#endif
+#ifdef B230400
+ case 230400:
+ return B230400;
+#endif
+ }
+ return -1;
}
-
-static int
-open_fd_to_bash (void) /*thump */
+void
+tty_pre_select (TTY * t, fd_set * rfds, fd_set * wfds)
{
- pid_t child;
- int fd;
- struct winsize winsize = { 0 };
- struct termios termios;
-
- default_termios (&termios);
-
- winsize.ws_row = VT102_ROWS;
- winsize.ws_col = VT102_COLS;
+ int line;
+ struct timeval now, dif;
- child = forkpty (&fd, NULL, &termios, &winsize);
-
- switch (child)
+ if (t->hanging_up)
{
- case -1: /*boo hiss */
- return -1;
- case 0: /*waaah */
- setenv ("TERM", "vt102", 1);
- execl ("/bin/sh", "-", (char *) 0);
- _exit (-1);
- }
- return fd;
-}
+ gettimeofday (&now, NULL);
+ timersub (&now, &t->hangup_clock, &dif);
+ if (dif.tv_sec)
+ {
+ fprintf (stderr, "+DTR\n");
+ line = TIOCM_DTR;
+ ioctl (t->rfd, TIOCMBIS, &line);
+ t->hanging_up = 0;
+ }
+ }
-TTY *
-tty_new_test (void)
-{
- TTY *t;
- t = (TTY *) malloc (sizeof (TTY));
- t->fd = open_fd_to_bash ();
-
- set_nonblocking (t->fd);
- return t;
+ FD_SET (t->rfd, rfds);
}
-static int
-wrap_read (int fd, void *buf, int len)
+int
+tty_get_status (TTY * t, TTY_Status * s)
{
- int red;
- red = read (fd, buf, len);
- if (!red)
+ s->lines = 0;
+ ioctl (t->rfd, TIOCMGET, &s->lines);
+ if (t->hanging_up)
+ fprintf (stderr, "s->lines & TIOCM_DTR=%x\n", s->lines & TIOCM_DTR);
+
+ if (tcgetattr (t->rfd, &s->termios))
return -1;
- if ((red < 0) && (errno == EAGAIN))
- red = 0;
+ s->baud = speed_t_to_baud (cfgetispeed (&s->termios));
+ s->blocked = t->blocked;
- return red;
+ return 0;
}
-static int
-wrap_write (int fd, void *buf, int len)
+void
+tty_set_baud (TTY * t, int rate)
{
- int writ;
+ struct termios tios = { 0 };
- writ = write (fd, buf, len);
- if (!writ)
- return -1;
+ speed_t s = baud_to_speed_t (rate);
- if ((writ < 0) && (errno == -EAGAIN))
- writ = 0;
+ if (s == (speed_t) - 1)
+ return;
- return writ;
+ if (tcgetattr (t->rfd, &tios))
+ return;
+
+ cfsetispeed (&tios, s);
+ cfsetospeed (&tios, s);
+
+ tcsetattr (t->rfd, TCSANOW, &tios);
}
-int
-tty_read (TTY * t, void *buf, int len)
+void
+tty_send_break (TTY * t)
{
- int red, done = 0;
+ tcsendbreak (t->wfd, 0);
+}
+void
+tty_set_flow (TTY * t, int flow)
+{
+ struct termios tios = { 0 };
- do
- {
+ if (tcgetattr (t->rfd, &tios))
+ return;
- red = wrap_read (t->fd, buf, len);
- if (red < 0)
- return -1;
- if (!red)
- return done;
+ if (flow)
+ tios.c_cflag |= CRTSCTS;
+ else
+ tios.c_cflag &= ~CRTSCTS;
- buf += red;
- len -= red;
- done += red;
- }
- while (len);
+ tcsetattr (t->rfd, TCSANOW, &tios);
+
+}
+
+void
+tty_hangup (TTY * t)
+{
+ int line;
+
+ line = TIOCM_DTR;
+ ioctl (t->rfd, TIOCMBIC, &line);
+ t->hanging_up = 1;
+ gettimeofday (&t->hangup_clock, NULL);
+ fprintf (stderr, "-DTR\n");
- return done;
}
+#if 0
int
-tty_write (TTY * t, void *buf, int len)
+tty_post_select (Context * c, fd_set * rfds, fd_set * wfds)
{
- int writ, done = 0;
-
-#if 0
- {
- int i;
- uint8_t *p = buf;
- for (i = 0; i < len; ++i)
- fprintf (stderr, "vw: %03o %c\n", p[i], p[i] > 31 ? p[i] : 32);
- }
-#endif
- do
+ if (FD_ISSET (c->t->rfd, rfds))
{
-
- writ = wrap_write (t->fd, buf, len);
- if (writ < 0)
+ if (vt102_dispatch (&c))
return -1;
- if (!writ)
- sleep (1);
-
- buf += writ;
- len -= writ;
- done += writ;
}
- while (len);
-
-
- return done;
+ return 0;
}
-void
-tty_free (TTY * t)
-{
- close (t->fd);
- free (t);
-}
+#endif