From: Jim Kingdon Date: Fri, 30 Apr 1993 22:15:28 +0000 (+0000) Subject: * ser-unix.c [USE_{TERMIO,ALARM}_TIMEOUT]: New code to deal with X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=eca2963437b7a2c50d906de4fea10f0a8f011a9d;p=binutils-gdb.git * ser-unix.c [USE_{TERMIO,ALARM}_TIMEOUT]: New code to deal with systems lacking select(). --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1eb22bc6911..f1bc880f1f0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,8 @@ Fri Apr 30 11:05:42 1993 Jim Kingdon (kingdon@cygnus.com) + * ser-unix.c [USE_{TERMIO,ALARM}_TIMEOUT]: New code to deal with + systems lacking select(). + * Makefile.in (TAGS): Doc fix. Deal with empty DEPFILES. Fri Apr 30 10:06:46 1993 Fred Fish (fnf@cygnus.com) diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c index afe6724221c..71f79a12ca8 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 #include + +/* 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 +#endif +#ifdef USE_ALARM_TIMEOUT +#include +#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)