Mercurial > xbps-search-tv
changeset 0:21b543c7aa14
Initial commit
| author | Yasuri <yasuri@charliesmp.net> |
|---|---|
| date | Sun, 13 Sep 2026 19:19:56 +0000 |
| parents | |
| children | a17d9d25e9ea |
| files | .hgignore Makefile main.cpp pipes.cpp process.h spawn.cpp |
| diffstat | 6 files changed, 148 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sun Sep 13 19:19:56 2026 +0000 @@ -0,0 +1,11 @@ +syntax: glob + +*.o +xt +xbpst +*.out +*.exe +.vscode/ +.idea/ +*.swp +*~
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Sun Sep 13 19:19:56 2026 +0000 @@ -0,0 +1,18 @@ +CXX := g++ +CXXFLAGS := -std=c++17 -Wall -Wextra +TARGET := xt +SRCS := main.cpp spawn.cpp pipes.cpp +OBJS := $(SRCS:.cpp=.o) + +.PHONY: all clean + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) $(CXXFLAGS) $(OBJS) -o $(TARGET) + +%.o: %.cpp process.h + $(CXX) $(CXXFLAGS) -c $< -o $@ + +clean: + rm -f $(OBJS) $(TARGET)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Sep 13 19:19:56 2026 +0000 @@ -0,0 +1,31 @@ +#include <iostream> +#include <sstream> +#include "process.h" +std::string extract_pkgname(const std::string& fzf_line) { + std::istringstream iss(fzf_line); + std::string marker, pkgver; + iss >> marker >> pkgver; + return pkgver; +} +int main() { + char* const query_argv[] = { const_cast<char*>("xbps-query"), const_cast<char*>("-Rs"), const_cast<char*>(""), nullptr }; + std::string package_list = run_piped("/usr/bin/xbps-query", query_argv, ""); + char* const fzf_argv[] = { const_cast<char*>("fzf"), nullptr }; + std::string result = run_piped("/usr/bin/fzf", fzf_argv, package_list); + + // strip trailing newline fzf adds + if (!result.empty() && result.back() == '\n') { + result.pop_back(); + } + std::string pkgname = extract_pkgname(result); + char* const install_argv[] = { + const_cast<char*>("doas"), + const_cast<char*>("xbps-install"), + const_cast<char*>("-Sy"), + pkgname.data(), + nullptr + }; + std::string status = spawn(install_argv, "/usr/bin/doas"); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pipes.cpp Sun Sep 13 19:19:56 2026 +0000 @@ -0,0 +1,55 @@ +#include <iostream> +#include <unistd.h> +#include <spawn.h> +#include <cstring> +#include <string> +#include <sys/wait.h> +#include "process.h" +extern char** environ; +std::string run_piped(const char* path, char* const argv[], const std::string& input) +{ + int status; + pid_t pid; + int pipeA[2]; + int pipeB[2]; + if (pipe(pipeA) < 0) + return "error"; + if (pipe(pipeB) < 0) + return "error"; + posix_spawn_file_actions_t actions; + posix_spawn_file_actions_init(&actions); // initialize actions + posix_spawn_file_actions_adddup2(&actions, pipeA[0], STDIN_FILENO); + posix_spawn_file_actions_adddup2(&actions, pipeB[1], STDOUT_FILENO); + posix_spawn_file_actions_addclose(&actions, pipeA[1]); // closes write end in child + posix_spawn_file_actions_addclose(&actions, pipeB[0]); // makes sure child doesn't read its own output pipe + posix_spawn_file_actions_addclose(&actions, pipeA[0]); // close read fd in child + posix_spawn_file_actions_addclose(&actions, pipeB[1]); // close read fd in child, part 2 + status = posix_spawn(&pid, path, &actions, NULL, const_cast<char* const*>(argv), environ); + close(pipeA[0]); + close(pipeB[1]); + if (status != 0) { + posix_spawn_file_actions_destroy(&actions); + close(pipeA[1]); + close(pipeB[0]); + std::cerr << "posix_spawn failed: " << strerror(status) << std::endl; + return "error"; + } + write(pipeA[1],input.c_str(), input.size()); + close(pipeA[1]); + char buf[256]; +std::string result; +ssize_t n; +while ((n = read(pipeB[0], buf, sizeof(buf))) > 0) { + result.append(buf, n); +} + close(pipeB[0]); + if (waitpid(pid, &status, 0) == -1) { + posix_spawn_file_actions_destroy(&actions); + close(pipeA[1]); + close(pipeB[0]); + perror("waitpid"); + return "error"; + } + posix_spawn_file_actions_destroy(&actions); + return result; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/process.h Sun Sep 13 19:19:56 2026 +0000 @@ -0,0 +1,4 @@ +#pragma once +#include <string> +std::string spawn(char* const argv[], const char* path); +std::string run_piped(const char* path, char* const argv[], const std::string& input);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spawn.cpp Sun Sep 13 19:19:56 2026 +0000 @@ -0,0 +1,29 @@ +#include <iostream> +#include <unistd.h> +#include <sys/wait.h> +#include <spawn.h> +#include <cstring> +#include <string> +#include "process.h" +extern char** environ; // idk what this does +std::string spawn(char* const argv[], const char* path) +{ + pid_t pid; + int status; + status = posix_spawn(&pid, path, NULL, NULL, const_cast<char* const*>(argv), environ); + if (status != 0) { + std::cerr << "posix_spawn failed:" << strerror(status) << std::endl; + return "error"; + } + if (waitpid(pid, &status, 0) == -1) { + perror("waitpid"); + return "error"; + } + if (WIFEXITED(status)) { + return std::to_string(WEXITSTATUS(status)); + } + if (WIFSIGNALED(status)) { + return std::to_string(WTERMSIG(status)); + } + return "success"; +}
