Skip to content

Commit 4d37830

Browse files
committed
realpath in c#
1 parent b01c655 commit 4d37830

File tree

3 files changed

+25
-89
lines changed

3 files changed

+25
-89
lines changed

src/Cli/dotnet/StatInterop.cs

Lines changed: 0 additions & 69 deletions
This file was deleted.

src/Resolvers/Microsoft.DotNet.NativeWrapper/EnvironmentProvider.cs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ private IEnumerable<string> SearchPaths
5959
}
6060

6161
string? dotnetExe;
62-
#if NETCOREAPP
62+
#if NET
6363
// The dotnet executable is loading only the .NET version of this code so there is no point checking
6464
// the current process path on .NET Framework. We are expected to find dotnet on PATH.
6565
dotnetExe = _getCurrentProcessPath();
@@ -70,12 +70,31 @@ private IEnumerable<string> SearchPaths
7070
{
7171
string? dotnetExeFromPath = GetCommandPath(Constants.DotNet);
7272

73-
if (dotnetExeFromPath != null && !Interop.RunningOnWindows)
73+
#if NET
74+
if (dotnetExeFromPath != null && !OperatingSystem.IsWindows())
7475
{
7576
// e.g. on Linux the 'dotnet' command from PATH is a symlink so we need to
7677
// resolve it to get the actual path to the binary
77-
dotnetExeFromPath = Interop.Unix.realpath(dotnetExeFromPath) ?? dotnetExeFromPath;
78+
dotnetExeFromPath = GetRealPath(dotnetExeFromPath) ?? dotnetExeFromPath;
79+
80+
static string? GetRealPath(string path)
81+
{
82+
string fullPath = Path.GetFullPath(path);
83+
if (!File.Exists(fullPath))
84+
return null;
85+
86+
FileInfo info = new(fullPath);
87+
if (info.LinkTarget != null)
88+
{
89+
var resolvedTarget = info.ResolveLinkTarget(returnFinalTarget: true);
90+
if (resolvedTarget != null)
91+
return resolvedTarget.FullName;
92+
}
93+
94+
return fullPath;
95+
}
7896
}
97+
#endif
7998

8099
if (!string.IsNullOrWhiteSpace(dotnetExeFromPath))
81100
{
@@ -86,7 +105,7 @@ private IEnumerable<string> SearchPaths
86105
log?.Invoke($"GetDotnetExeDirectory: dotnet command path not found. Using current process");
87106
log?.Invoke($"GetDotnetExeDirectory: Path variable: {_getEnvironmentVariable(Constants.PATH)}");
88107

89-
#if !NETCOREAPP
108+
#if !NET
90109
// If we failed to find dotnet on PATH, we revert to the old behavior of returning the current process
91110
// path. This is really an error state but we're keeping the contract of always returning a non-empty
92111
// path for backward compatibility.
@@ -123,7 +142,7 @@ private IEnumerable<string> SearchPaths
123142
private static string? GetCurrentProcessPath()
124143
{
125144
string? currentProcessPath;
126-
#if NET6_0_OR_GREATER
145+
#if NET
127146
currentProcessPath = Environment.ProcessPath;
128147
#else
129148
currentProcessPath = Process.GetCurrentProcess().MainModule.FileName;

src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ static Interop()
2828
}
2929

3030
// MSBuild SDK resolvers are required to be AnyCPU, but we have a native dependency and .NETFramework does not
31-
// have a built-in facility for dynamically loading user native dlls for the appropriate platform. We therefore
31+
// have a built-in facility for dynamically loading user native dlls for the appropriate platform. We therefore
3232
// preload the version with the correct architecture (from a corresponding sub-folder relative to us) on static
3333
// construction so that subsequent P/Invokes can find it.
3434
private static void PreloadWindowsLibrary(string dllFileName)
@@ -179,20 +179,6 @@ internal delegate void hostfxr_get_available_sdks_result_fn(
179179
internal static extern int hostfxr_get_available_sdks(
180180
string? exe_dir,
181181
hostfxr_get_available_sdks_result_fn result);
182-
183-
[DllImport("libc", CharSet = UTF8, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
184-
private static extern IntPtr realpath(string path, IntPtr buffer);
185-
186-
[DllImport("libc", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
187-
private static extern void free(IntPtr ptr);
188-
189-
public static string? realpath(string path)
190-
{
191-
var ptr = realpath(path, IntPtr.Zero);
192-
var result = PtrToStringUTF8(ptr);
193-
free(ptr);
194-
return result;
195-
}
196182
}
197183
}
198184
}

0 commit comments

Comments
 (0)