Skip to content

Commit

Permalink
private/python_ipc_system: Convert to Cygwin path when needed.
Browse files Browse the repository at this point in the history
This should fix some errors when Python is running in Cygwin-like
environment. But there could still be errors in other places.

See gnu-octave#1182.

* inst/private/cygpath.m: New function.
* inst/private/python_env_is_cygwin_like.m: New function.
* inst/private/python_ipc_system.m: Use them.
  • Loading branch information
Alex Vong authored and Alex Vong committed Jul 18, 2022
1 parent 1b9849e commit 1df0ae0
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 1 deletion.
50 changes: 50 additions & 0 deletions inst/private/cygpath.m
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @defun cygpath ()
%% Convert Windows native path to Cygwin POSIX-style path.
%%
%% @seealso{python_env_is_cygwin_like}
%% @end defun

function posix_path = cygpath (native_path)
args = {'-u', native_path};
[fin, fout, pid] = popen2 ('cygpath', args);
if pid == -1
error ('cygpath: failed to create cygpath subprocess');
end

assert (fclose (fin) == 0);

err = errno ('EAGAIN');
while err == errno ('EAGAIN')
pause (0.1);
posix_path = fgetl (fout);
err = errno ();
end

assert (ischar (posix_path));
assert (feof (fout));
assert (fclose (fout) == 0);

[retpid, status, msg] = waitpid (pid);
if retpid < 0
error ('cygpath: failed to wait for python: %s', msg);
end
end
64 changes: 64 additions & 0 deletions inst/private/python_env_is_cygwin_like.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
%% 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 <https://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @defun python_env_is_cygwin_like (pyexec)
%% Check if Python @var{pyexec} is running in a Cygwin-like POSIX environment,
%% such as Cygwin or MSYS2. The result is memoized to speed up subsequent
%% calls.
%%
%% @seealso{cygpath}
%% @end defun

function r = python_env_is_cygwin_like (pyexec)
persistent python_env_is_cygwin_like_memo

if ~isempty (python_env_is_cygwin_like_memo)
r = python_env_is_cygwin_like_memo;
elseif ispc ()
args = {'-c', 'import os; print(os.name)'};
[fin, fout, pid] = popen2 (pyexec, args);
if pid == -1
error ('python_env_is_cygwin_like: failed to create python subprocess');
end

assert (fclose (fin) == 0);

err = errno ('EAGAIN');
while err == errno ('EAGAIN')
pause (0.1);
os = fgetl (fout);
err = errno ();
end

assert (ischar (os));
assert (feof (fout));
assert (fclose (fout) == 0);

[retpid, status, msg] = waitpid (pid);
if retpid < 0
error ('python_env_is_cygwin_like: failed to wait for python: %s', msg);
end

r = strcmp (os, 'posix');
python_env_is_cygwin_like_memo = r;
else
r = false;
python_env_is_cygwin_like_memo = r;
end
end
9 changes: 8 additions & 1 deletion inst/private/python_ipc_system.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
%% Copyright (C) 2014-2016, 2022 Colin B. Macdonald
%% Copyright (C) 2022 Alex Vong
%%
%% This file is part of OctSymPy.
%%
Expand Down Expand Up @@ -131,7 +132,13 @@
error ('system ipc: failed to close %s (fd %d) after writing', ...
tmpfilename, fd);
end
[status, out] = system ([pyexec ' ' tmpfilename]);

if python_env_is_cygwin_like (pyexec)
converted_tmpfilename = cygpath (tmpfilename);
else
converted_tmpfilename = tmpfilename;
end
[status, out] = system ([pyexec ' ' converted_tmpfilename]);
end

info.raw = out;
Expand Down

0 comments on commit 1df0ae0

Please sign in to comment.