From 8eeb24ece919d11fcfc41144d27743a97c0b0791 Mon Sep 17 00:00:00 2001 From: Peter Honeder Date: Thu, 30 Jul 2015 16:53:35 +0200 Subject: [PATCH] added hostutil.h, added tests for hostutil, added more cmdline options to PS host --- CMakeLists.txt | 9 +++- host/cmdline/main.cpp | 53 +++++++++++++++++++++--- host/{cmdline => common}/coreclrutil.cpp | 4 ++ host/{cmdline => common}/coreclrutil.h | 0 host/common/hostutil.h | 48 +++++++++++++++++++++ tests/host/test-hostutil.cpp | 35 ++++++++++++++++ 6 files changed, 142 insertions(+), 7 deletions(-) rename host/{cmdline => common}/coreclrutil.cpp (96%) rename host/{cmdline => common}/coreclrutil.h (100%) create mode 100644 host/common/hostutil.h create mode 100644 tests/host/test-hostutil.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a7c35b542..a5d27e7bfc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,9 +9,11 @@ link_directories(${monad_native_BINARY_DIR}) # source file definitions set(LIB_SOURCE_FILES impl/getcurrentprocessorid.cpp impl/getusername.cpp impl/terminal.cpp) -set(TEST_SOURCE_FILES tests/test-getcurrentprocessid.cpp) +set(HOST_COMMON_SOURCE_FILES host/common/coreclrutil.cpp) +set(HOST_COMMON_TEST_SOURCE_FILES tests/host/test-hostutil.cpp) +set(TEST_SOURCE_FILES tests/test-getcurrentprocessid.cpp ${HOST_COMMON_SOURCE_FILES} ${HOST_COMMON_TEST_SOURCE_FILES}) set(SOURCE_FILES main.cpp ../ext-src/gtest/fused-src/gtest/gtest-all.cc) -SET(HOST_CMDLINE_SOURCE_FILES host/cmdline/main.cpp host/cmdline/coreclrutil.cpp) +SET(HOST_CMDLINE_SOURCE_FILES host/cmdline/main.cpp ${HOST_COMMON_SOURCE_FILES}) # target definitions add_library(ps SHARED ${LIB_SOURCE_FILES}) @@ -23,5 +25,8 @@ find_package(Threads) target_link_libraries(monad_native ${CMAKE_THREAD_LIBS_INIT} ps) target_link_libraries(host_cmdline dl icuuc) +# target specific include directories +target_include_directories(monad_native PRIVATE host) +target_include_directories(host_cmdline PRIVATE host) diff --git a/host/cmdline/main.cpp b/host/cmdline/main.cpp index 7793bf1439..740d99185c 100644 --- a/host/cmdline/main.cpp +++ b/host/cmdline/main.cpp @@ -1,6 +1,7 @@ #include #include -#include "coreclrutil.h" +#include "common/coreclrutil.h" +#include "common/hostutil.h" #include #include #include @@ -32,6 +33,7 @@ void printHelp() std::cerr << " + this assembly has to be located in the search path" << std::endl; std::cerr << "- by default the host will add the current working directory to the assembly search path" << std::endl; std::cerr << " + this can be overridden with the -s command line argument" << std::endl; + std::cerr << " + if -c is specified, it will be added to the search path instead of the current directory" << std::endl; std::cerr << "- by default the host assumes the PS base path for the assembly load context is the current" << std::endl; std::cerr << " working directory" << std::endl; std::cerr << " + this can be overridden with the -b command line argument" << std::endl; @@ -44,13 +46,17 @@ void printHelp() std::cerr << "-s a list of assembly search paths, separated by :" << std::endl; std::cerr << "-b the powershell assembly base path" << std::endl; std::cerr << "-v verbose output, show paths" << std::endl; + std::cerr << "-tpa additional list of trusted platform assemblies, this references dll and exe files" << std::endl; + std::cerr << " separated by :" << std::endl; + std::cerr << " unless part of the same folder as CoreCLR, the main assembly referenced with the assembly_name" << std::endl; + std::cerr << " argument, must always be added to the TPA list with this parameter" << std::endl; std::cerr << "assembly_name the assembly name of the assembly to execute" << std::endl; std::cerr << " must be available in the search path" << std::endl; std::cerr << "type_name the type name where the function can be found" << std::endl; std::cerr << "function_name the function to execute (must have the function signature described above!)" << std::endl; std::cerr << std::endl; std::cerr << "Example:" << std::endl; - std::cerr << "./host_cmdline -c /test/coreclr -alc /test/ps/Microsoft.PowerShell.CoreCLR.AssemblyLoadContext.dll -s /test/ps -b /test/ps 'powershell-simple, version=1.0.0.0, culture=neutral, PublicKeyToken=null' 'ps_hello_world.Program' 'UnmanagedMain' 'get-process'" << std::endl; + std::cerr << "./host_cmdline -c /test/coreclr -alc /test/ps/Microsoft.PowerShell.CoreCLR.AssemblyLoadContext.dll -s /test/ps -b /test/ps -tpa /test/ps/powershell-simple.exe 'powershell-simple, version=1.0.0.0, culture=neutral, PublicKeyToken=null' 'ps_hello_world.Program' 'UnmanagedMain' 'get-process'" << std::endl; } struct Args @@ -66,6 +72,7 @@ struct Args std::string assemblyLoadContextFilePath; std::string searchPaths; std::string basePath; + std::string tpaList; std::string entryAssemblyName; std::string entryTypeName; std::string entryFunctionName; @@ -80,6 +87,7 @@ struct Args std::cerr << "- assemblyLoadContextFilePath " << assemblyLoadContextFilePath << std::endl; std::cerr << "- searchPaths " << searchPaths << std::endl; std::cerr << "- basePath " << basePath << std::endl; + std::cerr << "- tpaList " << tpaList << std::endl; std::cerr << "- entryAssemblyName " << entryAssemblyName << std::endl; std::cerr << "- entryTypeName " << entryTypeName << std::endl; std::cerr << "- entryFunctionName " << entryFunctionName << std::endl; @@ -124,6 +132,11 @@ bool parseCmdline(const int argc, char** argv, Args& args) args.basePath = nextArg; ++i; } + else if (hasNextArg && arg == "-tpa") + { + args.tpaList = nextArg; + ++i; + } else if (arg == "-v") { args.verbose = true; @@ -145,6 +158,9 @@ bool parseCmdline(const int argc, char** argv, Args& args) // forward command line parameters args.argc = argc-i; args.argv = &argv[i]; + + // explicitly break here because the lines above consume all remaining arguments + break; } } @@ -200,6 +216,8 @@ int main(int argc, char** argv) std::cerr << "could not find absolute CLR path" << std::endl; return 1; } + if (args.verbose) + std::cerr << "clrAbsolutePath=" << clrAbsolutePath << std::endl; // the path to the CoreCLR library // @@ -225,7 +243,23 @@ int main(int argc, char** argv) CoreCLRUtil::AddFilesFromDirectoryToTpaList(clrAbsolutePath.c_str(),tpaList); if (args.assemblyLoadContextFilePath != "") - tpaList += ":" + args.assemblyLoadContextFilePath; + { + std::string assemblyLoadContextAbsoluteFilePath; + if (!CoreCLRUtil::GetAbsolutePath(args.assemblyLoadContextFilePath.c_str(),assemblyLoadContextAbsoluteFilePath)) + { + std::cerr << "Failed to get absolute file path for assembly load context" << std::endl; + return 1; + } + tpaList += ":" + assemblyLoadContextAbsoluteFilePath; + } + + // add the -tpa command line argument + if (args.tpaList != "") + { + std::string tpaAbsolutePathList = HostUtil::getAbsolutePathList(args.tpaList); + if (tpaAbsolutePathList != "") + tpaList += ":" + tpaAbsolutePathList; + } if (args.verbose) std::cerr << "tpaList: " << tpaList << std::endl; @@ -241,11 +275,18 @@ int main(int argc, char** argv) // assembly search paths // - // add the current directory and anything specified with the -s option + // add the current directory, and optionally the CoreCLR directory if -c was specified + // and anything specified with the -s option std::string appPath = currentDirAbsolutePath; + if (args.clrPath != "") + appPath += ":" + clrAbsolutePath; if (args.searchPaths != "") - appPath += ":" + args.searchPaths; + { + std::string searchAbsolutePathList = HostUtil::getAbsolutePathList(args.searchPaths); + if (searchAbsolutePathList != "") + appPath += ":" + searchAbsolutePathList; + } if (args.verbose) std::cerr << "appPath: " << appPath << std::endl; @@ -270,6 +311,8 @@ int main(int argc, char** argv) return 1; } } + if (args.verbose) + std::cerr << "psBasePath=" << psBasePath << std::endl; // make sure to leave 1 byte at the end for null termination std::basic_string psBasePath16(PATH_MAX+1,0); diff --git a/host/cmdline/coreclrutil.cpp b/host/common/coreclrutil.cpp similarity index 96% rename from host/cmdline/coreclrutil.cpp rename to host/common/coreclrutil.cpp index d67a1057f8..6aa8b9896a 100644 --- a/host/cmdline/coreclrutil.cpp +++ b/host/common/coreclrutil.cpp @@ -157,6 +157,10 @@ void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList) } closedir(dir); + + // strip any trailing : from the tpaList + if (tpaList.size() > 0 && tpaList[tpaList.size()-1] == ':') + tpaList.resize(tpaList.size()-1); } } // namespace CoreCLRUtil diff --git a/host/cmdline/coreclrutil.h b/host/common/coreclrutil.h similarity index 100% rename from host/cmdline/coreclrutil.h rename to host/common/coreclrutil.h diff --git a/host/common/hostutil.h b/host/common/hostutil.h new file mode 100644 index 0000000000..a8c9a208d3 --- /dev/null +++ b/host/common/hostutil.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include "common/coreclrutil.h" + +namespace HostUtil +{ + +//!\brief get a list of absolute paths separated by : from a list of relative/absolute paths separated by : +std::string getAbsolutePathList(const std::string& paths) +{ + //std::cerr << "getAbsolutePathList: paths=" << paths << std::endl; + std::string result; + + // split by : + size_t lastPos = 0; + size_t curPos = paths.find(':',lastPos); + do + { + const std::string token = paths.substr(lastPos,curPos-lastPos); + //std::cerr << "curPos=" << curPos << " lastPos=" << lastPos << " token=" << token << std::endl; + + // skip empty tokens + if (token != "") + { + std::string absolutePath; + if (CoreCLRUtil::GetAbsolutePath(token.c_str(),absolutePath)) + { + // add colons correctly + if (result.size() == 0) + result += absolutePath; + else + result += ":" + absolutePath; + } + } + + // increment lastPos to skip the : + lastPos += token.size() + 1; + curPos = paths.find(':',lastPos); + } + while (lastPos < paths.size()); + + return result; +} + +} + + diff --git a/tests/host/test-hostutil.cpp b/tests/host/test-hostutil.cpp new file mode 100644 index 0000000000..7a8b6b473b --- /dev/null +++ b/tests/host/test-hostutil.cpp @@ -0,0 +1,35 @@ +#include +#include "common/hostutil.h" + +TEST(HostUtilTest,simple) +{ + // syntactical corner cases + ASSERT_EQ("",HostUtil::getAbsolutePathList("")); + ASSERT_EQ("",HostUtil::getAbsolutePathList(":")); + ASSERT_EQ("",HostUtil::getAbsolutePathList("::")); + ASSERT_EQ("",HostUtil::getAbsolutePathList(":::::")); + + // current directory + char* cwd = get_current_dir_name(); + ASSERT_EQ(std::string(cwd),HostUtil::getAbsolutePathList(".")); + + // relative and absolute paths that don't exist + ASSERT_EQ("",HostUtil::getAbsolutePathList("/something/that/does/not/exist")); + ASSERT_EQ("",HostUtil::getAbsolutePathList(":/something/that/does/not/exist:")); + ASSERT_EQ("",HostUtil::getAbsolutePathList("something/relative/that/does/not/exist")); + ASSERT_EQ("",HostUtil::getAbsolutePathList(":something/relative/that/does/not/exist:")); + + // absolute existing paths + ASSERT_EQ("/tmp",HostUtil::getAbsolutePathList("/tmp")); + ASSERT_EQ("/tmp:/tmp",HostUtil::getAbsolutePathList("/tmp:/tmp")); + + // relative paths + chdir("/"); + ASSERT_EQ("/tmp",HostUtil::getAbsolutePathList("tmp")); + ASSERT_EQ("/tmp:/tmp",HostUtil::getAbsolutePathList("/tmp:tmp:")); + chdir(cwd); + + // cleanup + free(cwd); +} +