]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
libtextstyle: Protect better against EINTR.
authorBruno Haible <bruno@clisp.org>
Sat, 16 Mar 2019 22:17:39 +0000 (23:17 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 16 Mar 2019 22:17:39 +0000 (23:17 +0100)
* gnulib-local/lib/fd-ostream.oo.c (nonintr_tcdrain): New function.
(fd_ostream::flush): Use it instead of tcdrain.
* gnulib-local/lib/file-ostream.oo.c: Include <errno.h>.
(nonintr_tcdrain): New function.
(file_ostream::flush): Use it instead of tcdrain.
* gnulib-local/lib/term-ostream.oo.c (nonintr_tcdrain): New function.
(term_ostream::flush): Use it instead of tcdrain.

gnulib-local/lib/fd-ostream.oo.c
gnulib-local/lib/file-ostream.oo.c
gnulib-local/lib/term-ostream.oo.c

index cd0235d0ba3a8ce83d851d42c6504e952b7862a4..ccea297d31b8b29296082ab94efab53a5522d357 100644 (file)
@@ -47,6 +47,26 @@ fields:
 
 #define BUFSIZE 4096
 
+#if HAVE_TCDRAIN
+
+/* EINTR handling for tcdrain().
+   This function can return -1/EINTR even though we don't have any
+   signal handlers set up, namely when we get interrupted via SIGSTOP.  */
+
+static inline int
+nonintr_tcdrain (int fd)
+{
+  int retval;
+
+  do
+    retval = tcdrain (fd);
+  while (retval < 0 && errno == EINTR);
+
+  return retval;
+}
+
+#endif
+
 /* Implementation of ostream_t methods.  */
 
 static void
@@ -142,7 +162,7 @@ fd_ostream::flush (fd_ostream_t stream, ostream_flush_scope_t scope)
       fsync (stream->fd);
       #if HAVE_TCDRAIN
       /* For streams connected to a terminal:  */
-      tcdrain (stream->fd);
+      nonintr_tcdrain (stream->fd);
       #endif
     }
 }
index a62dc84c4dbe637ab89daccae6b3b8d930e05ed7..12565b04cb053688fea9932988ad3818ca08ee3c 100644 (file)
@@ -20,6 +20,7 @@
 /* Specification.  */
 #include "file-ostream.h"
 
+#include <errno.h>
 #include <stdlib.h>
 #include <unistd.h>
 #if HAVE_TCDRAIN
@@ -34,6 +35,26 @@ fields:
   FILE *fp;
 };
 
+#if HAVE_TCDRAIN
+
+/* EINTR handling for tcdrain().
+   This function can return -1/EINTR even though we don't have any
+   signal handlers set up, namely when we get interrupted via SIGSTOP.  */
+
+static inline int
+nonintr_tcdrain (int fd)
+{
+  int retval;
+
+  do
+    retval = tcdrain (fd);
+  while (retval < 0 && errno == EINTR);
+
+  return retval;
+}
+
+#endif
+
 /* Implementation of ostream_t methods.  */
 
 static void
@@ -60,7 +81,7 @@ file_ostream::flush (file_ostream_t stream, ostream_flush_scope_t scope)
               fsync (fd);
               #if HAVE_TCDRAIN
               /* For streams connected to a terminal:  */
-              tcdrain (fd);
+              nonintr_tcdrain (fd);
               #endif
             }
         }
index 517b67bbb337cc77f38e1e81961ec79bf6c8e1a3..53eb51911c6b5372c8c2ca6af34744343d086cfe 100644 (file)
@@ -938,6 +938,29 @@ typedef struct
 } attributes_t;
 
 
+/* ============================ EINTR handling ============================ */
+
+#if HAVE_TCDRAIN
+
+/* EINTR handling for tcdrain().
+   This function can return -1/EINTR even though we don't have any
+   signal handlers set up, namely when we get interrupted via SIGSTOP.  */
+
+static inline int
+nonintr_tcdrain (int fd)
+{
+  int retval;
+
+  do
+    retval = tcdrain (fd);
+  while (retval < 0 && errno == EINTR);
+
+  return retval;
+}
+
+#endif
+
+
 /* ============================ term_ostream_t ============================ */
 
 struct term_ostream : struct ostream
@@ -1670,7 +1693,7 @@ term_ostream::flush (term_ostream_t stream, ostream_flush_scope_t scope)
       fsync (stream->fd);
       #if HAVE_TCDRAIN
       /* For streams connected to a terminal:  */
-      tcdrain (stream->fd);
+      nonintr_tcdrain (stream->fd);
       #endif
     }
 }