# HG changeset patch # User Markus Mützel # Date 1648982299 -7200 # Node ID 1921d9d0e62bcfb99211b5823eb0092b59f5fbca # Parent 74089676bd9d82ddf7c0914bbc32583dc7b71d9e Unify detection of temporary directory (bug #62215). Instead of using differing implementations of detecting the temporary directory in multiple functions, use "sys::env::get_temp_directory" (in some of them). * libinterp/corefcn/file-io.cc (Ftempdir): Add implementation wrapping around "sys::env::get_temp_directory" replacing tempdir.m. (Ftempname): Remove local check of environment variable "TMPDIR". (Ftmpfile): Create temporary file in directory given by "sys::env::get_temp_directory". * libinterp/corefcn/gl2ps-print.cc (gl2ps_renderer::draw): Use Octave's functions for opening temporary file. * liboctave/system/oct-env.cc (sys::env::do_get_temp_directory): Check environment variable "TMPDIR" on all platforms. * liboctave/system/lo-sysdep.h, lo-sysdep.cc (sys::fopen_tmp): Add new function to open temporary file that deletes automatically after use. * scripts/miscellaneous/tempdir.m: Remove file that is replaced by DEFUN. * scripts/miscellaneous/module.mk: Remove deleted file from list. * bootstrap.conf, liboctave/wrappers/tmpfile-wrapper.h, tmpfile-wrapper.c, liboctave/wrappers/module.mk: Remove unused module "tmpfile". diff -r 74089676bd9d -r 1921d9d0e62b bootstrap.conf --- a/bootstrap.conf Fri Apr 01 14:39:54 2022 -0700 +++ b/bootstrap.conf Sun Apr 03 12:38:19 2022 +0200 @@ -101,7 +101,6 @@ sys_times sys_wait tempname - tmpfile uname unicase/u8-tolower unicase/u8-toupper diff -r 74089676bd9d -r 1921d9d0e62b libinterp/corefcn/file-io.cc --- a/libinterp/corefcn/file-io.cc Fri Apr 01 14:39:54 2022 -0700 +++ b/libinterp/corefcn/file-io.cc Sun Apr 03 12:38:19 2022 +0200 @@ -60,7 +60,6 @@ #include "mkostemp-wrapper.h" #include "oct-env.h" #include "oct-locbuf.h" -#include "tmpfile-wrapper.h" #include "unistd-wrappers.h" #include "builtin-defun-decls.h" @@ -2883,6 +2882,51 @@ return ovl (streams.remove (args(0), "pclose")); } +DEFUN (tempdir, args, , + doc: /* -*- texinfo -*- +@deftypefn {} {@var{dir} =} tempdir () +Return the name of the host system's directory for temporary files. + +The directory name is taken first from the environment variable @env{TMPDIR}. +If that does not exist, the environment variable @env{TMP} (and on Windows +platforms also with higher priority the environment variable @env{TEMP}) is +checked. If none of those are set, the system default returned by +@code{P_tmpdir} is used. +@seealso{P_tmpdir, tempname, mkstemp, tmpfile} +@end deftypefn */) +{ + int nargin = args.length (); + + if (nargin > 0) + print_usage (); + + std::string tmpdir = sys::env::get_temp_directory (); + + if (! sys::file_ops::is_dir_sep (tmpdir.back ())) + tmpdir += sys::file_ops::dir_sep_str (); + + return ovl (tmpdir); +} + +/* +%!assert (ischar (tempdir ())) + +%!test +%! old_wstate = warning ("off"); +%! old_tmpdir = getenv ("TMPDIR"); +%! unwind_protect +%! setenv ("TMPDIR", "__MY_TMP_DIR__"); +%! assert (tempdir (), ["__MY_TMP_DIR__" filesep()]); +%! unwind_protect_cleanup +%! if (! isempty (old_tmpdir)) +%! setenv ("TMPDIR", old_tmpdir); +%! else +%! unsetenv ("TMPDIR"); +%! endif +%! warning (old_wstate); +%! end_unwind_protect +*/ + DEFUN (tempname, args, , doc: /* -*- texinfo -*- @deftypefn {} {@var{fname} =} tempname () @@ -2912,8 +2956,6 @@ if (nargin > 0) dir = args(0).xstring_value ("tempname: DIR must be a string"); - else - dir = sys::env::getenv ("TMPDIR"); std::string pfx ("oct-"); @@ -2996,15 +3038,15 @@ octave_value_list retval; - FILE *fid = octave_tmpfile_wrapper (); + std::string tmpfile (sys::tempnam (sys::env::get_temp_directory (), "oct-")); + + FILE *fid = sys::fopen_tmp (tmpfile, "w+b"); if (fid) { - std::string nm; - std::ios::openmode md = fopen_mode_to_ios_mode ("w+b"); - stream s = stdiostream::create (nm, fid, md); + stream s = stdiostream::create (tmpfile, fid, md); if (! s) { diff -r 74089676bd9d -r 1921d9d0e62b libinterp/corefcn/gl2ps-print.cc --- a/libinterp/corefcn/gl2ps-print.cc Fri Apr 01 14:39:54 2022 -0700 +++ b/libinterp/corefcn/gl2ps-print.cc Sun Apr 03 12:38:19 2022 +0200 @@ -42,7 +42,7 @@ #include "file-ops.h" #include "lo-mappers.h" #include "oct-locbuf.h" -#include "tmpfile-wrapper.h" +#include "oct-env.h" #include "unistd-wrappers.h" #include "unistr-wrappers.h" #include "unwind-prot.h" @@ -396,7 +396,9 @@ gl2ps_sort = GL2PS_NO_SORT; // Use a temporary file in case an overflow happens - FILE *tmpf = octave_tmpfile_wrapper (); + std::string tmpfile (sys::tempnam (sys::env::get_temp_directory (), + "oct-")); + FILE *tmpf = sys::fopen_tmp (tmpfile, "w+b"); if (! tmpf) error ("gl2ps_renderer::draw: couldn't open temporary file for printing"); diff -r 74089676bd9d -r 1921d9d0e62b liboctave/system/lo-sysdep.cc --- a/liboctave/system/lo-sysdep.cc Fri Apr 01 14:39:54 2022 -0700 +++ b/liboctave/system/lo-sysdep.cc Sun Apr 03 12:38:19 2022 +0200 @@ -382,6 +382,30 @@ #endif } + std::FILE * + fopen_tmp (const std::string& name, const std::string& mode) + { +#if defined (OCTAVE_USE_WINDOWS_API) + + // Append "D" to the mode string to indicate that this is a temporary + // file that should be deleted when the last open handle is closed. + std::string tmp_mode = mode + "D"; + + return std::fopen (name.c_str (), tmp_mode.c_str ()); + +#else + + std::FILE *fptr = std::fopen (name.c_str (), mode.c_str ()); + + // From gnulib: This relies on the Unix semantics that a file is not + // really removed until it is closed. + octave_unlink_wrapper (name.c_str ()); + + return fptr; + +#endif + } + std::fstream fstream (const std::string& filename, const std::ios::openmode mode) { diff -r 74089676bd9d -r 1921d9d0e62b liboctave/system/lo-sysdep.h --- a/liboctave/system/lo-sysdep.h Fri Apr 01 14:39:54 2022 -0700 +++ b/liboctave/system/lo-sysdep.h Sun Apr 03 12:38:19 2022 +0200 @@ -54,6 +54,9 @@ extern OCTAVE_API std::FILE * fopen (const std::string& name, const std::string& mode); + extern OCTAVE_API std::FILE * + fopen_tmp (const std::string& name, const std::string& mode); + extern OCTAVE_API std::fstream fstream (const std::string& name, const std::ios::openmode mode = std::ios::in | std::ios::out); diff -r 74089676bd9d -r 1921d9d0e62b liboctave/system/oct-env.cc --- a/liboctave/system/oct-env.cc Fri Apr 01 14:39:54 2022 -0700 +++ b/liboctave/system/oct-env.cc Sun Apr 03 12:38:19 2022 +0200 @@ -207,11 +207,12 @@ std::string env::do_get_temp_directory (void) const { - std::string tempd; + std::string tempd = do_getenv ("TMPDIR"); #if defined (__MINGW32__) || defined (_MSC_VER) - tempd = do_getenv ("TEMP"); + if (tempd.empty ()) + tempd = do_getenv ("TEMP"); if (tempd.empty ()) tempd = do_getenv ("TMP"); @@ -228,7 +229,8 @@ #else - tempd = do_getenv ("TMP"); + if (tempd.empty ()) + tempd = do_getenv ("TMP"); #if defined (P_tmpdir) if (tempd.empty ()) diff -r 74089676bd9d -r 1921d9d0e62b liboctave/wrappers/module.mk --- a/liboctave/wrappers/module.mk Fri Apr 01 14:39:54 2022 -0700 +++ b/liboctave/wrappers/module.mk Sun Apr 03 12:38:19 2022 +0200 @@ -30,7 +30,6 @@ %reldir%/strmode-wrapper.h \ %reldir%/strptime-wrapper.h \ %reldir%/time-wrappers.h \ - %reldir%/tmpfile-wrapper.h \ %reldir%/uname-wrapper.h \ %reldir%/unicase-wrappers.h \ %reldir%/uniconv-wrappers.h \ @@ -74,7 +73,6 @@ %reldir%/strmode-wrapper.c \ %reldir%/strptime-wrapper.c \ %reldir%/time-wrappers.c \ - %reldir%/tmpfile-wrapper.c \ %reldir%/uname-wrapper.c \ %reldir%/unicase-wrappers.c \ %reldir%/uniconv-wrappers.c \ diff -r 74089676bd9d -r 1921d9d0e62b liboctave/wrappers/tmpfile-wrapper.c --- a/liboctave/wrappers/tmpfile-wrapper.c Fri Apr 01 14:39:54 2022 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2016-2022 The Octave Project Developers -// -// See the file COPYRIGHT.md in the top-level directory of this -// distribution or . -// -// This file is part of Octave. -// -// Octave is free software: you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Octave is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Octave; see the file COPYING. If not, see -// . -// -//////////////////////////////////////////////////////////////////////// - -// tmpfile may be provided by gnulib. We don't include gnulib headers -// directly in Octave's C++ source files to avoid problems that may be -// caused by the way that gnulib overrides standard library functions. - -#if defined (HAVE_CONFIG_H) -# include "config.h" -#endif - -#include - -#include "tmpfile-wrapper.h" - -FILE * -octave_tmpfile_wrapper (void) -{ - return tmpfile (); -} diff -r 74089676bd9d -r 1921d9d0e62b liboctave/wrappers/tmpfile-wrapper.h --- a/liboctave/wrappers/tmpfile-wrapper.h Fri Apr 01 14:39:54 2022 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -//////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2016-2022 The Octave Project Developers -// -// See the file COPYRIGHT.md in the top-level directory of this -// distribution or . -// -// This file is part of Octave. -// -// Octave is free software: you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Octave is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Octave; see the file COPYING. If not, see -// . -// -//////////////////////////////////////////////////////////////////////// - -#if ! defined (octave_tmpfile_wrapper_h) -#define octave_tmpfile_wrapper_h 1 - -#if defined __cplusplus -# include -#else -# include -#endif - -#if defined __cplusplus -extern "C" { -#endif - -// c++11 provides std::tmpfile but it appears to fail on 64-bit -// Windows systems. - -extern OCTAVE_API FILE * octave_tmpfile_wrapper (void); - -#if defined __cplusplus -} -#endif - -#endif diff -r 74089676bd9d -r 1921d9d0e62b scripts/miscellaneous/module.mk --- a/scripts/miscellaneous/module.mk Fri Apr 01 14:39:54 2022 -0700 +++ b/scripts/miscellaneous/module.mk Sun Apr 03 12:38:19 2022 +0200 @@ -94,7 +94,6 @@ %reldir%/swapbytes.m \ %reldir%/symvar.m \ %reldir%/tar.m \ - %reldir%/tempdir.m \ %reldir%/unix.m \ %reldir%/unpack.m \ %reldir%/untar.m \ diff -r 74089676bd9d -r 1921d9d0e62b scripts/miscellaneous/tempdir.m --- a/scripts/miscellaneous/tempdir.m Fri Apr 01 14:39:54 2022 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -######################################################################## -## -## Copyright (C) 2003-2022 The Octave Project Developers -## -## See the file COPYRIGHT.md in the top-level directory of this -## distribution or . -## -## This file is part of Octave. -## -## Octave is free software: you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## . -## -######################################################################## - -## -*- texinfo -*- -## @deftypefn {} {@var{dir} =} tempdir () -## Return the name of the host system's directory for temporary files. -## -## The directory name is taken first from the environment variable -## @env{TMPDIR}. If that does not exist the system default returned by -## @code{P_tmpdir} is used. -## @seealso{P_tmpdir, tempname, mkstemp, tmpfile} -## @end deftypefn - -function dirname = tempdir () - - dirname = getenv ("TMPDIR"); - if (isempty (dirname)) - dirname = P_tmpdir (); - endif - - if (! strcmp (dirname(end), filesep)) - dirname = [dirname filesep]; - endif - - if (! isfolder (dirname)) - warning ("tempdir: '%s' does not exist or is not a directory", dirname); - endif - -endfunction - - -%!assert (ischar (tempdir ())) - -%!test -%! old_wstate = warning ("query"); -%! warning ("off"); -%! old_tmpdir = getenv ("TMPDIR"); -%! unwind_protect -%! setenv ("TMPDIR", "__MY_TMP_DIR__"); -%! assert (tempdir (), ["__MY_TMP_DIR__" filesep()]); -%! unwind_protect_cleanup -%! if (! isempty (old_tmpdir)) -%! setenv ("TMPDIR", old_tmpdir); -%! else -%! unsetenv ("TMPDIR"); -%! endif -%! warning (old_wstate); -%! end_unwind_protect