/* Returns non-zero upon success, 0 upon failure. */
if (FlushFileBuffers(port->hdl) == 0)
RETURN_FAIL("FlushFileBuffers() failed");
+ RETURN_OK();
#else
- /* Returns 0 upon success, -1 upon failure. */
- if (tcdrain(port->fd) < 0)
- RETURN_FAIL("tcdrain() failed");
+ int result;
+ while (1) {
+ result = tcdrain(port->fd);
+ if (result < 0) {
+ if (errno == EINTR) {
+ DEBUG("tcdrain() was interrupted");
+ continue;
+ } else {
+ RETURN_FAIL("tcdrain() failed");
+ }
+ } else {
+ RETURN_OK();
+ }
+ }
#endif
-
- RETURN_OK();
}
enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout)
gettimeofday(&start, NULL);
/* Define duration of timeout. */
delta.tv_sec = timeout / 1000;
- delta.tv_usec = timeout % 1000;
+ delta.tv_usec = (timeout % 1000) * 1000;
/* Calculate time at which we should give up. */
timeradd(&start, &delta, &end);
}
timersub(&end, &now, &delta);
}
result = select(port->fd + 1, NULL, &fds, NULL, timeout ? &delta : NULL);
- if (result < 0)
- RETURN_FAIL("select() failed");
- if (result == 0) {
+ if (result < 0) {
+ if (errno == EINTR) {
+ DEBUG("select() call was interrupted, repeating");
+ continue;
+ } else {
+ RETURN_FAIL("select() failed");
+ }
+ } else if (result == 0) {
DEBUG("write timed out");
RETURN_VALUE("%d", bytes_written);
}
gettimeofday(&start, NULL);
/* Define duration of timeout. */
delta.tv_sec = timeout / 1000;
- delta.tv_usec = timeout % 1000;
+ delta.tv_usec = (timeout % 1000) * 1000;
/* Calculate time at which we should give up. */
timeradd(&start, &delta, &end);
}
timersub(&end, &now, &delta);
}
result = select(port->fd + 1, &fds, NULL, NULL, timeout ? &delta : NULL);
- if (result < 0)
- RETURN_FAIL("select() failed");
- if (result == 0) {
+ if (result < 0) {
+ if (errno == EINTR) {
+ DEBUG("select() call was interrupted, repeating");
+ continue;
+ } else {
+ RETURN_FAIL("select() failed");
+ }
+ } else if (result == 0) {
DEBUG("read timed out");
RETURN_VALUE("%d", bytes_read);
}
#endif
}
+enum sp_return sp_input_waiting(struct sp_port *port)
+{
+ TRACE("%p", port);
+
+ CHECK_OPEN_PORT();
+
+ DEBUG("Checking input bytes waiting on port %s", port->name);
+
+#ifdef _WIN32
+ DWORD errors;
+ COMSTAT comstat;
+
+ if (ClearCommError(port->hdl, &errors, &comstat) == 0)
+ RETURN_FAIL("ClearComError() failed");
+ RETURN_VALUE("%d", comstat.cbInQue);
+#else
+ int bytes_waiting;
+ if (ioctl(port->fd, TIOCINQ, &bytes_waiting) < 0)
+ RETURN_FAIL("TIOCINQ ioctl failed");
+ RETURN_VALUE("%d", bytes_waiting);
+#endif
+}
+
+enum sp_return sp_output_waiting(struct sp_port *port)
+{
+ TRACE("%p", port);
+
+ CHECK_OPEN_PORT();
+
+ DEBUG("Checking output bytes waiting on port %s", port->name);
+
+#ifdef _WIN32
+ DWORD errors;
+ COMSTAT comstat;
+
+ if (ClearCommError(port->hdl, &errors, &comstat) == 0)
+ RETURN_FAIL("ClearComError() failed");
+ RETURN_VALUE("%d", comstat.cbOutQue);
+#else
+ int bytes_waiting;
+ if (ioctl(port->fd, TIOCOUTQ, &bytes_waiting) < 0)
+ RETURN_FAIL("TIOCOUTQ ioctl failed");
+ RETURN_VALUE("%d", bytes_waiting);
+#endif
+}
+
#ifdef __linux__
static enum sp_return get_baudrate(int fd, int *baudrate)
{