diff liboctave/system/file-ops.cc @ 19492:d8fd3842a507

Use gnulib gen_tempname to create temporary names (Bug #43872). * bootstrap.conf: add tempname module. * liboctave/system/file-ops.cc: (toplevel): include tempname.h. (octave_tempnam): set up template based on input dir and prefix and call gen_tempname to get temporary name. * liboctave/system/oct-env.cc: (octave_env::get_temp_directory): New function. (octave_env::do_get_temp_directory): New function.
author John Donoghue <john.donoghue@ieee.org>
date Thu, 01 Jan 2015 10:01:18 -0500
parents eee9f111c164
children db92e7e28e1f
line wrap: on
line diff
--- a/liboctave/system/file-ops.cc	Wed Dec 31 15:57:37 2014 -0500
+++ b/liboctave/system/file-ops.cc	Thu Jan 01 10:01:18 2015 -0500
@@ -39,6 +39,10 @@
 #include "pathmax.h"
 #include "canonicalize.h"
 
+extern "C" {
+#include <tempname.h>
+}
+
 #include "dir-ops.h"
 #include "file-ops.h"
 #include "file-stat.h"
@@ -678,53 +682,37 @@
 
   std::string retval;
 
-  const char *pdir = dir.empty () ? 0 : dir.c_str ();
-
-  const char *ppfx = pfx.empty () ? 0 : pfx.c_str ();
-
-  char *tmp = tempnam (pdir, ppfx);
+  // get dir path to use for template
+  std::string templatename;
+  if (dir.empty ())
+    templatename = octave_env::get_temp_directory ();
+  else if (! file_stat (dir, false).is_dir ())
+    templatename = octave_env::get_temp_directory ();
+  else
+    templatename = dir;
 
-  if (tmp)
-    {
-      retval = tmp;
-      free (tmp);
-
-      if (! dir.empty ())
-        {
-          // Check that environment variable hasn't overridden dir argument
-          size_t pos = retval.rfind (file_ops::dir_sep_char ());
-          std::string tmpdir = retval.substr (0, pos);  
-          std::string dirarg = dir;
-          if (*dirarg.rbegin () == file_ops::dir_sep_char ())
-            dirarg.erase (--dirarg.end ());
+  // add dir sep char if it is not there
+  if (*templatename.rbegin () != file_ops::dir_sep_char ())
+    templatename += file_ops::dir_sep_char ();
 
-          if (tmpdir != dirarg)
-          {
-            // A different TMPDIR was used.
-            // Replace TMPDIR with given dir if is valid
-            file_stat fs (dirarg, false);
-            if (fs && fs.is_dir ())
-              retval.replace (0, pos, dirarg);
+  if (pfx.empty ())
+    templatename += "file";
+  else
+    templatename += pfx;
+
+  // add the required XXXXXX for the template
+  templatename += "XXXXXX";
 
-            // since we have changed the directory, it is possible that the name
-            // we are using is no longer unique, so check/modify
-            std::string tmppath = retval;
-            int attempt = 0;
-            while (++attempt < TMP_MAX && file_stat (tmppath, false).exists ())
-              {
-                char file_postfix[16];
+  // create and copy template to char array for call to gen_tempname
+  char tname [templatename.length () + 1];
 
-                sprintf(file_postfix, "t%d", attempt);
+  strcpy (tname, templatename.c_str ());
 
-                tmppath = retval + file_postfix;
-              }
-            retval = tmppath;
-          }
-        }
-    }
+  if (gen_tempname (tname, 0, 0, GT_NOCREATE) == -1)
+    msg = gnulib::strerror (errno);
   else
-    msg = gnulib::strerror (errno);
-
+    retval = tname;
+  
   return retval;
 }