Clean up IsExecutable and IsSymLink

This commit is contained in:
Andrew Schwartzmeyer
2016-07-14 17:34:12 -07:00
parent 4e518fe1c7
commit e89fa7b1dc
7 changed files with 56 additions and 120 deletions
@@ -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)]
+8 -50
View File
@@ -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;
}
+2 -1
View File
@@ -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
+12 -15
View File
@@ -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);
}
+2 -1
View File
@@ -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
+10 -20
View File
@@ -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));
}
+16 -31
View 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()));
}