Skip to content

Commit c4387e0

Browse files
committed
symlink: system fallback as these are important functions
1 parent 3c59a12 commit c4387e0

File tree

4 files changed

+45
-19
lines changed

4 files changed

+45
-19
lines changed

+stdlib/create_symlink.m

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,45 @@
2929
if stdlib.has_python()
3030
ok = py_create_symlink(target, link);
3131
elseif stdlib.dotnet_api() >= 6
32-
% https://learn.microsoft.com/en-us/dotnet/api/system.io.file.createsymboliclink
33-
try
34-
System.IO.File.CreateSymbolicLink(link, target);
35-
ok = true;
36-
catch e
37-
warning(e.identifier, "%s", e.message)
38-
end
32+
ok = dotnet_create_symlink(target, link);
3933
else
40-
warning(e.identifier, "%s", e.message)
34+
ok = system_create_symlink(target, link);
4135
end
42-
case "Octave:undefined-function"
43-
err = symlink(target, link);
44-
ok = err == 0;
36+
case "Octave:undefined-function", ok = symlink(target, link) == 0;
4537
otherwise, warning(e.identifier, "%s", e.message)
4638
end
4739
end
4840

4941
end
5042

43+
44+
function ok = system_create_symlink(target, link)
45+
46+
if ispc
47+
cmd = sprintf('pwsh -c "New-Item -ItemType SymbolicLink -Path "%s" -Target "%s""', link, target);
48+
else
49+
cmd = sprintf('ln -s "%s" "%s"', target, link);
50+
end
51+
52+
% suppress output text on powershell
53+
[stat, ~] = system(cmd);
54+
55+
ok = stat == 0;
56+
end
57+
58+
59+
function ok = dotnet_create_symlink(target, link)
60+
61+
% https://learn.microsoft.com/en-us/dotnet/api/system.io.file.createsymboliclink
62+
try
63+
System.IO.File.CreateSymbolicLink(link, target);
64+
ok = true;
65+
catch e
66+
warning(e.identifier, "%s", e.message)
67+
end
68+
69+
end
70+
5171
%!assert (create_symlink("https://invalid", "https://invalid"), false)
5272
%!test
5373
%! if !ispc

+stdlib/is_symlink.m

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
ok = java.nio.file.Files.isSymbolicLink(javaPathObject(stdlib.absolute(p)));
1717
elseif stdlib.has_python()
1818
ok = py_is_symlink(p);
19-
else
20-
ok = logical.empty;
19+
elseif isunix()
20+
ok = system(sprintf('test -L %s', p)) == 0;
21+
elseif ispc()
22+
[s, m] = system(sprintf('pwsh -command "(Get-Item -Path %s).Attributes"', p));
23+
ok = s == 0 && contains(m, 'ReparsePoint');
2124
end
2225
case "Octave:undefined-function"
2326
% use lstat() to work with a broken symlink, like Matlab isSymbolicLink

+stdlib/read_symlink.m

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,22 @@
1919
case "MATLAB:UndefinedFunction"
2020
if ~stdlib.is_symlink(p), return, end
2121

22-
if stdlib.has_python()
23-
r = py_read_symlink(p);
24-
elseif stdlib.dotnet_api() >= 6
22+
if stdlib.dotnet_api() >= 6
2523
r = System.IO.FileInfo(p).LinkTarget;
2624
elseif stdlib.has_java()
2725
% must be absolute path
2826
% must not be .canonical or symlink is gobbled!
2927
r = stdlib.absolute(p);
3028
% https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/nio/file/Files.html#readSymbolicLink(java.nio.file.Path)
3129
r = java.nio.file.Files.readSymbolicLink(javaPathObject(r)).string;
30+
elseif stdlib.has_python()
31+
r = py_read_symlink(p);
32+
elseif isunix()
33+
[s, m] = system(sprintf('readlink -fn %s', p));
34+
if s == 0, r = string(m); end
35+
elseif ispc()
36+
[s, m] = system(sprintf('pwsh -command "(Get-Item -Path %s).Target"', p));
37+
if s == 0, r = string(strip(m)); end
3238
end
3339
otherwise, rethrow(e)
3440
end

buildfile.m

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313

1414

1515
cnomex = ~HasTag("exe") & ~HasTag("mex") & ~HasTag("java");
16-
if isMATLABReleaseOlderThan("R2024b")
17-
cnomex = cnomex & ~HasTag("symlink");
18-
end
1916
if ispc()
2017
cnomex = cnomex & ~HasTag("unix");
2118
end

0 commit comments

Comments
 (0)