commit ef3beaf664347f7fce1f3475fe65de729320837e Author: Henrik Grimler Date: Tue May 11 09:36:52 2021 +0200 Use setlinebuf to make stderr line buffered If atomic writes are supported. Android >= 10 has a file descriptor sanitizer which errors if a stream is closed while there are still fd's associated with it. In emacs stderr is opened twice if line buffered streams are supported. Rather than opening a copy we can make stderr line buffered with setlinebuf instead. diff --git a/src/sysdep.c b/src/sysdep.c index d940acc4e0..77e1a0be3c 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -232,10 +232,6 @@ force_open (int fd, int flags) } } -/* A stream that is like stderr, except line buffered. It is NULL - during startup, or if line buffering is not in use. */ -static FILE *buferr; - /* Make sure stdin, stdout, and stderr are open to something, so that their file descriptors are not hijacked by later system calls. */ void @@ -249,12 +245,10 @@ init_standard_fds (void) force_open (STDOUT_FILENO, O_RDONLY); force_open (STDERR_FILENO, O_RDONLY); - /* Set buferr if possible on platforms defining _PC_PIPE_BUF, as + /* Make stderr line buffered on platforms defining _PC_PIPE_BUF, as they support the notion of atomic writes to pipes. */ #ifdef _PC_PIPE_BUF - buferr = fdopen (STDERR_FILENO, "w"); - if (buferr) - setvbuf (buferr, NULL, _IOLBF, 0); + setlinebuf (stderr); #endif } @@ -2650,11 +2644,11 @@ safe_strsignal (int code) static FILE * errstream (void) { - FILE *err = buferr; - if (!err) - return stderr; +#ifdef _PC_PIPE_BUF + /* flush line buffered stderr */ fflush_unlocked (stderr); - return err; +#endif + return stderr; } /* These functions are like fputc, vfprintf, and fwrite, @@ -2696,9 +2690,12 @@ close_output_streams (void) _exit (EXIT_FAILURE); } + bool err; +#ifdef _PC_PIPE_BUF + err = (fflush (stderr) != 0 || ferror (stderr)); +#endif /* Do not close stderr if addresses are being sanitized, as the sanitizer might report to stderr after this function is invoked. */ - bool err = buferr && (fflush (buferr) != 0 || ferror (buferr)); if (err | (ADDRESS_SANITIZER ? fflush (stderr) != 0 || ferror (stderr) : close_stream (stderr) != 0))