/* * ptty.c: * * Copyright (c) 2008 James McKenzie , * All rights reserved. * */ static char rcsid[] = "$Id$"; /* * $Log$ * Revision 1.24 2012/06/22 10:22:25 james * *** empty log message *** * * Revision 1.23 2008/03/12 01:30:23 james * *** empty log message *** * * Revision 1.22 2008/03/12 01:26:56 james * *** empty log message *** * * Revision 1.21 2008/03/10 11:49:33 james * *** empty log message *** * * Revision 1.20 2008/03/07 13:16:02 james * *** empty log message *** * * Revision 1.19 2008/03/07 12:37:04 james * *** empty log message *** * * Revision 1.18 2008/03/03 06:04:42 james * *** empty log message *** * * 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; if (path[0] == '/') execv (path, argv); else execvp (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 *) xmalloc (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; }