From 242603fa46bb68428d1bac66ded6fbf7ae8e2605 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Sun, 24 Mar 2024 15:19:11 -0400 Subject: [PATCH] [SV 65268] Un-set append mode for stdout/stderr on exit It turns out that options set on stdout/stderr last after exit. Leaving append-mode enabled can break other facilities, so reset the flags on stdout/stderr before we exit. * src/os.h: Add a new fd_reset_append() to reset flags on FDs. Modify fd_set_append() to return the old flags. * src/posixos.c (fd_reset_append): Set provided flags on the FD. (fd_set_append): Return the previous flags set on the FD. * src/output.c (output_init): Preserve old flags for stdout/stderr. (output_close): Reset flags for stdout/stderr. * src/w32/w32os.c: Implement dummy methods. --- src/os.h | 23 ++++++++++++++--------- src/output.c | 9 +++++++-- src/posixos.c | 20 ++++++++++++++++++-- src/w32/w32os.c | 9 +++++++-- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/os.h b/src/os.h index be98372d..3ab790b0 100644 --- a/src/os.h +++ b/src/os.h @@ -21,22 +21,27 @@ this program. If not, see . */ #define IO_STDERR_OK 0x0010 #if MK_OS_VMS || MK_OS_DOS -# define check_io_state() (IO_STDIN_OK|IO_STDOUT_OK|IO_STDERR_OK) -# define fd_inherit(_i) (0) -# define fd_noinherit(_i) (0) -# define fd_set_append(_i) (void)(0) -# define os_anontmp() (-1) +# define check_io_state() (IO_STDIN_OK|IO_STDOUT_OK|IO_STDERR_OK) +# define fd_inherit(_i) (0) +# define fd_noinherit(_i) (0) +# define fd_set_append(_i) (-1) +# define fd_reset_append(_i,_f) (void)(0) +# define os_anontmp() (-1) #else /* Determine the state of stdin/stdout/stderr. */ unsigned int check_io_state (void); /* Set a file descriptor to close/not close in a subprocess. */ -void fd_inherit (int); -void fd_noinherit (int); +void fd_inherit (int fd); +void fd_noinherit (int fd); -/* If the file descriptor is for a file put it into append mode. */ -void fd_set_append (int); +/* If the file descriptor is for a file put it into append mode. + Return the original flags for the file descriptor, or -1 if not found. */ +int fd_set_append (int fd); + +/* Reset the append mode to the flags returned by fd_set_append(). */ +void fd_reset_append (int fd, int flags); /* Return a file descriptor for a new anonymous temp file, or -1. */ int os_anontmp (void); diff --git a/src/output.c b/src/output.c index e6589817..775d1410 100644 --- a/src/output.c +++ b/src/output.c @@ -318,6 +318,9 @@ output_dump (struct output *out) #endif /* NO_OUTPUT_SYNC */ +static int stdout_flags = -1; +static int stderr_flags = -1; + void output_init (struct output *out) { @@ -330,8 +333,8 @@ output_init (struct output *out) /* Force stdout/stderr into append mode (if they are files) to ensure parallel jobs won't lose output due to overlapping writes. */ - fd_set_append (fileno (stdout)); - fd_set_append (fileno (stderr)); + stdout_flags = fd_set_append (fileno (stdout)); + stderr_flags = fd_set_append (fileno (stderr)); } void @@ -341,6 +344,8 @@ output_close (struct output *out) { if (stdio_traced) log_working_directory (0); + fd_reset_append(fileno (stdout), stdout_flags); + fd_reset_append(fileno (stderr), stderr_flags); return; } diff --git a/src/posixos.c b/src/posixos.c index bc6558df..7a723591 100644 --- a/src/posixos.c +++ b/src/posixos.c @@ -830,12 +830,12 @@ fd_noinherit (int fd) /* Set a file descriptor referring to a regular file to be in O_APPEND mode. If it fails, just ignore it. */ -void +int fd_set_append (int fd) { + int flags = -1; #if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND) struct stat stbuf; - int flags; if (fstat (fd, &stbuf) == 0 && S_ISREG (stbuf.st_mode)) { flags = fcntl (fd, F_GETFL, 0); @@ -845,6 +845,22 @@ fd_set_append (int fd) EINTRLOOP(r, fcntl (fd, F_SETFL, flags | O_APPEND)); } } +#endif + return flags; +} + +/* Reset a file descriptor referring to a regular file to be in O_APPEND mode. + If it fails, just ignore it. */ + +void +fd_reset_append (int fd, int flags) +{ +#if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND) + if (flags >= 0) + { + int r; + EINTRLOOP(r, fcntl (fd, F_SETFL, flags)); + } #endif } diff --git a/src/w32/w32os.c b/src/w32/w32os.c index ae2a6853..ac8fc59c 100644 --- a/src/w32/w32os.c +++ b/src/w32/w32os.c @@ -512,10 +512,15 @@ fd_noinherit(int fd) SetHandleInformation (fh, HANDLE_FLAG_INHERIT, 0); } -void +int fd_set_append (int fd UNUSED) -{} +{ + return -1; +} +void +fd_reset_append (int fd UNUSED, int flags UNUSED) +{} HANDLE get_handle_for_fd (int fd)