Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

realpath in c# #45637

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 0 additions & 70 deletions src/Cli/dotnet/StatInterop.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private IEnumerable<string> SearchPaths
}

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

if (dotnetExeFromPath != null && !Interop.RunningOnWindows)
#if NET
if (dotnetExeFromPath != null && !OperatingSystem.IsWindows())
{
// e.g. on Linux the 'dotnet' command from PATH is a symlink so we need to
// resolve it to get the actual path to the binary
dotnetExeFromPath = Interop.Unix.realpath(dotnetExeFromPath) ?? dotnetExeFromPath;
dotnetExeFromPath = GetRealPath(dotnetExeFromPath);

static string GetRealPath(string path)
{
FileInfo fileInfo = new FileInfo(path);
if (fileInfo.LinkTarget != null)
{
var resolved = fileInfo.ResolveLinkTarget(true);
return resolved?.Exists is true ? resolved.FullName : path;
}

string invariantPart = string.Empty;
DirectoryInfo? parentDirectory = fileInfo.Directory;
while (parentDirectory is not null)
{
invariantPart = path[parentDirectory.FullName.Length..];
if (parentDirectory.LinkTarget != null)
{
var resolved = parentDirectory.ResolveLinkTarget(true);
if (resolved?.Exists is true)
return Path.Join(resolved.FullName, invariantPart);
}

parentDirectory = parentDirectory.Parent;
}

return path;
}
}
#endif

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

#if !NETCOREAPP
#if !NET
// If we failed to find dotnet on PATH, we revert to the old behavior of returning the current process
// path. This is really an error state but we're keeping the contract of always returning a non-empty
// path for backward compatibility.
Expand Down Expand Up @@ -123,7 +152,7 @@ private IEnumerable<string> SearchPaths
private static string? GetCurrentProcessPath()
{
string? currentProcessPath;
#if NET6_0_OR_GREATER
#if NET
currentProcessPath = Environment.ProcessPath;
#else
currentProcessPath = Process.GetCurrentProcess().MainModule.FileName;
Expand Down
16 changes: 1 addition & 15 deletions src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static Interop()
}

// MSBuild SDK resolvers are required to be AnyCPU, but we have a native dependency and .NETFramework does not
// have a built-in facility for dynamically loading user native dlls for the appropriate platform. We therefore
// have a built-in facility for dynamically loading user native dlls for the appropriate platform. We therefore
// preload the version with the correct architecture (from a corresponding sub-folder relative to us) on static
// construction so that subsequent P/Invokes can find it.
private static void PreloadWindowsLibrary(string dllFileName)
Expand Down Expand Up @@ -179,20 +179,6 @@ internal delegate void hostfxr_get_available_sdks_result_fn(
internal static extern int hostfxr_get_available_sdks(
string? exe_dir,
hostfxr_get_available_sdks_result_fn result);

[DllImport("libc", CharSet = UTF8, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr realpath(string path, IntPtr buffer);

[DllImport("libc", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern void free(IntPtr ptr);

public static string? realpath(string path)
{
var ptr = realpath(path, IntPtr.Zero);
var result = PtrToStringUTF8(ptr);
free(ptr);
return result;
}
}
}
}
Loading