* ser-unix.c [USE_{TERMIO,ALARM}_TIMEOUT]: New code to deal with
[deliverable/binutils-gdb.git] / gdb / ser-unix.c
1 /* Serial interface for local (hardwired) serial ports on Un*x like systems
2 Copyright 1992, 1993 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "defs.h"
21 #include "serial.h"
22 #include <fcntl.h>
23 #include <sys/types.h>
24
25 /* Note: HAVE_SELECT is not yet defined on all the systems which could
26 define it. The USE_ALARM_TIMEOUT code seems to work OK, though, so
27 it doesn't really matter. */
28 #if !defined (HAVE_SELECT)
29 #if defined (HAVE_TERMIO)
30 #define USE_TERMIO_TIMEOUT 1
31 #else
32 #define USE_ALARM_TIMEOUT 1
33 #endif
34 #endif
35
36 #if defined (HAVE_SELECT)
37 #include <sys/time.h>
38 #endif
39 #ifdef USE_ALARM_TIMEOUT
40 #include <signal.h>
41 #endif
42
43 #if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
44 #define HAVE_SGTTY
45 #endif
46
47 #ifdef HAVE_TERMIOS
48 #include <termios.h>
49 #include <unistd.h>
50 #endif
51 #ifdef HAVE_TERMIO
52 #include <sys/termio.h>
53 #endif
54 #ifdef HAVE_SGTTY
55 #include <sgtty.h>
56 #endif
57
58 /* Open up a real live device for serial I/O */
59
60 static int
61 hardwire_open(scb, name)
62 serial_t scb;
63 const char *name;
64 {
65 scb->fd = open (name, O_RDWR);
66 if (scb->fd < 0)
67 return -1;
68
69 return 0;
70 }
71
72 static void
73 hardwire_raw(scb)
74 serial_t scb;
75 {
76 #ifdef HAVE_TERMIOS
77 struct termios termios;
78
79 if (tcgetattr(scb->fd, &termios))
80 {
81 fprintf(stderr, "tcgetattr failed: %s\n", safe_strerror(errno));
82 }
83
84 termios.c_iflag = 0;
85 termios.c_oflag = 0;
86 termios.c_lflag = 0;
87 termios.c_cflag &= ~(CSIZE|PARENB);
88 termios.c_cflag |= CS8;
89 termios.c_cc[VMIN] = 0;
90 termios.c_cc[VTIME] = 0;
91
92 if (tcsetattr(scb->fd, TCSANOW, &termios))
93 {
94 fprintf(stderr, "tcsetattr failed: %s\n", safe_strerror(errno));
95 }
96 #endif
97
98 #ifdef HAVE_TERMIO
99 struct termio termio;
100
101 if (ioctl (scb->fd, TCGETA, &termio))
102 {
103 fprintf(stderr, "TCGETA failed: %s\n", safe_strerror(errno));
104 }
105
106 termio.c_iflag = 0;
107 termio.c_oflag = 0;
108 termio.c_lflag = 0;
109 termio.c_cflag &= ~(CSIZE|PARENB);
110 termio.c_cflag |= CS8;
111 termio.c_cc[VMIN] = 0;
112 termio.c_cc[VTIME] = 0;
113
114 if (ioctl (scb->fd, TCSETA, &termio))
115 {
116 fprintf(stderr, "TCSETA failed: %s\n", safe_strerror(errno));
117 }
118 #endif
119
120 #ifdef HAVE_SGTTY
121 struct sgttyb sgttyb;
122
123 if (ioctl (scb->fd, TIOCGETP, &sgttyb))
124 fprintf(stderr, "TIOCGETP failed: %s\n", safe_strerror(errno));
125
126 sgttyb.sg_flags |= RAW | ANYP;
127 sgttyb.sg_flags &= ~(CBREAK | ECHO);
128
129 if (ioctl (scb->fd, TIOCSETP, &sgttyb))
130 fprintf(stderr, "TIOCSETP failed: %s\n", safe_strerror(errno));
131 #endif
132 }
133
134 #ifdef USE_ALARM_TIMEOUT
135 /* Called when SIGALRM sent. */
136 static void
137 remote_timer ()
138 {
139 }
140 #endif
141
142 /* Read a character with user-specified timeout. TIMEOUT is number of seconds
143 to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
144 char if successful. Returns -2 if timeout expired, EOF if line dropped
145 dead, or -3 for any other error (see errno in that case). */
146
147 static int
148 hardwire_readchar(scb, timeout)
149 serial_t scb;
150 int timeout;
151 {
152 if (scb->bufcnt-- > 0)
153 return *scb->bufp++;
154
155 #ifdef HAVE_SELECT
156 {
157 int numfds;
158 struct timeval tv;
159 fd_set readfds;
160
161 FD_ZERO (&readfds);
162
163 tv.tv_sec = timeout;
164 tv.tv_usec = 0;
165
166 FD_SET(scb->fd, &readfds);
167
168 if (timeout >= 0)
169 numfds = select(scb->fd+1, &readfds, 0, 0, &tv);
170 else
171 numfds = select(scb->fd+1, &readfds, 0, 0, 0);
172
173 if (numfds <= 0)
174 if (numfds == 0)
175 return SERIAL_TIMEOUT;
176 else
177 return SERIAL_ERROR; /* Got an error from select */
178
179 scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
180 }
181 #endif /* HAVE_SELECT. */
182
183 #ifdef USE_TERMIO_TIMEOUT
184 {
185 struct termio termio;
186
187 if (ioctl (scb->fd, TCGETA, &termio))
188 {
189 fprintf(stderr, "TCGETA failed: %s\n", safe_strerror(errno));
190 }
191
192 termio.c_cc[VTIME] = timeout * 10;
193
194 if (ioctl (scb->fd, TCSETA, &termio))
195 {
196 fprintf(stderr, "TCSETA failed: %s\n", safe_strerror(errno));
197 }
198
199 scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
200 if (scb->bufcnt == 0)
201 /* Can this also mean end of file? Does "end of file" have any
202 meaning with ICANON clear? */
203 return SERIAL_TIMEOUT;
204 }
205 #endif /* USE_TERMIO_TIMEOUT. */
206
207 #ifdef USE_ALARM_TIMEOUT
208 {
209 void (*old_sigalrm_handler) ();
210 int save_errno;
211 #ifndef NO_SIGINTERRUPT
212 /* Cause SIGARLM to make read fail with EINTR. */
213 if (siginterrupt (SIGALRM, 1) != 0)
214 fprintf (stderr, "siginterrupt failed: %s\n", safe_strerror (errno));
215 #endif
216
217 old_sigalrm_handler = (void (*) ()) signal (SIGALRM, remote_timer);
218 if (old_sigalrm_handler == (void (*) ()) -1)
219 fprintf (stderr, "signal failed: %s\n", safe_strerror (errno));
220
221 alarm (timeout);
222 scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
223 save_errno = errno;
224 alarm (0);
225 signal (SIGALRM, old_sigalrm_handler);
226 if (scb->bufcnt < 0 && errno == EINTR)
227 {
228 return SERIAL_TIMEOUT;
229 }
230 }
231 #endif /* USE_ALARM_TIMEOUT */
232
233 if (scb->bufcnt <= 0)
234 if (scb->bufcnt == 0)
235 return SERIAL_EOF; /* 0 chars means end of file */
236 else
237 return SERIAL_ERROR; /* Got an error from read */
238
239 scb->bufcnt--;
240 scb->bufp = scb->buf;
241 return *scb->bufp++;
242 }
243
244 #ifndef B19200
245 #define B19200 EXTA
246 #endif
247
248 #ifndef B38400
249 #define B38400 EXTB
250 #endif
251
252 /* Translate baud rates from integers to damn B_codes. Unix should
253 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
254
255 static struct
256 {
257 int rate;
258 int code;
259 }
260 baudtab[] =
261 {
262 {50, B50},
263 {75, B75},
264 {110, B110},
265 {134, B134},
266 {150, B150},
267 {200, B200},
268 {300, B300},
269 {600, B600},
270 {1200, B1200},
271 {1800, B1800},
272 {2400, B2400},
273 {4800, B4800},
274 {9600, B9600},
275 {19200, B19200},
276 {38400, B38400},
277 {-1, -1},
278 };
279
280 static int
281 rate_to_code(rate)
282 int rate;
283 {
284 int i;
285
286 for (i = 0; baudtab[i].rate != -1; i++)
287 if (rate == baudtab[i].rate)
288 return baudtab[i].code;
289
290 return -1;
291 }
292
293 static int
294 hardwire_setbaudrate(scb, rate)
295 serial_t scb;
296 int rate;
297 {
298 #ifdef HAVE_TERMIOS
299 struct termios termios;
300
301 if (tcgetattr (scb->fd, &termios))
302 return -1;
303
304 cfsetospeed (&termios, rate_to_code (rate));
305 cfsetispeed (&termios, rate_to_code (rate));
306
307 if (tcsetattr (scb->fd, TCSANOW, &termios))
308 return -1;
309 #endif
310
311 #ifdef HAVE_TERMIO
312 struct termio termio;
313
314 if (ioctl (scb->fd, TCGETA, &termio))
315 return -1;
316
317 #ifndef CIBAUD
318 #define CIBAUD CBAUD
319 #endif
320
321 termio.c_cflag &= ~(CBAUD | CIBAUD);
322 termio.c_cflag |= rate_to_code (rate);
323
324 if (ioctl (scb->fd, TCSETA, &termio))
325 return -1;
326 #endif
327
328 #ifdef HAVE_SGTTY
329 struct sgttyb sgttyb;
330
331 if (ioctl (scb->fd, TIOCGETP, &sgttyb))
332 return -1;
333
334 sgttyb.sg_ispeed = rate_to_code (rate);
335 sgttyb.sg_ospeed = rate_to_code (rate);
336
337 if (ioctl (scb->fd, TIOCSETP, &sgttyb))
338 return -1;
339 #endif
340 return 0;
341 }
342
343 static int
344 hardwire_write(scb, str, len)
345 serial_t scb;
346 const char *str;
347 int len;
348 {
349 int cc;
350
351 while (len > 0)
352 {
353 cc = write(scb->fd, str, len);
354
355 if (cc < 0)
356 return 1;
357 len -= cc;
358 str += cc;
359 }
360 return 0;
361 }
362
363 static void
364 hardwire_restore(scb)
365 serial_t scb;
366 {
367 }
368
369 static void
370 hardwire_close(scb)
371 serial_t scb;
372 {
373 if (scb->fd < 0)
374 return;
375
376 close(scb->fd);
377 scb->fd = -1;
378 }
379
380 static struct serial_ops hardwire_ops =
381 {
382 "hardwire",
383 0,
384 hardwire_open,
385 hardwire_close,
386 hardwire_readchar,
387 hardwire_write,
388 hardwire_raw,
389 hardwire_restore,
390 hardwire_setbaudrate
391 };
392
393 _initialize_ser_hardwire ()
394 {
395 serial_add_interface (&hardwire_ops);
396 }
This page took 0.038991 seconds and 5 git commands to generate.