* ser-unix.c [USE_{TERMIO,ALARM}_TIMEOUT]: New code to deal with
[deliverable/binutils-gdb.git] / gdb / ser-unix.c
CommitLineData
4e772f44
SG
1/* Serial interface for local (hardwired) serial ports on Un*x like systems
2 Copyright 1992, 1993 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, 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>
eca29634
JK
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)
4e772f44 37#include <sys/time.h>
eca29634
JK
38#endif
39#ifdef USE_ALARM_TIMEOUT
40#include <signal.h>
41#endif
4e772f44
SG
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
60static int
61hardwire_open(scb, name)
62 serial_t scb;
63 const char *name;
64{
65 scb->fd = open (name, O_RDWR);
66 if (scb->fd < 0)
4febd102 67 return -1;
4e772f44
SG
68
69 return 0;
70}
71
72static void
73hardwire_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
eca29634
JK
134#ifdef USE_ALARM_TIMEOUT
135/* Called when SIGALRM sent. */
136static void
137remote_timer ()
138{
139}
140#endif
141
4e772f44
SG
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
147static int
148hardwire_readchar(scb, timeout)
149 serial_t scb;
150 int timeout;
151{
4e772f44
SG
152 if (scb->bufcnt-- > 0)
153 return *scb->bufp++;
154
eca29634
JK
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 */
4e772f44 178
eca29634
JK
179 scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
180 }
181#endif /* HAVE_SELECT. */
4e772f44 182
eca29634
JK
183#ifdef USE_TERMIO_TIMEOUT
184 {
185 struct termio termio;
4e772f44 186
eca29634
JK
187 if (ioctl (scb->fd, TCGETA, &termio))
188 {
189 fprintf(stderr, "TCGETA failed: %s\n", safe_strerror(errno));
190 }
4e772f44 191
eca29634
JK
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? */
4febd102 203 return SERIAL_TIMEOUT;
eca29634
JK
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
4e772f44 216
eca29634
JK
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 */
4e772f44
SG
232
233 if (scb->bufcnt <= 0)
234 if (scb->bufcnt == 0)
4febd102 235 return SERIAL_EOF; /* 0 chars means end of file */
4e772f44 236 else
4febd102 237 return SERIAL_ERROR; /* Got an error from read */
4e772f44
SG
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
255static struct
256{
257 int rate;
258 int code;
259}
260baudtab[] =
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
280static int
281rate_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
293static int
294hardwire_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))
4febd102 302 return -1;
4e772f44
SG
303
304 cfsetospeed (&termios, rate_to_code (rate));
305 cfsetispeed (&termios, rate_to_code (rate));
306
307 if (tcsetattr (scb->fd, TCSANOW, &termios))
4febd102 308 return -1;
4e772f44
SG
309#endif
310
311#ifdef HAVE_TERMIO
312 struct termio termio;
313
314 if (ioctl (scb->fd, TCGETA, &termio))
4febd102 315 return -1;
4e772f44
SG
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))
4febd102 325 return -1;
4e772f44
SG
326#endif
327
328#ifdef HAVE_SGTTY
329 struct sgttyb sgttyb;
330
331 if (ioctl (scb->fd, TIOCGETP, &sgttyb))
4febd102 332 return -1;
4e772f44
SG
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))
4febd102 338 return -1;
4e772f44 339#endif
4febd102 340 return 0;
4e772f44
SG
341}
342
343static int
344hardwire_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
363static void
364hardwire_restore(scb)
365 serial_t scb;
366{
367}
368
369static void
370hardwire_close(scb)
371 serial_t scb;
372{
373 if (scb->fd < 0)
374 return;
375
4e772f44
SG
376 close(scb->fd);
377 scb->fd = -1;
378}
379
380static 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.043009 seconds and 4 git commands to generate.