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