diff options
| -rw-r--r-- | src/serial.c | 176 | 
1 files changed, 176 insertions, 0 deletions
diff --git a/src/serial.c b/src/serial.c new file mode 100644 index 0000000..5fff1bd --- /dev/null +++ b/src/serial.c @@ -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; +}  | 
