changeset 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 cb35d695713c
children f765fea3ca14
files bootstrap.conf liboctave/system/file-ops.cc liboctave/system/oct-env.cc liboctave/system/oct-env.h
diffstat 4 files changed, 80 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/bootstrap.conf	Wed Dec 31 15:57:37 2014 -0500
+++ b/bootstrap.conf	Thu Jan 01 10:01:18 2015 -0500
@@ -93,6 +93,7 @@
   sys_stat
   sys_time
   sys_times
+  tempname
   time
   times
   tmpfile
--- 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;
 }
 
--- a/liboctave/system/oct-env.cc	Wed Dec 31 15:57:37 2014 -0500
+++ b/liboctave/system/oct-env.cc	Thu Jan 01 10:01:18 2015 -0500
@@ -150,6 +150,13 @@
 }
 
 std::string
+octave_env::get_temp_directory ()
+{
+  return (instance_ok ())
+         ? instance->do_get_temp_directory () : std::string ();
+}
+
+std::string
 octave_env::get_program_name (void)
 {
   return (instance_ok ())
@@ -184,6 +191,45 @@
          ? instance->do_get_host_name () : std::string ();
 }
 
+std::string
+octave_env::do_get_temp_directory (void) const
+{
+  std::string tempd;
+
+#if defined (__MINGW32__) || defined (_MSC_VER)
+  
+  tempd = do_getenv ("TEMP");
+
+  if (tempd.empty ())
+    tempd = do_getenv ("TMP");
+
+  #if defined (P_tmpdir)
+  if (tempd.empty ())
+    tempd = P_tmpdir;
+  #endif
+
+  // Some versions of MinGW and MSVC either don't define P_tmpdir, or
+  // define it to a single backslash.  In such cases just use C:\temp.
+  if (tempd.empty () || tempd == "\\")
+    tempd = "c:\\temp";
+
+#else    ## Unix-like OS
+
+  tempd = do_getenv ("TMP");
+
+  #if defined (P_tmpdir)
+  if (tempd.empty ())
+    tempd = P_tmpdir;
+  #else
+  if (tempd.empty ())
+    tempd = "/tmp";
+  #endif
+
+#endif
+
+  return tempd;
+}
+
 // FIXME: this leaves no way to distinguish between a
 // variable that is not set and one that is set to the empty string.
 // Is this a problem?
--- a/liboctave/system/oct-env.h	Wed Dec 31 15:57:37 2014 -0500
+++ b/liboctave/system/oct-env.h	Thu Jan 01 10:01:18 2015 -0500
@@ -51,6 +51,8 @@
 
   static std::string get_home_directory (void);
 
+  static std::string get_temp_directory (void);
+
   static std::string get_program_name (void);
 
   static std::string get_program_invocation_name (void);
@@ -88,6 +90,8 @@
 
   std::string do_get_home_directory (void) const;
 
+  std::string do_get_temp_directory (void) const;
+
   std::string do_get_user_name (void) const;
 
   std::string do_get_host_name (void) const;