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 struct hardwire_ttystate
51 /* Needed for the code which uses select(). We would include <sys/select.h>
52 too if it existed on all systems. */
57 struct hardwire_ttystate
62 /* Line discipline flags. */
66 /* This is only used for the ultra. Does it have pid_t? */
74 static int hardwire_open
PARAMS ((serial_t scb
, const char *name
));
75 static void hardwire_raw
PARAMS ((serial_t scb
));
76 static int wait_for
PARAMS ((serial_t scb
, int timeout
));
77 static int hardwire_readchar
PARAMS ((serial_t scb
, int timeout
));
78 static int rate_to_code
PARAMS ((int rate
));
79 static int hardwire_setbaudrate
PARAMS ((serial_t scb
, int rate
));
80 static int hardwire_write
PARAMS ((serial_t scb
, const char *str
, int len
));
81 static void hardwire_restore
PARAMS ((serial_t scb
));
82 static void hardwire_close
PARAMS ((serial_t scb
));
83 static int get_tty_state
PARAMS ((serial_t scb
, struct hardwire_ttystate
*state
));
84 static int set_tty_state
PARAMS ((serial_t scb
, struct hardwire_ttystate
*state
));
85 static serial_ttystate hardwire_get_tty_state
PARAMS ((serial_t scb
));
86 static int hardwire_set_tty_state
PARAMS ((serial_t scb
, serial_ttystate state
));
88 /* Open up a real live device for serial I/O */
91 hardwire_open(scb
, name
)
95 scb
->fd
= open (name
, O_RDWR
);
103 get_tty_state(scb
, state
)
105 struct hardwire_ttystate
*state
;
108 pid_t new_process_group
;
110 if (tcgetattr(scb
->fd
, &state
->termios
) < 0)
116 new_process_group
= tcgetpgrp (scb
->fd
);
117 if (new_process_group
== (pid_t
)-1)
119 state
->process_group
= new_process_group
;
124 if (ioctl (scb
->fd
, TCGETA
, &state
->termio
) < 0)
130 return ioctl (scb
->fd
, TIOCGPGRP
, &state
->process_group
);
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 /* Need to ignore errors, at least if attach_flag is set. */
175 ioctl (scb
->fd
, TIOCSPGRP
, &state
->process_group
);
180 if (ioctl (scb
->fd
, TIOCSETN
, &state
->sgttyb
) < 0)
186 /* Need to ignore errors, at least if attach_flag is set. */
187 ioctl (scb
->fd
, TIOCSPGRP
, &state
->process_group
);
192 static serial_ttystate
193 hardwire_get_tty_state(scb
)
196 struct hardwire_ttystate
*state
;
198 state
= (struct hardwire_ttystate
*)xmalloc(sizeof *state
);
200 if (get_tty_state(scb
, state
))
203 return (serial_ttystate
)state
;
207 hardwire_set_tty_state(scb
, ttystate
)
209 serial_ttystate ttystate
;
211 struct hardwire_ttystate
*state
;
213 state
= (struct hardwire_ttystate
*)ttystate
;
215 return set_tty_state(scb
, state
);
219 hardwire_noflush_set_tty_state (scb
, new_ttystate
, old_ttystate
)
221 serial_ttystate new_ttystate
;
222 serial_ttystate old_ttystate
;
224 struct hardwire_ttystate new_state
=
225 *(struct hardwire_ttystate
*)new_ttystate
;
226 struct hardwire_ttystate
*state
= (struct hardwire_ttystate
*) old_ttystate
;
229 /* I'm not sure whether this is necessary; the manpage makes no mention
230 of discarding input when switching to/from ICANON. */
231 if (state
->termios
.c_lflag
& ICANON
)
232 new_state
.termios
.c_lflag
|= ICANON
;
234 new_state
.termios
.c_lflag
&= ~ICANON
;
238 /* I'm not sure whether this is necessary; the manpage makes no mention
239 of discarding input when switching to/from ICANON. */
240 if (state
->termio
.c_lflag
& ICANON
)
241 new_state
.termio
.c_lflag
|= ICANON
;
243 new_state
.termio
.c_lflag
&= ~ICANON
;
247 if (state
->sgttyb
.sg_flags
& RAW
)
248 new_state
.sgttyb
.sg_flags
|= RAW
;
250 new_state
.sgttyb
.sg_flags
&= ~RAW
;
252 /* I'm not sure whether this is necessary; the manpage just mentions
254 if (state
->sgttyb
.sg_flags
& CBREAK
)
255 new_state
.sgttyb
.sg_flags
|= CBREAK
;
257 new_state
.sgttyb
.sg_flags
&= ~CBREAK
;
260 return set_tty_state (scb
, &new_state
);
264 hardwire_print_tty_state (scb
, ttystate
)
266 serial_ttystate ttystate
;
268 struct hardwire_ttystate
*state
= (struct hardwire_ttystate
*) ttystate
;
271 printf_filtered ("Process group = %d\n", state
->process_group
);
274 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
275 state
->termios
.c_iflag
, state
->termios
.c_oflag
);
276 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
277 state
->termios
.c_cflag
, state
->termios
.c_lflag
,
278 state
->termios
.c_line
);
279 printf_filtered ("c_cc: ");
280 for (i
= 0; i
< NCCS
; i
+= 1)
281 printf_filtered ("0x%x ", state
->termios
.c_cc
[i
]);
282 printf_filtered ("\n");
286 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
287 state
->termio
.c_iflag
, state
->termio
.c_oflag
);
288 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
289 state
->termio
.c_cflag
, state
->termio
.c_lflag
,
290 state
->termio
.c_line
);
291 printf_filtered ("c_cc: ");
292 for (i
= 0; i
< NCC
; i
+= 1)
293 printf_filtered ("0x%x ", state
->termio
.c_cc
[i
]);
294 printf_filtered ("\n");
298 printf_filtered ("sgttyb.sg_flags = 0x%x.\n", state
->sgttyb
.sg_flags
);
300 printf_filtered ("tchars: ");
301 for (i
= 0; i
< (int)sizeof (struct tchars
); i
++)
302 printf_filtered ("0x%x ", ((unsigned char *)&state
->tc
)[i
]);
303 printf_filtered ("\n");
305 printf_filtered ("ltchars: ");
306 for (i
= 0; i
< (int)sizeof (struct ltchars
); i
++)
307 printf_filtered ("0x%x ", ((unsigned char *)&state
->ltc
)[i
]);
308 printf_filtered ("\n");
310 printf_filtered ("lmode: 0x%x\n", state
->lmode
);
315 hardwire_flush_output (scb
)
319 return tcflush (scb
->fd
, TCOFLUSH
);
323 return ioctl (scb
->fd
, TCFLSH
, 1);
327 /* This flushes both input and output, but we can't do better. */
328 return ioctl (scb
->fd
, TIOCFLUSH
, 0);
336 struct hardwire_ttystate state
;
338 if (get_tty_state(scb
, &state
))
339 fprintf(stderr
, "get_tty_state failed: %s\n", safe_strerror(errno
));
342 state
.termios
.c_iflag
= 0;
343 state
.termios
.c_oflag
= 0;
344 state
.termios
.c_lflag
= 0;
345 state
.termios
.c_cflag
&= ~(CSIZE
|PARENB
);
346 state
.termios
.c_cflag
|= CS8
;
347 state
.termios
.c_cc
[VMIN
] = 0;
348 state
.termios
.c_cc
[VTIME
] = 0;
352 state
.termio
.c_iflag
= 0;
353 state
.termio
.c_oflag
= 0;
354 state
.termio
.c_lflag
= 0;
355 state
.termio
.c_cflag
&= ~(CSIZE
|PARENB
);
356 state
.termio
.c_cflag
|= CS8
;
357 state
.termio
.c_cc
[VMIN
] = 0;
358 state
.termio
.c_cc
[VTIME
] = 0;
362 state
.sgttyb
.sg_flags
|= RAW
| ANYP
;
363 state
.sgttyb
.sg_flags
&= ~(CBREAK
| ECHO
);
366 scb
->current_timeout
= 0;
368 if (set_tty_state (scb
, &state
))
369 fprintf(stderr
, "set_tty_state failed: %s\n", safe_strerror(errno
));
372 /* Wait for input on scb, with timeout seconds. Returns 0 on success,
373 otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
375 For termio{s}, we actually just setup VTIME if necessary, and let the
376 timeout occur in the read() in hardwire_read().
380 wait_for(scb
, timeout
)
395 FD_SET(scb
->fd
, &readfds
);
400 numfds
= select(scb
->fd
+1, &readfds
, 0, 0, &tv
);
402 numfds
= select(scb
->fd
+1, &readfds
, 0, 0, 0);
406 return SERIAL_TIMEOUT
;
407 else if (errno
== EINTR
)
410 return SERIAL_ERROR
; /* Got an error from select or poll */
415 #endif /* HAVE_SGTTY */
417 #if defined HAVE_TERMIO || defined HAVE_TERMIOS
418 if (timeout
== scb
->current_timeout
)
422 struct hardwire_ttystate state
;
424 if (get_tty_state(scb
, &state
))
425 fprintf(stderr
, "get_tty_state failed: %s\n", safe_strerror(errno
));
428 state
.termios
.c_cc
[VTIME
] = timeout
* 10;
432 state
.termio
.c_cc
[VTIME
] = timeout
* 10;
435 scb
->current_timeout
= timeout
;
437 if (set_tty_state (scb
, &state
))
438 fprintf(stderr
, "set_tty_state failed: %s\n", safe_strerror(errno
));
442 #endif /* HAVE_TERMIO || HAVE_TERMIOS */
445 /* Read a character with user-specified timeout. TIMEOUT is number of seconds
446 to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
447 char if successful. Returns -2 if timeout expired, EOF if line dropped
448 dead, or -3 for any other error (see errno in that case). */
451 hardwire_readchar(scb
, timeout
)
457 if (scb
->bufcnt
-- > 0)
460 status
= wait_for(scb
, timeout
);
465 scb
->bufcnt
= read(scb
->fd
, scb
->buf
, BUFSIZ
);
467 if (scb
->bufcnt
<= 0)
468 if (scb
->bufcnt
== 0)
469 return SERIAL_TIMEOUT
; /* 0 chars means timeout [may need to
470 distinguish between EOF & timeouts
473 return SERIAL_ERROR
; /* Got an error from read */
476 scb
->bufp
= scb
->buf
;
488 /* Translate baud rates from integers to damn B_codes. Unix should
489 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
522 for (i
= 0; baudtab
[i
].rate
!= -1; i
++)
523 if (rate
== baudtab
[i
].rate
)
524 return baudtab
[i
].code
;
530 hardwire_setbaudrate(scb
, rate
)
534 struct hardwire_ttystate state
;
536 if (get_tty_state(scb
, &state
))
540 cfsetospeed (&state
.termios
, rate_to_code (rate
));
541 cfsetispeed (&state
.termios
, rate_to_code (rate
));
549 state
.termio
.c_cflag
&= ~(CBAUD
| CIBAUD
);
550 state
.termio
.c_cflag
|= rate_to_code (rate
);
554 state
.sgttyb
.sg_ispeed
= rate_to_code (rate
);
555 state
.sgttyb
.sg_ospeed
= rate_to_code (rate
);
558 return set_tty_state (scb
, &state
);
562 hardwire_set_process_group (scb
, ttystate
, group
)
564 serial_ttystate ttystate
;
567 ((struct hardwire_ttystate
*)ttystate
)->process_group
= group
;
572 hardwire_write(scb
, str
, len
)
581 cc
= write(scb
->fd
, str
, len
);
602 static struct serial_ops hardwire_ops
=
610 hardwire_flush_output
,
612 hardwire_get_tty_state
,
613 hardwire_set_tty_state
,
614 hardwire_print_tty_state
,
615 hardwire_noflush_set_tty_state
,
616 hardwire_setbaudrate
,
617 hardwire_set_process_group
621 #if defined (HAVE_TERMIOS)
625 /* This is here because this is where we figure out whether we (probably)
626 have job control. Just using job_control only does part of it because
627 setpgid or setpgrp might not exist on a system without job control.
628 It might be considered misplaced (on the other hand, process groups and
629 job control are closely related to ttys).
631 For a more clean implementation, in libiberty, put a setpgid which merely
632 calls setpgrp and a setpgrp which does nothing (any system with job control
633 will have one or the other). */
640 #if defined (NEED_POSIX_SETPGID) || defined (HAVE_TERMIOS)
641 /* Do all systems with termios have setpgid? I hope so. */
642 retval
= setpgid (0, 0);
644 #if defined (TIOCGPGRP)
645 #if defined(USG) && !defined(SETPGRP_ARGS)
648 retval
= setpgrp (getpid (), getpid ());
650 #endif /* TIOCGPGRP. */
651 #endif /* NEED_POSIX_SETPGID */
657 _initialize_ser_hardwire ()
659 serial_add_interface (&hardwire_ops
);
661 /* OK, figure out whether we have job control. */
663 #if defined (HAVE_TERMIOS)
664 /* Do all systems with termios have the POSIX way of identifying job
665 control? I hope so. */
666 #ifdef _POSIX_JOB_CONTROL
667 job_control
= _POSIX_JOB_CONTROL
;
669 job_control
= sysconf (_SC_JOB_CONTROL
);
672 #else /* not termios. */
678 #endif /* TIOCGPGRP */
680 #endif /* not termios. */