mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Merge pull request #1264 from PowerShell/childitem
Fixing symlink to use absolute paths instead of relative
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "followsymlink.h"
|
||||
#include "issymlink.h"
|
||||
|
||||
//! @brief Followsymlink determines target path of a sym link
|
||||
//!
|
||||
@@ -38,53 +39,122 @@ char* FollowSymLink(const char* fileName)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
// Check parameters
|
||||
// if filename is null, return null value
|
||||
if (!fileName)
|
||||
{
|
||||
errno = ERROR_INVALID_PARAMETER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char buffer[PATH_MAX];
|
||||
ssize_t sz = readlink(fileName, buffer, PATH_MAX);
|
||||
|
||||
if (sz == -1)
|
||||
//if lstat in IsSymLink returns -1, path does not exist
|
||||
if (IsSymLink(fileName) == -1)
|
||||
{
|
||||
switch(errno)
|
||||
{
|
||||
case EACCES:
|
||||
errno = ERROR_ACCESS_DENIED;
|
||||
break;
|
||||
case EFAULT:
|
||||
errno = ERROR_INVALID_ADDRESS;
|
||||
break;
|
||||
case EINVAL:
|
||||
errno = ERROR_INVALID_NAME;
|
||||
break;
|
||||
case EIO:
|
||||
errno = ERROR_GEN_FAILURE;
|
||||
break;
|
||||
case ELOOP:
|
||||
errno = ERROR_STOPPED_ON_SYMLINK;
|
||||
break;
|
||||
case ENAMETOOLONG:
|
||||
errno = ERROR_BAD_PATH_NAME;
|
||||
break;
|
||||
case ENOENT:
|
||||
errno = ERROR_FILE_NOT_FOUND;
|
||||
break;
|
||||
case ENOMEM:
|
||||
errno = ERROR_OUTOFMEMORY;
|
||||
break;
|
||||
case ENOTDIR:
|
||||
errno = ERROR_BAD_PATH_NAME;
|
||||
break;
|
||||
default:
|
||||
errno = ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer[sz] = '\0';
|
||||
return strndup(buffer, sz + 1);
|
||||
/*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/
|
||||
if (IsSymLink(fileName))
|
||||
{
|
||||
//Attempt to resolve with the absolute filepath
|
||||
char actualpath[PATH_MAX+1];
|
||||
char* realPath = realpath(fileName, actualpath);
|
||||
|
||||
//if realPath is null, go onto the readlink implementation
|
||||
if (realPath == NULL)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
ssize_t sz = readlink(fileName, buffer, PATH_MAX);
|
||||
|
||||
if (sz == -1)
|
||||
{
|
||||
switch(errno)
|
||||
{
|
||||
case EACCES:
|
||||
errno = ERROR_ACCESS_DENIED;
|
||||
break;
|
||||
case EFAULT:
|
||||
errno = ERROR_INVALID_ADDRESS; /*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/
|
||||
break;
|
||||
case EINVAL:
|
||||
errno = ERROR_INVALID_NAME;
|
||||
case EIO:
|
||||
errno = ERROR_GEN_FAILURE;
|
||||
break;
|
||||
case ELOOP:
|
||||
errno = ERROR_STOPPED_ON_SYMLINK;
|
||||
break;
|
||||
case ENAMETOOLONG:
|
||||
errno = ERROR_BAD_PATH_NAME;
|
||||
break;
|
||||
case ENOENT:
|
||||
errno = ERROR_FILE_NOT_FOUND;
|
||||
break;
|
||||
case ENOMEM:
|
||||
errno = ERROR_OUTOFMEMORY;
|
||||
break;
|
||||
case ENOTDIR:
|
||||
errno = ERROR_BAD_PATH_NAME;
|
||||
break;
|
||||
default:
|
||||
errno = ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer[sz] = '\0';
|
||||
return strndup(buffer, sz + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return strndup(realPath, strlen(realPath) + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
ssize_t sz = readlink(fileName, buffer, PATH_MAX);
|
||||
|
||||
if (sz == -1)
|
||||
{
|
||||
switch(errno)
|
||||
{
|
||||
case EACCES:
|
||||
errno = ERROR_ACCESS_DENIED;
|
||||
break;
|
||||
case EFAULT:
|
||||
errno = ERROR_INVALID_ADDRESS; /*If the path is a symlink, the function return the absolute filepath if valid. if not valid, return null*/
|
||||
break;
|
||||
case EINVAL:
|
||||
errno = ERROR_INVALID_NAME;
|
||||
case EIO:
|
||||
errno = ERROR_GEN_FAILURE;
|
||||
break;
|
||||
case ELOOP:
|
||||
errno = ERROR_STOPPED_ON_SYMLINK;
|
||||
break;
|
||||
case ENAMETOOLONG:
|
||||
errno = ERROR_BAD_PATH_NAME;
|
||||
break;
|
||||
case ENOENT:
|
||||
errno = ERROR_FILE_NOT_FOUND;
|
||||
break;
|
||||
case ENOMEM:
|
||||
errno = ERROR_OUTOFMEMORY;
|
||||
break;
|
||||
case ENOTDIR:
|
||||
errno = ERROR_BAD_PATH_NAME;
|
||||
break;
|
||||
default:
|
||||
errno = ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer[sz] = '\0';
|
||||
return strndup(buffer, sz + 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ Describe "New-Item" {
|
||||
It "Should create a file without error" {
|
||||
New-Item -Name $testfile -Path $tmpDirectory -ItemType file
|
||||
|
||||
Test-Path $FullyQualifiedFile | Should Be $true
|
||||
Test-Path $FullyQualifiedFile | Should Be $true
|
||||
|
||||
$fileInfo = Get-ChildItem $FullyQualifiedFile
|
||||
$fileInfo.Target | Should Be $null
|
||||
@@ -105,14 +105,14 @@ Describe "New-Item" {
|
||||
}
|
||||
|
||||
It "Should create a symbolic link of a file without error" {
|
||||
New-Item -Name $testfile -Path $tmpDirectory -ItemType file
|
||||
Test-Path $FullyQualifiedFile | Should Be $true
|
||||
New-Item -Name $testfile -Path $tmpDirectory -ItemType file
|
||||
Test-Path $FullyQualifiedFile | Should Be $true
|
||||
|
||||
New-Item -ItemType SymbolicLink -Target $FullyQualifiedFile -Name $testlink -Path $tmpDirectory
|
||||
Test-Path $FullyQualifiedLink | Should Be $true
|
||||
New-Item -ItemType SymbolicLink -Target $FullyQualifiedFile -Name $testlink -Path $tmpDirectory
|
||||
Test-Path $FullyQualifiedLink | Should Be $true
|
||||
|
||||
$fileInfo = Get-ChildItem $FullyQualifiedLink
|
||||
$fileInfo.Target | Should Be $FullyQualifiedFile
|
||||
$fileInfo.Target | Should Match ([regex]::Escape($FullyQualifiedFile))
|
||||
$fileInfo.LinkType | Should Be "SymbolicLink"
|
||||
}
|
||||
|
||||
@@ -128,18 +128,18 @@ Describe "New-Item" {
|
||||
}
|
||||
|
||||
It "Should create a symbolic link from directory without error" {
|
||||
New-Item -Name $testFolder -Path $tmpDirectory -ItemType directory
|
||||
Test-Path $FullyQualifiedFolder | Should Be $true
|
||||
New-Item -Name $testFolder -Path $tmpDirectory -ItemType directory
|
||||
Test-Path $FullyQualifiedFolder | Should Be $true
|
||||
|
||||
New-Item -ItemType SymbolicLink -Target $FullyQualifiedFolder -Name $testlink -Path $tmpDirectory
|
||||
Test-Path $FullyQualifiedLink | Should Be $true
|
||||
New-Item -ItemType SymbolicLink -Target $FullyQualifiedFolder -Name $testlink -Path $tmpDirectory
|
||||
Test-Path $FullyQualifiedLink | Should Be $true
|
||||
|
||||
$fileInfo = Get-ChildItem $FullyQualifiedLink
|
||||
$fileInfo.Target | Should Be $FullyQualifiedFolder
|
||||
$fileInfo.Target | Should Match ([regex]::Escape($FullyQualifiedFolder))
|
||||
$fileInfo.LinkType | Should Be "SymbolicLink"
|
||||
|
||||
# Remove the link explicitly to avoid broken symlink issue
|
||||
Remove-Item $FullyQualifiedLink -Force
|
||||
# Remove the link explicitly to avoid broken symlink issue
|
||||
Remove-Item $FullyQualifiedLink -Force
|
||||
}
|
||||
|
||||
It "Should create a hard link of a file without error" {
|
||||
@@ -154,6 +154,4 @@ Describe "New-Item" {
|
||||
$fileInfo.LinkType | Should Be "HardLink"
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user