fix build on windows

This commit is contained in:
Joseph Aquino 2026-01-02 22:36:20 -05:00
parent 328b96a33e
commit e1500b8e6d
3 changed files with 58 additions and 44 deletions

View File

@ -14,6 +14,7 @@ target_include_directories(shell PRIVATE include)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows") if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT shell) set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT shell)
target_compile_definitions(shell PRIVATE _CRT_SECURE_NO_WARNINGS)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
endif() endif()

View File

@ -92,8 +92,11 @@ int main()
result = sh::isExec(tokens[0]); result = sh::isExec(tokens[0]);
if (result) if (result)
{ {
std::vector<char*> args; std::string filename = result.value().filename().string();
args.push_back(const_cast<char*>(result.value().filename().c_str()));// have exe path on seperate element for execv std::string fullPath = result.value().string();
#ifdef _WIN32
std::vector<const char*> args;
args.push_back(filename.c_str());// have exe path on seperate element for _spawnv
for (size_t i = 1; i < tokens.size(); i++) for (size_t i = 1; i < tokens.size(); i++)
{ {
@ -101,8 +104,8 @@ int main()
} }
args.push_back(nullptr); args.push_back(nullptr);
#ifdef _WIN32
intptr_t status = _spawnv(_P_WAIT, result.value().c_str(), args.data()); intptr_t status = _spawnv(_P_WAIT, fullPath.c_str(), args.data());
if (status == -1) if (status == -1)
{ {
@ -110,6 +113,15 @@ int main()
return 1; return 1;
} }
#else #else
std::vector<char*> args;
args.push_back(const_cast<char*>(filename.c_str()));// have exe path on seperate element for execv
for (size_t i = 1; i < tokens.size(); i++)
{
args.push_back(const_cast<char*>(tokens[i].c_str()));
}
args.push_back(nullptr);
pid_t pid = fork(); pid_t pid = fork();
if (pid == 0) if (pid == 0)
{// child process {// child process

View File

@ -96,14 +96,16 @@ namespace sh
std::optional<std::filesystem::path> isExec(const std::string& input) std::optional<std::filesystem::path> isExec(const std::string& input)
{ {
std::string pathEnv{ std::getenv("PATH") };
std::string pathEnv {std::getenv("PATH")};
#ifdef _WIN32 #ifdef _WIN32
constexpr char delimiter {';'}; constexpr char delimiter{';'};
// windows executable extensions
const std::vector<std::string> extensions{ "", ".exe", ".bat", ".cmd", ".com" };
#else #else
constexpr char delimiter {':'}; constexpr char delimiter{':'};
const std::vector<std::string> extensions{""};
#endif #endif
//add our current path, put a delimiter so std::string::find doesn't skip the last token
pathEnv.append(1, delimiter); pathEnv.append(1, delimiter);
pathEnv.append(std::filesystem::current_path().string()); pathEnv.append(std::filesystem::current_path().string());
pathEnv.append(1, delimiter); pathEnv.append(1, delimiter);
@ -114,28 +116,27 @@ namespace sh
while (nextDelimIndex != std::string::npos) while (nextDelimIndex != std::string::npos)
{ {
std::filesystem::path basePath = pathEnv.substr(startCharIndex, nextDelimIndex - startCharIndex);
currentPath = pathEnv.substr(startCharIndex, nextDelimIndex - startCharIndex); for (const auto& ext : extensions)
currentPath /= input; {
currentPath = basePath / (input + ext);
namespace fs = std::filesystem; namespace fs = std::filesystem;
if (!fs::exists(currentPath)) if (fs::exists(currentPath))
{ {
startCharIndex = nextDelimIndex + 1;
nextDelimIndex = pathEnv.find(delimiter, startCharIndex);
continue;
}
if ((fs::status(currentPath).permissions() & fs::perms::owner_exec) != fs::perms::owner_exec) if ((fs::status(currentPath).permissions() & fs::perms::owner_exec) != fs::perms::owner_exec)
{// fullPath exists but cant executed {
startCharIndex = nextDelimIndex + 1;
nextDelimIndex = pathEnv.find(delimiter, startCharIndex);
continue; continue;
} }
return currentPath; return currentPath;
} }
}
startCharIndex = nextDelimIndex + 1;
nextDelimIndex = pathEnv.find(delimiter, startCharIndex);
}
return std::nullopt; return std::nullopt;
} }