Add config and command executor
Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
82
src/App.cpp
82
src/App.cpp
@@ -8,7 +8,9 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <poll.h>
|
||||
#include <print>
|
||||
#include <pthread.h>
|
||||
#include <ranges>
|
||||
#include <signal.h>
|
||||
#include <span>
|
||||
#include <sys/mman.h>
|
||||
@@ -159,6 +161,25 @@ App::App()
|
||||
std::filesystem::create_directories(m_data_home_dir);
|
||||
}
|
||||
|
||||
{
|
||||
auto const env = getenv("XDG_CONFIG_HOME");
|
||||
if (env && *env) {
|
||||
if (std::filesystem::exists(env)) {
|
||||
m_config_home_dir = env;
|
||||
}
|
||||
}
|
||||
if (m_config_home_dir.empty()) {
|
||||
auto const home = getenv("HOME");
|
||||
assert(home && *home);
|
||||
m_config_home_dir = std::filesystem::path(home) / ".config";
|
||||
std::filesystem::create_directories(m_config_home_dir);
|
||||
}
|
||||
m_config_home_dir /= "waylight";
|
||||
std::filesystem::create_directories(m_config_home_dir);
|
||||
|
||||
m_config = Config::load(m_config_home_dir);
|
||||
}
|
||||
|
||||
m_db = std::make_shared<SQLite::Database>(m_data_home_dir / "data.db",
|
||||
SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
|
||||
@@ -1243,4 +1264,65 @@ auto App::clipboard(std::string_view const &str) -> void
|
||||
wl_display_flush(m_wayland.display);
|
||||
}
|
||||
|
||||
void App::execute_command(bool terminal, std::string_view const command)
|
||||
{
|
||||
constexpr auto resolve_cmdline { [](std::string_view const cmdline,
|
||||
std::vector<std::string> &out) {
|
||||
std::ranges::copy(cmdline | std::views::split(' ')
|
||||
| std::views::transform(
|
||||
[](auto &&s) { return std::string(s.begin(), s.end()); }),
|
||||
std::back_inserter(out));
|
||||
} };
|
||||
|
||||
std::vector<std::string> args;
|
||||
if (terminal) {
|
||||
resolve_cmdline(m_config.terminal_cmdline, args);
|
||||
} else {
|
||||
args.push_back("/bin/sh");
|
||||
args.push_back("-c");
|
||||
}
|
||||
|
||||
args.push_back(std::string(command));
|
||||
if (auto const &exe { args.at(0) }; exe.at(0) != '/') {
|
||||
auto const *path_env { getenv("PATH") };
|
||||
if (!(path_env && *path_env)) {
|
||||
path_env = "/bin";
|
||||
}
|
||||
auto const path { std::string(path_env) };
|
||||
|
||||
for (auto const &dir :
|
||||
path | std::views::split(':') | std::views::transform([](auto &&s) {
|
||||
return std::filesystem::path(s.begin(), s.end());
|
||||
}) | std::views::filter([](auto &&p) {
|
||||
return std::filesystem::is_directory(p);
|
||||
})) {
|
||||
auto const path = dir / exe;
|
||||
if (std::filesystem::is_regular_file(path)) {
|
||||
args[0] = path.string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::print("Final args: ");
|
||||
for (auto const &arg : args) {
|
||||
std::print("{} ", arg);
|
||||
}
|
||||
std::println("");
|
||||
|
||||
std::vector<char const *> cargs;
|
||||
std::transform(args.begin(), args.end(), std::back_inserter(cargs),
|
||||
[](auto &&s) { return s.c_str(); });
|
||||
cargs.push_back(nullptr);
|
||||
auto cargsc { const_cast<char *const *>(cargs.data()) };
|
||||
|
||||
auto const pid = fork();
|
||||
if (pid == 0) {
|
||||
setsid();
|
||||
|
||||
execv(args.at(0).c_str(), cargsc);
|
||||
} else if (pid < 0) {
|
||||
throw std::runtime_error("Failed to fork process");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Waylight
|
||||
|
||||
Reference in New Issue
Block a user