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,17 +92,20 @@ 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();
for (size_t i = 1; i < tokens.size(); i++)
{
args.push_back(const_cast<char*>(tokens[i].c_str()));
}
args.push_back(nullptr);
#ifdef _WIN32 #ifdef _WIN32
intptr_t status = _spawnv(_P_WAIT, result.value().c_str(), args.data()); 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++)
{
args.push_back(const_cast<char*>(tokens[i].c_str()));
}
args.push_back(nullptr);
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

@ -94,50 +94,51 @@ 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(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)}; 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); 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; if ((fs::status(currentPath).permissions() & fs::perms::owner_exec) != fs::perms::owner_exec)
nextDelimIndex = pathEnv.find(delimiter, startCharIndex); {
continue; continue;
} }
return currentPath;
}
}
if ((fs::status(currentPath).permissions() & fs::perms::owner_exec) != fs::perms::owner_exec) startCharIndex = nextDelimIndex + 1;
{// fullPath exists but cant executed nextDelimIndex = pathEnv.find(delimiter, startCharIndex);
startCharIndex = nextDelimIndex + 1; }
nextDelimIndex = pathEnv.find(delimiter, startCharIndex); return std::nullopt;
continue; }
}
return currentPath;
}
return std::nullopt;
}
void printType(const std::string& input) void printType(const std::string& input)
{ {