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
|
||||
into a temporary file and read from that. */
|
||||
FILE *outfile;
|
||||
char *template;
|
||||
char *newnm;
|
||||
const char *tmpdir;
|
||||
|
||||
if (stdin_offset >= 0)
|
||||
O (fatal, NILF,
|
||||
_("Makefile from standard input specified twice"));
|
||||
|
||||
#ifdef VMS
|
||||
# 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);
|
||||
outfile = get_tmpfile (&newnm);
|
||||
if (outfile == 0)
|
||||
OSS (fatal, NILF,
|
||||
_("fopen: temporary file %s: %s"), newnm, strerror (errno));
|
||||
|
|
|
@ -546,7 +546,8 @@ int alpha_compare (const void *, const void *);
|
|||
void print_spaces (unsigned int);
|
||||
char *find_percent (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 readbuf (int, void *, size_t);
|
||||
|
||||
|
|
88
src/misc.c
88
src/misc.c
|
@ -505,8 +505,76 @@ umask (mode_t mask)
|
|||
}
|
||||
#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 *
|
||||
get_tmpfile (char **name, const char *template)
|
||||
get_tmpfile (char **name)
|
||||
{
|
||||
FILE *file;
|
||||
#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. */
|
||||
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)
|
||||
*name = get_tmptemplate ();
|
||||
|
||||
/* It's safest to use mkstemp(), if we can. */
|
||||
EINTRLOOP (fd, mkstemp (*name));
|
||||
if (fd == -1)
|
||||
|
@ -532,14 +594,10 @@ get_tmpfile (char **name, const char *template)
|
|||
else
|
||||
file = fdopen (fd, "w");
|
||||
#else
|
||||
# ifdef HAVE_MKTEMP
|
||||
(void) mktemp (*name);
|
||||
# else
|
||||
(void) tmpnam (*name);
|
||||
# endif
|
||||
*name = get_tmppath ();
|
||||
|
||||
# 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));
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
|
|
|
@ -1241,9 +1241,7 @@ child_execute_job (struct childbase *child, int good_stdin UNUSED, char *argv)
|
|||
FILE *outfile;
|
||||
int cmd_len;
|
||||
|
||||
outfile = get_tmpfile (&child->comname,
|
||||
"sys$scratch:gnv$make_cmdXXXXXX.com");
|
||||
/* 123456789012345678901234567890 */
|
||||
outfile = get_tmpfile (&child->comname);
|
||||
if (outfile == 0)
|
||||
pfatal_with_name (_("fopen (temporary file)"));
|
||||
comnamelen = strlen (child->comname);
|
||||
|
|
Loading…
Reference in a new issue