new native code and test for obtaining target of symlinks
This commit is contained in:
parent
86801f0457
commit
454524cf72
@ -8,6 +8,7 @@ add_library(psl-native SHARED
|
||||
isexecutable.cpp
|
||||
setdate.cpp
|
||||
createhardlink.cpp
|
||||
createsymlink.cpp)
|
||||
createsymlink.cpp
|
||||
followsymlink.cpp)
|
||||
|
||||
target_include_directories(psl-native PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
90
src/followsymlink.cpp
Normal file
90
src/followsymlink.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
//! @file followSymLink.cpp
|
||||
//! @author George FLeming <v-geflem@microsoft.com>
|
||||
//! @brief returns whether a path is a symbolic link
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "followsymlink.h"
|
||||
|
||||
//! @brief Followsymlink determines target path of a sym link
|
||||
//!
|
||||
//! Followsymlink
|
||||
//!
|
||||
//! @param[in] fileName
|
||||
//! @parblock
|
||||
//! A pointer to the buffer that contains the file name
|
||||
//!
|
||||
//! char* is marshaled as an LPStr, which on Linux is UTF-8.
|
||||
//! @endparblock
|
||||
//!
|
||||
//! @exception errno Passes these errors via errno to GetLastError:
|
||||
//! - ERROR_INVALID_PARAMETER: parameter is not valid
|
||||
//! - ERROR_FILE_NOT_FOUND: file does not exist
|
||||
//! - ERROR_ACCESS_DENIED: access is denied
|
||||
//! - ERROR_INVALID_ADDRESS: attempt to access invalid address
|
||||
//! - ERROR_STOPPED_ON_SYMLINK: too many symbolic links
|
||||
//! - ERROR_GEN_FAILURE: I/O error occurred
|
||||
//! - ERROR_INVALID_NAME: file provided is not a symbolic link
|
||||
//! - ERROR_INVALID_FUNCTION: incorrect function
|
||||
//! - ERROR_BAD_PATH_NAME: pathname is too long
|
||||
//! - ERROR_OUTOFMEMORY insufficient kernal memory
|
||||
//!
|
||||
//! @retval target path, or NULL if unsuccessful
|
||||
//!
|
||||
|
||||
char* FollowSymLink(const char* fileName)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
// Check parameters
|
||||
if (!fileName)
|
||||
{
|
||||
errno = ERROR_INVALID_PARAMETER;
|
||||
return 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;
|
||||
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);
|
||||
}
|
9
src/followsymlink.h
Normal file
9
src/followsymlink.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "pal.h"
|
||||
|
||||
PAL_BEGIN_EXTERNC
|
||||
|
||||
char* FollowSymLink(const char* fileName);
|
||||
|
||||
PAL_END_EXTERNC
|
@ -1,12 +1,13 @@
|
||||
//! @file test-issymlink.cpp
|
||||
//! @file test-createsymlink.cpp
|
||||
//! @author George Fleming <v-geflem@microsoft.com>
|
||||
//! @brief Implements test for isSymLink()
|
||||
//! @brief Implements test for CreateSymLink() and FollowSymLink()
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include "issymlink.h"
|
||||
#include "createsymlink.h"
|
||||
#include "followsymlink.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -84,6 +85,9 @@ TEST_F(CreateSymLinkTest, FilePathNameDoesNotExist)
|
||||
int retVal = CreateSymLink(invalidLink.c_str(), invalidFile.c_str());
|
||||
EXPECT_EQ(retVal, 1);
|
||||
|
||||
std::string target = FollowSymLink(invalidLink.c_str());
|
||||
EXPECT_EQ(target, invalidFile);
|
||||
|
||||
unlink(invalidLink.c_str());
|
||||
}
|
||||
|
||||
@ -91,12 +95,18 @@ TEST_F(CreateSymLinkTest, SymLinkToFile)
|
||||
{
|
||||
int retVal = IsSymLink(fileSymLink.c_str());
|
||||
EXPECT_EQ(1, retVal);
|
||||
|
||||
std::string target = FollowSymLink(fileSymLink.c_str());
|
||||
EXPECT_EQ(target, file);
|
||||
}
|
||||
|
||||
TEST_F(CreateSymLinkTest, SymLinkToDirectory)
|
||||
{
|
||||
int retVal = IsSymLink(dirSymLink.c_str());
|
||||
EXPECT_EQ(1, retVal);
|
||||
|
||||
std::string target = FollowSymLink(dirSymLink.c_str());
|
||||
EXPECT_EQ(target, dir);
|
||||
}
|
||||
|
||||
TEST_F(CreateSymLinkTest, SymLinkAgain)
|
||||
|
Loading…
Reference in New Issue
Block a user