]> sigrok.org Git - libserialport.git/commitdiff
Handle EINTR from tcdrain() in sp_drain().
authorMartin Ling <redacted>
Wed, 27 Nov 2013 14:31:54 +0000 (14:31 +0000)
committerMartin Ling <redacted>
Wed, 27 Nov 2013 14:35:36 +0000 (14:35 +0000)
libserialport.h.in
serialport.c

index 46e2fda55fc467f2ba770cf56259081b7db76e0d..41948c1828eee3bab22fdc1e60187233489e88c8 100644 (file)
@@ -878,6 +878,13 @@ enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers);
 /**
  * Wait for buffered data to be transmitted.
  *
+ * @warning If your program runs on Unix, defines its own signal handlers, and
+ *          needs to abort draining the output buffer when when these are
+ *          called, then you should not use this function. It repeats system
+ *          calls that return with EINTR. To be able to abort a drain from a
+ *          signal handler, you would need to implement your own blocking
+ *          drain by polling the result of sp_output_waiting().
+ *
  * @param port Pointer to port structure.
  *
  * @return SP_OK upon success, a negative error code otherwise.
index 51eda87d4983761238fdd06721c9f150db0c4f16..bbb53bdc64941d9aac6bab6a484d031a4653303b 100644 (file)
@@ -799,13 +799,23 @@ enum sp_return sp_drain(struct sp_port *port)
        /* 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)