/* Serial interface for local (hardwired) serial ports on Un*x like systems
- Copyright 1992-1994, 1998-2000 Free Software Foundation, Inc.
+ Copyright 1992-1994, 1998-2000, 2001 Free Software Foundation, Inc.
This file is part of GDB.
#include <fcntl.h>
#include <sys/types.h>
#include "terminal.h"
-#include "gdb_wait.h"
#include <sys/socket.h>
#include <sys/time.h>
fprintf_filtered (stream, "tchars: ");
for (i = 0; i < (int) sizeof (struct tchars); i++)
fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->tc)[i]);
- fprintf_filtered ("\n");
+ fprintf_filtered (stream, "\n");
fprintf_filtered (stream, "ltchars: ");
for (i = 0; i < (int) sizeof (struct ltchars); i++)
wait_for (serial_t scb, int timeout)
{
#ifdef HAVE_SGTTY
- {
- struct timeval tv;
- fd_set readfds;
+ while (1)
+ {
+ struct timeval tv;
+ fd_set readfds;
+ int numfds;
- FD_ZERO (&readfds);
+ /* NOTE: Some OS's can scramble the READFDS when the select()
+ call fails (ex the kernel with Red Hat 5.2). Initialize all
+ arguments before each call. */
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
- FD_SET (scb->fd, &readfds);
+ FD_ZERO (&readfds);
+ FD_SET (scb->fd, &readfds);
- while (1)
- {
- int numfds;
+ if (timeout >= 0)
+ numfds = select (scb->fd + 1, &readfds, 0, 0, &tv);
+ else
+ numfds = select (scb->fd + 1, &readfds, 0, 0, 0);
- if (timeout >= 0)
- numfds = select (scb->fd + 1, &readfds, 0, 0, &tv);
+ if (numfds <= 0)
+ if (numfds == 0)
+ return SERIAL_TIMEOUT;
+ else if (errno == EINTR)
+ continue;
else
- numfds = select (scb->fd + 1, &readfds, 0, 0, 0);
+ return SERIAL_ERROR; /* Got an error from select or poll */
- if (numfds <= 0)
- if (numfds == 0)
- return SERIAL_TIMEOUT;
- else if (errno == EINTR)
- continue;
- else
- return SERIAL_ERROR; /* Got an error from select or poll */
-
- return 0;
- }
- }
+ return 0;
+ }
#endif /* HAVE_SGTTY */
#if defined HAVE_TERMIO || defined HAVE_TERMIOS
}
static int
-hardwire_setstopbits (scb, num)
- serial_t scb;
- int num;
+hardwire_setstopbits (serial_t scb, int num)
{
struct hardwire_ttystate state;
int newbit;
int
ser_unix_wait_for (serial_t scb, int timeout)
{
- int numfds;
- struct timeval tv;
- fd_set readfds, exceptfds;
+ while (1)
+ {
+ int numfds;
+ struct timeval tv;
+ fd_set readfds, exceptfds;
- FD_ZERO (&readfds);
- FD_ZERO (&exceptfds);
+ /* NOTE: Some OS's can scramble the READFDS when the select()
+ call fails (ex the kernel with Red Hat 5.2). Initialize all
+ arguments before each call. */
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
- FD_SET (scb->fd, &readfds);
- FD_SET (scb->fd, &exceptfds);
+ FD_ZERO (&readfds);
+ FD_ZERO (&exceptfds);
+ FD_SET (scb->fd, &readfds);
+ FD_SET (scb->fd, &exceptfds);
- while (1)
- {
if (timeout >= 0)
numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
else
each time through the loop.
Also, timeout = 0 means to poll, so we just set the delta to 0, so we
- will only go through the loop once. timeout < 0 means to wait forever. */
+ will only go through the loop once. */
- delta = (timeout <= 0 ? 0 : 1);
+ delta = (timeout == 0 ? 0 : 1);
while (1)
{
return SERIAL_TIMEOUT;
}
- status = ser_unix_wait_for (scb, timeout < 0 ? timeout : delta);
- timeout -= delta;
+ status = ser_unix_wait_for (scb, delta);
+ if (timeout > 0)
+ timeout -= delta;
- /* If we got an error back from wait_for, then we can return */
+ /* If we got a character or an error back from wait_for, then we can
+ break from the loop before the timeout is completed. */
- if (status == SERIAL_ERROR)
- return status;
+ if (status != SERIAL_TIMEOUT)
+ {
+ break;
+ }
- status = read (scb->fd, scb->buf, BUFSIZ);
+ /* If we have exhausted the original timeout, then generate
+ a SERIAL_TIMEOUT, and pass it out of the loop. */
- if (status <= 0)
- {
- if (status == 0)
- {
- if (timeout != 0)
- continue;
- else
- return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
- distinguish between EOF & timeouts
- someday] */
- }
- else if (errno == EINTR)
- continue;
- else
- return SERIAL_ERROR; /* Got an error from read */
+ else if (timeout == 0)
+ {
+ status = SERIAL_TIMEOUT;
+ break;
}
+ }
- scb->bufcnt = status;
- scb->bufcnt--;
- scb->bufp = scb->buf;
- return *scb->bufp++;
+ if (status < 0)
+ return status;
+
+ while (1)
+ {
+ status = read (scb->fd, scb->buf, BUFSIZ);
+ if (status != -1 || errno != EINTR)
+ break;
+ }
+
+ if (status <= 0)
+ {
+ if (status == 0)
+ return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
+ distinguish between EOF & timeouts
+ someday] */
+ else
+ return SERIAL_ERROR; /* Got an error from read */
}
+
+ scb->bufcnt = status;
+ scb->bufcnt--;
+ scb->bufp = scb->buf;
+ return *scb->bufp++;
}
/* Perform operations common to both old and new readchar. */
if (SERIAL_DEBUG_P (scb))
fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n",
scb->fd);
- /* De-schedule what ever tasks are currently scheduled. */
+ /* De-schedule whatever tasks are currently scheduled. */
switch (scb->async_state)
{
case FD_SCHEDULED: