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.
#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);
#endif /* NO_OUTPUT_SYNC */
\f
+static int stdout_flags = -1;
+static int stderr_flags = -1;
+
void
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
{
if (stdio_traced)
log_working_directory (0);
+ fd_reset_append(fileno (stdout), stdout_flags);
+ fd_reset_append(fileno (stderr), stderr_flags);
return;
}
/* 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);
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
}
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)