Mercurial > hg > octave-nkf
changeset 19655: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 +++ b/bootstrap.conf @@ -93,6 +93,7 @@ sys_stat sys_time sys_times + tempname time times tmpfile
--- a/liboctave/system/file-ops.cc +++ b/liboctave/system/file-ops.cc @@ -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 +++ b/liboctave/system/oct-env.cc @@ -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 +++ b/liboctave/system/oct-env.h @@ -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;