]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Set O_APPEND mode for stdout/stderr and output-sync temporary files.
authorPaul Smith <psmith@gnu.org>
Sat, 29 Jun 2013 01:57:59 +0000 (21:57 -0400)
committerPaul Smith <psmith@gnu.org>
Sat, 29 Jun 2013 01:57:59 +0000 (21:57 -0400)
POSIX does not guarantee that writes will be atomic if a file is
opened for normal (non-append) output.  That means if multiple processes
are writing to the same file, output could be lost.  I can't think of
a real use-case where we would NOT want append for stdout/stderr, so
force it if we can.

ChangeLog
main.c
makeint.h
misc.c

index fe97e4ab13622d169fe2662313c1102916cbbf92..b24186af6f6e6a1f0da0813885ef5f845ceabe7c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2013-06-28  Paul Smith  <psmith@gnu.org>
+
+       * misc.c (set_append_mode): Set the O_APPEND flag on a file descriptor.
+       (open_tmpfd): Set append mode on the temporary file descriptor.
+       * main.c (main): Set append mode on stdout and stderr.
+       * makeint.h (set_append_mode): Declare it.
+
 2013-06-22  Eli Zaretskii  <eliz@gnu.org>
 
        * build_w32.bat (LinkGCC): Prevent a comment from being displayed
@@ -55,7 +62,7 @@
        * main.c (verify_flag): Global variable to determine whether to
        verify the database or not.
        (decode_debug_flags): If debug mode, enable verify_flag.
-       (main): If MAKE_MAINTAINTER_MODE, enable verify_flag, otherwise not.
+       (main): If MAKE_MAINTAINER_MODE, enable verify_flag, otherwise not.
        (die): Only verify the database if verify_flag is set.
        * file.c (enter_file): Don't check caching unless verify_flag.
        * makeint.h: Export verify_flag.
diff --git a/main.c b/main.c
index fe8d3559626af336d8dcf7086f46cef0f28185d6..83a95dbab870f5e0c44c709724696dd0da70a342 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1195,6 +1195,12 @@ main (int argc, char **argv, char **envp)
   setlinebuf (stdout);
 #endif  /* setlinebuf missing.  */
 
+  /* Configure stdout/stderr to be in append mode.
+     This keeps parallel jobs from losing output due to overlapping writes.  */
+
+  set_append_mode (fileno (stdout));
+  set_append_mode (fileno (stderr));
+
   /* Figure out where this program lives.  */
 
   if (argv[0] == 0)
index f119680716c85ff38b65ce662b54a0ab53d9dea6..b51e914fccee6f7a7c05f5e954f4a8af7a65d65e 100644 (file)
--- a/makeint.h
+++ b/makeint.h
@@ -453,6 +453,7 @@ int alpha_compare (const void *, const void *);
 void print_spaces (unsigned int);
 char *find_percent (char *);
 const char *find_percent_cached (const char **);
+void set_append_mode (int);
 int open_tmpfd (void);
 FILE *open_tmpfile (char **, const char *);
 
diff --git a/misc.c b/misc.c
index 1b1441b1dd770c2efc6a90eb297bfb824cc34b00..d3a1da5284d0a638878c989b5a724dd1b371729a 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -22,6 +22,11 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <stdarg.h>
 
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#else
+# include <sys/file.h>
+#endif
 
 /* Compare strings *S1 and *S2.
    Return negative if the first is less, positive if it is greater,
@@ -897,6 +902,19 @@ get_path_max (void)
 #endif
 \f
 
+/* Set a file descriptor to be in O_APPEND mode.
+   If it fails, just ignore it.  */
+
+void
+set_append_mode (int fd)
+{
+#if defined(F_GETFL) && defined(F_SETFL) && defined(O_APPEND)
+  int flags = fcntl (fd, F_GETFL, 0);
+  if (flags >= 0)
+    fcntl (fd, F_SETFL, flags | O_APPEND);
+#endif
+}
+
 /* Provide support for temporary files.  */
 
 #ifndef HAVE_STDLIB_H
@@ -928,6 +946,8 @@ open_tmpfd ()
 
   fclose (tfile);
 
+  set_append_mode (fd);
+
   return fd;
 }