changeset 30881:1921d9d0e62b

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".
author Markus Mützel <markus.muetzel@gmx.de>
date Sun, 03 Apr 2022 12:38:19 +0200
parents 74089676bd9d
children b77b321f1ac5
files bootstrap.conf libinterp/corefcn/file-io.cc libinterp/corefcn/gl2ps-print.cc liboctave/system/lo-sysdep.cc liboctave/system/lo-sysdep.h liboctave/system/oct-env.cc liboctave/wrappers/module.mk liboctave/wrappers/tmpfile-wrapper.c liboctave/wrappers/tmpfile-wrapper.h scripts/miscellaneous/module.mk scripts/miscellaneous/tempdir.m
diffstat 11 files changed, 85 insertions(+), 176 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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)
         {
--- 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");
--- 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)
     {
--- 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);
--- 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 ())
--- 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 \
--- 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 <https://octave.org/copyright/>.
-//
-// 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
-// <https://www.gnu.org/licenses/>.
-//
-////////////////////////////////////////////////////////////////////////
-
-// 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 <stdio.h>
-
-#include "tmpfile-wrapper.h"
-
-FILE *
-octave_tmpfile_wrapper (void)
-{
-  return tmpfile ();
-}
--- 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 <https://octave.org/copyright/>.
-//
-// 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
-// <https://www.gnu.org/licenses/>.
-//
-////////////////////////////////////////////////////////////////////////
-
-#if ! defined (octave_tmpfile_wrapper_h)
-#define octave_tmpfile_wrapper_h 1
-
-#if defined __cplusplus
-#  include <cstdio>
-#else
-#  include <stdio.h>
-#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
--- 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 \
--- 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 <https://octave.org/copyright/>.
-##
-## 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
-## <https://www.gnu.org/licenses/>.
-##
-########################################################################
-
-## -*- 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