aboutsummaryrefslogtreecommitdiffstats
path: root/src/tty.c
diff options
context:
space:
mode:
authorjames <>2008-02-07 01:05:06 +0000
committerjames <>2008-02-07 01:05:06 +0000
commit6928bcea1545df58c3cda2fecd0d90a27aeee9fe (patch)
tree0f19086c840ab64e39fbc8fd8208b19621d0122c /src/tty.c
parent9de8271b7ff6749da455c0224c16962c85d971ec (diff)
downloadsympathy-6928bcea1545df58c3cda2fecd0d90a27aeee9fe.tar.gz
sympathy-6928bcea1545df58c3cda2fecd0d90a27aeee9fe.tar.bz2
sympathy-6928bcea1545df58c3cda2fecd0d90a27aeee9fe.zip
*** empty log message ***
Diffstat (limited to 'src/tty.c')
-rw-r--r--src/tty.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/src/tty.c b/src/tty.c
new file mode 100644
index 0000000..adee8bf
--- /dev/null
+++ b/src/tty.c
@@ -0,0 +1,215 @@
+/*
+ * testtty.c:
+ *
+ * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
+ * All rights reserved.
+ *
+ */
+
+static char rcsid[] = "$Id$";
+
+/*
+ * $Log$
+ * Revision 1.1 2008/02/07 01:02:52 james
+ * *** empty log message ***
+ *
+ * Revision 1.3 2008/02/06 17:53:28 james
+ * *** empty log message ***
+ *
+ * Revision 1.2 2008/02/04 02:05:06 james
+ * *** empty log message ***
+ *
+ * Revision 1.1 2008/02/04 01:32:39 james
+ * *** empty log message ***
+ *
+ */
+
+#include "project.h"
+
+static void
+set_nonblocking (int fd)
+{
+ long arg;
+ arg = fcntl (fd, F_GETFL, arg);
+ arg |= O_NONBLOCK;
+ fcntl (fd, F_SETFL, arg);
+}
+
+static void
+set_blocking (int fd)
+{
+ long arg;
+ arg = fcntl (fd, F_GETFL, arg);
+ arg &= ~O_NONBLOCK;
+ fcntl (fd, F_SETFL, arg);
+}
+
+static void
+default_termios (struct termios *termios)
+{
+
+ 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);
+}
+
+
+static int
+open_fd_to_bash (void) /*thump */
+{
+ 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;
+
+ child = forkpty (&fd, NULL, &termios, &winsize);
+
+ switch (child)
+ {
+ case -1: /*boo hiss */
+ return -1;
+ case 0: /*waaah */
+ setenv ("TERM", "vt102", 1);
+ execl ("/bin/sh", "-", (char *) 0);
+ _exit (-1);
+ }
+
+ return fd;
+}
+
+
+TTY *
+tty_new_test (void)
+{
+ TTY *t;
+ t = (TTY *) malloc (sizeof (TTY));
+ t->fd = open_fd_to_bash ();
+
+ set_nonblocking (t->fd);
+
+ return t;
+}
+
+static int
+wrap_read (int fd, void *buf, int len)
+{
+ int red;
+
+ red = read (fd, buf, len);
+ if (!red)
+ return -1;
+
+ if ((red < 0) && (errno == EAGAIN))
+ red = 0;
+
+ return red;
+}
+
+static int
+wrap_write (int fd, void *buf, int len)
+{
+ int writ;
+
+ writ = write (fd, buf, len);
+ if (!writ)
+ return -1;
+
+ if ((writ < 0) && (errno == -EAGAIN))
+ writ = 0;
+
+ return writ;
+}
+
+int
+tty_read (TTY * t, void *buf, int len)
+{
+ int red, done = 0;
+
+
+ do
+ {
+
+ red = wrap_read (t->fd, buf, len);
+ if (red < 0)
+ return -1;
+ if (!red)
+ return done;
+
+ buf += red;
+ len -= red;
+ done += red;
+ }
+ while (len);
+
+
+ return done;
+}
+
+
+int
+tty_write (TTY * t, void *buf, int len)
+{
+ 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
+ {
+
+ writ = wrap_write (t->fd, buf, len);
+ if (writ < 0)
+ return -1;
+ if (!writ)
+ sleep (1);
+
+ buf += writ;
+ len -= writ;
+ done += writ;
+ }
+ while (len);
+
+
+ return done;
+}
+
+void
+tty_free (TTY * t)
+{
+ close (t->fd);
+ free (t);
+}