chiark / gitweb /
serialmgr: Look for things in /usr, not /usr/local
[sympathy.git] / src / ptty.c
1 /* 
2  * ptty.c:
3  *
4  * Copyright (c) 2008 James McKenzie <sympathy@madingley.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id: ptty.c,v 1.23 2008/03/12 01:30:23 james Exp $";
10
11 /* 
12  * $Log: ptty.c,v $
13  * Revision 1.23  2008/03/12 01:30:23  james
14  * *** empty log message ***
15  *
16  * Revision 1.22  2008/03/12 01:26:56  james
17  * *** empty log message ***
18  *
19  * Revision 1.21  2008/03/10 11:49:33  james
20  * *** empty log message ***
21  *
22  * Revision 1.20  2008/03/07 13:16:02  james
23  * *** empty log message ***
24  *
25  * Revision 1.19  2008/03/07 12:37:04  james
26  * *** empty log message ***
27  *
28  * Revision 1.18  2008/03/03 06:04:42  james
29  * *** empty log message ***
30  *
31  * Revision 1.17  2008/03/02 10:37:56  james
32  * *** empty log message ***
33  *
34  * Revision 1.16  2008/02/28 16:57:52  james
35  * *** empty log message ***
36  *
37  * Revision 1.15  2008/02/27 09:42:53  james
38  * *** empty log message ***
39  *
40  * Revision 1.14  2008/02/27 09:42:22  james
41  * *** empty log message ***
42  *
43  * Revision 1.13  2008/02/27 01:31:38  james
44  * *** empty log message ***
45  *
46  * Revision 1.12  2008/02/27 01:31:14  james
47  * *** empty log message ***
48  *
49  * Revision 1.11  2008/02/26 23:23:17  james
50  * *** empty log message ***
51  *
52  * Revision 1.10  2008/02/24 00:42:53  james
53  * *** empty log message ***
54  *
55  * Revision 1.9  2008/02/23 13:05:58  staffcvs
56  * *** empty log message ***
57  *
58  * Revision 1.8  2008/02/23 11:48:37  james
59  * *** empty log message ***
60  *
61  * Revision 1.7  2008/02/22 17:07:00  james
62  * *** empty log message ***
63  *
64  * Revision 1.6  2008/02/22 14:51:54  james
65  * *** empty log message ***
66  *
67  * Revision 1.5  2008/02/15 23:52:12  james
68  * *** empty log message ***
69  *
70  * Revision 1.4  2008/02/14 10:39:14  james
71  * *** empty log message ***
72  *
73  * Revision 1.3  2008/02/13 09:12:21  james
74  * *** empty log message ***
75  *
76  * Revision 1.2  2008/02/12 22:36:46  james
77  * *** empty log message ***
78  *
79  * Revision 1.1  2008/02/09 15:47:28  james
80  * *** empty log message ***
81  *
82  * Revision 1.2  2008/02/07 11:11:14  staffcvs
83  * *** empty log message ***
84  *
85  * Revision 1.1  2008/02/07 01:02:52  james
86  * *** empty log message ***
87  *
88  * Revision 1.3  2008/02/06 17:53:28  james
89  * *** empty log message ***
90  *
91  * Revision 1.2  2008/02/04 02:05:06  james
92  * *** empty log message ***
93  *
94  * Revision 1.1  2008/02/04 01:32:39  james
95  * *** empty log message ***
96  *
97  */
98
99 #include "project.h"
100
101
102 typedef struct {
103   TTY_SIGNATURE;
104   int fd;
105   pid_t child;
106 } PTTY;
107
108
109 static void
110 ptty_close (TTY * _t)
111 {
112   PTTY *t = (PTTY *) _t;
113
114   if (!t)
115     return;
116
117   close (t->fd);
118   free (t);
119 }
120
121
122
123 static int
124 ptty_read (TTY * _t, void *buf, int len)
125 {
126   PTTY *t = (PTTY *) _t;
127   int red, done = 0;
128
129   do {
130
131     red = wrap_read (t->fd, buf, len);
132     if (red < 0)
133       return -1;
134     if (!red)
135       return done;
136
137     buf += red;
138     len -= red;
139     done += red;
140   }
141   while (len);
142
143
144   return done;
145 }
146
147
148 static int
149 ptty_write (TTY * _t, void *buf, int len)
150 {
151   int writ, done = 0;
152   PTTY *t = (PTTY *) _t;
153
154   do {
155
156     writ = wrap_write (t->fd, buf, len);
157     if (writ < 0)
158       return -1;
159     if (!writ)
160       sleep (1);
161
162     buf += writ;
163     len -= writ;
164     done += writ;
165   }
166   while (len);
167
168
169   return done;
170 }
171
172 TTY *
173 ptty_open (char *path, char *argv[], CRT_Pos * size)
174 {
175   PTTY *t;
176   pid_t child;
177   char name[1024];
178   struct winsize winsize = { 0 };
179   struct termios ctermios = { 0 };
180   int fd;
181   char *default_argv[] = { "-", (char *) 0 };
182
183
184   client_termios (&ctermios);
185   winsize.ws_row = size ? size->y : VT102_ROWS_24;
186   winsize.ws_col = size ? size->x : VT102_COLS_80;
187
188   child = forkpty (&fd, name, &ctermios, &winsize);
189
190   switch (child) {
191   case -1:                     /* boo hiss */
192     return NULL;
193   case 0:                      /* waaah */
194     setenv ("TERM", "xterm", 1);
195     if (!path)
196       path = "/bin/sh";
197
198     if (!argv)
199       argv = default_argv;
200
201     if (path[0] == '/')
202       execv (path, argv);
203     else
204       execvp (path, argv);
205
206     _exit (-1);
207   }
208
209   set_nonblocking (fd);
210
211 #if 0
212   {
213     struct termios termios = { 0 };
214
215     tcgetattr (fd, &termios);
216     default_termios (&termios);
217     tcsetattr (fd, TCSANOW, &termios);
218   }
219 #endif
220
221   t = (PTTY *) xmalloc (sizeof (PTTY));
222
223   strncpy (t->name, name, sizeof (t->name));
224   t->name[sizeof (t->name) - 1] = 0;
225
226   t->recv = ptty_read;
227   t->xmit = ptty_write;
228   t->close = ptty_close;
229   t->fd = fd;
230   t->child = child;
231   t->rfd = t->fd;
232   t->wfd = t->fd;
233   t->size.x = winsize.ws_row;
234   t->size.y = winsize.ws_col;
235   t->blocked = 0;
236   t->hanging_up = 0;
237
238   return (TTY *) t;
239 }