81 lines
2.1 KiB
C++
81 lines
2.1 KiB
C++
#include "shellUtils.h"
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <map>
|
|
#include <cstdlib>
|
|
#include <filesystem>
|
|
|
|
namespace sh
|
|
{
|
|
Command getCommand(std::string_view input)
|
|
{
|
|
if (commandMap.contains(input.
|
|
substr(0, input.find(' '))))
|
|
{
|
|
return commandMap.at(input.substr(0, input.find(' ')));
|
|
}
|
|
else
|
|
{
|
|
return Command::unknown;
|
|
}
|
|
}
|
|
|
|
std::optional<std::filesystem::path> isExec(const std::string& input)
|
|
{
|
|
|
|
const std::string_view pathEnv {std::getenv("PATH")};
|
|
#if WIN32
|
|
constexpr char delimiter {';'};
|
|
#else
|
|
constexpr char delimiter {':'};
|
|
#endif
|
|
size_t startCharIndex{};
|
|
size_t nextDelimIndex{pathEnv.find(delimiter)};
|
|
while (nextDelimIndex != std::string::npos)
|
|
{
|
|
std::filesystem::path currentPath {pathEnv.substr(startCharIndex, nextDelimIndex - startCharIndex)};
|
|
std::filesystem::path fullPath;
|
|
fullPath = currentPath / input;
|
|
namespace fs = std::filesystem;
|
|
|
|
if (!fs::exists(fullPath))
|
|
{
|
|
startCharIndex = nextDelimIndex + 1;
|
|
nextDelimIndex = pathEnv.find(delimiter, startCharIndex);
|
|
continue;
|
|
}
|
|
|
|
if ((fs::status(fullPath).permissions() & fs::perms::owner_exec) != fs::perms::owner_exec)
|
|
{
|
|
startCharIndex = nextDelimIndex + 1;
|
|
nextDelimIndex = pathEnv.find(delimiter, startCharIndex);
|
|
continue;
|
|
}
|
|
|
|
return fullPath;
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
void printType(const std::string& input)
|
|
{
|
|
if (commandMap.contains(input))
|
|
{
|
|
std::cout << input;
|
|
std::cout << " is a shell builtin\n";
|
|
return;
|
|
}
|
|
|
|
if (const auto fullPath {isExec(input)})
|
|
{
|
|
std::cout << input;
|
|
std::cout << " is " << fullPath.value() << "\n";
|
|
return;
|
|
}
|
|
|
|
std::cout << input;
|
|
std::cout << ": not found\n";
|
|
}
|
|
}
|