diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2025-06-26 19:43:39 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-26 19:43:39 +0200 |
| commit | 3d6476c9021519995239ec93bbb11f0dce6c60a0 (patch) | |
| tree | 381edc199f4348e4bb42863b55d47a01e4f550ab /hyprtester/src/hyprctlCompat.cpp | |
| parent | 9a67e0421b49596060719566996ee4ca81ae8843 (diff) | |
Core: Add a test suite (#9297)
Adds a test suite for testing hyprland's features with a runtime tester
---------
Co-authored-by: Mihai Fufezan <mihai@fufexan.net>
Diffstat (limited to 'hyprtester/src/hyprctlCompat.cpp')
| -rw-r--r-- | hyprtester/src/hyprctlCompat.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/hyprtester/src/hyprctlCompat.cpp b/hyprtester/src/hyprctlCompat.cpp new file mode 100644 index 00000000..6e6cfc0f --- /dev/null +++ b/hyprtester/src/hyprctlCompat.cpp @@ -0,0 +1,136 @@ +#include "hyprctlCompat.hpp" +#include "shared.hpp" + +#include <pwd.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/un.h> +#include <unistd.h> + +#include <filesystem> +#include <fstream> +#include <algorithm> +#include <csignal> +#include <cerrno> +#include <print> + +static int getUID() { + const auto UID = getuid(); + const auto PWUID = getpwuid(UID); + return PWUID ? PWUID->pw_uid : UID; +} + +static std::string getRuntimeDir() { + const auto XDG = getenv("XDG_RUNTIME_DIR"); + + if (!XDG) { + const std::string USERID = std::to_string(getUID()); + return "/run/user/" + USERID + "/hypr"; + } + + return std::string{XDG} + "/hypr"; +} + +std::vector<SInstanceData> instances() { + std::vector<SInstanceData> result; + + try { + if (!std::filesystem::exists(getRuntimeDir())) + return {}; + } catch (std::exception& e) { return {}; } + + for (const auto& el : std::filesystem::directory_iterator(getRuntimeDir())) { + if (!el.is_directory() || !std::filesystem::exists(el.path().string() + "/hyprland.lock")) + continue; + + // read lock + SInstanceData* data = &result.emplace_back(); + data->id = el.path().filename().string(); + + try { + data->time = std::stoull(data->id.substr(data->id.find_first_of('_') + 1, data->id.find_last_of('_') - (data->id.find_first_of('_') + 1))); + } catch (std::exception& e) { continue; } + + // read file + std::ifstream ifs(el.path().string() + "/hyprland.lock"); + + int i = 0; + for (std::string line; std::getline(ifs, line); ++i) { + if (i == 0) { + try { + data->pid = std::stoull(line); + } catch (std::exception& e) { continue; } + } else if (i == 1) { + data->wlSocket = line; + } else + break; + } + + ifs.close(); + } + + std::erase_if(result, [&](const auto& el) { return kill(el.pid, 0) != 0 && errno == ESRCH; }); + + std::sort(result.begin(), result.end(), [&](const auto& a, const auto& b) { return a.time < b.time; }); + + return result; +} + +std::string getFromSocket(const std::string& cmd) { + const auto SERVERSOCKET = socket(AF_UNIX, SOCK_STREAM, 0); + + auto t = timeval{.tv_sec = 5, .tv_usec = 0}; + setsockopt(SERVERSOCKET, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(struct timeval)); + + if (SERVERSOCKET < 0) { + std::println("socket: Couldn't open a socket (1)"); + return ""; + } + + sockaddr_un serverAddress = {0}; + serverAddress.sun_family = AF_UNIX; + + std::string socketPath = getRuntimeDir() + "/" + HIS + "/.socket.sock"; + + strncpy(serverAddress.sun_path, socketPath.c_str(), sizeof(serverAddress.sun_path) - 1); + + if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, SUN_LEN(&serverAddress)) < 0) { + std::println("Couldn't connect to {}. (3)", socketPath); + return ""; + } + + auto sizeWritten = write(SERVERSOCKET, cmd.c_str(), cmd.length()); + + if (sizeWritten < 0) { + std::println("Couldn't write (4)"); + return ""; + } + + std::string reply = ""; + char buffer[8192] = {0}; + + sizeWritten = read(SERVERSOCKET, buffer, 8192); + + if (sizeWritten < 0) { + if (errno == EWOULDBLOCK) + std::println("Hyprland IPC didn't respond in time"); + std::println("Couldn't read (5)"); + return ""; + } + + reply += std::string(buffer, sizeWritten); + + while (sizeWritten == 8192) { + sizeWritten = read(SERVERSOCKET, buffer, 8192); + if (sizeWritten < 0) { + std::println("Couldn't read (5)"); + return ""; + } + reply += std::string(buffer, sizeWritten); + } + + close(SERVERSOCKET); + + return reply; +}
\ No newline at end of file |
