From e1500b8e6d9f37cd278cc3105810ca02c163d422 Mon Sep 17 00:00:00 2001 From: Joseph Aquino Date: Fri, 2 Jan 2026 22:36:20 -0500 Subject: [PATCH] fix build on windows --- CMakeLists.txt | 1 + src/main.cpp | 32 ++++++++++++++------- src/shellUtils.cpp | 69 +++++++++++++++++++++++----------------------- 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fef876..21013e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ target_include_directories(shell PRIVATE include) if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set_property(GLOBAL PROPERTY USE_FOLDERS ON) 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") endif() diff --git a/src/main.cpp b/src/main.cpp index f88e21d..2b42e0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -92,17 +92,20 @@ int main() result = sh::isExec(tokens[0]); if (result) { - std::vector args; - args.push_back(const_cast(result.value().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(tokens[i].c_str())); - } - - args.push_back(nullptr); + std::string filename = result.value().filename().string(); + std::string fullPath = result.value().string(); #ifdef _WIN32 - intptr_t status = _spawnv(_P_WAIT, result.value().c_str(), args.data()); + std::vector args; + args.push_back(filename.c_str());// have exe path on seperate element for _spawnv + + for (size_t i = 1; i < tokens.size(); i++) + { + args.push_back(const_cast(tokens[i].c_str())); + } + + args.push_back(nullptr); + + intptr_t status = _spawnv(_P_WAIT, fullPath.c_str(), args.data()); if (status == -1) { @@ -110,6 +113,15 @@ int main() return 1; } #else + std::vector args; + args.push_back(const_cast(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(tokens[i].c_str())); + } + + args.push_back(nullptr); pid_t pid = fork(); if (pid == 0) {// child process diff --git a/src/shellUtils.cpp b/src/shellUtils.cpp index 48342ee..6243614 100644 --- a/src/shellUtils.cpp +++ b/src/shellUtils.cpp @@ -94,50 +94,51 @@ namespace sh } } - std::optional isExec(const std::string& input) - { - - std::string pathEnv {std::getenv("PATH")}; + std::optional isExec(const std::string& input) + { + std::string pathEnv{ std::getenv("PATH") }; #ifdef _WIN32 - constexpr char delimiter {';'}; + constexpr char delimiter{';'}; + // windows executable extensions + const std::vector extensions{ "", ".exe", ".bat", ".cmd", ".com" }; #else - constexpr char delimiter {':'}; + constexpr char delimiter{':'}; + const std::vector extensions{""}; #endif - //add our current path, put a delimiter so std::string::find doesn't skip the last token - pathEnv.append(1, delimiter); - pathEnv.append(std::filesystem::current_path().string()); - pathEnv.append(1, delimiter); - size_t startCharIndex{}; + pathEnv.append(1, delimiter); + pathEnv.append(std::filesystem::current_path().string()); + pathEnv.append(1, delimiter); + + size_t startCharIndex{}; size_t nextDelimIndex{pathEnv.find(delimiter)}; - std::filesystem::path currentPath; + std::filesystem::path currentPath; - 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); - currentPath /= input; + for (const auto& ext : extensions) + { + currentPath = basePath / (input + ext); - namespace fs = std::filesystem; + namespace fs = std::filesystem; - if (!fs::exists(currentPath)) - { - startCharIndex = nextDelimIndex + 1; - nextDelimIndex = pathEnv.find(delimiter, startCharIndex); - continue; - } + if (fs::exists(currentPath)) + { + if ((fs::status(currentPath).permissions() & fs::perms::owner_exec) != fs::perms::owner_exec) + { + continue; + } + return currentPath; + } + } - 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; - } - - return currentPath; - } - return std::nullopt; - } + startCharIndex = nextDelimIndex + 1; + nextDelimIndex = pathEnv.find(delimiter, startCharIndex); + } + return std::nullopt; + } void printType(const std::string& input) {