chiark / gitweb /
*** empty log message ***
[sympathy.git] / src / ptty.c
1 /*
2  * ptty.c:
3  *
4  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id$";
10
11 /*
12  * $Log$
13  * Revision 1.1  2008/02/09 15:47:28  james
14  * *** empty log message ***
15  *
16  * Revision 1.2  2008/02/07 11:11:14  staffcvs
17  * *** empty log message ***
18  *
19  * Revision 1.1  2008/02/07 01:02:52  james
20  * *** empty log message ***
21  *
22  * Revision 1.3  2008/02/06 17:53:28  james
23  * *** empty log message ***
24  *
25  * Revision 1.2  2008/02/04 02:05:06  james
26  * *** empty log message ***
27  *
28  * Revision 1.1  2008/02/04 01:32:39  james
29  * *** empty log message ***
30  *
31  */
32
33 #include "project.h"
34
35
36 typedef struct {
37         TTY_SIGNATURE;
38         int fd;
39         pid_t child;
40 } PTTY;
41
42
43 void ptty_close(TTY *_t)
44 {
45 PTTY *t=(PTTY *) _t;
46
47 if (!t) return;
48
49 close(t->fd);
50 free(t);
51 }
52
53
54
55 static int
56 ptty_read (TTY * _t, void *buf, int len)
57 {
58 PTTY *t=(PTTY *)_t;
59   int red, done = 0;
60
61   do
62     {
63
64       red = wrap_read (t->fd, buf, len);
65       if (red < 0)
66         return -1;
67       if (!red)
68         return done;
69
70       buf += red;
71       len -= red;
72       done += red;
73     }
74   while (len);
75
76
77   return done;
78 }
79
80
81 static int
82 ptty_write (TTY * _t, void *buf, int len)
83 {
84   int writ, done = 0;
85   PTTY *t=(PTTY *) _t;
86
87   do
88     {
89
90       writ = wrap_write (t->fd, buf, len);
91       if (writ < 0)
92         return -1;
93       if (!writ)
94         sleep (1);
95
96       buf += writ;
97       len -= writ;
98       done += writ;
99     }
100   while (len);
101
102
103   return done;
104 }
105
106 TTY * ptty_open(char *path,char *argv[])
107 {
108   PTTY *t;
109   pid_t child;
110   char name[1024];
111   struct winsize winsize = { 0 };
112   struct termios termios;
113   int fd;
114   char *default_argv={"-",(char *) 0};
115
116   child = forkpty (&fd, name, &termios, &winsize);
117
118   switch (child)
119     {
120     case -1:                   /*boo hiss */
121       return -1;
122     case 0:                    /*waaah */
123       setenv ("TERM", "vt102", 1);
124       setenv ("LANG", "C", 1);
125         if (!path) 
126                 path="/bin/sh";
127  
128         if (!argv) 
129                 argv=default_argv;
130                 
131       execv (path,argv);
132       _exit (-1);
133     }
134
135   set_nonblocking (fd);
136
137   t=(PTTY*) malloc(sizeof(PTTY));
138
139   strncpy(t->name,name,sizeof(t->name));
140   t->name[sizeof(t->name)-1]=0;
141
142   t->read=ptty_read;
143   t->write=ptty_write;
144   t->close=ptty_close;
145
146   default_termios (&termios);
147
148   winsize.ws_row = VT102_ROWS;
149   winsize.ws_col = VT102_COLS;
150
151   t->fd = open_fd_to_pty (path,argv);
152   t->pid=child;
153   t->rfd=t->fd;
154   t->wfd=0;
155
156   return (TTY *) t;
157 }