mirror of
https://git.savannah.gnu.org/git/make.git
synced 2024-12-24 12:58:39 +00:00
Enhance get_tmpfile() and add get_tmppath()
Move all the logic on creating temporary files into misc.c, and add a new function get_tmppath() that returns the pathname to a temporary file without creating or opening it. * src/makeint.h: Add a declaration for get_tmppath(). Remove the template argument from get_tmpfile(): it will compute its own. * src/main.c (main): Remove the logic for computing templates. * src/vmsjobs.c (child_execute_job): Ditto. * src/misc.c (get_tmptemplate): New function to return an allocated template string for use with various mktemp-style functions. (get_tmppath): Return an allocated path to a temporary file, but do not create it. Generally this should be avoided due to TOCTOU issues. (get_tmpfile): Use get_tmptemplate() to generate a template rather than using one passed in. If we don't have mkstemp() then use get_tmppath() to compute the path of a temp file.
This commit is contained in:
parent
07eea3aa49
commit
09cce75c30
4 changed files with 77 additions and 55 deletions
37
src/main.c
37
src/main.c
|
@ -1813,48 +1813,13 @@ main (int argc, char **argv, char **envp)
|
||||||
and thus re-read the makefiles, we read standard input
|
and thus re-read the makefiles, we read standard input
|
||||||
into a temporary file and read from that. */
|
into a temporary file and read from that. */
|
||||||
FILE *outfile;
|
FILE *outfile;
|
||||||
char *template;
|
|
||||||
char *newnm;
|
char *newnm;
|
||||||
const char *tmpdir;
|
|
||||||
|
|
||||||
if (stdin_offset >= 0)
|
if (stdin_offset >= 0)
|
||||||
O (fatal, NILF,
|
O (fatal, NILF,
|
||||||
_("Makefile from standard input specified twice"));
|
_("Makefile from standard input specified twice"));
|
||||||
|
|
||||||
#ifdef VMS
|
outfile = get_tmpfile (&newnm);
|
||||||
# define DEFAULT_TMPDIR "/sys$scratch/"
|
|
||||||
#else
|
|
||||||
# ifdef P_tmpdir
|
|
||||||
# define DEFAULT_TMPDIR P_tmpdir
|
|
||||||
# else
|
|
||||||
# define DEFAULT_TMPDIR "/tmp"
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#define DEFAULT_TMPFILE "GmXXXXXX"
|
|
||||||
|
|
||||||
if (
|
|
||||||
#if defined (__MSDOS__) || defined (WINDOWS32) || defined (__EMX__)
|
|
||||||
((tmpdir = getenv ("TMP")) == NULL || *tmpdir == '\0') &&
|
|
||||||
((tmpdir = getenv ("TEMP")) == NULL || *tmpdir == '\0') &&
|
|
||||||
#endif
|
|
||||||
((tmpdir = getenv ("TMPDIR")) == NULL || *tmpdir == '\0'))
|
|
||||||
tmpdir = DEFAULT_TMPDIR;
|
|
||||||
|
|
||||||
template = alloca (strlen (tmpdir) + CSTRLEN (DEFAULT_TMPFILE) + 2);
|
|
||||||
strcpy (template, tmpdir);
|
|
||||||
|
|
||||||
#ifdef HAVE_DOS_PATHS
|
|
||||||
if (strchr ("/\\", template[strlen (template) - 1]) == NULL)
|
|
||||||
strcat (template, "/");
|
|
||||||
#else
|
|
||||||
# ifndef VMS
|
|
||||||
if (template[strlen (template) - 1] != '/')
|
|
||||||
strcat (template, "/");
|
|
||||||
# endif /* !VMS */
|
|
||||||
#endif /* !HAVE_DOS_PATHS */
|
|
||||||
|
|
||||||
strcat (template, DEFAULT_TMPFILE);
|
|
||||||
outfile = get_tmpfile (&newnm, template);
|
|
||||||
if (outfile == 0)
|
if (outfile == 0)
|
||||||
OSS (fatal, NILF,
|
OSS (fatal, NILF,
|
||||||
_("fopen: temporary file %s: %s"), newnm, strerror (errno));
|
_("fopen: temporary file %s: %s"), newnm, strerror (errno));
|
||||||
|
|
|
@ -546,7 +546,8 @@ 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 **);
|
||||||
FILE *get_tmpfile (char **, const char *);
|
char *get_tmppath ();
|
||||||
|
FILE *get_tmpfile (char **);
|
||||||
ssize_t writebuf (int, const void *, size_t);
|
ssize_t writebuf (int, const void *, size_t);
|
||||||
ssize_t readbuf (int, void *, size_t);
|
ssize_t readbuf (int, void *, size_t);
|
||||||
|
|
||||||
|
|
88
src/misc.c
88
src/misc.c
|
@ -505,8 +505,76 @@ umask (mode_t mask)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static char *
|
||||||
|
get_tmptemplate ()
|
||||||
|
{
|
||||||
|
const char *tmpdir;
|
||||||
|
char *template;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
# define DEFAULT_TMPFILE "sys$scratch:gnv$make_cmdXXXXXX.com"
|
||||||
|
#else
|
||||||
|
# define DEFAULT_TMPFILE "GmXXXXXX"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
# define DEFAULT_TMPDIR "/sys$scratch/"
|
||||||
|
#else
|
||||||
|
# ifdef P_tmpdir
|
||||||
|
# define DEFAULT_TMPDIR P_tmpdir
|
||||||
|
# else
|
||||||
|
# define DEFAULT_TMPDIR "/tmp"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (
|
||||||
|
#if defined (__MSDOS__) || defined (WINDOWS32) || defined (__EMX__)
|
||||||
|
((tmpdir = getenv ("TMP")) == NULL || *tmpdir == '\0') &&
|
||||||
|
((tmpdir = getenv ("TEMP")) == NULL || *tmpdir == '\0') &&
|
||||||
|
#endif
|
||||||
|
((tmpdir = getenv ("TMPDIR")) == NULL || *tmpdir == '\0'))
|
||||||
|
tmpdir = DEFAULT_TMPDIR;
|
||||||
|
|
||||||
|
len = strlen (tmpdir);
|
||||||
|
template = xmalloc (len + CSTRLEN (DEFAULT_TMPFILE) + 2);
|
||||||
|
strcpy (template, tmpdir);
|
||||||
|
|
||||||
|
#ifdef HAVE_DOS_PATHS
|
||||||
|
if (template[len - 1] != '/' && template[len - 1] != '\\')
|
||||||
|
strcat (template, "/");
|
||||||
|
#else
|
||||||
|
# ifndef VMS
|
||||||
|
if (template[len - 1] != '/')
|
||||||
|
strcat (template, "/");
|
||||||
|
# endif /* !VMS */
|
||||||
|
#endif /* !HAVE_DOS_PATHS */
|
||||||
|
|
||||||
|
strcat (template, DEFAULT_TMPFILE);
|
||||||
|
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
get_tmppath ()
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
#ifdef HAVE_MKTEMP
|
||||||
|
path = get_tmptemplate();
|
||||||
|
if (*mktemp (path) == '\0')
|
||||||
|
pfatal_with_name ("mktemp");
|
||||||
|
#else
|
||||||
|
path = xmalloc (L_tmpnam + 1);
|
||||||
|
if (tmpnam (path) == NULL)
|
||||||
|
pfatal_with_name ("tmpnam");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
FILE *
|
FILE *
|
||||||
get_tmpfile (char **name, const char *template)
|
get_tmpfile (char **name)
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
#ifdef HAVE_FDOPEN
|
#ifdef HAVE_FDOPEN
|
||||||
|
@ -516,15 +584,9 @@ get_tmpfile (char **name, const char *template)
|
||||||
/* Preserve the current umask, and set a restrictive one for temp files. */
|
/* Preserve the current umask, and set a restrictive one for temp files. */
|
||||||
mode_t mask = umask (0077);
|
mode_t mask = umask (0077);
|
||||||
|
|
||||||
#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)
|
#if defined(HAVE_MKSTEMP) && defined(HAVE_FDOPEN)
|
||||||
|
*name = get_tmptemplate ();
|
||||||
|
|
||||||
/* It's safest to use mkstemp(), if we can. */
|
/* It's safest to use mkstemp(), if we can. */
|
||||||
EINTRLOOP (fd, mkstemp (*name));
|
EINTRLOOP (fd, mkstemp (*name));
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
|
@ -532,14 +594,10 @@ get_tmpfile (char **name, const char *template)
|
||||||
else
|
else
|
||||||
file = fdopen (fd, "w");
|
file = fdopen (fd, "w");
|
||||||
#else
|
#else
|
||||||
# ifdef HAVE_MKTEMP
|
*name = get_tmppath ();
|
||||||
(void) mktemp (*name);
|
|
||||||
# else
|
|
||||||
(void) tmpnam (*name);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef HAVE_FDOPEN
|
# ifdef HAVE_FDOPEN
|
||||||
/* Can't use mkstemp(), but guard against a race condition. */
|
/* Can't use mkstemp(), but try to guard against a race condition. */
|
||||||
EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
|
EINTRLOOP (fd, open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600));
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1241,9 +1241,7 @@ child_execute_job (struct childbase *child, int good_stdin UNUSED, char *argv)
|
||||||
FILE *outfile;
|
FILE *outfile;
|
||||||
int cmd_len;
|
int cmd_len;
|
||||||
|
|
||||||
outfile = get_tmpfile (&child->comname,
|
outfile = get_tmpfile (&child->comname);
|
||||||
"sys$scratch:gnv$make_cmdXXXXXX.com");
|
|
||||||
/* 123456789012345678901234567890 */
|
|
||||||
if (outfile == 0)
|
if (outfile == 0)
|
||||||
pfatal_with_name (_("fopen (temporary file)"));
|
pfatal_with_name (_("fopen (temporary file)"));
|
||||||
comnamelen = strlen (child->comname);
|
comnamelen = strlen (child->comname);
|
||||||
|
|
Loading…
Reference in a new issue