]> git.ipfire.org Git - thirdparty/make.git/commitdiff
Enhance get_tmpfile() and add get_tmppath()
authorPaul Smith <psmith@gnu.org>
Mon, 1 Aug 2022 16:57:12 +0000 (12:57 -0400)
committerPaul Smith <psmith@gnu.org>
Wed, 3 Aug 2022 03:36:35 +0000 (23:36 -0400)
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.

src/main.c
src/makeint.h
src/misc.c
src/vmsjobs.c

index e3658f052c67a01f75dfe969ae07db06a471ccbd..723325df48615565b59b9b8c1312faff9562d0b4 100644 (file)
@@ -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));
index e711a3c883c34835f90aceff7da16923fb43aca9..737f6a0eed4ccb2520f7401825d8e544bdce834b 100644 (file)
@@ -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);
 
index 0e88964784953a1798907c21e68513a21ee2e327..fa0669ada7b26973fe6492b7b73aaf251a4a4a0e 100644 (file)
@@ -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;
index ef4ed064012b6ff0029dc070faf1a1fc017ed731..e3226acf4570a7934cd9cbab8ceef33f11bed5e1 100644 (file)
@@ -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);