Commit | Line | Data |
---|---|---|
c906108c | 1 | /* Serial interface for local (hardwired) serial ports on Un*x like systems |
1e4728e7 | 2 | |
6aba47ca DJ |
3 | Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2003, |
4 | 2004, 2005, 2007 Free Software Foundation, Inc. | |
c906108c | 5 | |
c5aa993b | 6 | This file is part of GDB. |
c906108c | 7 | |
c5aa993b JM |
8 | This program is free software; you can redistribute it and/or modify |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2 of the License, or | |
11 | (at your option) any later version. | |
c906108c | 12 | |
c5aa993b JM |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
c906108c | 17 | |
c5aa993b JM |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software | |
197e01b6 EZ |
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, |
21 | Boston, MA 02110-1301, USA. */ | |
c906108c SS |
22 | |
23 | #include "defs.h" | |
24 | #include "serial.h" | |
3eb25fda | 25 | #include "ser-base.h" |
c2c6d25f JM |
26 | #include "ser-unix.h" |
27 | ||
c906108c SS |
28 | #include <fcntl.h> |
29 | #include <sys/types.h> | |
30 | #include "terminal.h" | |
c2c6d25f JM |
31 | #include <sys/socket.h> |
32 | #include <sys/time.h> | |
33 | ||
0ea3f30e | 34 | #include "gdb_select.h" |
c2c6d25f | 35 | #include "gdb_string.h" |
23776285 | 36 | #include "gdbcmd.h" |
c2c6d25f | 37 | |
c906108c SS |
38 | #ifdef HAVE_TERMIOS |
39 | ||
40 | struct hardwire_ttystate | |
c5aa993b JM |
41 | { |
42 | struct termios termios; | |
43 | }; | |
23776285 MR |
44 | |
45 | #ifdef CRTSCTS | |
46 | /* Boolean to explicitly enable or disable h/w flow control. */ | |
47 | static int serial_hwflow; | |
48 | static void | |
49 | show_serial_hwflow (struct ui_file *file, int from_tty, | |
50 | struct cmd_list_element *c, const char *value) | |
51 | { | |
52 | fprintf_filtered (file, _("Hardware flow control is %s.\n"), value); | |
53 | } | |
54 | #endif | |
55 | ||
c906108c SS |
56 | #endif /* termios */ |
57 | ||
58 | #ifdef HAVE_TERMIO | |
59 | ||
60 | /* It is believed that all systems which have added job control to SVR3 | |
61 | (e.g. sco) have also added termios. Even if not, trying to figure out | |
62 | all the variations (TIOCGPGRP vs. TCGETPGRP, etc.) would be pretty | |
63 | bewildering. So we don't attempt it. */ | |
64 | ||
65 | struct hardwire_ttystate | |
c5aa993b JM |
66 | { |
67 | struct termio termio; | |
68 | }; | |
c906108c SS |
69 | #endif /* termio */ |
70 | ||
71 | #ifdef HAVE_SGTTY | |
c906108c | 72 | struct hardwire_ttystate |
c5aa993b JM |
73 | { |
74 | struct sgttyb sgttyb; | |
75 | struct tchars tc; | |
76 | struct ltchars ltc; | |
77 | /* Line discipline flags. */ | |
78 | int lmode; | |
79 | }; | |
c906108c SS |
80 | #endif /* sgtty */ |
81 | ||
819cc324 AC |
82 | static int hardwire_open (struct serial *scb, const char *name); |
83 | static void hardwire_raw (struct serial *scb); | |
84 | static int wait_for (struct serial *scb, int timeout); | |
85 | static int hardwire_readchar (struct serial *scb, int timeout); | |
86 | static int do_hardwire_readchar (struct serial *scb, int timeout); | |
c2c6d25f | 87 | static int rate_to_code (int rate); |
819cc324 AC |
88 | static int hardwire_setbaudrate (struct serial *scb, int rate); |
89 | static void hardwire_close (struct serial *scb); | |
90 | static int get_tty_state (struct serial *scb, | |
91 | struct hardwire_ttystate * state); | |
92 | static int set_tty_state (struct serial *scb, | |
93 | struct hardwire_ttystate * state); | |
94 | static serial_ttystate hardwire_get_tty_state (struct serial *scb); | |
95 | static int hardwire_set_tty_state (struct serial *scb, serial_ttystate state); | |
96 | static int hardwire_noflush_set_tty_state (struct serial *, serial_ttystate, | |
97 | serial_ttystate); | |
98 | static void hardwire_print_tty_state (struct serial *, serial_ttystate, | |
99 | struct ui_file *); | |
100 | static int hardwire_drain_output (struct serial *); | |
101 | static int hardwire_flush_output (struct serial *); | |
102 | static int hardwire_flush_input (struct serial *); | |
103 | static int hardwire_send_break (struct serial *); | |
104 | static int hardwire_setstopbits (struct serial *, int); | |
105 | ||
c2c6d25f JM |
106 | void _initialize_ser_hardwire (void); |
107 | ||
c906108c SS |
108 | /* Open up a real live device for serial I/O */ |
109 | ||
110 | static int | |
819cc324 | 111 | hardwire_open (struct serial *scb, const char *name) |
c906108c SS |
112 | { |
113 | scb->fd = open (name, O_RDWR); | |
114 | if (scb->fd < 0) | |
115 | return -1; | |
116 | ||
117 | return 0; | |
118 | } | |
119 | ||
120 | static int | |
819cc324 | 121 | get_tty_state (struct serial *scb, struct hardwire_ttystate *state) |
c906108c SS |
122 | { |
123 | #ifdef HAVE_TERMIOS | |
c5aa993b | 124 | if (tcgetattr (scb->fd, &state->termios) < 0) |
c906108c SS |
125 | return -1; |
126 | ||
127 | return 0; | |
128 | #endif | |
129 | ||
130 | #ifdef HAVE_TERMIO | |
131 | if (ioctl (scb->fd, TCGETA, &state->termio) < 0) | |
132 | return -1; | |
133 | return 0; | |
134 | #endif | |
135 | ||
136 | #ifdef HAVE_SGTTY | |
137 | if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0) | |
138 | return -1; | |
139 | if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0) | |
140 | return -1; | |
141 | if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0) | |
142 | return -1; | |
143 | if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0) | |
144 | return -1; | |
145 | ||
146 | return 0; | |
147 | #endif | |
148 | } | |
149 | ||
150 | static int | |
819cc324 | 151 | set_tty_state (struct serial *scb, struct hardwire_ttystate *state) |
c906108c SS |
152 | { |
153 | #ifdef HAVE_TERMIOS | |
c5aa993b | 154 | if (tcsetattr (scb->fd, TCSANOW, &state->termios) < 0) |
c906108c SS |
155 | return -1; |
156 | ||
157 | return 0; | |
158 | #endif | |
159 | ||
160 | #ifdef HAVE_TERMIO | |
161 | if (ioctl (scb->fd, TCSETA, &state->termio) < 0) | |
162 | return -1; | |
163 | return 0; | |
164 | #endif | |
165 | ||
166 | #ifdef HAVE_SGTTY | |
167 | if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0) | |
168 | return -1; | |
169 | if (ioctl (scb->fd, TIOCSETC, &state->tc) < 0) | |
170 | return -1; | |
171 | if (ioctl (scb->fd, TIOCSLTC, &state->ltc) < 0) | |
172 | return -1; | |
173 | if (ioctl (scb->fd, TIOCLSET, &state->lmode) < 0) | |
174 | return -1; | |
175 | ||
176 | return 0; | |
177 | #endif | |
178 | } | |
179 | ||
180 | static serial_ttystate | |
819cc324 | 181 | hardwire_get_tty_state (struct serial *scb) |
c906108c SS |
182 | { |
183 | struct hardwire_ttystate *state; | |
184 | ||
c5aa993b | 185 | state = (struct hardwire_ttystate *) xmalloc (sizeof *state); |
c906108c | 186 | |
c5aa993b | 187 | if (get_tty_state (scb, state)) |
c906108c SS |
188 | return NULL; |
189 | ||
c5aa993b | 190 | return (serial_ttystate) state; |
c906108c SS |
191 | } |
192 | ||
193 | static int | |
819cc324 | 194 | hardwire_set_tty_state (struct serial *scb, serial_ttystate ttystate) |
c906108c SS |
195 | { |
196 | struct hardwire_ttystate *state; | |
197 | ||
c5aa993b | 198 | state = (struct hardwire_ttystate *) ttystate; |
c906108c | 199 | |
c5aa993b | 200 | return set_tty_state (scb, state); |
c906108c SS |
201 | } |
202 | ||
203 | static int | |
819cc324 | 204 | hardwire_noflush_set_tty_state (struct serial *scb, |
c2c6d25f JM |
205 | serial_ttystate new_ttystate, |
206 | serial_ttystate old_ttystate) | |
c906108c SS |
207 | { |
208 | struct hardwire_ttystate new_state; | |
209 | #ifdef HAVE_SGTTY | |
210 | struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate; | |
211 | #endif | |
212 | ||
c5aa993b | 213 | new_state = *(struct hardwire_ttystate *) new_ttystate; |
c906108c SS |
214 | |
215 | /* Don't change in or out of raw mode; we don't want to flush input. | |
216 | termio and termios have no such restriction; for them flushing input | |
217 | is separate from setting the attributes. */ | |
218 | ||
219 | #ifdef HAVE_SGTTY | |
220 | if (state->sgttyb.sg_flags & RAW) | |
221 | new_state.sgttyb.sg_flags |= RAW; | |
222 | else | |
223 | new_state.sgttyb.sg_flags &= ~RAW; | |
224 | ||
225 | /* I'm not sure whether this is necessary; the manpage just mentions | |
226 | RAW not CBREAK. */ | |
227 | if (state->sgttyb.sg_flags & CBREAK) | |
228 | new_state.sgttyb.sg_flags |= CBREAK; | |
229 | else | |
230 | new_state.sgttyb.sg_flags &= ~CBREAK; | |
231 | #endif | |
232 | ||
233 | return set_tty_state (scb, &new_state); | |
234 | } | |
235 | ||
236 | static void | |
819cc324 | 237 | hardwire_print_tty_state (struct serial *scb, |
c2c6d25f | 238 | serial_ttystate ttystate, |
d9fcf2fb | 239 | struct ui_file *stream) |
c906108c SS |
240 | { |
241 | struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate; | |
242 | int i; | |
243 | ||
244 | #ifdef HAVE_TERMIOS | |
c2c6d25f | 245 | fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n", |
2acceee2 JM |
246 | (int) state->termios.c_iflag, |
247 | (int) state->termios.c_oflag); | |
c2c6d25f | 248 | fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x\n", |
2acceee2 JM |
249 | (int) state->termios.c_cflag, |
250 | (int) state->termios.c_lflag); | |
c906108c SS |
251 | #if 0 |
252 | /* This not in POSIX, and is not really documented by those systems | |
253 | which have it (at least not Sun). */ | |
c2c6d25f | 254 | fprintf_filtered (stream, "c_line = 0x%x.\n", state->termios.c_line); |
c906108c | 255 | #endif |
c2c6d25f | 256 | fprintf_filtered (stream, "c_cc: "); |
c906108c | 257 | for (i = 0; i < NCCS; i += 1) |
c2c6d25f JM |
258 | fprintf_filtered (stream, "0x%x ", state->termios.c_cc[i]); |
259 | fprintf_filtered (stream, "\n"); | |
c906108c SS |
260 | #endif |
261 | ||
262 | #ifdef HAVE_TERMIO | |
c2c6d25f JM |
263 | fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n", |
264 | state->termio.c_iflag, state->termio.c_oflag); | |
265 | fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n", | |
266 | state->termio.c_cflag, state->termio.c_lflag, | |
267 | state->termio.c_line); | |
268 | fprintf_filtered (stream, "c_cc: "); | |
c906108c | 269 | for (i = 0; i < NCC; i += 1) |
c2c6d25f JM |
270 | fprintf_filtered (stream, "0x%x ", state->termio.c_cc[i]); |
271 | fprintf_filtered (stream, "\n"); | |
c906108c SS |
272 | #endif |
273 | ||
274 | #ifdef HAVE_SGTTY | |
c2c6d25f JM |
275 | fprintf_filtered (stream, "sgttyb.sg_flags = 0x%x.\n", |
276 | state->sgttyb.sg_flags); | |
c906108c | 277 | |
c2c6d25f | 278 | fprintf_filtered (stream, "tchars: "); |
c5aa993b | 279 | for (i = 0; i < (int) sizeof (struct tchars); i++) |
c2c6d25f | 280 | fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->tc)[i]); |
64122a8b | 281 | fprintf_filtered (stream, "\n"); |
c906108c | 282 | |
c2c6d25f | 283 | fprintf_filtered (stream, "ltchars: "); |
c5aa993b | 284 | for (i = 0; i < (int) sizeof (struct ltchars); i++) |
c2c6d25f JM |
285 | fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->ltc)[i]); |
286 | fprintf_filtered (stream, "\n"); | |
c906108c | 287 | |
c2c6d25f | 288 | fprintf_filtered (stream, "lmode: 0x%x\n", state->lmode); |
c906108c SS |
289 | #endif |
290 | } | |
291 | ||
292 | /* Wait for the output to drain away, as opposed to flushing (discarding) it */ | |
293 | ||
294 | static int | |
819cc324 | 295 | hardwire_drain_output (struct serial *scb) |
c906108c SS |
296 | { |
297 | #ifdef HAVE_TERMIOS | |
298 | return tcdrain (scb->fd); | |
299 | #endif | |
300 | ||
301 | #ifdef HAVE_TERMIO | |
302 | return ioctl (scb->fd, TCSBRK, 1); | |
303 | #endif | |
304 | ||
305 | #ifdef HAVE_SGTTY | |
306 | /* Get the current state and then restore it using TIOCSETP, | |
307 | which should cause the output to drain and pending input | |
308 | to be discarded. */ | |
309 | { | |
310 | struct hardwire_ttystate state; | |
311 | if (get_tty_state (scb, &state)) | |
312 | { | |
313 | return (-1); | |
314 | } | |
315 | else | |
316 | { | |
317 | return (ioctl (scb->fd, TIOCSETP, &state.sgttyb)); | |
318 | } | |
319 | } | |
c5aa993b | 320 | #endif |
c906108c SS |
321 | } |
322 | ||
323 | static int | |
819cc324 | 324 | hardwire_flush_output (struct serial *scb) |
c906108c SS |
325 | { |
326 | #ifdef HAVE_TERMIOS | |
327 | return tcflush (scb->fd, TCOFLUSH); | |
328 | #endif | |
329 | ||
330 | #ifdef HAVE_TERMIO | |
331 | return ioctl (scb->fd, TCFLSH, 1); | |
332 | #endif | |
333 | ||
334 | #ifdef HAVE_SGTTY | |
335 | /* This flushes both input and output, but we can't do better. */ | |
336 | return ioctl (scb->fd, TIOCFLUSH, 0); | |
c5aa993b | 337 | #endif |
c906108c SS |
338 | } |
339 | ||
340 | static int | |
819cc324 | 341 | hardwire_flush_input (struct serial *scb) |
c906108c | 342 | { |
dd5da072 | 343 | ser_base_flush_input (scb); |
c906108c SS |
344 | |
345 | #ifdef HAVE_TERMIOS | |
346 | return tcflush (scb->fd, TCIFLUSH); | |
347 | #endif | |
348 | ||
349 | #ifdef HAVE_TERMIO | |
350 | return ioctl (scb->fd, TCFLSH, 0); | |
351 | #endif | |
352 | ||
353 | #ifdef HAVE_SGTTY | |
354 | /* This flushes both input and output, but we can't do better. */ | |
355 | return ioctl (scb->fd, TIOCFLUSH, 0); | |
c5aa993b | 356 | #endif |
c906108c SS |
357 | } |
358 | ||
359 | static int | |
819cc324 | 360 | hardwire_send_break (struct serial *scb) |
c906108c SS |
361 | { |
362 | #ifdef HAVE_TERMIOS | |
363 | return tcsendbreak (scb->fd, 0); | |
364 | #endif | |
365 | ||
366 | #ifdef HAVE_TERMIO | |
367 | return ioctl (scb->fd, TCSBRK, 0); | |
368 | #endif | |
369 | ||
370 | #ifdef HAVE_SGTTY | |
371 | { | |
372 | int status; | |
373 | struct timeval timeout; | |
374 | ||
375 | status = ioctl (scb->fd, TIOCSBRK, 0); | |
376 | ||
377 | /* Can't use usleep; it doesn't exist in BSD 4.2. */ | |
378 | /* Note that if this select() is interrupted by a signal it will not wait | |
379 | the full length of time. I think that is OK. */ | |
380 | timeout.tv_sec = 0; | |
381 | timeout.tv_usec = 250000; | |
0ea3f30e | 382 | gdb_select (0, 0, 0, 0, &timeout); |
c906108c SS |
383 | status = ioctl (scb->fd, TIOCCBRK, 0); |
384 | return status; | |
385 | } | |
c5aa993b | 386 | #endif |
c906108c SS |
387 | } |
388 | ||
389 | static void | |
819cc324 | 390 | hardwire_raw (struct serial *scb) |
c906108c SS |
391 | { |
392 | struct hardwire_ttystate state; | |
393 | ||
c5aa993b JM |
394 | if (get_tty_state (scb, &state)) |
395 | fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n", safe_strerror (errno)); | |
c906108c SS |
396 | |
397 | #ifdef HAVE_TERMIOS | |
398 | state.termios.c_iflag = 0; | |
399 | state.termios.c_oflag = 0; | |
400 | state.termios.c_lflag = 0; | |
c5aa993b | 401 | state.termios.c_cflag &= ~(CSIZE | PARENB); |
c906108c | 402 | state.termios.c_cflag |= CLOCAL | CS8; |
23776285 MR |
403 | #ifdef CRTSCTS |
404 | /* h/w flow control. */ | |
405 | if (serial_hwflow) | |
406 | state.termios.c_cflag |= CRTSCTS; | |
407 | else | |
408 | state.termios.c_cflag &= ~CRTSCTS; | |
409 | #ifdef CRTS_IFLOW | |
410 | if (serial_hwflow) | |
411 | state.termios.c_cflag |= CRTS_IFLOW; | |
412 | else | |
413 | state.termios.c_cflag &= ~CRTS_IFLOW; | |
414 | #endif | |
415 | #endif | |
c906108c SS |
416 | state.termios.c_cc[VMIN] = 0; |
417 | state.termios.c_cc[VTIME] = 0; | |
418 | #endif | |
419 | ||
420 | #ifdef HAVE_TERMIO | |
421 | state.termio.c_iflag = 0; | |
422 | state.termio.c_oflag = 0; | |
423 | state.termio.c_lflag = 0; | |
c5aa993b | 424 | state.termio.c_cflag &= ~(CSIZE | PARENB); |
c906108c SS |
425 | state.termio.c_cflag |= CLOCAL | CS8; |
426 | state.termio.c_cc[VMIN] = 0; | |
427 | state.termio.c_cc[VTIME] = 0; | |
428 | #endif | |
429 | ||
430 | #ifdef HAVE_SGTTY | |
431 | state.sgttyb.sg_flags |= RAW | ANYP; | |
432 | state.sgttyb.sg_flags &= ~(CBREAK | ECHO); | |
433 | #endif | |
434 | ||
435 | scb->current_timeout = 0; | |
436 | ||
437 | if (set_tty_state (scb, &state)) | |
c5aa993b | 438 | fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n", safe_strerror (errno)); |
c906108c SS |
439 | } |
440 | ||
441 | /* Wait for input on scb, with timeout seconds. Returns 0 on success, | |
442 | otherwise SERIAL_TIMEOUT or SERIAL_ERROR. | |
443 | ||
444 | For termio{s}, we actually just setup VTIME if necessary, and let the | |
445 | timeout occur in the read() in hardwire_read(). | |
446 | */ | |
447 | ||
2acceee2 | 448 | /* FIXME: cagney/1999-09-16: Don't replace this with the equivalent |
b4505029 | 449 | ser_base*() until the old TERMIOS/SGTTY/... timer code has been |
2acceee2 JM |
450 | flushed. . */ |
451 | ||
452 | /* NOTE: cagney/1999-09-30: Much of the code below is dead. The only | |
453 | possible values of the TIMEOUT parameter are ONE and ZERO. | |
454 | Consequently all the code that tries to handle the possability of | |
455 | an overflowed timer is unnecessary. */ | |
c2c6d25f | 456 | |
c906108c | 457 | static int |
819cc324 | 458 | wait_for (struct serial *scb, int timeout) |
c906108c | 459 | { |
c906108c | 460 | #ifdef HAVE_SGTTY |
ab5ba170 AC |
461 | while (1) |
462 | { | |
463 | struct timeval tv; | |
464 | fd_set readfds; | |
465 | int numfds; | |
c906108c | 466 | |
ab5ba170 AC |
467 | /* NOTE: Some OS's can scramble the READFDS when the select() |
468 | call fails (ex the kernel with Red Hat 5.2). Initialize all | |
469 | arguments before each call. */ | |
c906108c | 470 | |
ab5ba170 AC |
471 | tv.tv_sec = timeout; |
472 | tv.tv_usec = 0; | |
c906108c | 473 | |
ab5ba170 AC |
474 | FD_ZERO (&readfds); |
475 | FD_SET (scb->fd, &readfds); | |
c906108c | 476 | |
ab5ba170 | 477 | if (timeout >= 0) |
0ea3f30e | 478 | numfds = gdb_select (scb->fd + 1, &readfds, 0, 0, &tv); |
ab5ba170 | 479 | else |
0ea3f30e | 480 | numfds = gdb_select (scb->fd + 1, &readfds, 0, 0, 0); |
c906108c | 481 | |
ab5ba170 AC |
482 | if (numfds <= 0) |
483 | if (numfds == 0) | |
484 | return SERIAL_TIMEOUT; | |
485 | else if (errno == EINTR) | |
486 | continue; | |
c906108c | 487 | else |
ab5ba170 | 488 | return SERIAL_ERROR; /* Got an error from select or poll */ |
c906108c | 489 | |
ab5ba170 AC |
490 | return 0; |
491 | } | |
c5aa993b | 492 | #endif /* HAVE_SGTTY */ |
c906108c SS |
493 | |
494 | #if defined HAVE_TERMIO || defined HAVE_TERMIOS | |
495 | if (timeout == scb->current_timeout) | |
496 | return 0; | |
497 | ||
498 | scb->current_timeout = timeout; | |
499 | ||
500 | { | |
501 | struct hardwire_ttystate state; | |
502 | ||
c5aa993b JM |
503 | if (get_tty_state (scb, &state)) |
504 | fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n", safe_strerror (errno)); | |
c906108c SS |
505 | |
506 | #ifdef HAVE_TERMIOS | |
507 | if (timeout < 0) | |
508 | { | |
509 | /* No timeout. */ | |
510 | state.termios.c_cc[VTIME] = 0; | |
511 | state.termios.c_cc[VMIN] = 1; | |
512 | } | |
513 | else | |
514 | { | |
515 | state.termios.c_cc[VMIN] = 0; | |
516 | state.termios.c_cc[VTIME] = timeout * 10; | |
517 | if (state.termios.c_cc[VTIME] != timeout * 10) | |
518 | { | |
519 | ||
520 | /* If c_cc is an 8-bit signed character, we can't go | |
521 | bigger than this. If it is always unsigned, we could use | |
522 | 25. */ | |
523 | ||
524 | scb->current_timeout = 12; | |
525 | state.termios.c_cc[VTIME] = scb->current_timeout * 10; | |
526 | scb->timeout_remaining = timeout - scb->current_timeout; | |
527 | } | |
528 | } | |
529 | #endif | |
530 | ||
531 | #ifdef HAVE_TERMIO | |
532 | if (timeout < 0) | |
533 | { | |
534 | /* No timeout. */ | |
535 | state.termio.c_cc[VTIME] = 0; | |
536 | state.termio.c_cc[VMIN] = 1; | |
537 | } | |
538 | else | |
539 | { | |
540 | state.termio.c_cc[VMIN] = 0; | |
541 | state.termio.c_cc[VTIME] = timeout * 10; | |
542 | if (state.termio.c_cc[VTIME] != timeout * 10) | |
543 | { | |
544 | /* If c_cc is an 8-bit signed character, we can't go | |
545 | bigger than this. If it is always unsigned, we could use | |
546 | 25. */ | |
547 | ||
548 | scb->current_timeout = 12; | |
549 | state.termio.c_cc[VTIME] = scb->current_timeout * 10; | |
550 | scb->timeout_remaining = timeout - scb->current_timeout; | |
551 | } | |
552 | } | |
553 | #endif | |
554 | ||
555 | if (set_tty_state (scb, &state)) | |
c5aa993b | 556 | fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n", safe_strerror (errno)); |
c906108c SS |
557 | |
558 | return 0; | |
559 | } | |
c5aa993b | 560 | #endif /* HAVE_TERMIO || HAVE_TERMIOS */ |
c906108c SS |
561 | } |
562 | ||
563 | /* Read a character with user-specified timeout. TIMEOUT is number of seconds | |
564 | to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns | |
565 | char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line | |
566 | dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */ | |
c2c6d25f JM |
567 | |
568 | /* FIXME: cagney/1999-09-16: Don't replace this with the equivalent | |
b4505029 | 569 | ser_base*() until the old TERMIOS/SGTTY/... timer code has been |
c2c6d25f JM |
570 | flushed. */ |
571 | ||
572 | /* NOTE: cagney/1999-09-16: This function is not identical to | |
b4505029 | 573 | ser_base_readchar() as part of replacing it with ser_base*() |
c2c6d25f | 574 | merging will be required - this code handles the case where read() |
b4505029 | 575 | times out due to no data while ser_base_readchar() doesn't expect |
c2c6d25f JM |
576 | that. */ |
577 | ||
c906108c | 578 | static int |
819cc324 | 579 | do_hardwire_readchar (struct serial *scb, int timeout) |
c906108c | 580 | { |
7a292a7a SS |
581 | int status, delta; |
582 | int detach = 0; | |
c906108c | 583 | |
c906108c SS |
584 | if (timeout > 0) |
585 | timeout++; | |
c906108c | 586 | |
2c1ab592 MS |
587 | /* We have to be able to keep the GUI alive here, so we break the |
588 | original timeout into steps of 1 second, running the "keep the | |
589 | GUI alive" hook each time through the loop. | |
590 | ||
591 | Also, timeout = 0 means to poll, so we just set the delta to 0, | |
592 | so we will only go through the loop once. */ | |
c5aa993b | 593 | |
7a292a7a | 594 | delta = (timeout == 0 ? 0 : 1); |
c906108c SS |
595 | while (1) |
596 | { | |
c906108c | 597 | |
7a292a7a SS |
598 | /* N.B. The UI may destroy our world (for instance by calling |
599 | remote_stop,) in which case we want to get out of here as | |
600 | quickly as possible. It is not safe to touch scb, since | |
98bbd631 AC |
601 | someone else might have freed it. The |
602 | deprecated_ui_loop_hook signals that we should exit by | |
603 | returning 1. */ | |
7a292a7a | 604 | |
98bbd631 AC |
605 | if (deprecated_ui_loop_hook) |
606 | detach = deprecated_ui_loop_hook (0); | |
7a292a7a SS |
607 | |
608 | if (detach) | |
609 | return SERIAL_TIMEOUT; | |
610 | ||
611 | scb->timeout_remaining = (timeout < 0 ? timeout : timeout - delta); | |
612 | status = wait_for (scb, delta); | |
613 | ||
c906108c SS |
614 | if (status < 0) |
615 | return status; | |
616 | ||
2acceee2 | 617 | status = read (scb->fd, scb->buf, BUFSIZ); |
c906108c | 618 | |
2acceee2 | 619 | if (status <= 0) |
c906108c | 620 | { |
2acceee2 | 621 | if (status == 0) |
c906108c SS |
622 | { |
623 | /* Zero characters means timeout (it could also be EOF, but | |
c5aa993b | 624 | we don't (yet at least) distinguish). */ |
c906108c SS |
625 | if (scb->timeout_remaining > 0) |
626 | { | |
627 | timeout = scb->timeout_remaining; | |
628 | continue; | |
629 | } | |
c5aa993b JM |
630 | else if (scb->timeout_remaining < 0) |
631 | continue; | |
c906108c SS |
632 | else |
633 | return SERIAL_TIMEOUT; | |
634 | } | |
635 | else if (errno == EINTR) | |
636 | continue; | |
637 | else | |
638 | return SERIAL_ERROR; /* Got an error from read */ | |
639 | } | |
640 | ||
2acceee2 | 641 | scb->bufcnt = status; |
c906108c SS |
642 | scb->bufcnt--; |
643 | scb->bufp = scb->buf; | |
644 | return *scb->bufp++; | |
645 | } | |
646 | } | |
647 | ||
2acceee2 | 648 | static int |
819cc324 | 649 | hardwire_readchar (struct serial *scb, int timeout) |
2acceee2 JM |
650 | { |
651 | return generic_readchar (scb, timeout, do_hardwire_readchar); | |
652 | } | |
653 | ||
654 | ||
c906108c SS |
655 | #ifndef B19200 |
656 | #define B19200 EXTA | |
657 | #endif | |
658 | ||
659 | #ifndef B38400 | |
660 | #define B38400 EXTB | |
661 | #endif | |
662 | ||
663 | /* Translate baud rates from integers to damn B_codes. Unix should | |
664 | have outgrown this crap years ago, but even POSIX wouldn't buck it. */ | |
665 | ||
666 | static struct | |
667 | { | |
668 | int rate; | |
669 | int code; | |
670 | } | |
671 | baudtab[] = | |
672 | { | |
c5aa993b JM |
673 | { |
674 | 50, B50 | |
675 | } | |
676 | , | |
677 | { | |
678 | 75, B75 | |
679 | } | |
680 | , | |
681 | { | |
682 | 110, B110 | |
683 | } | |
684 | , | |
685 | { | |
686 | 134, B134 | |
687 | } | |
688 | , | |
689 | { | |
690 | 150, B150 | |
691 | } | |
692 | , | |
693 | { | |
694 | 200, B200 | |
695 | } | |
696 | , | |
697 | { | |
698 | 300, B300 | |
699 | } | |
700 | , | |
701 | { | |
702 | 600, B600 | |
703 | } | |
704 | , | |
705 | { | |
706 | 1200, B1200 | |
707 | } | |
708 | , | |
709 | { | |
710 | 1800, B1800 | |
711 | } | |
712 | , | |
713 | { | |
714 | 2400, B2400 | |
715 | } | |
716 | , | |
717 | { | |
718 | 4800, B4800 | |
719 | } | |
720 | , | |
721 | { | |
722 | 9600, B9600 | |
723 | } | |
724 | , | |
725 | { | |
726 | 19200, B19200 | |
727 | } | |
728 | , | |
729 | { | |
730 | 38400, B38400 | |
731 | } | |
732 | , | |
c906108c | 733 | #ifdef B57600 |
c5aa993b JM |
734 | { |
735 | 57600, B57600 | |
736 | } | |
737 | , | |
c906108c SS |
738 | #endif |
739 | #ifdef B115200 | |
c5aa993b JM |
740 | { |
741 | 115200, B115200 | |
742 | } | |
743 | , | |
c906108c SS |
744 | #endif |
745 | #ifdef B230400 | |
c5aa993b JM |
746 | { |
747 | 230400, B230400 | |
748 | } | |
749 | , | |
c906108c SS |
750 | #endif |
751 | #ifdef B460800 | |
c5aa993b JM |
752 | { |
753 | 460800, B460800 | |
754 | } | |
755 | , | |
c906108c | 756 | #endif |
c5aa993b JM |
757 | { |
758 | -1, -1 | |
759 | } | |
760 | , | |
c906108c SS |
761 | }; |
762 | ||
c5aa993b | 763 | static int |
c2c6d25f | 764 | rate_to_code (int rate) |
c906108c SS |
765 | { |
766 | int i; | |
767 | ||
768 | for (i = 0; baudtab[i].rate != -1; i++) | |
08b4f080 FN |
769 | { |
770 | /* test for perfect macth. */ | |
771 | if (rate == baudtab[i].rate) | |
772 | return baudtab[i].code; | |
773 | else | |
774 | { | |
775 | /* check if it is in between valid values. */ | |
776 | if (rate < baudtab[i].rate) | |
777 | { | |
778 | if (i) | |
779 | { | |
8a3fe4f8 | 780 | warning (_("Invalid baud rate %d. Closest values are %d and %d."), |
08b4f080 FN |
781 | rate, baudtab[i - 1].rate, baudtab[i].rate); |
782 | } | |
783 | else | |
784 | { | |
8a3fe4f8 | 785 | warning (_("Invalid baud rate %d. Minimum value is %d."), |
08b4f080 FN |
786 | rate, baudtab[0].rate); |
787 | } | |
788 | return -1; | |
789 | } | |
790 | } | |
791 | } | |
792 | ||
793 | /* The requested speed was too large. */ | |
8a3fe4f8 | 794 | warning (_("Invalid baud rate %d. Maximum value is %d."), |
08b4f080 | 795 | rate, baudtab[i - 1].rate); |
c906108c SS |
796 | return -1; |
797 | } | |
798 | ||
799 | static int | |
819cc324 | 800 | hardwire_setbaudrate (struct serial *scb, int rate) |
c906108c SS |
801 | { |
802 | struct hardwire_ttystate state; | |
08b4f080 FN |
803 | int baud_code = rate_to_code (rate); |
804 | ||
805 | if (baud_code < 0) | |
806 | { | |
807 | /* The baud rate was not valid. | |
808 | A warning has already been issued. */ | |
809 | errno = EINVAL; | |
810 | return -1; | |
811 | } | |
c906108c | 812 | |
c5aa993b | 813 | if (get_tty_state (scb, &state)) |
c906108c SS |
814 | return -1; |
815 | ||
816 | #ifdef HAVE_TERMIOS | |
08b4f080 FN |
817 | cfsetospeed (&state.termios, baud_code); |
818 | cfsetispeed (&state.termios, baud_code); | |
c906108c SS |
819 | #endif |
820 | ||
821 | #ifdef HAVE_TERMIO | |
822 | #ifndef CIBAUD | |
823 | #define CIBAUD CBAUD | |
824 | #endif | |
825 | ||
826 | state.termio.c_cflag &= ~(CBAUD | CIBAUD); | |
08b4f080 | 827 | state.termio.c_cflag |= baud_code; |
c906108c SS |
828 | #endif |
829 | ||
830 | #ifdef HAVE_SGTTY | |
08b4f080 FN |
831 | state.sgttyb.sg_ispeed = baud_code; |
832 | state.sgttyb.sg_ospeed = baud_code; | |
c906108c SS |
833 | #endif |
834 | ||
835 | return set_tty_state (scb, &state); | |
836 | } | |
837 | ||
838 | static int | |
819cc324 | 839 | hardwire_setstopbits (struct serial *scb, int num) |
c906108c SS |
840 | { |
841 | struct hardwire_ttystate state; | |
842 | int newbit; | |
843 | ||
c5aa993b | 844 | if (get_tty_state (scb, &state)) |
c906108c SS |
845 | return -1; |
846 | ||
847 | switch (num) | |
848 | { | |
849 | case SERIAL_1_STOPBITS: | |
850 | newbit = 0; | |
851 | break; | |
852 | case SERIAL_1_AND_A_HALF_STOPBITS: | |
853 | case SERIAL_2_STOPBITS: | |
854 | newbit = 1; | |
855 | break; | |
856 | default: | |
857 | return 1; | |
858 | } | |
859 | ||
860 | #ifdef HAVE_TERMIOS | |
861 | if (!newbit) | |
862 | state.termios.c_cflag &= ~CSTOPB; | |
863 | else | |
c5aa993b | 864 | state.termios.c_cflag |= CSTOPB; /* two bits */ |
c906108c SS |
865 | #endif |
866 | ||
867 | #ifdef HAVE_TERMIO | |
868 | if (!newbit) | |
869 | state.termio.c_cflag &= ~CSTOPB; | |
870 | else | |
c5aa993b | 871 | state.termio.c_cflag |= CSTOPB; /* two bits */ |
c906108c SS |
872 | #endif |
873 | ||
874 | #ifdef HAVE_SGTTY | |
875 | return 0; /* sgtty doesn't support this */ | |
876 | #endif | |
877 | ||
878 | return set_tty_state (scb, &state); | |
879 | } | |
880 | ||
c906108c | 881 | static void |
819cc324 | 882 | hardwire_close (struct serial *scb) |
c906108c SS |
883 | { |
884 | if (scb->fd < 0) | |
885 | return; | |
886 | ||
c5aa993b | 887 | close (scb->fd); |
c906108c SS |
888 | scb->fd = -1; |
889 | } | |
c2c6d25f | 890 | \f |
2acceee2 | 891 | \f |
c906108c | 892 | void |
c2c6d25f | 893 | _initialize_ser_hardwire (void) |
c906108c | 894 | { |
c2c6d25f | 895 | struct serial_ops *ops = XMALLOC (struct serial_ops); |
2fdbdd39 | 896 | memset (ops, 0, sizeof (struct serial_ops)); |
c2c6d25f JM |
897 | ops->name = "hardwire"; |
898 | ops->next = 0; | |
899 | ops->open = hardwire_open; | |
900 | ops->close = hardwire_close; | |
b4505029 | 901 | /* FIXME: Don't replace this with the equivalent ser_base*() until |
c2c6d25f JM |
902 | the old TERMIOS/SGTTY/... timer code has been flushed. cagney |
903 | 1999-09-16. */ | |
904 | ops->readchar = hardwire_readchar; | |
dd5da072 | 905 | ops->write = ser_base_write; |
c2c6d25f JM |
906 | ops->flush_output = hardwire_flush_output; |
907 | ops->flush_input = hardwire_flush_input; | |
908 | ops->send_break = hardwire_send_break; | |
909 | ops->go_raw = hardwire_raw; | |
910 | ops->get_tty_state = hardwire_get_tty_state; | |
911 | ops->set_tty_state = hardwire_set_tty_state; | |
912 | ops->print_tty_state = hardwire_print_tty_state; | |
913 | ops->noflush_set_tty_state = hardwire_noflush_set_tty_state; | |
914 | ops->setbaudrate = hardwire_setbaudrate; | |
915 | ops->setstopbits = hardwire_setstopbits; | |
916 | ops->drain_output = hardwire_drain_output; | |
dd5da072 | 917 | ops->async = ser_base_async; |
b4505029 MM |
918 | ops->read_prim = ser_unix_read_prim; |
919 | ops->write_prim = ser_unix_write_prim; | |
c2c6d25f | 920 | serial_add_interface (ops); |
23776285 MR |
921 | |
922 | #ifdef HAVE_TERMIOS | |
923 | #ifdef CRTSCTS | |
924 | add_setshow_boolean_cmd ("remoteflow", no_class, | |
925 | &serial_hwflow, _("\ | |
926 | Set use of hardware flow control for remote serial I/O."), _("\ | |
927 | Show use of hardware flow control for remote serial I/O."), _("\ | |
928 | Enable or disable hardware flow control (RTS/CTS) on the serial port\n\ | |
929 | when debugging using remote targets."), | |
930 | NULL, | |
931 | show_serial_hwflow, | |
932 | &setlist, &showlist); | |
933 | #endif | |
934 | #endif | |
c906108c | 935 | } |
b4505029 MM |
936 | |
937 | int | |
938 | ser_unix_read_prim (struct serial *scb, size_t count) | |
939 | { | |
940 | int status; | |
941 | ||
942 | while (1) | |
943 | { | |
944 | status = read (scb->fd, scb->buf, count); | |
945 | if (status != -1 || errno != EINTR) | |
946 | break; | |
947 | } | |
948 | return status; | |
949 | } | |
950 | ||
951 | int | |
952 | ser_unix_write_prim (struct serial *scb, const void *buf, size_t len) | |
953 | { | |
954 | /* ??? Historically, GDB has not retried calls to "write" that | |
955 | result in EINTR. */ | |
956 | return write (scb->fd, buf, len); | |
957 | } |