1 /* Serial interface for local (hardwired) serial ports on Un*x like systems
2 Copyright 1992, 1993 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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. */
23 #include <sys/types.h>
25 #if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
33 struct hardwire_ttystate
35 struct termios termios;
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. */
48 struct hardwire_ttystate
55 /* Needed for the code which uses select(). We would include <sys/select.h>
56 too if it existed on all systems. */
61 struct hardwire_ttystate
66 /* Line discipline flags. */
70 /* This is only used for the ultra. Does it have pid_t? */
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 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));
92 /* Open up a real live device for serial I/O */
95 hardwire_open(scb, name)
99 scb->fd = open (name, O_RDWR);
107 get_tty_state(scb, state)
109 struct hardwire_ttystate *state;
112 pid_t new_process_group;
114 if (tcgetattr(scb->fd, &state->termios) < 0)
120 new_process_group = tcgetpgrp (scb->fd);
121 if (new_process_group == (pid_t)-1)
123 state->process_group = new_process_group;
128 if (ioctl (scb->fd, TCGETA, &state->termio) < 0)
134 if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0)
136 if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0)
138 if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0)
140 if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0)
146 return ioctl (scb->fd, TIOCGPGRP, &state->process_group);
151 set_tty_state(scb, state)
153 struct hardwire_ttystate *state;
156 if (tcsetattr(scb->fd, TCSANOW, &state->termios) < 0)
162 /* Need to ignore errors, at least if attach_flag is set. */
163 tcsetpgrp (scb->fd, state->process_group);
168 if (ioctl (scb->fd, TCSETA, &state->termio) < 0)
174 if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0)
180 /* Need to ignore errors, at least if attach_flag is set. */
181 ioctl (scb->fd, TIOCSPGRP, &state->process_group);
186 static serial_ttystate
187 hardwire_get_tty_state(scb)
190 struct hardwire_ttystate *state;
192 state = (struct hardwire_ttystate *)xmalloc(sizeof *state);
194 if (get_tty_state(scb, state))
197 return (serial_ttystate)state;
201 hardwire_set_tty_state(scb, ttystate)
203 serial_ttystate ttystate;
205 struct hardwire_ttystate *state;
207 state = (struct hardwire_ttystate *)ttystate;
209 return set_tty_state(scb, state);
213 hardwire_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
215 serial_ttystate new_ttystate;
216 serial_ttystate old_ttystate;
218 struct hardwire_ttystate new_state;
219 struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate;
221 new_state = *(struct hardwire_ttystate *)new_ttystate;
224 /* I'm not sure whether this is necessary; the manpage makes no mention
225 of discarding input when switching to/from ICANON. */
226 if (state->termios.c_lflag & ICANON)
227 new_state.termios.c_lflag |= ICANON;
229 new_state.termios.c_lflag &= ~ICANON;
233 /* I'm not sure whether this is necessary; the manpage makes no mention
234 of discarding input when switching to/from ICANON. */
235 if (state->termio.c_lflag & ICANON)
236 new_state.termio.c_lflag |= ICANON;
238 new_state.termio.c_lflag &= ~ICANON;
242 if (state->sgttyb.sg_flags & RAW)
243 new_state.sgttyb.sg_flags |= RAW;
245 new_state.sgttyb.sg_flags &= ~RAW;
247 /* I'm not sure whether this is necessary; the manpage just mentions
249 if (state->sgttyb.sg_flags & CBREAK)
250 new_state.sgttyb.sg_flags |= CBREAK;
252 new_state.sgttyb.sg_flags &= ~CBREAK;
255 return set_tty_state (scb, &new_state);
259 hardwire_print_tty_state (scb, ttystate)
261 serial_ttystate ttystate;
263 struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate;
267 printf_filtered ("Process group = %d\n", state->process_group);
269 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
270 state->termios.c_iflag, state->termios.c_oflag);
271 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x\n",
272 state->termios.c_cflag, state->termios.c_lflag);
274 /* This not in POSIX, and is not really documented by those systems
275 which have it (at least not Sun). */
276 printf_filtered ("c_line = 0x%x.\n", state->termios.c_line);
278 printf_filtered ("c_cc: ");
279 for (i = 0; i < NCCS; i += 1)
280 printf_filtered ("0x%x ", state->termios.c_cc[i]);
281 printf_filtered ("\n");
285 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
286 state->termio.c_iflag, state->termio.c_oflag);
287 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
288 state->termio.c_cflag, state->termio.c_lflag,
289 state->termio.c_line);
290 printf_filtered ("c_cc: ");
291 for (i = 0; i < NCC; i += 1)
292 printf_filtered ("0x%x ", state->termio.c_cc[i]);
293 printf_filtered ("\n");
297 printf_filtered ("Process group = %d\n", state->process_group);
299 printf_filtered ("sgttyb.sg_flags = 0x%x.\n", state->sgttyb.sg_flags);
301 printf_filtered ("tchars: ");
302 for (i = 0; i < (int)sizeof (struct tchars); i++)
303 printf_filtered ("0x%x ", ((unsigned char *)&state->tc)[i]);
304 printf_filtered ("\n");
306 printf_filtered ("ltchars: ");
307 for (i = 0; i < (int)sizeof (struct ltchars); i++)
308 printf_filtered ("0x%x ", ((unsigned char *)&state->ltc)[i]);
309 printf_filtered ("\n");
311 printf_filtered ("lmode: 0x%x\n", state->lmode);
316 hardwire_flush_output (scb)
320 return tcflush (scb->fd, TCOFLUSH);
324 return ioctl (scb->fd, TCFLSH, 1);
328 /* This flushes both input and output, but we can't do better. */
329 return ioctl (scb->fd, TIOCFLUSH, 0);
337 struct hardwire_ttystate state;
339 if (get_tty_state(scb, &state))
340 fprintf(stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
343 state.termios.c_iflag = 0;
344 state.termios.c_oflag = 0;
345 state.termios.c_lflag = 0;
346 state.termios.c_cflag &= ~(CSIZE|PARENB);
347 state.termios.c_cflag |= CS8;
348 state.termios.c_cc[VMIN] = 0;
349 state.termios.c_cc[VTIME] = 0;
353 state.termio.c_iflag = 0;
354 state.termio.c_oflag = 0;
355 state.termio.c_lflag = 0;
356 state.termio.c_cflag &= ~(CSIZE|PARENB);
357 state.termio.c_cflag |= CS8;
358 state.termio.c_cc[VMIN] = 0;
359 state.termio.c_cc[VTIME] = 0;
363 state.sgttyb.sg_flags |= RAW | ANYP;
364 state.sgttyb.sg_flags &= ~(CBREAK | ECHO);
367 scb->current_timeout = 0;
369 if (set_tty_state (scb, &state))
370 fprintf(stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
373 /* Wait for input on scb, with timeout seconds. Returns 0 on success,
374 otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
376 For termio{s}, we actually just setup VTIME if necessary, and let the
377 timeout occur in the read() in hardwire_read().
381 wait_for(scb, timeout)
396 FD_SET(scb->fd, &readfds);
401 numfds = select(scb->fd+1, &readfds, 0, 0, &tv);
403 numfds = select(scb->fd+1, &readfds, 0, 0, 0);
407 return SERIAL_TIMEOUT;
408 else if (errno == EINTR)
411 return SERIAL_ERROR; /* Got an error from select or poll */
416 #endif /* HAVE_SGTTY */
418 #if defined HAVE_TERMIO || defined HAVE_TERMIOS
419 if (timeout == scb->current_timeout)
423 struct hardwire_ttystate state;
425 if (get_tty_state(scb, &state))
426 fprintf(stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
429 state.termios.c_cc[VTIME] = timeout * 10;
433 state.termio.c_cc[VTIME] = timeout * 10;
436 scb->current_timeout = timeout;
438 if (set_tty_state (scb, &state))
439 fprintf(stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
443 #endif /* HAVE_TERMIO || HAVE_TERMIOS */
446 /* Read a character with user-specified timeout. TIMEOUT is number of seconds
447 to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
448 char if successful. Returns -2 if timeout expired, EOF if line dropped
449 dead, or -3 for any other error (see errno in that case). */
452 hardwire_readchar(scb, timeout)
458 if (scb->bufcnt-- > 0)
461 status = wait_for(scb, timeout);
466 scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
468 if (scb->bufcnt <= 0)
469 if (scb->bufcnt == 0)
470 return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
471 distinguish between EOF & timeouts
474 return SERIAL_ERROR; /* Got an error from read */
477 scb->bufp = scb->buf;
489 /* Translate baud rates from integers to damn B_codes. Unix should
490 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
523 for (i = 0; baudtab[i].rate != -1; i++)
524 if (rate == baudtab[i].rate)
525 return baudtab[i].code;
531 hardwire_setbaudrate(scb, rate)
535 struct hardwire_ttystate state;
537 if (get_tty_state(scb, &state))
541 cfsetospeed (&state.termios, rate_to_code (rate));
542 cfsetispeed (&state.termios, rate_to_code (rate));
550 state.termio.c_cflag &= ~(CBAUD | CIBAUD);
551 state.termio.c_cflag |= rate_to_code (rate);
555 state.sgttyb.sg_ispeed = rate_to_code (rate);
556 state.sgttyb.sg_ospeed = rate_to_code (rate);
559 return set_tty_state (scb, &state);
563 hardwire_set_process_group (scb, ttystate, group)
565 serial_ttystate ttystate;
568 #if defined (HAVE_SGTTY) || defined (HAVE_TERMIOS)
569 ((struct hardwire_ttystate *)ttystate)->process_group = group;
575 hardwire_write(scb, str, len)
584 cc = write(scb->fd, str, len);
605 static struct serial_ops hardwire_ops =
613 hardwire_flush_output,
615 hardwire_get_tty_state,
616 hardwire_set_tty_state,
617 hardwire_print_tty_state,
618 hardwire_noflush_set_tty_state,
619 hardwire_setbaudrate,
620 hardwire_set_process_group
624 #if defined (HAVE_TERMIOS)
628 /* This is here because this is where we figure out whether we (probably)
629 have job control. Just using job_control only does part of it because
630 setpgid or setpgrp might not exist on a system without job control.
631 It might be considered misplaced (on the other hand, process groups and
632 job control are closely related to ttys).
634 For a more clean implementation, in libiberty, put a setpgid which merely
635 calls setpgrp and a setpgrp which does nothing (any system with job control
636 will have one or the other). */
643 #if defined (NEED_POSIX_SETPGID) || defined (HAVE_TERMIOS)
644 /* Do all systems with termios have setpgid? I hope so. */
645 retval = setpgid (0, 0);
647 #if defined (TIOCGPGRP)
648 #if defined(USG) && !defined(SETPGRP_ARGS)
651 retval = setpgrp (getpid (), getpid ());
653 #endif /* TIOCGPGRP. */
654 #endif /* NEED_POSIX_SETPGID */
660 _initialize_ser_hardwire ()
662 serial_add_interface (&hardwire_ops);
664 /* OK, figure out whether we have job control. */
666 #if defined (HAVE_TERMIOS)
667 /* Do all systems with termios have the POSIX way of identifying job
668 control? I hope so. */
669 #ifdef _POSIX_JOB_CONTROL
672 job_control = sysconf (_SC_JOB_CONTROL);
677 /* See comment at top of file about trying to support process groups
687 #endif /* TIOCGPGRP */