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.10  2008/02/24 00:42:53  james
14  * *** empty log message ***
15  *
16  * Revision 1.9  2008/02/23 13:05:58  staffcvs
17  * *** empty log message ***
18  *
19  * Revision 1.8  2008/02/23 11:48:37  james
20  * *** empty log message ***
21  *
22  * Revision 1.7  2008/02/22 17:07:00  james
23  * *** empty log message ***
24  *
25  * Revision 1.6  2008/02/22 14:51:54  james
26  * *** empty log message ***
27  *
28  * Revision 1.5  2008/02/15 23:52:12  james
29  * *** empty log message ***
30  *
31  * Revision 1.4  2008/02/14 10:39:14  james
32  * *** empty log message ***
33  *
34  * Revision 1.3  2008/02/13 09:12:21  james
35  * *** empty log message ***
36  *
37  * Revision 1.2  2008/02/12 22:36:46  james
38  * *** empty log message ***
39  *
40  * Revision 1.1  2008/02/09 15:47:28  james
41  * *** empty log message ***
42  *
43  * Revision 1.2  2008/02/07 11:11:14  staffcvs
44  * *** empty log message ***
45  *
46  * Revision 1.1  2008/02/07 01:02:52  james
47  * *** empty log message ***
48  *
49  * Revision 1.3  2008/02/06 17:53:28  james
50  * *** empty log message ***
51  *
52  * Revision 1.2  2008/02/04 02:05:06  james
53  * *** empty log message ***
54  *
55  * Revision 1.1  2008/02/04 01:32:39  james
56  * *** empty log message ***
57  *
58  */
59
60 #include "project.h"
61
62
63 typedef struct
64 {
65   TTY_SIGNATURE;
66   int fd;
67   pid_t child;
68 } PTTY;
69
70
71 static void
72 ptty_close (TTY * _t)
73 {
74   PTTY *t = (PTTY *) _t;
75
76   if (!t)
77     return;
78
79   close (t->fd);
80   free (t);
81 }
82
83
84
85 static int
86 ptty_read (TTY * _t, void *buf, int len)
87 {
88   PTTY *t = (PTTY *) _t;
89   int red, done = 0;
90
91   do
92     {
93
94       red = wrap_read (t->fd, buf, len);
95       if (red < 0)
96         return -1;
97       if (!red)
98         return done;
99
100       buf += red;
101       len -= red;
102       done += red;
103     }
104   while (len);
105
106
107   return done;
108 }
109
110
111 static int
112 ptty_write (TTY * _t, void *buf, int len)
113 {
114   int writ, done = 0;
115   PTTY *t = (PTTY *) _t;
116
117   do
118     {
119
120       writ = wrap_write (t->fd, buf, len);
121       if (writ < 0)
122         return -1;
123       if (!writ)
124         sleep (1);
125
126       buf += writ;
127       len -= writ;
128       done += writ;
129     }
130   while (len);
131
132
133   return done;
134 }
135
136 TTY *
137 ptty_open (char *path, char *argv[])
138 {
139   PTTY *t;
140   pid_t child;
141   char name[1024];
142   struct winsize winsize = { 0 };
143   struct termios ctermios = { 0 };
144   int fd;
145   char *default_argv[] = { "-", (char *) 0 };
146
147
148   client_termios (&ctermios);
149   winsize.ws_row = VT102_ROWS;
150   winsize.ws_col = VT102_COLS;
151
152   child = forkpty (&fd, name, &ctermios, &winsize);
153
154   switch (child)
155     {
156     case -1:                   /*boo hiss */
157       return NULL;
158     case 0:                    /*waaah */
159       setenv ("TERM", "xterm", 1);
160       if (!path)
161         path = "/bin/sh";
162
163       if (!argv)
164         argv = default_argv;
165
166       execv (path, argv);
167       _exit (-1);
168     }
169
170   set_nonblocking (fd);
171
172 #if 0
173   {
174     struct termios termios = { 0 };
175
176     tcgetattr (fd, &termios);
177     default_termios (&termios);
178     tcsetattr (fd, TCSANOW, &termios);
179   }
180 #endif
181
182   t = (PTTY *) malloc (sizeof (PTTY));
183
184   strncpy (t->name, name, sizeof (t->name));
185   t->name[sizeof (t->name) - 1] = 0;
186
187   t->recv = ptty_read;
188   t->xmit = ptty_write;
189   t->close = ptty_close;
190   t->fd = fd;
191   t->child = child;
192   t->rfd = t->fd;
193   t->wfd = t->fd;
194   t->size.x = winsize.ws_row;
195   t->size.y = winsize.ws_col;
196   t->blocked = 0;
197   t->hanging_up = 0;
198
199   return (TTY *) t;
200 }