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