chiark / gitweb /
*** empty log message ***
authorjames <james>
Thu, 14 Feb 2008 12:51:14 +0000 (12:51 +0000)
committerjames <james>
Thu, 14 Feb 2008 12:51:14 +0000 (12:51 +0000)
src/serial.c [new file with mode: 0644]

diff --git a/src/serial.c b/src/serial.c
new file mode 100644 (file)
index 0000000..5fff1bd
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * ptty.c:
+ *
+ * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
+ * All rights reserved.
+ *
+ */
+
+static char rcsid[] = "$Id$";
+
+/*
+ * $Log$
+ * Revision 1.1  2008/02/14 12:51:14  james
+ * *** empty log message ***
+ *
+ * Revision 1.4  2008/02/14 10:39:14  james
+ * *** empty log message ***
+ *
+ * Revision 1.3  2008/02/13 09:12:21  james
+ * *** empty log message ***
+ *
+ * Revision 1.2  2008/02/12 22:36:46  james
+ * *** empty log message ***
+ *
+ * Revision 1.1  2008/02/09 15:47:28  james
+ * *** empty log message ***
+ *
+ * Revision 1.2  2008/02/07 11:11:14  staffcvs
+ * *** empty log message ***
+ *
+ * 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"
+
+
+typedef struct
+{
+  TTY_SIGNATURE;
+  int fd;
+  pid_t child;
+} PTTY;
+
+
+static void
+ptty_close (TTY * _t)
+{
+  PTTY *t = (PTTY *) _t;
+
+  if (!t)
+    return;
+
+  close (t->fd);
+  free (t);
+}
+
+
+
+static int
+ptty_read (TTY * _t, void *buf, int len)
+{
+  PTTY *t = (PTTY *) _t;
+  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;
+}
+
+
+static int
+ptty_write (TTY * _t, void *buf, int len)
+{
+  int writ, done = 0;
+  PTTY *t = (PTTY *) _t;
+
+  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;
+}
+
+TTY *
+ptty_open (char *path, char *argv[])
+{
+  PTTY *t;
+  pid_t child;
+  char name[1024];
+  struct winsize winsize = { 0 };
+  struct termios termios;
+  int fd;
+  char *default_argv[] = { "-", (char *) 0 };
+
+
+  default_termios (&termios);
+
+  winsize.ws_row = VT102_ROWS;
+  winsize.ws_col = VT102_COLS;
+
+  child = forkpty (&fd, name, &termios, &winsize);
+
+  switch (child)
+    {
+    case -1:                   /*boo hiss */
+      return NULL;
+    case 0:                    /*waaah */
+      setenv ("TERM", "vt102", 1);
+      setenv ("LANG", "C", 1);
+      if (!path)
+        path = "/bin/sh";
+
+      if (!argv)
+        argv = default_argv;
+
+      execv (path, argv);
+      _exit (-1);
+    }
+
+  set_nonblocking (fd);
+
+  t = (PTTY *) malloc (sizeof (PTTY));
+
+  strncpy (t->name, name, sizeof (t->name));
+  t->name[sizeof (t->name) - 1] = 0;
+
+  t->recv = ptty_read;
+  t->xmit = ptty_write;
+  t->close = ptty_close;
+  t->fd = fd;
+  t->child = child;
+  t->rfd = t->fd;
+  t->wfd = t->fd;
+  t->size.x = winsize.ws_row;
+  t->size.y = winsize.ws_col;
+  t->blocked = 0;
+
+  return (TTY *) t;
+}