diff options
author | Jim Kingdon <jkingdon@engr.sgi.com> | 1993-04-30 22:15:28 +0000 |
---|---|---|
committer | Jim Kingdon <jkingdon@engr.sgi.com> | 1993-04-30 22:15:28 +0000 |
commit | eca2963437b7a2c50d906de4fea10f0a8f011a9d (patch) | |
tree | f6ed899e12d523469c876798083e7056d0b36dea /gdb/ser-unix.c | |
parent | db7c818b4de503a24641242ce195a02c2a461c17 (diff) | |
download | gdb-eca2963437b7a2c50d906de4fea10f0a8f011a9d.zip gdb-eca2963437b7a2c50d906de4fea10f0a8f011a9d.tar.gz gdb-eca2963437b7a2c50d906de4fea10f0a8f011a9d.tar.bz2 |
* ser-unix.c [USE_{TERMIO,ALARM}_TIMEOUT]: New code to deal with
systems lacking select().
Diffstat (limited to 'gdb/ser-unix.c')
-rw-r--r-- | gdb/ser-unix.c | 113 |
1 files changed, 96 insertions, 17 deletions
diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c index afe6724..71f79a1 100644 --- a/gdb/ser-unix.c +++ b/gdb/ser-unix.c @@ -21,7 +21,24 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "serial.h" #include <fcntl.h> #include <sys/types.h> + +/* Note: HAVE_SELECT is not yet defined on all the systems which could + define it. The USE_ALARM_TIMEOUT code seems to work OK, though, so + it doesn't really matter. */ +#if !defined (HAVE_SELECT) +#if defined (HAVE_TERMIO) +#define USE_TERMIO_TIMEOUT 1 +#else +#define USE_ALARM_TIMEOUT 1 +#endif +#endif + +#if defined (HAVE_SELECT) #include <sys/time.h> +#endif +#ifdef USE_ALARM_TIMEOUT +#include <signal.h> +#endif #if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY) #define HAVE_SGTTY @@ -114,6 +131,14 @@ hardwire_raw(scb) #endif } +#ifdef USE_ALARM_TIMEOUT +/* Called when SIGALRM sent. */ +static void +remote_timer () +{ +} +#endif + /* Read a character with user-specified timeout. TIMEOUT is number of seconds to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns char if successful. Returns -2 if timeout expired, EOF if line dropped @@ -124,32 +149,86 @@ hardwire_readchar(scb, timeout) serial_t scb; int timeout; { - int numfds; - struct timeval tv; - fd_set readfds; - if (scb->bufcnt-- > 0) return *scb->bufp++; - FD_ZERO (&readfds); +#ifdef HAVE_SELECT + { + int numfds; + struct timeval tv; + fd_set readfds; + + FD_ZERO (&readfds); + + tv.tv_sec = timeout; + tv.tv_usec = 0; + + FD_SET(scb->fd, &readfds); + + if (timeout >= 0) + numfds = select(scb->fd+1, &readfds, 0, 0, &tv); + else + numfds = select(scb->fd+1, &readfds, 0, 0, 0); + + if (numfds <= 0) + if (numfds == 0) + return SERIAL_TIMEOUT; + else + return SERIAL_ERROR; /* Got an error from select */ - tv.tv_sec = timeout; - tv.tv_usec = 0; + scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ); + } +#endif /* HAVE_SELECT. */ - FD_SET(scb->fd, &readfds); +#ifdef USE_TERMIO_TIMEOUT + { + struct termio termio; - if (timeout >= 0) - numfds = select(scb->fd+1, &readfds, 0, 0, &tv); - else - numfds = select(scb->fd+1, &readfds, 0, 0, 0); + if (ioctl (scb->fd, TCGETA, &termio)) + { + fprintf(stderr, "TCGETA failed: %s\n", safe_strerror(errno)); + } - if (numfds <= 0) - if (numfds == 0) + termio.c_cc[VTIME] = timeout * 10; + + if (ioctl (scb->fd, TCSETA, &termio)) + { + fprintf(stderr, "TCSETA failed: %s\n", safe_strerror(errno)); + } + + scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ); + if (scb->bufcnt == 0) + /* Can this also mean end of file? Does "end of file" have any + meaning with ICANON clear? */ return SERIAL_TIMEOUT; - else - return SERIAL_ERROR; /* Got an error from select */ + } +#endif /* USE_TERMIO_TIMEOUT. */ + +#ifdef USE_ALARM_TIMEOUT + { + void (*old_sigalrm_handler) (); + int save_errno; +#ifndef NO_SIGINTERRUPT + /* Cause SIGARLM to make read fail with EINTR. */ + if (siginterrupt (SIGALRM, 1) != 0) + fprintf (stderr, "siginterrupt failed: %s\n", safe_strerror (errno)); +#endif - scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ); + old_sigalrm_handler = (void (*) ()) signal (SIGALRM, remote_timer); + if (old_sigalrm_handler == (void (*) ()) -1) + fprintf (stderr, "signal failed: %s\n", safe_strerror (errno)); + + alarm (timeout); + scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ); + save_errno = errno; + alarm (0); + signal (SIGALRM, old_sigalrm_handler); + if (scb->bufcnt < 0 && errno == EINTR) + { + return SERIAL_TIMEOUT; + } + } +#endif /* USE_ALARM_TIMEOUT */ if (scb->bufcnt <= 0) if (scb->bufcnt == 0) |