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