# HG changeset patch # User Yasuri # Date 1789327196 0 # Node ID 21b543c7aa14cafd127fd87544f5c029e455924b Initial commit diff -r 000000000000 -r 21b543c7aa14 .hgignore --- /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 +*~ diff -r 000000000000 -r 21b543c7aa14 Makefile --- /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) diff -r 000000000000 -r 21b543c7aa14 main.cpp --- /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 +#include +#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("xbps-query"), const_cast("-Rs"), const_cast(""), nullptr }; + std::string package_list = run_piped("/usr/bin/xbps-query", query_argv, ""); + char* const fzf_argv[] = { const_cast("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("doas"), + const_cast("xbps-install"), + const_cast("-Sy"), + pkgname.data(), + nullptr + }; + std::string status = spawn(install_argv, "/usr/bin/doas"); + + return 0; +} diff -r 000000000000 -r 21b543c7aa14 pipes.cpp --- /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 +#include +#include +#include +#include +#include +#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(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; +} diff -r 000000000000 -r 21b543c7aa14 process.h --- /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 +std::string spawn(char* const argv[], const char* path); +std::string run_piped(const char* path, char* const argv[], const std::string& input); diff -r 000000000000 -r 21b543c7aa14 spawn.cpp --- /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 +#include +#include +#include +#include +#include +#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(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"; +}