xref: /netbsd-src/external/gpl3/gdb/dist/gdb/ser-unix.c (revision 889f3bb010ad20d396fb291b89f202288dac2c87)
1 /* Serial interface for local (hardwired) serial ports on Un*x like systems
2 
3    Copyright (C) 1992-2024 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 "serial.h"
21 #include "ser-base.h"
22 #include "ser-unix.h"
23 
24 #include <fcntl.h>
25 #include <sys/types.h>
26 #include "terminal.h"
27 #include <sys/socket.h>
28 #include "gdbsupport/gdb_sys_time.h"
29 
30 #include "gdbsupport/gdb_select.h"
31 #include "cli/cli-cmds.h"
32 #include "gdbsupport/filestuff.h"
33 #include <termios.h>
34 #include "gdbsupport/scoped_ignore_sigttou.h"
35 
36 struct hardwire_ttystate
37   {
38     struct termios termios;
39   };
40 
41 #ifdef CRTSCTS
42 /* Boolean to explicitly enable or disable h/w flow control.  */
43 static bool serial_hwflow;
44 static void
45 show_serial_hwflow (struct ui_file *file, int from_tty,
46 		    struct cmd_list_element *c, const char *value)
47 {
48   gdb_printf (file, _("Hardware flow control is %s.\n"), value);
49 }
50 #endif
51 
52 static void hardwire_raw (struct serial *scb);
53 static int rate_to_code (int rate);
54 static void hardwire_setbaudrate (struct serial *scb, int rate);
55 static int hardwire_setparity (struct serial *scb, int parity);
56 static void hardwire_close (struct serial *scb);
57 static int get_tty_state (struct serial *scb,
58 			  struct hardwire_ttystate * state);
59 static int set_tty_state (struct serial *scb,
60 			  struct hardwire_ttystate * state);
61 static serial_ttystate hardwire_get_tty_state (struct serial *scb);
62 static int hardwire_set_tty_state (struct serial *scb, serial_ttystate state);
63 static void hardwire_print_tty_state (struct serial *, serial_ttystate,
64 				      struct ui_file *);
65 static int hardwire_drain_output (struct serial *);
66 static int hardwire_flush_output (struct serial *);
67 static int hardwire_flush_input (struct serial *);
68 static void hardwire_send_break (struct serial *);
69 static int hardwire_setstopbits (struct serial *, int);
70 
71 /* Open up a real live device for serial I/O.  */
72 
73 static void
74 hardwire_open (struct serial *scb, const char *name)
75 {
76   scb->fd = gdb_open_cloexec (name, O_RDWR, 0).release ();
77   if (scb->fd < 0)
78     perror_with_name ("could not open device");
79 }
80 
81 static int
82 get_tty_state (struct serial *scb, struct hardwire_ttystate *state)
83 {
84   if (tcgetattr (scb->fd, &state->termios) < 0)
85     return -1;
86 
87   return 0;
88 }
89 
90 static int
91 set_tty_state (struct serial *scb, struct hardwire_ttystate *state)
92 {
93   if (tcsetattr (scb->fd, TCSANOW, &state->termios) < 0)
94     return -1;
95 
96   return 0;
97 }
98 
99 static serial_ttystate
100 hardwire_get_tty_state (struct serial *scb)
101 {
102   struct hardwire_ttystate *state = XNEW (struct hardwire_ttystate);
103 
104   if (get_tty_state (scb, state))
105     {
106       xfree (state);
107       return NULL;
108     }
109 
110   return (serial_ttystate) state;
111 }
112 
113 static serial_ttystate
114 hardwire_copy_tty_state (struct serial *scb, serial_ttystate ttystate)
115 {
116   struct hardwire_ttystate *state = XNEW (struct hardwire_ttystate);
117 
118   *state = *(struct hardwire_ttystate *) ttystate;
119 
120   return (serial_ttystate) state;
121 }
122 
123 static int
124 hardwire_set_tty_state (struct serial *scb, serial_ttystate ttystate)
125 {
126   struct hardwire_ttystate *state;
127 
128   state = (struct hardwire_ttystate *) ttystate;
129 
130   return set_tty_state (scb, state);
131 }
132 
133 static void
134 hardwire_print_tty_state (struct serial *scb,
135 			  serial_ttystate ttystate,
136 			  struct ui_file *stream)
137 {
138   struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate;
139   int i;
140 
141   gdb_printf (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n",
142 	      (int) state->termios.c_iflag,
143 	      (int) state->termios.c_oflag);
144   gdb_printf (stream, "c_cflag = 0x%x, c_lflag = 0x%x\n",
145 	      (int) state->termios.c_cflag,
146 	      (int) state->termios.c_lflag);
147 #if 0
148   /* This not in POSIX, and is not really documented by those systems
149      which have it (at least not Sun).  */
150   gdb_printf (stream, "c_line = 0x%x.\n", state->termios.c_line);
151 #endif
152   gdb_printf (stream, "c_cc: ");
153   for (i = 0; i < NCCS; i += 1)
154     gdb_printf (stream, "0x%x ", state->termios.c_cc[i]);
155   gdb_printf (stream, "\n");
156 }
157 
158 /* Wait for the output to drain away, as opposed to flushing
159    (discarding) it.  */
160 
161 static int
162 hardwire_drain_output (struct serial *scb)
163 {
164   /* Ignore SIGTTOU which may occur during the drain.  */
165   scoped_ignore_sigttou ignore_sigttou;
166 
167   return tcdrain (scb->fd);
168 }
169 
170 static int
171 hardwire_flush_output (struct serial *scb)
172 {
173   return tcflush (scb->fd, TCOFLUSH);
174 }
175 
176 static int
177 hardwire_flush_input (struct serial *scb)
178 {
179   ser_base_flush_input (scb);
180 
181   return tcflush (scb->fd, TCIFLUSH);
182 }
183 
184 static void
185 hardwire_send_break (struct serial *scb)
186 {
187   if (tcsendbreak (scb->fd, 0) == -1)
188     perror_with_name ("sending break");
189 }
190 
191 static void
192 hardwire_raw (struct serial *scb)
193 {
194   struct hardwire_ttystate state;
195 
196   if (get_tty_state (scb, &state))
197     gdb_printf (gdb_stderr, "get_tty_state failed: %s\n",
198 		safe_strerror (errno));
199 
200   state.termios.c_iflag = 0;
201   state.termios.c_oflag = 0;
202   state.termios.c_lflag = 0;
203   state.termios.c_cflag &= ~CSIZE;
204   state.termios.c_cflag |= CLOCAL | CS8;
205 #ifdef CRTSCTS
206   /* h/w flow control.  */
207   if (serial_hwflow)
208     state.termios.c_cflag |= CRTSCTS;
209   else
210     state.termios.c_cflag &= ~CRTSCTS;
211 #ifdef CRTS_IFLOW
212   if (serial_hwflow)
213     state.termios.c_cflag |= CRTS_IFLOW;
214   else
215     state.termios.c_cflag &= ~CRTS_IFLOW;
216 #endif
217 #endif
218   state.termios.c_cc[VMIN] = 0;
219   state.termios.c_cc[VTIME] = 0;
220 
221   if (set_tty_state (scb, &state))
222     gdb_printf (gdb_stderr, "set_tty_state failed: %s\n",
223 		safe_strerror (errno));
224 }
225 
226 #ifndef B19200
227 #define B19200 EXTA
228 #endif
229 
230 #ifndef B38400
231 #define B38400 EXTB
232 #endif
233 
234 /* Translate baud rates from integers to damn B_codes.  Unix should
235    have outgrown this crap years ago, but even POSIX wouldn't buck it.  */
236 
237 static struct
238 {
239   int rate;
240   int code;
241 }
242 baudtab[] =
243 {
244   {
245     50, B50
246   }
247   ,
248   {
249     75, B75
250   }
251   ,
252   {
253     110, B110
254   }
255   ,
256   {
257     134, B134
258   }
259   ,
260   {
261     150, B150
262   }
263   ,
264   {
265     200, B200
266   }
267   ,
268   {
269     300, B300
270   }
271   ,
272   {
273     600, B600
274   }
275   ,
276   {
277     1200, B1200
278   }
279   ,
280   {
281     1800, B1800
282   }
283   ,
284   {
285     2400, B2400
286   }
287   ,
288   {
289     4800, B4800
290   }
291   ,
292   {
293     9600, B9600
294   }
295   ,
296   {
297     19200, B19200
298   }
299   ,
300   {
301     38400, B38400
302   }
303   ,
304 #ifdef B57600
305   {
306     57600, B57600
307   }
308   ,
309 #endif
310 #ifdef B115200
311   {
312     115200, B115200
313   }
314   ,
315 #endif
316 #ifdef B230400
317   {
318     230400, B230400
319   }
320   ,
321 #endif
322 #ifdef B460800
323   {
324     460800, B460800
325   }
326   ,
327 #endif
328 #ifdef B500000
329   {
330     500000, B500000
331   }
332   ,
333 #endif
334 #ifdef B576000
335   {
336     576000, B576000
337   }
338   ,
339 #endif
340 #ifdef B921600
341   {
342     921600, B921600
343   }
344   ,
345 #endif
346 #ifdef B1000000
347   {
348     1000000, B1000000
349   }
350   ,
351 #endif
352 #ifdef B1152000
353   {
354     1152000, B1152000
355   }
356   ,
357 #endif
358 #ifdef B1500000
359   {
360     1500000, B1500000
361   }
362   ,
363 #endif
364 #ifdef B2000000
365   {
366     2000000, B2000000
367   }
368   ,
369 #endif
370 #ifdef B2500000
371   {
372     2500000, B2500000
373   }
374   ,
375 #endif
376 #ifdef B3000000
377   {
378     3000000, B3000000
379   }
380   ,
381 #endif
382 #ifdef B3500000
383   {
384     3500000, B3500000
385   }
386   ,
387 #endif
388 #ifdef B4000000
389   {
390     4000000, B4000000
391   }
392   ,
393 #endif
394   {
395     -1, -1
396   }
397   ,
398 };
399 
400 static int
401 rate_to_code (int rate)
402 {
403   int i;
404 
405   for (i = 0; baudtab[i].rate != -1; i++)
406     {
407       /* test for perfect macth.  */
408       if (rate == baudtab[i].rate)
409 	return baudtab[i].code;
410       else
411 	{
412 	  /* check if it is in between valid values.  */
413 	  if (rate < baudtab[i].rate)
414 	    {
415 	      if (i)
416 		{
417 		  error (_("Invalid baud rate %d.  "
418 			   "Closest values are %d and %d."),
419 			 rate, baudtab[i - 1].rate, baudtab[i].rate);
420 		}
421 	      else
422 		{
423 		  error (_("Invalid baud rate %d.  Minimum value is %d."),
424 			 rate, baudtab[0].rate);
425 		}
426 	    }
427 	}
428     }
429 
430   /* The requested speed was too large.  */
431   error (_("Invalid baud rate %d.  Maximum value is %d."),
432 	 rate, baudtab[i - 1].rate);
433 }
434 
435 static void
436 hardwire_setbaudrate (struct serial *scb, int rate)
437 {
438   struct hardwire_ttystate state;
439   int baud_code = rate_to_code (rate);
440 
441   if (get_tty_state (scb, &state))
442     perror_with_name ("could not get tty state");
443 
444   cfsetospeed (&state.termios, baud_code);
445   cfsetispeed (&state.termios, baud_code);
446 
447   if (set_tty_state (scb, &state))
448     perror_with_name ("could not set tty state");
449 }
450 
451 static int
452 hardwire_setstopbits (struct serial *scb, int num)
453 {
454   struct hardwire_ttystate state;
455   int newbit;
456 
457   if (get_tty_state (scb, &state))
458     return -1;
459 
460   switch (num)
461     {
462     case SERIAL_1_STOPBITS:
463       newbit = 0;
464       break;
465     case SERIAL_1_AND_A_HALF_STOPBITS:
466     case SERIAL_2_STOPBITS:
467       newbit = 1;
468       break;
469     default:
470       return 1;
471     }
472 
473   if (!newbit)
474     state.termios.c_cflag &= ~CSTOPB;
475   else
476     state.termios.c_cflag |= CSTOPB;	/* two bits */
477 
478   return set_tty_state (scb, &state);
479 }
480 
481 /* Implement the "setparity" serial_ops callback.  */
482 
483 static int
484 hardwire_setparity (struct serial *scb, int parity)
485 {
486   struct hardwire_ttystate state;
487   int newparity = 0;
488 
489   if (get_tty_state (scb, &state))
490     return -1;
491 
492   switch (parity)
493     {
494     case GDBPARITY_NONE:
495       newparity = 0;
496       break;
497     case GDBPARITY_ODD:
498       newparity = PARENB | PARODD;
499       break;
500     case GDBPARITY_EVEN:
501       newparity = PARENB;
502       break;
503     default:
504       internal_warning ("Incorrect parity value: %d", parity);
505       return -1;
506     }
507 
508   state.termios.c_cflag &= ~(PARENB | PARODD);
509   state.termios.c_cflag |= newparity;
510 
511   return set_tty_state (scb, &state);
512 }
513 
514 
515 static void
516 hardwire_close (struct serial *scb)
517 {
518   if (scb->fd < 0)
519     return;
520 
521   close (scb->fd);
522   scb->fd = -1;
523 }
524 
525 
526 
527 /* The hardwire ops.  */
528 
529 static const struct serial_ops hardwire_ops =
530 {
531   "hardwire",
532   hardwire_open,
533   hardwire_close,
534   NULL,
535   ser_base_readchar,
536   ser_base_write,
537   hardwire_flush_output,
538   hardwire_flush_input,
539   hardwire_send_break,
540   hardwire_raw,
541   hardwire_get_tty_state,
542   hardwire_copy_tty_state,
543   hardwire_set_tty_state,
544   hardwire_print_tty_state,
545   hardwire_setbaudrate,
546   hardwire_setstopbits,
547   hardwire_setparity,
548   hardwire_drain_output,
549   ser_base_async,
550   ser_unix_read_prim,
551   ser_unix_write_prim
552 };
553 
554 void _initialize_ser_hardwire ();
555 void
556 _initialize_ser_hardwire ()
557 {
558   serial_add_interface (&hardwire_ops);
559 
560 #ifdef CRTSCTS
561   add_setshow_boolean_cmd ("remoteflow", no_class,
562 			   &serial_hwflow, _("\
563 Set use of hardware flow control for remote serial I/O."), _("\
564 Show use of hardware flow control for remote serial I/O."), _("\
565 Enable or disable hardware flow control (RTS/CTS) on the serial port\n\
566 when debugging using remote targets."),
567 			   NULL,
568 			   show_serial_hwflow,
569 			   &setlist, &showlist);
570 #endif
571 }
572 
573 int
574 ser_unix_read_prim (struct serial *scb, size_t count)
575 {
576   int result = read (scb->fd, scb->buf, count);
577   if (result == -1 && errno != EINTR)
578     perror_with_name ("error while reading");
579   return result;
580 }
581 
582 int
583 ser_unix_write_prim (struct serial *scb, const void *buf, size_t len)
584 {
585   int result = write (scb->fd, buf, len);
586   if (result == -1 && errno != EINTR)
587     perror_with_name ("error while writing");
588   return result;
589 }
590