mirror of
https://github.com/mirror/make.git
synced 2024-12-27 13:20:34 +08:00
Create an open_tmpfd() function to return temp files by FD. Use it.
This commit is contained in:
parent
79e9347892
commit
b5d017c624
3
AUTHORS
3
AUTHORS
@ -41,6 +41,7 @@ GNU make porting efforts:
|
|||||||
Jonathan Grant <jg@jguk.org>
|
Jonathan Grant <jg@jguk.org>
|
||||||
Andreas Beuning <andreas.buening@nexgo.de>
|
Andreas Beuning <andreas.buening@nexgo.de>
|
||||||
Earnie Boyd <earnie@uses.sf.net>
|
Earnie Boyd <earnie@uses.sf.net>
|
||||||
|
Troy Runkel <Troy.Runkel@mathworks.com>
|
||||||
|
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
Other contributors:
|
Other contributors:
|
||||||
@ -64,6 +65,8 @@ Other contributors:
|
|||||||
Carl Staelin (Princeton University)
|
Carl Staelin (Princeton University)
|
||||||
Ian Stewartson (Data Logic Limited)
|
Ian Stewartson (Data Logic Limited)
|
||||||
David A. Wheeler <dwheeler@dwheeler.com>
|
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 ...
|
With suggestions/comments/bug reports from a cast of ... well ...
|
||||||
hundreds, anyway :)
|
hundreds, anyway :)
|
||||||
|
@ -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>
|
2013-04-15 Paul Smith <psmith@gnu.org>
|
||||||
|
|
||||||
* makeint.h (OUTPUT_SYNC_TARGET, OUTPUT_SYNC_MAKE): Rename.
|
* makeint.h (OUTPUT_SYNC_TARGET, OUTPUT_SYNC_MAKE): Rename.
|
||||||
|
10
NEWS
10
NEWS
@ -1,6 +1,6 @@
|
|||||||
GNU make NEWS -*-indented-text-*-
|
GNU make NEWS -*-indented-text-*-
|
||||||
History of user-visible changes.
|
History of user-visible changes.
|
||||||
05 March 2012
|
16 April 2013
|
||||||
|
|
||||||
See the end of this file for copyrights and conditions.
|
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
|
See the README file and the GNU make manual for instructions for
|
||||||
reporting bugs.
|
reporting bugs.
|
||||||
|
|
||||||
Version 3.99.90
|
Version 3.82.90
|
||||||
|
|
||||||
A complete list of bugs fixed in this version is available here:
|
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
|
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.
|
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.
|
* New feature: The "job server" capability is now supported on Windows.
|
||||||
Implementation contributed by Troy Runkel <Troy.Runkel@mathworks.com>
|
Implementation contributed by Troy Runkel <Troy.Runkel@mathworks.com>
|
||||||
|
|
||||||
|
63
job.c
63
job.c
@ -558,7 +558,6 @@ static int
|
|||||||
assign_child_tempfiles (struct child *c, int combined)
|
assign_child_tempfiles (struct child *c, int combined)
|
||||||
{
|
{
|
||||||
FILE *outstrm = NULL, *errstrm = NULL;
|
FILE *outstrm = NULL, *errstrm = NULL;
|
||||||
int o_ok, e_ok;
|
|
||||||
const char *suppressed = "output-sync suppressed: ";
|
const char *suppressed = "output-sync suppressed: ";
|
||||||
char *failmode = NULL;
|
char *failmode = NULL;
|
||||||
|
|
||||||
@ -566,70 +565,24 @@ assign_child_tempfiles (struct child *c, int combined)
|
|||||||
if (c->outfd != -1 && c->errfd != -1)
|
if (c->outfd != -1 && c->errfd != -1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Check status of stdout and stderr before hooking up temp files. */
|
if (STREAM_OK (stdout))
|
||||||
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 ()))
|
c->outfd = open_tmpfd ();
|
||||||
failmode = "tmpfile()";
|
CLOSE_ON_EXEC (c->outfd);
|
||||||
else
|
|
||||||
errstrm = outstrm;
|
|
||||||
}
|
|
||||||
else if (o_ok && e_ok)
|
|
||||||
{
|
|
||||||
if (!(outstrm = tmpfile ()) || !(errstrm = tmpfile ()))
|
|
||||||
failmode = "tmpfile()";
|
|
||||||
}
|
|
||||||
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 ((c->outfd = dup (fileno (outstrm))) == -1)
|
|
||||||
failmode = "dup2()";
|
|
||||||
else
|
|
||||||
CLOSE_ON_EXEC (c->outfd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!failmode && errstrm)
|
if (STREAM_OK (stderr))
|
||||||
{
|
{
|
||||||
if (combined)
|
if (c->outfd >= 0 && combined)
|
||||||
c->errfd = c->outfd;
|
c->errfd = c->outfd;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((c->errfd = dup (fileno (errstrm))) == -1)
|
c->errfd = open_tmpfd ();
|
||||||
failmode = "dup2()";
|
CLOSE_ON_EXEC (c->errfd);
|
||||||
else
|
|
||||||
CLOSE_ON_EXEC (c->errfd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failmode)
|
return 1;
|
||||||
perror_with_name (suppressed, failmode);
|
|
||||||
|
|
||||||
if (outstrm)
|
|
||||||
(void) fclose (outstrm);
|
|
||||||
|
|
||||||
if (errstrm && errstrm != outstrm)
|
|
||||||
(void) fclose (errstrm);
|
|
||||||
|
|
||||||
return failmode == NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Support routine for sync_output() */
|
/* Support routine for sync_output() */
|
||||||
|
4
job.h
4
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)
|
# define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef POSIX
|
|
||||||
# define OUTPUT_SYNC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Structure describing a running or dead child process. */
|
/* Structure describing a running or dead child process. */
|
||||||
|
|
||||||
struct child
|
struct child
|
||||||
|
44
main.c
44
main.c
@ -907,50 +907,6 @@ msdos_return_to_initial_directory (void)
|
|||||||
}
|
}
|
||||||
#endif /* __MSDOS__ */
|
#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
|
#ifdef _AMIGA
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
|
@ -413,6 +413,7 @@ int alpha_compare (const void *, const void *);
|
|||||||
void print_spaces (unsigned int);
|
void print_spaces (unsigned int);
|
||||||
char *find_percent (char *);
|
char *find_percent (char *);
|
||||||
const char *find_percent_cached (const char **);
|
const char *find_percent_cached (const char **);
|
||||||
|
int open_tmpfd (void);
|
||||||
FILE *open_tmpfile (char **, const char *);
|
FILE *open_tmpfile (char **, const char *);
|
||||||
|
|
||||||
#ifndef NO_ARCHIVES
|
#ifndef NO_ARCHIVES
|
||||||
@ -525,6 +526,10 @@ int strncasecmp (const char *s1, const char *s2, int n);
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef POSIX
|
||||||
|
# define OUTPUT_SYNC
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OUTPUT_SYNC_TARGET 1
|
#define OUTPUT_SYNC_TARGET 1
|
||||||
#define OUTPUT_SYNC_MAKE 2
|
#define OUTPUT_SYNC_MAKE 2
|
||||||
|
|
||||||
|
79
misc.c
79
misc.c
@ -930,6 +930,85 @@ get_path_max (void)
|
|||||||
#endif
|
#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.
|
/* This code is stolen from gnulib.
|
||||||
If/when we abandon the requirement to work with K&R compilers, we can
|
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
|
remove this (and perhaps other parts of GNU make!) and migrate to using
|
||||||
|
Loading…
Reference in New Issue
Block a user