summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2013-04-16 00:35:48 -0400
committerPaul Smith <psmith@gnu.org>2013-04-16 01:03:59 -0400
commitb5d017c6241ac356915b178d0a9588653d18d460 (patch)
treee101b46d62edb0881bb09fc5ddec6d6bd1ed891c
parent79e9347892dd2b6caa246e18fe050583da744bd8 (diff)
downloadgunmake-b5d017c6241ac356915b178d0a9588653d18d460.tar.gz
Create an open_tmpfd() function to return temp files by FD. Use it.
-rw-r--r--AUTHORS3
-rw-r--r--ChangeLog7
-rw-r--r--NEWS10
-rw-r--r--job.c63
-rw-r--r--job.h4
-rw-r--r--main.c44
-rw-r--r--makeint.h5
-rw-r--r--misc.c79
8 files changed, 110 insertions, 105 deletions
diff --git a/AUTHORS b/AUTHORS
index 9e43cb4..84a7126 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -41,6 +41,7 @@ GNU make porting efforts:
Jonathan Grant <jg@jguk.org>
Andreas Beuning <andreas.buening@nexgo.de>
Earnie Boyd <earnie@uses.sf.net>
+ Troy Runkel <Troy.Runkel@mathworks.com>
-----------------------------------
Other contributors:
@@ -64,6 +65,8 @@ Other contributors:
Carl Staelin (Princeton University)
Ian Stewartson (Data Logic Limited)
David A. Wheeler <dwheeler@dwheeler.com>
+ David Boyce <dsb@boyski.com>
+ Frank Heckenbach <f.heckenbach@fh-soft.de>
With suggestions/comments/bug reports from a cast of ... well ...
hundreds, anyway :)
diff --git a/ChangeLog b/ChangeLog
index deca62a..2e3458f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2013-04-16 Paul Smith <psmith@gnu.org>
+
+ * misc.c (open_tmpfd): Add a new function that returns a temporary
+ file by file descriptor.
+ (open_tmpfile): Move here from main.c.
+ * job.c (assign_child_tempfiles): Use the new open_tmpfd().
+
2013-04-15 Paul Smith <psmith@gnu.org>
* makeint.h (OUTPUT_SYNC_TARGET, OUTPUT_SYNC_MAKE): Rename.
diff --git a/NEWS b/NEWS
index 3e48acc..8442311 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
GNU make NEWS -*-indented-text-*-
History of user-visible changes.
- 05 March 2012
+ 16 April 2013
See the end of this file for copyrights and conditions.
@@ -9,7 +9,7 @@ manual, which is contained in this distribution as the file doc/make.texi.
See the README file and the GNU make manual for instructions for
reporting bugs.
-Version 3.99.90
+Version 3.82.90
A complete list of bugs fixed in this version is available here:
@@ -29,6 +29,12 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=101&set
makefile name and linenumber where it was defined are shown as well as the
prerequisites that caused the target to be considered out of date.
+* New command line option: --output-sync (-O) enables grouping of output by
+ target or by recursive make. This is useful during parallel builds to avoid
+ mixing output from different jobs together giving hard-to-understand results.
+ Original implementation by David Boyce <dsb@boyski.com>. Patch was reworked
+ by Frank Heckenbach <f.heckenbach@fh-soft.de>.
+
* New feature: The "job server" capability is now supported on Windows.
Implementation contributed by Troy Runkel <Troy.Runkel@mathworks.com>
diff --git a/job.c b/job.c
index 2c76be3..df1991b 100644
--- a/job.c
+++ b/job.c
@@ -558,7 +558,6 @@ static int
assign_child_tempfiles (struct child *c, int combined)
{
FILE *outstrm = NULL, *errstrm = NULL;
- int o_ok, e_ok;
const char *suppressed = "output-sync suppressed: ";
char *failmode = NULL;
@@ -566,70 +565,24 @@ assign_child_tempfiles (struct child *c, int combined)
if (c->outfd != -1 && c->errfd != -1)
return 1;
- /* Check status of stdout and stderr before hooking up temp files. */
- o_ok = STREAM_OK (stdout);
- e_ok = STREAM_OK (stderr);
-
- /* The tmpfile() function returns a FILE pointer but those can be in
- limited supply, so we immediately dup its file descriptor and keep
- only that, closing the FILE pointer. */
-
- if (combined)
- {
- if (!(outstrm = tmpfile ()))
- failmode = "tmpfile()";
- else
- errstrm = outstrm;
- }
- else if (o_ok && e_ok)
+ if (STREAM_OK (stdout))
{
- if (!(outstrm = tmpfile ()) || !(errstrm = tmpfile ()))
- failmode = "tmpfile()";
+ c->outfd = open_tmpfd ();
+ CLOSE_ON_EXEC (c->outfd);
}
- else if (o_ok)
- {
- if (!(outstrm = tmpfile ()))
- failmode = "tmpfile()";
- }
- else if (e_ok)
- {
- if (!(errstrm = tmpfile ()))
- failmode = "tmpfile()";
- }
- else
- failmode = "stdout";
- if (!failmode && outstrm)
+ if (STREAM_OK (stderr))
{
- if ((c->outfd = dup (fileno (outstrm))) == -1)
- failmode = "dup2()";
- else
- CLOSE_ON_EXEC (c->outfd);
- }
-
- if (!failmode && errstrm)
- {
- if (combined)
+ if (c->outfd >= 0 && combined)
c->errfd = c->outfd;
else
{
- if ((c->errfd = dup (fileno (errstrm))) == -1)
- failmode = "dup2()";
- else
- CLOSE_ON_EXEC (c->errfd);
+ c->errfd = open_tmpfd ();
+ CLOSE_ON_EXEC (c->errfd);
}
}
- if (failmode)
- perror_with_name (suppressed, failmode);
-
- if (outstrm)
- (void) fclose (outstrm);
-
- if (errstrm && errstrm != outstrm)
- (void) fclose (errstrm);
-
- return failmode == NULL;
+ return 1;
}
/* Support routine for sync_output() */
diff --git a/job.h b/job.h
index 399c0b8..0e4e118 100644
--- a/job.h
+++ b/job.h
@@ -34,10 +34,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
# define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC)
#endif
-#ifdef POSIX
-# define OUTPUT_SYNC
-#endif
-
/* Structure describing a running or dead child process. */
struct child
diff --git a/main.c b/main.c
index 985c765..89596c7 100644
--- a/main.c
+++ b/main.c
@@ -907,50 +907,6 @@ msdos_return_to_initial_directory (void)
}
#endif /* __MSDOS__ */
-char *mktemp (char *template);
-int mkstemp (char *template);
-
-FILE *
-open_tmpfile(char **name, const char *template)
-{
-#ifdef HAVE_FDOPEN
- int fd;
-#endif
-
-#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
-# define TEMPLATE_LEN strlen (template)
-#else
-# define TEMPLATE_LEN L_tmpnam
-#endif
- *name = xmalloc (TEMPLATE_LEN + 1);
- strcpy (*name, template);
-
-#if defined HAVE_MKSTEMP && defined HAVE_FDOPEN
- /* It's safest to use mkstemp(), if we can. */
- fd = mkstemp (*name);
- if (fd == -1)
- return 0;
- return fdopen (fd, "w");
-#else
-# ifdef HAVE_MKTEMP
- (void) mktemp (*name);
-# else
- (void) tmpnam (*name);
-# endif
-
-# ifdef HAVE_FDOPEN
- /* Can't use mkstemp(), but guard against a race condition. */
- fd = open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600);
- if (fd == -1)
- return 0;
- return fdopen (fd, "w");
-# else
- /* Not secure, but what can we do? */
- return fopen (*name, "w");
-# endif
-#endif
-}
-
#ifdef _AMIGA
int
main (int argc, char **argv)
diff --git a/makeint.h b/makeint.h
index fe43260..976b040 100644
--- a/makeint.h
+++ b/makeint.h
@@ -413,6 +413,7 @@ int alpha_compare (const void *, const void *);
void print_spaces (unsigned int);
char *find_percent (char *);
const char *find_percent_cached (const char **);
+int open_tmpfd (void);
FILE *open_tmpfile (char **, const char *);
#ifndef NO_ARCHIVES
@@ -525,6 +526,10 @@ int strncasecmp (const char *s1, const char *s2, int n);
# endif
#endif
+#ifdef POSIX
+# define OUTPUT_SYNC
+#endif
+
#define OUTPUT_SYNC_TARGET 1
#define OUTPUT_SYNC_MAKE 2
diff --git a/misc.c b/misc.c
index df208a6..800e857 100644
--- a/misc.c
+++ b/misc.c
@@ -930,6 +930,85 @@ get_path_max (void)
#endif
+/* Provide support for temporary files. */
+
+#ifndef HAVE_STDLIB_H
+# ifdef HAVE_MKSTEMP
+int mkstemp (char *template);
+# else
+char *mktemp (char *template);
+# endif
+#endif
+
+/* This is only used by output-sync, and it may not be portable to Windows. */
+#ifdef OUTPUT_SYNC
+
+/* Returns a file descriptor to a temporary file. The file is automatically
+ closed/deleted on exit. Don't use a FILE* stream. */
+int
+open_tmpfd()
+{
+ int fd = -1;
+ FILE *tfile = tmpfile();
+
+ if (! tfile)
+ pfatal_with_name ("tmpfile");
+
+ /* Create a duplicate so we can close the stream. */
+ fd = dup (fileno (tfile));
+ if (fd < 0)
+ pfatal_with_name ("dup");
+
+ fclose (tfile);
+
+ return fd;
+}
+
+#endif
+
+FILE *
+open_tmpfile(char **name, const char *template)
+{
+#ifdef HAVE_FDOPEN
+ int fd;
+#endif
+
+#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
+# define TEMPLATE_LEN strlen (template)
+#else
+# define TEMPLATE_LEN L_tmpnam
+#endif
+ *name = xmalloc (TEMPLATE_LEN + 1);
+ strcpy (*name, template);
+
+#if defined HAVE_MKSTEMP && defined HAVE_FDOPEN
+ /* It's safest to use mkstemp(), if we can. */
+ fd = mkstemp (*name);
+ if (fd == -1)
+ return 0;
+ return fdopen (fd, "w");
+#else
+# ifdef HAVE_MKTEMP
+ (void) mktemp (*name);
+# else
+ (void) tmpnam (*name);
+# endif
+
+# ifdef HAVE_FDOPEN
+ /* Can't use mkstemp(), but guard against a race condition. */
+ fd = open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600);
+ if (fd == -1)
+ return 0;
+ return fdopen (fd, "w");
+# else
+ /* Not secure, but what can we do? */
+ return fopen (*name, "w");
+# endif
+#endif
+}
+
+
+
/* This code is stolen from gnulib.
If/when we abandon the requirement to work with K&R compilers, we can
remove this (and perhaps other parts of GNU make!) and migrate to using