xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/ser-unix.c (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1 /* Serial interface for local (hardwired) serial ports on Un*x like systems
2 
3    Copyright (C) 1992-2017 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "defs.h"
21 #include "serial.h"
22 #include "ser-base.h"
23 #include "ser-unix.h"
24 
25 #include <fcntl.h>
26 #include <sys/types.h>
27 #include "terminal.h"
28 #include <sys/socket.h>
29 #include "gdb_sys_time.h"
30 
31 #include "gdb_select.h"
32 #include "gdbcmd.h"
33 #include "filestuff.h"
34 #include "gdb_termios.h"
35 
36 #ifdef HAVE_TERMIOS
37 
38 struct hardwire_ttystate
39   {
40     struct termios termios;
41   };
42 
43 #ifdef CRTSCTS
44 /* Boolean to explicitly enable or disable h/w flow control.  */
45 static int serial_hwflow;
46 static void
47 show_serial_hwflow (struct ui_file *file, int from_tty,
48 		    struct cmd_list_element *c, const char *value)
49 {
50   fprintf_filtered (file, _("Hardware flow control is %s.\n"), value);
51 }
52 #endif
53 
54 #endif /* termios */
55 
56 #ifdef HAVE_TERMIO
57 
58 /* It is believed that all systems which have added job control to SVR3
59    (e.g. sco) have also added termios.  Even if not, trying to figure out
60    all the variations (TIOCGPGRP vs. TCGETPGRP, etc.) would be pretty
61    bewildering.  So we don't attempt it.  */
62 
63 struct hardwire_ttystate
64   {
65     struct termio termio;
66   };
67 #endif /* termio */
68 
69 #ifdef HAVE_SGTTY
70 struct hardwire_ttystate
71   {
72     struct sgttyb sgttyb;
73     struct tchars tc;
74     struct ltchars ltc;
75     /* Line discipline flags.  */
76     int lmode;
77   };
78 #endif /* sgtty */
79 
80 static int hardwire_open (struct serial *scb, const char *name);
81 static void hardwire_raw (struct serial *scb);
82 static int rate_to_code (int rate);
83 static int hardwire_setbaudrate (struct serial *scb, int rate);
84 static int hardwire_setparity (struct serial *scb, int parity);
85 static void hardwire_close (struct serial *scb);
86 static int get_tty_state (struct serial *scb,
87 			  struct hardwire_ttystate * state);
88 static int set_tty_state (struct serial *scb,
89 			  struct hardwire_ttystate * state);
90 static serial_ttystate hardwire_get_tty_state (struct serial *scb);
91 static int hardwire_set_tty_state (struct serial *scb, serial_ttystate state);
92 static int hardwire_noflush_set_tty_state (struct serial *, serial_ttystate,
93 					   serial_ttystate);
94 static void hardwire_print_tty_state (struct serial *, serial_ttystate,
95 				      struct ui_file *);
96 static int hardwire_drain_output (struct serial *);
97 static int hardwire_flush_output (struct serial *);
98 static int hardwire_flush_input (struct serial *);
99 static int hardwire_send_break (struct serial *);
100 static int hardwire_setstopbits (struct serial *, int);
101 
102 void _initialize_ser_hardwire (void);
103 
104 /* Open up a real live device for serial I/O.  */
105 
106 static int
107 hardwire_open (struct serial *scb, const char *name)
108 {
109   scb->fd = gdb_open_cloexec (name, O_RDWR, 0);
110   if (scb->fd < 0)
111     return -1;
112 
113   return 0;
114 }
115 
116 static int
117 get_tty_state (struct serial *scb, struct hardwire_ttystate *state)
118 {
119 #ifdef HAVE_TERMIOS
120   if (tcgetattr (scb->fd, &state->termios) < 0)
121     return -1;
122 
123   return 0;
124 #endif
125 
126 #ifdef HAVE_TERMIO
127   if (ioctl (scb->fd, TCGETA, &state->termio) < 0)
128     return -1;
129   return 0;
130 #endif
131 
132 #ifdef HAVE_SGTTY
133   if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0)
134     return -1;
135   if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0)
136     return -1;
137   if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0)
138     return -1;
139   if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0)
140     return -1;
141 
142   return 0;
143 #endif
144 }
145 
146 static int
147 set_tty_state (struct serial *scb, struct hardwire_ttystate *state)
148 {
149 #ifdef HAVE_TERMIOS
150   if (tcsetattr (scb->fd, TCSANOW, &state->termios) < 0)
151     return -1;
152 
153   return 0;
154 #endif
155 
156 #ifdef HAVE_TERMIO
157   if (ioctl (scb->fd, TCSETA, &state->termio) < 0)
158     return -1;
159   return 0;
160 #endif
161 
162 #ifdef HAVE_SGTTY
163   if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0)
164     return -1;
165   if (ioctl (scb->fd, TIOCSETC, &state->tc) < 0)
166     return -1;
167   if (ioctl (scb->fd, TIOCSLTC, &state->ltc) < 0)
168     return -1;
169   if (ioctl (scb->fd, TIOCLSET, &state->lmode) < 0)
170     return -1;
171 
172   return 0;
173 #endif
174 }
175 
176 static serial_ttystate
177 hardwire_get_tty_state (struct serial *scb)
178 {
179   struct hardwire_ttystate *state = XNEW (struct hardwire_ttystate);
180 
181   if (get_tty_state (scb, state))
182     {
183       xfree (state);
184       return NULL;
185     }
186 
187   return (serial_ttystate) state;
188 }
189 
190 static serial_ttystate
191 hardwire_copy_tty_state (struct serial *scb, serial_ttystate ttystate)
192 {
193   struct hardwire_ttystate *state = XNEW (struct hardwire_ttystate);
194 
195   *state = *(struct hardwire_ttystate *) ttystate;
196 
197   return (serial_ttystate) state;
198 }
199 
200 static int
201 hardwire_set_tty_state (struct serial *scb, serial_ttystate ttystate)
202 {
203   struct hardwire_ttystate *state;
204 
205   state = (struct hardwire_ttystate *) ttystate;
206 
207   return set_tty_state (scb, state);
208 }
209 
210 static int
211 hardwire_noflush_set_tty_state (struct serial *scb,
212 				serial_ttystate new_ttystate,
213 				serial_ttystate old_ttystate)
214 {
215   struct hardwire_ttystate new_state;
216 #ifdef HAVE_SGTTY
217   struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate;
218 #endif
219 
220   new_state = *(struct hardwire_ttystate *) new_ttystate;
221 
222   /* Don't change in or out of raw mode; we don't want to flush input.
223      termio and termios have no such restriction; for them flushing input
224      is separate from setting the attributes.  */
225 
226 #ifdef HAVE_SGTTY
227   if (state->sgttyb.sg_flags & RAW)
228     new_state.sgttyb.sg_flags |= RAW;
229   else
230     new_state.sgttyb.sg_flags &= ~RAW;
231 
232   /* I'm not sure whether this is necessary; the manpage just mentions
233      RAW not CBREAK.  */
234   if (state->sgttyb.sg_flags & CBREAK)
235     new_state.sgttyb.sg_flags |= CBREAK;
236   else
237     new_state.sgttyb.sg_flags &= ~CBREAK;
238 #endif
239 
240   return set_tty_state (scb, &new_state);
241 }
242 
243 static void
244 hardwire_print_tty_state (struct serial *scb,
245 			  serial_ttystate ttystate,
246 			  struct ui_file *stream)
247 {
248   struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate;
249   int i;
250 
251 #ifdef HAVE_TERMIOS
252   fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n",
253 		    (int) state->termios.c_iflag,
254 		    (int) state->termios.c_oflag);
255   fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x\n",
256 		    (int) state->termios.c_cflag,
257 		    (int) state->termios.c_lflag);
258 #if 0
259   /* This not in POSIX, and is not really documented by those systems
260      which have it (at least not Sun).  */
261   fprintf_filtered (stream, "c_line = 0x%x.\n", state->termios.c_line);
262 #endif
263   fprintf_filtered (stream, "c_cc: ");
264   for (i = 0; i < NCCS; i += 1)
265     fprintf_filtered (stream, "0x%x ", state->termios.c_cc[i]);
266   fprintf_filtered (stream, "\n");
267 #endif
268 
269 #ifdef HAVE_TERMIO
270   fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n",
271 		    state->termio.c_iflag, state->termio.c_oflag);
272   fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
273 		    state->termio.c_cflag, state->termio.c_lflag,
274 		    state->termio.c_line);
275   fprintf_filtered (stream, "c_cc: ");
276   for (i = 0; i < NCC; i += 1)
277     fprintf_filtered (stream, "0x%x ", state->termio.c_cc[i]);
278   fprintf_filtered (stream, "\n");
279 #endif
280 
281 #ifdef HAVE_SGTTY
282   fprintf_filtered (stream, "sgttyb.sg_flags = 0x%x.\n",
283 		    state->sgttyb.sg_flags);
284 
285   fprintf_filtered (stream, "tchars: ");
286   for (i = 0; i < (int) sizeof (struct tchars); i++)
287     fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->tc)[i]);
288   fprintf_filtered (stream, "\n");
289 
290   fprintf_filtered (stream, "ltchars: ");
291   for (i = 0; i < (int) sizeof (struct ltchars); i++)
292     fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->ltc)[i]);
293   fprintf_filtered (stream, "\n");
294 
295   fprintf_filtered (stream, "lmode:  0x%x\n", state->lmode);
296 #endif
297 }
298 
299 /* Wait for the output to drain away, as opposed to flushing
300    (discarding) it.  */
301 
302 static int
303 hardwire_drain_output (struct serial *scb)
304 {
305 #ifdef HAVE_TERMIOS
306   return tcdrain (scb->fd);
307 #endif
308 
309 #ifdef HAVE_TERMIO
310   return ioctl (scb->fd, TCSBRK, 1);
311 #endif
312 
313 #ifdef HAVE_SGTTY
314   /* Get the current state and then restore it using TIOCSETP,
315      which should cause the output to drain and pending input
316      to be discarded.  */
317   {
318     struct hardwire_ttystate state;
319 
320     if (get_tty_state (scb, &state))
321       {
322 	return (-1);
323       }
324     else
325       {
326 	return (ioctl (scb->fd, TIOCSETP, &state.sgttyb));
327       }
328   }
329 #endif
330 }
331 
332 static int
333 hardwire_flush_output (struct serial *scb)
334 {
335 #ifdef HAVE_TERMIOS
336   return tcflush (scb->fd, TCOFLUSH);
337 #endif
338 
339 #ifdef HAVE_TERMIO
340   return ioctl (scb->fd, TCFLSH, 1);
341 #endif
342 
343 #ifdef HAVE_SGTTY
344   /* This flushes both input and output, but we can't do better.  */
345   return ioctl (scb->fd, TIOCFLUSH, 0);
346 #endif
347 }
348 
349 static int
350 hardwire_flush_input (struct serial *scb)
351 {
352   ser_base_flush_input (scb);
353 
354 #ifdef HAVE_TERMIOS
355   return tcflush (scb->fd, TCIFLUSH);
356 #endif
357 
358 #ifdef HAVE_TERMIO
359   return ioctl (scb->fd, TCFLSH, 0);
360 #endif
361 
362 #ifdef HAVE_SGTTY
363   /* This flushes both input and output, but we can't do better.  */
364   return ioctl (scb->fd, TIOCFLUSH, 0);
365 #endif
366 }
367 
368 static int
369 hardwire_send_break (struct serial *scb)
370 {
371 #ifdef HAVE_TERMIOS
372   return tcsendbreak (scb->fd, 0);
373 #endif
374 
375 #ifdef HAVE_TERMIO
376   return ioctl (scb->fd, TCSBRK, 0);
377 #endif
378 
379 #ifdef HAVE_SGTTY
380   {
381     int status;
382 
383     status = ioctl (scb->fd, TIOCSBRK, 0);
384 
385     /* Can't use usleep; it doesn't exist in BSD 4.2.  */
386     /* Note that if this gdb_select() is interrupted by a signal it will not
387        wait the full length of time.  I think that is OK.  */
388     gdb_usleep (250000);
389     status = ioctl (scb->fd, TIOCCBRK, 0);
390     return status;
391   }
392 #endif
393 }
394 
395 static void
396 hardwire_raw (struct serial *scb)
397 {
398   struct hardwire_ttystate state;
399 
400   if (get_tty_state (scb, &state))
401     fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n",
402 			safe_strerror (errno));
403 
404 #ifdef HAVE_TERMIOS
405   state.termios.c_iflag = 0;
406   state.termios.c_oflag = 0;
407   state.termios.c_lflag = 0;
408   state.termios.c_cflag &= ~CSIZE;
409   state.termios.c_cflag |= CLOCAL | CS8;
410 #ifdef CRTSCTS
411   /* h/w flow control.  */
412   if (serial_hwflow)
413     state.termios.c_cflag |= CRTSCTS;
414   else
415     state.termios.c_cflag &= ~CRTSCTS;
416 #ifdef CRTS_IFLOW
417   if (serial_hwflow)
418     state.termios.c_cflag |= CRTS_IFLOW;
419   else
420     state.termios.c_cflag &= ~CRTS_IFLOW;
421 #endif
422 #endif
423   state.termios.c_cc[VMIN] = 0;
424   state.termios.c_cc[VTIME] = 0;
425 #endif
426 
427 #ifdef HAVE_TERMIO
428   state.termio.c_iflag = 0;
429   state.termio.c_oflag = 0;
430   state.termio.c_lflag = 0;
431   state.termio.c_cflag &= ~CSIZE;
432   state.termio.c_cflag |= CLOCAL | CS8;
433   state.termio.c_cc[VMIN] = 0;
434   state.termio.c_cc[VTIME] = 0;
435 #endif
436 
437 #ifdef HAVE_SGTTY
438   state.sgttyb.sg_flags |= RAW | ANYP;
439   state.sgttyb.sg_flags &= ~(CBREAK | ECHO);
440 #endif
441 
442   if (set_tty_state (scb, &state))
443     fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n",
444 			safe_strerror (errno));
445 }
446 
447 #ifndef B19200
448 #define B19200 EXTA
449 #endif
450 
451 #ifndef B38400
452 #define B38400 EXTB
453 #endif
454 
455 /* Translate baud rates from integers to damn B_codes.  Unix should
456    have outgrown this crap years ago, but even POSIX wouldn't buck it.  */
457 
458 static struct
459 {
460   int rate;
461   int code;
462 }
463 baudtab[] =
464 {
465   {
466     50, B50
467   }
468   ,
469   {
470     75, B75
471   }
472   ,
473   {
474     110, B110
475   }
476   ,
477   {
478     134, B134
479   }
480   ,
481   {
482     150, B150
483   }
484   ,
485   {
486     200, B200
487   }
488   ,
489   {
490     300, B300
491   }
492   ,
493   {
494     600, B600
495   }
496   ,
497   {
498     1200, B1200
499   }
500   ,
501   {
502     1800, B1800
503   }
504   ,
505   {
506     2400, B2400
507   }
508   ,
509   {
510     4800, B4800
511   }
512   ,
513   {
514     9600, B9600
515   }
516   ,
517   {
518     19200, B19200
519   }
520   ,
521   {
522     38400, B38400
523   }
524   ,
525 #ifdef B57600
526   {
527     57600, B57600
528   }
529   ,
530 #endif
531 #ifdef B115200
532   {
533     115200, B115200
534   }
535   ,
536 #endif
537 #ifdef B230400
538   {
539     230400, B230400
540   }
541   ,
542 #endif
543 #ifdef B460800
544   {
545     460800, B460800
546   }
547   ,
548 #endif
549   {
550     -1, -1
551   }
552   ,
553 };
554 
555 static int
556 rate_to_code (int rate)
557 {
558   int i;
559 
560   for (i = 0; baudtab[i].rate != -1; i++)
561     {
562       /* test for perfect macth.  */
563       if (rate == baudtab[i].rate)
564         return baudtab[i].code;
565       else
566         {
567 	  /* check if it is in between valid values.  */
568           if (rate < baudtab[i].rate)
569 	    {
570 	      if (i)
571 	        {
572 	          warning (_("Invalid baud rate %d.  "
573 			     "Closest values are %d and %d."),
574 			   rate, baudtab[i - 1].rate, baudtab[i].rate);
575 		}
576 	      else
577 	        {
578 	          warning (_("Invalid baud rate %d.  Minimum value is %d."),
579 			   rate, baudtab[0].rate);
580 		}
581 	      return -1;
582 	    }
583         }
584     }
585 
586   /* The requested speed was too large.  */
587   warning (_("Invalid baud rate %d.  Maximum value is %d."),
588             rate, baudtab[i - 1].rate);
589   return -1;
590 }
591 
592 static int
593 hardwire_setbaudrate (struct serial *scb, int rate)
594 {
595   struct hardwire_ttystate state;
596   int baud_code = rate_to_code (rate);
597 
598   if (baud_code < 0)
599     {
600       /* The baud rate was not valid.
601          A warning has already been issued.  */
602       errno = EINVAL;
603       return -1;
604     }
605 
606   if (get_tty_state (scb, &state))
607     return -1;
608 
609 #ifdef HAVE_TERMIOS
610   cfsetospeed (&state.termios, baud_code);
611   cfsetispeed (&state.termios, baud_code);
612 #endif
613 
614 #ifdef HAVE_TERMIO
615 #ifndef CIBAUD
616 #define CIBAUD CBAUD
617 #endif
618 
619   state.termio.c_cflag &= ~(CBAUD | CIBAUD);
620   state.termio.c_cflag |= baud_code;
621 #endif
622 
623 #ifdef HAVE_SGTTY
624   state.sgttyb.sg_ispeed = baud_code;
625   state.sgttyb.sg_ospeed = baud_code;
626 #endif
627 
628   return set_tty_state (scb, &state);
629 }
630 
631 static int
632 hardwire_setstopbits (struct serial *scb, int num)
633 {
634   struct hardwire_ttystate state;
635   int newbit;
636 
637   if (get_tty_state (scb, &state))
638     return -1;
639 
640   switch (num)
641     {
642     case SERIAL_1_STOPBITS:
643       newbit = 0;
644       break;
645     case SERIAL_1_AND_A_HALF_STOPBITS:
646     case SERIAL_2_STOPBITS:
647       newbit = 1;
648       break;
649     default:
650       return 1;
651     }
652 
653 #ifdef HAVE_TERMIOS
654   if (!newbit)
655     state.termios.c_cflag &= ~CSTOPB;
656   else
657     state.termios.c_cflag |= CSTOPB;	/* two bits */
658 #endif
659 
660 #ifdef HAVE_TERMIO
661   if (!newbit)
662     state.termio.c_cflag &= ~CSTOPB;
663   else
664     state.termio.c_cflag |= CSTOPB;	/* two bits */
665 #endif
666 
667 #ifdef HAVE_SGTTY
668   return 0;			/* sgtty doesn't support this */
669 #endif
670 
671   return set_tty_state (scb, &state);
672 }
673 
674 /* Implement the "setparity" serial_ops callback.  */
675 
676 static int
677 hardwire_setparity (struct serial *scb, int parity)
678 {
679   struct hardwire_ttystate state;
680   int newparity = 0;
681 
682   if (get_tty_state (scb, &state))
683     return -1;
684 
685   switch (parity)
686     {
687     case GDBPARITY_NONE:
688       newparity = 0;
689       break;
690     case GDBPARITY_ODD:
691       newparity = PARENB | PARODD;
692       break;
693     case GDBPARITY_EVEN:
694       newparity = PARENB;
695       break;
696     default:
697       internal_warning (__FILE__, __LINE__,
698 			"Incorrect parity value: %d", parity);
699       return -1;
700     }
701 
702 #ifdef HAVE_TERMIOS
703   state.termios.c_cflag &= ~(PARENB | PARODD);
704   state.termios.c_cflag |= newparity;
705 #endif
706 
707 #ifdef HAVE_TERMIO
708   state.termio.c_cflag &= ~(PARENB | PARODD);
709   state.termio.c_cflag |= newparity;
710 #endif
711 
712 #ifdef HAVE_SGTTY
713   return 0;            /* sgtty doesn't support this */
714 #endif
715   return set_tty_state (scb, &state);
716 }
717 
718 
719 static void
720 hardwire_close (struct serial *scb)
721 {
722   if (scb->fd < 0)
723     return;
724 
725   close (scb->fd);
726   scb->fd = -1;
727 }
728 
729 
730 
731 /* The hardwire ops.  */
732 
733 static const struct serial_ops hardwire_ops =
734 {
735   "hardwire",
736   hardwire_open,
737   hardwire_close,
738   NULL,
739   ser_base_readchar,
740   ser_base_write,
741   hardwire_flush_output,
742   hardwire_flush_input,
743   hardwire_send_break,
744   hardwire_raw,
745   hardwire_get_tty_state,
746   hardwire_copy_tty_state,
747   hardwire_set_tty_state,
748   hardwire_print_tty_state,
749   hardwire_noflush_set_tty_state,
750   hardwire_setbaudrate,
751   hardwire_setstopbits,
752   hardwire_setparity,
753   hardwire_drain_output,
754   ser_base_async,
755   ser_unix_read_prim,
756   ser_unix_write_prim
757 };
758 
759 void
760 _initialize_ser_hardwire (void)
761 {
762   serial_add_interface (&hardwire_ops);
763 
764 #ifdef HAVE_TERMIOS
765 #ifdef CRTSCTS
766   add_setshow_boolean_cmd ("remoteflow", no_class,
767 			   &serial_hwflow, _("\
768 Set use of hardware flow control for remote serial I/O."), _("\
769 Show use of hardware flow control for remote serial I/O."), _("\
770 Enable or disable hardware flow control (RTS/CTS) on the serial port\n\
771 when debugging using remote targets."),
772 			   NULL,
773 			   show_serial_hwflow,
774 			   &setlist, &showlist);
775 #endif
776 #endif
777 }
778 
779 int
780 ser_unix_read_prim (struct serial *scb, size_t count)
781 {
782   return read (scb->fd, scb->buf, count);
783 }
784 
785 int
786 ser_unix_write_prim (struct serial *scb, const void *buf, size_t len)
787 {
788   return write (scb->fd, buf, len);
789 }
790