093143cfdba8f002d4cfc91d1cb4d4a0faf69394
[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, 1994 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include "defs.h"
21 #include "serial.h"
22 #include <fcntl.h>
23 #include <sys/types.h>
24
25 #if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
26 #define HAVE_SGTTY
27 #endif
28
29 #ifdef HAVE_TERMIOS
30 #include <termios.h>
31 #include <unistd.h>
32
33 struct hardwire_ttystate
34 {
35 struct termios termios;
36 };
37 #endif /* termios */
38
39 #ifdef HAVE_TERMIO
40 #include <termio.h>
41
42 /* It is believed that all systems which have added job control to SVR3
43 (e.g. sco) have also added termios. Even if not, trying to figure out
44 all the variations (TIOCGPGRP vs. TCGETPGRP, etc.) would be pretty
45 bewildering. So we don't attempt it. */
46
47 struct hardwire_ttystate
48 {
49 struct termio termio;
50 };
51 #endif /* termio */
52
53 #ifdef HAVE_SGTTY
54 /* Needed for the code which uses select(). We would include <sys/select.h>
55 too if it existed on all systems. */
56 #include <sys/time.h>
57
58 #include <sgtty.h>
59
60 struct hardwire_ttystate
61 {
62 struct sgttyb sgttyb;
63 struct tchars tc;
64 struct ltchars ltc;
65 /* Line discipline flags. */
66 int lmode;
67 };
68 #endif /* sgtty */
69
70 static int hardwire_open PARAMS ((serial_t scb, const char *name));
71 static void hardwire_raw PARAMS ((serial_t scb));
72 static int wait_for PARAMS ((serial_t scb, int timeout));
73 static int hardwire_readchar PARAMS ((serial_t scb, int timeout));
74 static int rate_to_code PARAMS ((int rate));
75 static int hardwire_setbaudrate PARAMS ((serial_t scb, int rate));
76 static int hardwire_write PARAMS ((serial_t scb, const char *str, int len));
77 /* FIXME: static void hardwire_restore PARAMS ((serial_t scb)); */
78 static void hardwire_close PARAMS ((serial_t scb));
79 static int get_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
80 static int set_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
81 static serial_ttystate hardwire_get_tty_state PARAMS ((serial_t scb));
82 static int hardwire_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
83
84 /* Open up a real live device for serial I/O */
85
86 static int
87 hardwire_open(scb, name)
88 serial_t scb;
89 const char *name;
90 {
91 scb->fd = open (name, O_RDWR);
92 if (scb->fd < 0)
93 return -1;
94
95 return 0;
96 }
97
98 static int
99 get_tty_state(scb, state)
100 serial_t scb;
101 struct hardwire_ttystate *state;
102 {
103 #ifdef HAVE_TERMIOS
104 extern int errno;
105
106 if (tcgetattr(scb->fd, &state->termios) < 0)
107 return -1;
108
109 return 0;
110 #endif
111
112 #ifdef HAVE_TERMIO
113 if (ioctl (scb->fd, TCGETA, &state->termio) < 0)
114 return -1;
115 return 0;
116 #endif
117
118 #ifdef HAVE_SGTTY
119 if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0)
120 return -1;
121 if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0)
122 return -1;
123 if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0)
124 return -1;
125 if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0)
126 return -1;
127
128 return 0;
129 #endif
130 }
131
132 static int
133 set_tty_state(scb, state)
134 serial_t scb;
135 struct hardwire_ttystate *state;
136 {
137 #ifdef HAVE_TERMIOS
138 if (tcsetattr(scb->fd, TCSANOW, &state->termios) < 0)
139 return -1;
140
141 return 0;
142 #endif
143
144 #ifdef HAVE_TERMIO
145 if (ioctl (scb->fd, TCSETA, &state->termio) < 0)
146 return -1;
147 return 0;
148 #endif
149
150 #ifdef HAVE_SGTTY
151 if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0)
152 return -1;
153 if (ioctl (scb->fd, TIOCSETC, &state->tc) < 0)
154 return -1;
155 if (ioctl (scb->fd, TIOCSLTC, &state->ltc) < 0)
156 return -1;
157 if (ioctl (scb->fd, TIOCLSET, &state->lmode) < 0)
158 return -1;
159
160 return 0;
161 #endif
162 }
163
164 static serial_ttystate
165 hardwire_get_tty_state(scb)
166 serial_t scb;
167 {
168 struct hardwire_ttystate *state;
169
170 state = (struct hardwire_ttystate *)xmalloc(sizeof *state);
171
172 if (get_tty_state(scb, state))
173 return NULL;
174
175 return (serial_ttystate)state;
176 }
177
178 static int
179 hardwire_set_tty_state(scb, ttystate)
180 serial_t scb;
181 serial_ttystate ttystate;
182 {
183 struct hardwire_ttystate *state;
184
185 state = (struct hardwire_ttystate *)ttystate;
186
187 return set_tty_state(scb, state);
188 }
189
190 static int
191 hardwire_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
192 serial_t scb;
193 serial_ttystate new_ttystate;
194 serial_ttystate old_ttystate;
195 {
196 struct hardwire_ttystate new_state;
197 #ifdef HAVE_SGTTY
198 struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate;
199 #endif
200
201 new_state = *(struct hardwire_ttystate *)new_ttystate;
202
203 /* Don't change in or out of raw mode; we don't want to flush input.
204 termio and termios have no such restriction; for them flushing input
205 is separate from setting the attributes. */
206
207 #ifdef HAVE_SGTTY
208 if (state->sgttyb.sg_flags & RAW)
209 new_state.sgttyb.sg_flags |= RAW;
210 else
211 new_state.sgttyb.sg_flags &= ~RAW;
212
213 /* I'm not sure whether this is necessary; the manpage just mentions
214 RAW not CBREAK. */
215 if (state->sgttyb.sg_flags & CBREAK)
216 new_state.sgttyb.sg_flags |= CBREAK;
217 else
218 new_state.sgttyb.sg_flags &= ~CBREAK;
219 #endif
220
221 return set_tty_state (scb, &new_state);
222 }
223
224 static void
225 hardwire_print_tty_state (scb, ttystate)
226 serial_t scb;
227 serial_ttystate ttystate;
228 {
229 struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate;
230 int i;
231
232 #ifdef HAVE_TERMIOS
233 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
234 state->termios.c_iflag, state->termios.c_oflag);
235 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x\n",
236 state->termios.c_cflag, state->termios.c_lflag);
237 #if 0
238 /* This not in POSIX, and is not really documented by those systems
239 which have it (at least not Sun). */
240 printf_filtered ("c_line = 0x%x.\n", state->termios.c_line);
241 #endif
242 printf_filtered ("c_cc: ");
243 for (i = 0; i < NCCS; i += 1)
244 printf_filtered ("0x%x ", state->termios.c_cc[i]);
245 printf_filtered ("\n");
246 #endif
247
248 #ifdef HAVE_TERMIO
249 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
250 state->termio.c_iflag, state->termio.c_oflag);
251 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
252 state->termio.c_cflag, state->termio.c_lflag,
253 state->termio.c_line);
254 printf_filtered ("c_cc: ");
255 for (i = 0; i < NCC; i += 1)
256 printf_filtered ("0x%x ", state->termio.c_cc[i]);
257 printf_filtered ("\n");
258 #endif
259
260 #ifdef HAVE_SGTTY
261 printf_filtered ("sgttyb.sg_flags = 0x%x.\n", state->sgttyb.sg_flags);
262
263 printf_filtered ("tchars: ");
264 for (i = 0; i < (int)sizeof (struct tchars); i++)
265 printf_filtered ("0x%x ", ((unsigned char *)&state->tc)[i]);
266 printf_filtered ("\n");
267
268 printf_filtered ("ltchars: ");
269 for (i = 0; i < (int)sizeof (struct ltchars); i++)
270 printf_filtered ("0x%x ", ((unsigned char *)&state->ltc)[i]);
271 printf_filtered ("\n");
272
273 printf_filtered ("lmode: 0x%x\n", state->lmode);
274 #endif
275 }
276
277 static int
278 hardwire_flush_output (scb)
279 serial_t scb;
280 {
281 #ifdef HAVE_TERMIOS
282 return tcflush (scb->fd, TCOFLUSH);
283 #endif
284
285 #ifdef HAVE_TERMIO
286 return ioctl (scb->fd, TCFLSH, 1);
287 #endif
288
289 #ifdef HAVE_SGTTY
290 /* This flushes both input and output, but we can't do better. */
291 return ioctl (scb->fd, TIOCFLUSH, 0);
292 #endif
293 }
294
295 static int
296 hardwire_flush_input (scb)
297 serial_t scb;
298 {
299 #ifdef HAVE_TERMIOS
300 return tcflush (scb->fd, TCIFLUSH);
301 #endif
302
303 #ifdef HAVE_TERMIO
304 return ioctl (scb->fd, TCFLSH, 0);
305 #endif
306
307 #ifdef HAVE_SGTTY
308 /* This flushes both input and output, but we can't do better. */
309 return ioctl (scb->fd, TIOCFLUSH, 0);
310 #endif
311 }
312
313 static int
314 hardwire_send_break (scb)
315 serial_t scb;
316 {
317 #ifdef HAVE_TERMIOS
318 return tcsendbreak (scb->fd, 0);
319 #endif
320
321 #ifdef HAVE_TERMIO
322 return ioctl (scb->fd, TCSBRK, 0);
323 #endif
324
325 #ifdef HAVE_SGTTY
326 {
327 int status;
328 struct timeval timeout;
329
330 status = ioctl (scb->fd, TIOCSBRK, 0);
331
332 /* Can't use usleep; it doesn't exist in BSD 4.2. */
333 /* Note that if this select() is interrupted by a signal it will not wait
334 the full length of time. I think that is OK. */
335 timeout.tv_sec = 0;
336 timeout.tv_usec = 250000;
337 select (0, 0, 0, 0, &timeout);
338 status = ioctl (scb->fd, TIOCCBRK, 0);
339 return status;
340 }
341 #endif
342 }
343
344 static void
345 hardwire_raw(scb)
346 serial_t scb;
347 {
348 struct hardwire_ttystate state;
349
350 if (get_tty_state(scb, &state))
351 fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
352
353 #ifdef HAVE_TERMIOS
354 state.termios.c_iflag = 0;
355 state.termios.c_oflag = 0;
356 state.termios.c_lflag = 0;
357 state.termios.c_cflag &= ~(CSIZE|PARENB);
358 state.termios.c_cflag |= CLOCAL | CS8;
359 state.termios.c_cc[VMIN] = 0;
360 state.termios.c_cc[VTIME] = 0;
361 #endif
362
363 #ifdef HAVE_TERMIO
364 state.termio.c_iflag = 0;
365 state.termio.c_oflag = 0;
366 state.termio.c_lflag = 0;
367 state.termio.c_cflag &= ~(CSIZE|PARENB);
368 state.termio.c_cflag |= CLOCAL | CS8;
369 state.termio.c_cc[VMIN] = 0;
370 state.termio.c_cc[VTIME] = 0;
371 #endif
372
373 #ifdef HAVE_SGTTY
374 state.sgttyb.sg_flags |= RAW | ANYP;
375 state.sgttyb.sg_flags &= ~(CBREAK | ECHO);
376 #endif
377
378 scb->current_timeout = 0;
379
380 if (set_tty_state (scb, &state))
381 fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
382 }
383
384 /* Wait for input on scb, with timeout seconds. Returns 0 on success,
385 otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
386
387 For termio{s}, we actually just setup VTIME if necessary, and let the
388 timeout occur in the read() in hardwire_read().
389 */
390
391 static int
392 wait_for(scb, timeout)
393 serial_t scb;
394 int timeout;
395 {
396 scb->timeout_remaining = 0;
397
398 #ifdef HAVE_SGTTY
399 {
400 struct timeval tv;
401 fd_set readfds;
402
403 FD_ZERO (&readfds);
404
405 tv.tv_sec = timeout;
406 tv.tv_usec = 0;
407
408 FD_SET(scb->fd, &readfds);
409
410 while (1)
411 {
412 int numfds;
413
414 if (timeout >= 0)
415 numfds = select(scb->fd+1, &readfds, 0, 0, &tv);
416 else
417 numfds = select(scb->fd+1, &readfds, 0, 0, 0);
418
419 if (numfds <= 0)
420 if (numfds == 0)
421 return SERIAL_TIMEOUT;
422 else if (errno == EINTR)
423 continue;
424 else
425 return SERIAL_ERROR; /* Got an error from select or poll */
426
427 return 0;
428 }
429 }
430 #endif /* HAVE_SGTTY */
431
432 #if defined HAVE_TERMIO || defined HAVE_TERMIOS
433 if (timeout == scb->current_timeout)
434 return 0;
435
436 scb->current_timeout = timeout;
437
438 {
439 struct hardwire_ttystate state;
440
441 if (get_tty_state(scb, &state))
442 fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
443
444 #ifdef HAVE_TERMIOS
445 if (timeout < 0)
446 {
447 /* No timeout. */
448 state.termios.c_cc[VTIME] = 0;
449 state.termios.c_cc[VMIN] = 1;
450 }
451 else
452 {
453 state.termios.c_cc[VMIN] = 0;
454 state.termios.c_cc[VTIME] = timeout * 10;
455 if (state.termios.c_cc[VTIME] != timeout * 10)
456 {
457
458 /* If c_cc is an 8-bit signed character, we can't go
459 bigger than this. If it is always unsigned, we could use
460 25. */
461
462 scb->current_timeout = 12;
463 state.termios.c_cc[VTIME] = scb->current_timeout * 10;
464 scb->timeout_remaining = timeout - scb->current_timeout;
465 }
466 }
467 #endif
468
469 #ifdef HAVE_TERMIO
470 if (timeout < 0)
471 {
472 /* No timeout. */
473 state.termio.c_cc[VTIME] = 0;
474 state.termio.c_cc[VMIN] = 1;
475 }
476 else
477 {
478 state.termio.c_cc[VMIN] = 0;
479 state.termio.c_cc[VTIME] = timeout * 10;
480 if (state.termio.c_cc[VTIME] != timeout * 10)
481 {
482 /* If c_cc is an 8-bit signed character, we can't go
483 bigger than this. If it is always unsigned, we could use
484 25. */
485
486 scb->current_timeout = 12;
487 state.termio.c_cc[VTIME] = scb->current_timeout * 10;
488 scb->timeout_remaining = timeout - scb->current_timeout;
489 }
490 }
491 #endif
492
493 if (set_tty_state (scb, &state))
494 fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
495
496 return 0;
497 }
498 #endif /* HAVE_TERMIO || HAVE_TERMIOS */
499 }
500
501 /* Read a character with user-specified timeout. TIMEOUT is number of seconds
502 to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
503 char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line
504 dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */
505
506 static int
507 hardwire_readchar(scb, timeout)
508 serial_t scb;
509 int timeout;
510 {
511 int status;
512
513 if (scb->bufcnt-- > 0)
514 return *scb->bufp++;
515
516 while (1)
517 {
518 status = wait_for (scb, timeout);
519
520 if (status < 0)
521 return status;
522
523 scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ);
524
525 if (scb->bufcnt <= 0)
526 {
527 if (scb->bufcnt == 0)
528 {
529 /* Zero characters means timeout (it could also be EOF, but
530 we don't (yet at least) distinguish). */
531 if (scb->timeout_remaining > 0)
532 {
533 timeout = scb->timeout_remaining;
534 continue;
535 }
536 else
537 return SERIAL_TIMEOUT;
538 }
539 else if (errno == EINTR)
540 continue;
541 else
542 return SERIAL_ERROR; /* Got an error from read */
543 }
544
545 scb->bufcnt--;
546 scb->bufp = scb->buf;
547 return *scb->bufp++;
548 }
549 }
550
551 #ifndef B19200
552 #define B19200 EXTA
553 #endif
554
555 #ifndef B38400
556 #define B38400 EXTB
557 #endif
558
559 /* Translate baud rates from integers to damn B_codes. Unix should
560 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
561
562 static struct
563 {
564 int rate;
565 int code;
566 }
567 baudtab[] =
568 {
569 {50, B50},
570 {75, B75},
571 {110, B110},
572 {134, B134},
573 {150, B150},
574 {200, B200},
575 {300, B300},
576 {600, B600},
577 {1200, B1200},
578 {1800, B1800},
579 {2400, B2400},
580 {4800, B4800},
581 {9600, B9600},
582 {19200, B19200},
583 {38400, B38400},
584 {-1, -1},
585 };
586
587 static int
588 rate_to_code(rate)
589 int rate;
590 {
591 int i;
592
593 for (i = 0; baudtab[i].rate != -1; i++)
594 if (rate == baudtab[i].rate)
595 return baudtab[i].code;
596
597 return -1;
598 }
599
600 static int
601 hardwire_setbaudrate(scb, rate)
602 serial_t scb;
603 int rate;
604 {
605 struct hardwire_ttystate state;
606
607 if (get_tty_state(scb, &state))
608 return -1;
609
610 #ifdef HAVE_TERMIOS
611 cfsetospeed (&state.termios, rate_to_code (rate));
612 cfsetispeed (&state.termios, rate_to_code (rate));
613 #endif
614
615 #ifdef HAVE_TERMIO
616 #ifndef CIBAUD
617 #define CIBAUD CBAUD
618 #endif
619
620 state.termio.c_cflag &= ~(CBAUD | CIBAUD);
621 state.termio.c_cflag |= rate_to_code (rate);
622 #endif
623
624 #ifdef HAVE_SGTTY
625 state.sgttyb.sg_ispeed = rate_to_code (rate);
626 state.sgttyb.sg_ospeed = rate_to_code (rate);
627 #endif
628
629 return set_tty_state (scb, &state);
630 }
631
632 static int
633 hardwire_setstopbits(scb, num)
634 serial_t scb;
635 int num;
636 {
637 struct hardwire_ttystate state;
638 int newbit;
639
640 if (get_tty_state(scb, &state))
641 return -1;
642
643 switch (num)
644 {
645 case SERIAL_1_STOPBITS:
646 newbit = 0;
647 break;
648 case SERIAL_1_AND_A_HALF_STOPBITS:
649 case SERIAL_2_STOPBITS:
650 newbit = 1;
651 break;
652 default:
653 return 1;
654 }
655
656 #ifdef HAVE_TERMIOS
657 if (!newbit)
658 state.termios.c_cflag &= ~CSTOPB;
659 else
660 state.termios.c_cflag |= CSTOPB; /* two bits */
661 #endif
662
663 #ifdef HAVE_TERMIO
664 if (!newbit)
665 state.termio.c_cflag &= ~CSTOPB;
666 else
667 state.termio.c_cflag |= CSTOPB; /* two bits */
668 #endif
669
670 #ifdef HAVE_SGTTY
671 return 0; /* sgtty doesn't support this */
672 #endif
673
674 return set_tty_state (scb, &state);
675 }
676
677 static int
678 hardwire_write(scb, str, len)
679 serial_t scb;
680 const char *str;
681 int len;
682 {
683 int cc;
684
685 while (len > 0)
686 {
687 cc = write(scb->fd, str, len);
688
689 if (cc < 0)
690 return 1;
691 len -= cc;
692 str += cc;
693 }
694 return 0;
695 }
696
697 static void
698 hardwire_close(scb)
699 serial_t scb;
700 {
701 if (scb->fd < 0)
702 return;
703
704 close(scb->fd);
705 scb->fd = -1;
706 }
707
708 static struct serial_ops hardwire_ops =
709 {
710 "hardwire",
711 0,
712 hardwire_open,
713 hardwire_close,
714 hardwire_readchar,
715 hardwire_write,
716 hardwire_flush_output,
717 hardwire_flush_input,
718 hardwire_send_break,
719 hardwire_raw,
720 hardwire_get_tty_state,
721 hardwire_set_tty_state,
722 hardwire_print_tty_state,
723 hardwire_noflush_set_tty_state,
724 hardwire_setbaudrate,
725 hardwire_setstopbits,
726 };
727
728 void
729 _initialize_ser_hardwire ()
730 {
731 serial_add_interface (&hardwire_ops);
732 }
This page took 0.064593 seconds and 4 git commands to generate.