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