diff --git a/inst/@sym/function_handle.m b/inst/@sym/function_handle.m
index e130e7e4a..61d63a787 100644
--- a/inst/@sym/function_handle.m
+++ b/inst/@sym/function_handle.m
@@ -1,4 +1,5 @@
%% Copyright (C) 2014-2019 Colin B. Macdonald
+%% Copyright (C) 2022 Alex Vong
%%
%% This file is part of OctSymPy.
%%
@@ -255,13 +256,13 @@
%!test
%! % output to disk
%! fprintf('\n')
+%! temp_path = make_temp_dir__ (tempdir (), 'octsympy-temp-dir-');
%! if (exist ('OCTAVE_VERSION', 'builtin'))
-%! temp_file = tempname('', 'oct_');
+%! temp_file = [temp_path '/oct_temp_file'];
%! else
-%! temp_file = tempname();
+%! temp_file = [temp_path '/temp_file'];
%! end
%! % allow loading function from temp_file
-%! [temp_path, ans, ans] = fileparts(temp_file);
%! addpath(temp_path);
%! f = function_handle(2*x*y, 2^x, 'vars', {x y z}, 'file', temp_file);
%! assert( isa(f, 'function_handle'))
@@ -280,13 +281,13 @@
%!test
%! % output to disk: also works with .m specified
+%! temp_path = make_temp_dir__ (tempdir (), 'octsympy-temp-dir-');
%! if (exist ('OCTAVE_VERSION', 'builtin'))
-%! temp_file = [tempname('', 'oct_') '.m'];
+%! temp_file = [temp_path '/oct_temp_file.m'];
%! else
-%! temp_file = [tempname() '.m'];
+%! temp_file = [temp_path '/temp_file.m'];
%! end
%! % allow loading function from temp_file
-%! [temp_path, ans, ans] = fileparts(temp_file);
%! addpath(temp_path);
%! f = function_handle(2*x*y, 2^x, 'vars', {x y z}, 'file', temp_file);
%! assert( isa(f, 'function_handle'))
@@ -319,13 +320,13 @@
%! H = [x y z];
%! M = [x y; z 16];
%! V = [x;y;z];
+%! temp_path = make_temp_dir__ (tempdir (), 'octsympy-temp-dir-');
%! if (exist ('OCTAVE_VERSION', 'builtin'))
-%! temp_file = tempname('', 'oct_');
+%! temp_file = [temp_path '/oct_temp_file'];
%! else
-%! temp_file = tempname();
+%! temp_file = [temp_path '/temp_file'];
%! end
%! % allow loading function from temp_file
-%! [temp_path, ans, ans] = fileparts(temp_file);
%! addpath(temp_path);
%! h = function_handle(H, M, V, 'vars', {x y z}, 'file', temp_file);
%! assert( isa(h, 'function_handle'))
diff --git a/inst/@sym/sym.m b/inst/@sym/sym.m
index 90a4a395b..31e44d567 100644
--- a/inst/@sym/sym.m
+++ b/inst/@sym/sym.m
@@ -1,5 +1,6 @@
%% Copyright (C) 2014-2019, 2022 Colin B. Macdonald
%% Copyright (C) 2016 Lagu
+%% Copyright (C) 2022 Alex Vong
%%
%% This file is part of OctSymPy.
%%
@@ -953,7 +954,7 @@
%! syms x
%! y = 2*x;
%! a = 42;
-%! myfile = tempname ();
+%! [fd, myfile] = make_temp_file__ (tempdir (), 'octsympy-myfile-');
%! save (myfile, 'x', 'y', 'a')
%! clear x y a
%! load (myfile)
diff --git a/inst/make_temp_dir__.m b/inst/make_temp_dir__.m
new file mode 100644
index 000000000..0eab4cdad
--- /dev/null
+++ b/inst/make_temp_dir__.m
@@ -0,0 +1,50 @@
+%% Copyright (C) 2022 Alex Vong
+%%
+%% This file is part of OctSymPy.
+%%
+%% OctSymPy 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.
+%%
+%% This software 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 this software; see the file COPYING.
+%% If not, see .
+
+%% -*- texinfo -*-
+%% @documentencoding UTF-8
+%% @deftypefun {@var{path} =} make_temp_dir__ (@var{tmpdir}, @var{prefix})
+%% Try to create temporary directory in temporary directory @var{tmpdir} with
+%% prefix @var{prefix} in the most secure and portable way possible.
+%%
+%% This function is not really intended for end users.
+%%
+%% @end deftypefun
+
+
+function path = make_temp_dir__ (tmpdir, prefix)
+ cmd = {'import tempfile'
+ '(tmpdir, prefix) = _ins'
+ 'return tempfile.mkdtemp(dir=tmpdir, prefix=prefix)'};
+ path = pycall_sympy__ (cmd, tmpdir, prefix);
+end
+
+
+%!test
+%! % general test
+%! path = make_temp_dir__ (tempdir (), 'octsympy-');
+%! assert (~isempty (strfind (path, tempdir ())));
+%! assert (~isempty (strfind (path, 'octsympy-')));
+%! assert (isfolder (path));
+%! assert (isequal (ls (path), ''));
+%! assert (rmdir (path));
+
+%!error
+%! if (exist ('OCTAVE_VERSION', 'builtin'))
+%! make_temp_dir__ ('/nonexistent', '');
+%! end
diff --git a/inst/make_temp_file__.m b/inst/make_temp_file__.m
new file mode 100644
index 000000000..67a0fd7bc
--- /dev/null
+++ b/inst/make_temp_file__.m
@@ -0,0 +1,78 @@
+%% Copyright (C) 2022 Alex Vong
+%%
+%% This file is part of OctSymPy.
+%%
+%% OctSymPy 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.
+%%
+%% This software 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 this software; see the file COPYING.
+%% If not, see .
+
+%% -*- texinfo -*-
+%% @documentencoding UTF-8
+%% @deftypefun {[@var{fd}, @var{filename}] =} make_temp_file__ (@var{tmpdir}, @var{prefix})
+%% Try to create temporary file in temporary directory @var{tmpdir} with prefix
+%% @var{prefix} in the most secure and portable way possible.
+%%
+%% This function is not really intended for end users.
+%%
+%% @end deftypefun
+
+
+%% This function is used in private/python_ipc_*.m
+%% Assume Python IPC is not initialized yet
+
+function [fd, filename] = make_temp_file__ (tmpdir, prefix)
+ if (exist ('OCTAVE_VERSION', 'builtin'))
+ template = [tmpdir '/' prefix 'XXXXXX'];
+ [fd, filename, msg] = mkstemp (template);
+ if (fd == -1 || isequal (filename, ''))
+ error ('make_temp_file__: cannot create temp file: %s', msg);
+ end
+
+ elseif (usejava ('jvm')) % java is required when not running octave
+ attrs = javaArray ('java.nio.file.attribute.FileAttribute', 0);
+ path = javaMethod ('createTempFile', 'java.nio.file.Files',
+ prefix, '',
+ attrs);
+ filename = javaMethod ('toString', path);
+ fd = fopen (filename, 'r+');
+
+ else
+ error ('make_temp_file__: cannot create temp file: please enable java');
+ end
+end
+
+
+%!test
+%! % general test
+%! [fd, filename] = make_temp_file__ (tempdir (), 'octsympy-');
+%! assert (~isempty (strfind (filename, tempdir ())));
+%! assert (~isempty (strfind (filename, 'octsympy-')));
+%! assert (mod (fd, 1) == 0 && fd > 2);
+%! s = 'hello, world';
+%! fprintf (fd, s);
+%! assert (fclose (fd) == 0);
+%! fd2 = fopen (filename);
+%! s2 = fgets (fd2);
+%! assert (isequal (s, s2));
+%! assert (fgets (fd2) == -1);
+%! assert (fclose (fd2) == 0);
+%! if (exist ('OCTAVE_VERSION', 'builtin'))
+%! assert (unlink (filename) == 0);
+%! else
+%! delete (filename);
+%! end
+
+%!error
+%! if (exist ('OCTAVE_VERSION', 'builtin'))
+%! make_temp_file__ ('/nonexistent', '');
+%! end
diff --git a/inst/private/python_ipc_system.m b/inst/private/python_ipc_system.m
index 1d2d03c6a..556d5c5ad 100644
--- a/inst/private/python_ipc_system.m
+++ b/inst/private/python_ipc_system.m
@@ -1,4 +1,5 @@
%% Copyright (C) 2014-2016, 2022 Colin B. Macdonald
+%% Copyright (C) 2022 Alex Vong
%%
%% This file is part of OctSymPy.
%%
@@ -108,12 +109,13 @@
%% Generate a temp .py file then execute it with system()
% can be useful for debugging, or if "python -c" fails for you
if (isempty (tmpfilename))
- tmpfilename = [tempname() '_octsympytmp.py'];
+ [fd, tmpfilename] = make_temp_file__ (tempdir (), 'octsympy-tmpfile-');
if (verbose)
disp (['This session will use the temp file "' tmpfilename '"'])
end
+ else
+ fd = fopen (tmpfilename, 'w');
end
- fd = fopen (tmpfilename, 'w');
fprintf(fd, '# temporary autogenerated code\n\n');
% we just added two more lines at the top
info.prelines = info.prelines + 2;