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