size_t bytes_written = 0;
unsigned char *ptr = (unsigned char *) buf;
struct timeval start, delta, now, end = {0, 0};
+ int started = 0;
fd_set fds;
int result;
/* Loop until we have written the requested number of bytes. */
while (bytes_written < count) {
- /* Wait until space is available. */
- if (timeout_ms) {
+ /*
+ * Check timeout only if we have run select() at least once,
+ * to avoid any issues if a short timeout is reached before
+ * select() is even run.
+ */
+ if (timeout_ms && started) {
gettimeofday(&now, NULL);
- if (timercmp(&now, &end, >)) {
- DEBUG("Write timed out");
- RETURN_INT(bytes_written);
- }
+ if (timercmp(&now, &end, >))
+ /* Timeout has expired. */
+ break;
timersub(&end, &now, &delta);
}
result = select(port->fd + 1, NULL, &fds, NULL, timeout_ms ? &delta : NULL);
+ started = 1;
if (result < 0) {
if (errno == EINTR) {
DEBUG("select() call was interrupted, repeating");
RETURN_FAIL("select() failed");
}
} else if (result == 0) {
- DEBUG("Write timed out");
- RETURN_INT(bytes_written);
+ /* Timeout has expired. */
+ break;
}
/* Do write. */
ptr += result;
}
+ if (bytes_written < count)
+ DEBUG("Write timed out");
+
RETURN_INT(bytes_written);
#endif
}
/* Set timeout. */
if (port->timeouts.ReadIntervalTimeout != 0 ||
+ port->timeouts.ReadTotalTimeoutMultiplier != 0 ||
port->timeouts.ReadTotalTimeoutConstant != timeout_ms) {
port->timeouts.ReadIntervalTimeout = 0;
+ port->timeouts.ReadTotalTimeoutMultiplier = 0;
port->timeouts.ReadTotalTimeoutConstant = timeout_ms;
if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
RETURN_FAIL("SetCommTimeouts() failed");
size_t bytes_read = 0;
unsigned char *ptr = (unsigned char *) buf;
struct timeval start, delta, now, end = {0, 0};
+ int started = 0;
fd_set fds;
int result;
/* Loop until we have the requested number of bytes. */
while (bytes_read < count) {
- /* Wait until data is available. */
- if (timeout_ms) {
+ /*
+ * Check timeout only if we have run select() at least once,
+ * to avoid any issues if a short timeout is reached before
+ * select() is even run.
+ */
+ if (timeout_ms && started) {
gettimeofday(&now, NULL);
if (timercmp(&now, &end, >))
/* Timeout has expired. */
- RETURN_INT(bytes_read);
+ break;
timersub(&end, &now, &delta);
}
result = select(port->fd + 1, &fds, NULL, NULL, timeout_ms ? &delta : NULL);
+ started = 1;
if (result < 0) {
if (errno == EINTR) {
DEBUG("select() call was interrupted, repeating");
RETURN_FAIL("select() failed");
}
} else if (result == 0) {
- DEBUG("Read timed out");
- RETURN_INT(bytes_read);
+ /* Timeout has expired. */
+ break;
}
/* Do read. */
if (result < 0) {
if (errno == EAGAIN)
- /* This shouldn't happen because we did a select() first, but handle anyway. */
+ /*
+ * This shouldn't happen because we did a
+ * select() first, but handle anyway.
+ */
continue;
else
/* This is an actual failure. */
ptr += result;
}
+ if (bytes_read < count)
+ DEBUG("Read timed out");
+
RETURN_INT(bytes_read);
#endif
}
/* Set timeout. */
if (port->timeouts.ReadIntervalTimeout != MAXDWORD ||
+ port->timeouts.ReadTotalTimeoutMultiplier != 0 ||
port->timeouts.ReadTotalTimeoutConstant != 0) {
port->timeouts.ReadIntervalTimeout = MAXDWORD;
+ port->timeouts.ReadTotalTimeoutMultiplier = 0;
port->timeouts.ReadTotalTimeoutConstant = 0;
if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
RETURN_FAIL("SetCommTimeouts() failed");
RETURN_OK();
#else
struct timeval start, delta, now, end = {0, 0};
+ int started = 0;
int result, timeout_remaining_ms;
struct pollfd *pollfds;
unsigned int i;
/* Loop until an event occurs. */
while (1) {
- if (timeout_ms) {
+ /*
+ * Check timeout only if we have run poll() at least once,
+ * to avoid any issues if a short timeout is reached before
+ * poll() is even run.
+ */
+ if (timeout_ms && started) {
gettimeofday(&now, NULL);
if (timercmp(&now, &end, >)) {
DEBUG("Wait timed out");
}
result = poll(pollfds, event_set->count, timeout_ms ? timeout_remaining_ms : -1);
+ started = 1;
if (result < 0) {
if (errno == EINTR) {