Powershell: On Unix, the .Target property should report a symlink's target path as defined, not resolved to a full path

Created on 6 Aug 2020  路  6Comments  路  Source: PowerShell/PowerShell

Following up from https://github.com/PowerShell/PowerShell/pull/13082#discussion_r466009551:

On Windows, the .Target property (an ETS property added to FileSystemInfo instances) has always returned a symlink's target _as defined in the link itself_ - which may be a relative or an absolute path.

On Unix, we currently unexpectedly resolve the target path to a _full_ path in .Target, with no ability to inspect the target path _as defined_.

Note: It would also be convenient to have a separate property that always reflects the _full_ path, irrespective of whether the symlink is defined with a relative or full target path - see #13366.

Steps to reproduce

On macOS or Linux:

Push-Location Temp:/

mkdir -p f$PID

# Define a symlink with  a *relative* target path.
New-Item -Type SymbolicLink f$PID_L -Target ./f$PID

# Querying .Target should return the target path *as defined*.
(Get-Item f$PID_L).Target | Should -Be ./f$PID

Remove-Item -Recurse f$PID, f$PID_L; Pop-Location

Expected behavior

The test should succeed.

Actual behavior

The test fails, because the target path is returned not as defined, but as a full path.

Environment data

PowerShell Core 7.1.0-preview.5
Issue-Bug WG-Engine-Providers

Most helpful comment

Thanks, @iSazonov, I've added a suggestion to add a System.IO.Path.GetFullPath() overload for canonical path resolution there: https://github.com/dotnet/runtime/issues/24271#issuecomment-670709364

All 6 comments

There is a problem with Target property on Unix-s. We call FollowSymLink() that is a native code from PowerShell-Native (libpsl-native)
https://github.com/PowerShell/PowerShell-Native/blob/7b7b889e8a331fd0ea47082d5edbf80402ea51ad/src/libpsl-native/src/followsymlink.cpp#L39-L47

Docs explicitly say that realpath() always returns absolute path.

It is should be fixed in psl (PowerShell-Native repository) and we need an approve from @adityapatwardhan .

GitHub
Contribute to PowerShell/PowerShell-Native development by creating an account on GitHub.

@iSazonov, looks like the FollowSymLink() function needs another, optional argument that specifies whether realpath() should be called for resolution to a full path (or, alternatively, introduce a separate ReadSymLink() function).

If not, a call to readlink() is sufficient , which FollowSymLink() already does - but only _as a fallback_ (if the target path doesn't exist).

If we think about a script users will use either Target or ResolvedTarget but not both. In the case I'd add new p/invoke FollowSymLinkResolved().
I don't know whether we need this or no but if we need we could resolve the full path in C# without complication psl.

It certainly would be nice to have cross-platform realpath() functionality available in .NET itself, and to surface that via Convert-Path, as suggested in #10640 - I never got around to asking in the dotnet repo for such an API.

I never got around to asking in the dotnet repo for such an API

There is an issue to add symlink support - you can share thoughts there.

Thanks, @iSazonov, I've added a suggestion to add a System.IO.Path.GetFullPath() overload for canonical path resolution there: https://github.com/dotnet/runtime/issues/24271#issuecomment-670709364

Was this page helpful?
0 / 5 - 0 ratings