mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Clean up IsExecutable and IsSymLink
This commit is contained in:
@@ -700,6 +700,8 @@ namespace System.Management.Automation
|
||||
|
||||
// Ansi is a misnomer, it is hardcoded to UTF-8 on Linux and OS X
|
||||
|
||||
// C bools are 1 byte and so must be marshaled as I1
|
||||
|
||||
[DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.LPStr)]
|
||||
internal static extern string GetUserName();
|
||||
@@ -708,10 +710,12 @@ namespace System.Management.Automation
|
||||
internal static extern int GetLinkCount([MarshalAs(UnmanagedType.LPStr)]string filePath, out int linkCount);
|
||||
|
||||
[DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
internal static extern int IsSymLink([MarshalAs(UnmanagedType.LPStr)]string filePath);
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
internal static extern bool IsSymLink([MarshalAs(UnmanagedType.LPStr)]string filePath);
|
||||
|
||||
[DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
internal static extern int IsExecutable([MarshalAs(UnmanagedType.LPStr)]string filePath);
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
internal static extern bool IsExecutable([MarshalAs(UnmanagedType.LPStr)]string filePath);
|
||||
|
||||
[DllImport(psLib, CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.LPStr)]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! @file isExecutable.cpp
|
||||
//! @author George FLeming <v-geflem@microsoft.com>
|
||||
//! @file isexecutable.cpp
|
||||
//! @author George Fleming <v-geflem@microsoft.com>
|
||||
//! @brief returns whether a file is executable
|
||||
|
||||
#include <errno.h>
|
||||
@@ -11,7 +11,7 @@
|
||||
//!
|
||||
//! IsExecutable
|
||||
//!
|
||||
//! @param[in] fileName
|
||||
//! @param[in] path
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
@@ -19,63 +19,21 @@
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @exception errno Passes these errors via errno to GetLastError:
|
||||
//! - ERROR_FILE_NOT_FOUND: the system cannot find the file specified
|
||||
//! - ERROR_INVALID_ADDRESS: attempt to access invalid address
|
||||
//! - ERROR_GEN_FAILURE: device attached to the system is not functioning
|
||||
//! - ERROR_INVALID_NAME: filename, directory name, or volume label syntax is incorrect
|
||||
//! - ERROR_INVALID_FUNCTION: incorrect function
|
||||
//! - ERROR_INVALID_PARAMETER: parameter to access(2) call is incorrect
|
||||
//!
|
||||
//! @retval 1 if path is an executable
|
||||
//! @retval 0 if path is not a executable
|
||||
//! @retval -1 If the function fails.. To get extended error information, call GetLastError.
|
||||
//! @retval true if path is an executable, false otherwise
|
||||
//!
|
||||
|
||||
int32_t IsExecutable(const char* fileName)
|
||||
bool IsExecutable(const char* path)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
// Check parameters
|
||||
if (!fileName)
|
||||
if (!path)
|
||||
{
|
||||
errno = ERROR_INVALID_PARAMETER;
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
int returnCode = access(fileName, X_OK);
|
||||
|
||||
if (returnCode == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch(errno)
|
||||
{
|
||||
case EACCES:
|
||||
return 0;
|
||||
case EBADF:
|
||||
case ENOENT:
|
||||
errno = ERROR_FILE_NOT_FOUND;
|
||||
break;
|
||||
case EFAULT:
|
||||
errno = ERROR_INVALID_ADDRESS;
|
||||
break;
|
||||
case ELOOP:
|
||||
errno = ERROR_STOPPED_ON_SYMLINK;
|
||||
break;
|
||||
case EIO:
|
||||
case ENOMEM:
|
||||
errno = ERROR_GEN_FAILURE;
|
||||
break;
|
||||
case ENOTDIR:
|
||||
case ENAMETOOLONG:
|
||||
errno = ERROR_INVALID_NAME;
|
||||
break;
|
||||
case EINVAL:
|
||||
errno = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
default:
|
||||
errno = ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
return -1;
|
||||
return access(path, X_OK) != -1;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
int32_t IsExecutable(const char* fileName);
|
||||
bool IsExecutable(const char* path);
|
||||
|
||||
PAL_END_EXTERNC
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
#include <string>
|
||||
#include "issymlink.h"
|
||||
|
||||
//! @brief IsSymLink determines if path is a symbolic link
|
||||
//! @brief IsSymlink determines if path is a symbolic link
|
||||
//!
|
||||
//! IsSymLink
|
||||
//! IsSymlink
|
||||
//!
|
||||
//! @param[in] fileName
|
||||
//! @param[in] path
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
@@ -34,28 +34,25 @@
|
||||
//! - ERROR_INVALID_FUNCTION: incorrect function
|
||||
//! - ERROR_BAD_PATH_NAME: pathname is too long, or contains invalid characters
|
||||
//!
|
||||
//! @retval 1 if path is a symbolic link
|
||||
//! @retval 0 if path is not a symbolic link
|
||||
//! @retval -1 If the function fails.. To get extended error information, call GetLastError.
|
||||
//! @retval true if path is a symbolic link, false otherwise
|
||||
//!
|
||||
|
||||
int32_t IsSymLink(const char* fileName)
|
||||
bool IsSymLink(const char* path)
|
||||
{
|
||||
|
||||
errno = 0;
|
||||
errno = 0;
|
||||
|
||||
// Check parameters
|
||||
if (!fileName)
|
||||
if (!path)
|
||||
{
|
||||
errno = ERROR_INVALID_PARAMETER;
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat statBuf;
|
||||
|
||||
int returnCode = lstat(fileName, &statBuf);
|
||||
int ret = lstat(path, &statBuf);
|
||||
|
||||
if (returnCode != 0)
|
||||
if (ret != 0)
|
||||
{
|
||||
switch(errno)
|
||||
{
|
||||
@@ -89,8 +86,8 @@ int32_t IsSymLink(const char* fileName)
|
||||
default:
|
||||
errno = ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return S_ISLNK(statBuf.st_mode) ? 1 : 0;
|
||||
return S_ISLNK(statBuf.st_mode);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
int32_t IsSymLink(const char* fileName);
|
||||
bool IsSymLink(const char* path);
|
||||
|
||||
PAL_END_EXTERNC
|
||||
|
||||
@@ -33,62 +33,52 @@ protected:
|
||||
// First create a file
|
||||
int fd = mkstemp(fileTemplateBuf);
|
||||
EXPECT_TRUE(fd != -1);
|
||||
file = fileTemplateBuf;
|
||||
file = fileTemplateBuf;
|
||||
}
|
||||
|
||||
~IsExecutableTest()
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = unlink(file);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_FALSE(unlink(file));
|
||||
}
|
||||
|
||||
void ChangeFilePermission(const char* file, mode_t mode)
|
||||
{
|
||||
int ret = chmod(file, mode);
|
||||
EXPECT_EQ(ret, 0);
|
||||
EXPECT_FALSE(chmod(file, mode));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(IsExecutableTest, FilePathNameIsNull)
|
||||
{
|
||||
int32_t retVal = IsExecutable(NULL);
|
||||
EXPECT_EQ(retVal, -1);
|
||||
EXPECT_FALSE(IsExecutable(NULL));
|
||||
EXPECT_EQ(ERROR_INVALID_PARAMETER, errno);
|
||||
}
|
||||
|
||||
TEST_F(IsExecutableTest, FilePathNameDoesNotExist)
|
||||
{
|
||||
std::string invalidFile = "/tmp/isexecutabletest_invalidFile";
|
||||
int32_t retVal = IsExecutable(invalidFile.c_str());
|
||||
EXPECT_EQ(retVal, -1);
|
||||
EXPECT_FALSE(IsExecutable(invalidFile.c_str()));
|
||||
EXPECT_EQ(ERROR_FILE_NOT_FOUND, errno);
|
||||
}
|
||||
|
||||
TEST_F(IsExecutableTest, NormalFileIsNotIsexecutable)
|
||||
{
|
||||
int32_t retVal = IsExecutable(file);
|
||||
EXPECT_EQ(0, retVal);
|
||||
|
||||
EXPECT_FALSE(IsExecutable(file));
|
||||
|
||||
ChangeFilePermission(file, mode_444);
|
||||
|
||||
retVal = IsExecutable(file);
|
||||
EXPECT_EQ(0, retVal);
|
||||
EXPECT_FALSE(IsExecutable(file));
|
||||
}
|
||||
|
||||
TEST_F(IsExecutableTest, FilePermission_700)
|
||||
{
|
||||
ChangeFilePermission(file, mode_700);
|
||||
|
||||
int32_t retVal = IsExecutable(file);
|
||||
EXPECT_EQ(1, retVal);
|
||||
EXPECT_TRUE(IsExecutable(file));
|
||||
}
|
||||
|
||||
TEST_F(IsExecutableTest, FilePermission_777)
|
||||
{
|
||||
ChangeFilePermission(file, mode_777);
|
||||
|
||||
int32_t retVal = IsExecutable(file);
|
||||
EXPECT_EQ(1, retVal);
|
||||
EXPECT_TRUE(IsExecutable(file));
|
||||
}
|
||||
|
||||
@@ -30,75 +30,60 @@ protected:
|
||||
// First create a file
|
||||
int fd = mkstemp(fileTemplateBuf);
|
||||
EXPECT_TRUE(fd != -1);
|
||||
file = fileTemplateBuf;
|
||||
file = fileTemplateBuf;
|
||||
|
||||
// Create a temp directory
|
||||
dir = mkdtemp(dirTemplateBuf);
|
||||
// Create a temp directory
|
||||
dir = mkdtemp(dirTemplateBuf);
|
||||
EXPECT_TRUE(dir != NULL);
|
||||
|
||||
// Create symbolic link to file
|
||||
int ret1 = symlink(file, fileSymLink.c_str());
|
||||
EXPECT_EQ(ret1, 0);
|
||||
|
||||
EXPECT_FALSE(symlink(file, fileSymLink.c_str()));
|
||||
|
||||
// Create symbolic link to directory
|
||||
int ret2 = symlink(dir, dirSymLink.c_str());
|
||||
EXPECT_EQ(ret2, 0);
|
||||
EXPECT_FALSE(symlink(dir, dirSymLink.c_str()));
|
||||
}
|
||||
|
||||
~isSymLinkTest()
|
||||
{
|
||||
int ret;
|
||||
EXPECT_FALSE(unlink(fileSymLink.c_str()));
|
||||
|
||||
ret = unlink(fileSymLink.c_str());
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_FALSE(unlink(dirSymLink.c_str()));
|
||||
|
||||
ret = unlink(dirSymLink.c_str());
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_FALSE(unlink(file));
|
||||
|
||||
ret = unlink(file);
|
||||
EXPECT_EQ(0, ret);
|
||||
|
||||
ret = rmdir(dir);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_FALSE(rmdir(dir));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(isSymLinkTest, FilePathNameIsNull)
|
||||
{
|
||||
int retVal = IsSymLink(NULL);
|
||||
EXPECT_EQ(retVal, -1);
|
||||
EXPECT_FALSE(IsSymLink(NULL));
|
||||
EXPECT_EQ(ERROR_INVALID_PARAMETER, errno);
|
||||
}
|
||||
|
||||
TEST_F(isSymLinkTest, FilePathNameDoesNotExist)
|
||||
{
|
||||
std::string invalidFile = "/tmp/symlinktest_invalidFile";
|
||||
int retVal = IsSymLink(invalidFile.c_str());
|
||||
EXPECT_EQ(retVal, -1);
|
||||
EXPECT_FALSE(IsSymLink(invalidFile.c_str()));
|
||||
EXPECT_EQ(ERROR_FILE_NOT_FOUND, errno);
|
||||
}
|
||||
|
||||
TEST_F(isSymLinkTest, NormalFileIsNotSymLink)
|
||||
{
|
||||
int retVal = IsSymLink(file);
|
||||
EXPECT_EQ(0, retVal);
|
||||
EXPECT_FALSE(IsSymLink(file));
|
||||
}
|
||||
|
||||
TEST_F(isSymLinkTest, SymLinkToFile)
|
||||
{
|
||||
int retVal = IsSymLink(fileSymLink.c_str());
|
||||
EXPECT_EQ(1, retVal);
|
||||
EXPECT_TRUE(IsSymLink(fileSymLink.c_str()));
|
||||
}
|
||||
|
||||
TEST_F(isSymLinkTest, NormalDirectoryIsNotSymbLink)
|
||||
{
|
||||
int retVal = IsSymLink(dir);
|
||||
EXPECT_EQ(0, retVal);
|
||||
EXPECT_FALSE(IsSymLink(dir));
|
||||
}
|
||||
|
||||
TEST_F(isSymLinkTest, SymLinkToDirectory)
|
||||
{
|
||||
int retVal = IsSymLink(dirSymLink.c_str());
|
||||
EXPECT_EQ(1, retVal);
|
||||
EXPECT_TRUE(IsSymLink(dirSymLink.c_str()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user