From: Bruno Haible Date: Sat, 16 Mar 2019 22:17:39 +0000 (+0100) Subject: libtextstyle: Protect better against EINTR. X-Git-Tag: v0.20~125 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2eb9e18fc62d2e1b5f7ffeea33a59ee736e28bb1;p=thirdparty%2Fgettext.git libtextstyle: Protect better against EINTR. * 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 . (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. --- diff --git a/gnulib-local/lib/fd-ostream.oo.c b/gnulib-local/lib/fd-ostream.oo.c index cd0235d0b..ccea297d3 100644 --- a/gnulib-local/lib/fd-ostream.oo.c +++ b/gnulib-local/lib/fd-ostream.oo.c @@ -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 } } diff --git a/gnulib-local/lib/file-ostream.oo.c b/gnulib-local/lib/file-ostream.oo.c index a62dc84c4..12565b04c 100644 --- a/gnulib-local/lib/file-ostream.oo.c +++ b/gnulib-local/lib/file-ostream.oo.c @@ -20,6 +20,7 @@ /* Specification. */ #include "file-ostream.h" +#include #include #include #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 } } diff --git a/gnulib-local/lib/term-ostream.oo.c b/gnulib-local/lib/term-ostream.oo.c index 517b67bbb..53eb51911 100644 --- a/gnulib-local/lib/term-ostream.oo.c +++ b/gnulib-local/lib/term-ostream.oo.c @@ -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 } }