/*
* ptty.c:
*
* Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
* All rights reserved.
*
*/
static char rcsid[] = "$Id$";
/*
* $Log$
* Revision 1.17 2008/03/02 10:37:56 james
* *** empty log message ***
*
* Revision 1.16 2008/02/28 16:57:52 james
* *** empty log message ***
*
* Revision 1.15 2008/02/27 09:42:53 james
* *** empty log message ***
*
* Revision 1.14 2008/02/27 09:42:22 james
* *** empty log message ***
*
* Revision 1.13 2008/02/27 01:31:38 james
* *** empty log message ***
*
* Revision 1.12 2008/02/27 01:31:14 james
* *** empty log message ***
*
* Revision 1.11 2008/02/26 23:23:17 james
* *** empty log message ***
*
* Revision 1.10 2008/02/24 00:42:53 james
* *** empty log message ***
*
* Revision 1.9 2008/02/23 13:05:58 staffcvs
* *** empty log message ***
*
* Revision 1.8 2008/02/23 11:48:37 james
* *** empty log message ***
*
* Revision 1.7 2008/02/22 17:07:00 james
* *** empty log message ***
*
* Revision 1.6 2008/02/22 14:51:54 james
* *** empty log message ***
*
* Revision 1.5 2008/02/15 23:52:12 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[], CRT_Pos * size)
{
PTTY *t;
pid_t child;
char name[1024];
struct winsize winsize = { 0 };
struct termios ctermios = { 0 };
int fd;
char *default_argv[] = { "-", (char *) 0 };
client_termios (&ctermios);
winsize.ws_row = size ? size->y : VT102_ROWS_24;
winsize.ws_col = size ? size->x : VT102_COLS_80;
child = forkpty (&fd, name, &ctermios, &winsize);
switch (child) {
case -1: /*boo hiss */
return NULL;
case 0: /*waaah */
setenv ("TERM", "xterm", 1);
if (!path)
path = "/bin/sh";
if (!argv)
argv = default_argv;
execv (path, argv);
_exit (-1);
}
set_nonblocking (fd);
#if 0
{
struct termios termios = { 0 };
tcgetattr (fd, &termios);
default_termios (&termios);
tcsetattr (fd, TCSANOW, &termios);
}
#endif
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;
t->hanging_up = 0;
return (TTY *) t;
}