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