changeset 2:00b62a080354

fix numerous bugs
author Yasuri <yasuri@charliesmp.net>
date Sun, 13 Sep 2026 19:40:11 +0000
parents a17d9d25e9ea
children ae3a6d7bcca6
files README main.cpp pipes.cpp process.h spawn.cpp
diffstat 5 files changed, 37 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/README	Sun Sep 13 19:25:50 2026 +0000
+++ b/README	Sun Sep 13 19:40:11 2026 +0000
@@ -6,7 +6,6 @@
 ------------
 
 fzf, xbps, and doas.
-Locations of these are hard-coded for now, will be fixed soon.
 
 How to build
 ------------
--- a/main.cpp	Sun Sep 13 19:25:50 2026 +0000
+++ b/main.cpp	Sun Sep 13 19:40:11 2026 +0000
@@ -9,9 +9,9 @@
 }
 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, ""); 
+    std::string package_list = run_piped(query_argv, ""); 
     char* const fzf_argv[] = { const_cast<char*>("fzf"), nullptr };
-    std::string result = run_piped("/usr/bin/fzf", fzf_argv, package_list);
+    std::string result = run_piped(fzf_argv, package_list);
 
     // strip trailing newline fzf adds
     if (!result.empty() && result.back() == '\n') {
@@ -25,7 +25,18 @@
         pkgname.data(),
         nullptr
     };
-    std::string status = spawn(install_argv, "/usr/bin/doas");
-
+    std::string status = spawn(install_argv);
+    if (status == "error") {
+        std::cerr << "failed to launch doas/xbps-install\n";
+        return 1;
+    }
+    if (status.rfind("sig:", 0) == 0) {
+        std::cerr << "xbps-install was killed by signal " << status.substr(4) << "\n";
+        return 1;
+    }
+    if (status != "0") {
+        std::cerr << "xbps-install exited with code " << status << "\n";
+        return 1;
+    }
     return 0;
 }
--- a/pipes.cpp	Sun Sep 13 19:25:50 2026 +0000
+++ b/pipes.cpp	Sun Sep 13 19:40:11 2026 +0000
@@ -2,11 +2,12 @@
 #include <unistd.h>
 #include <spawn.h>
 #include <cstring>
+#include <cerrno>
 #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) 
+std::string run_piped(char* const argv[], const std::string& input) 
 {
     int status;
     pid_t pid;
@@ -24,17 +25,28 @@
     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);
+    status = posix_spawnp(&pid, argv[0], &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;
+        std::cerr << "posix_spawnp failed for " << argv[0] << ": " << strerror(status) << std::endl;
         return "error";
     }
-    write(pipeA[1],input.c_str(), input.size());
+    size_t total_written = 0;
+    while (total_written < input.size()) {
+        ssize_t n = write(pipeA[1], input.c_str() + total_written, input.size() - total_written);
+        if (n < 0) {
+            if (errno == EINTR) {
+                continue; // interrupted
+            }
+            perror("write");
+            break; // error, give up
+        }
+        total_written += n;
+    }
     close(pipeA[1]);
     char buf[256];
 std::string result;
--- a/process.h	Sun Sep 13 19:25:50 2026 +0000
+++ b/process.h	Sun Sep 13 19:40:11 2026 +0000
@@ -1,4 +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);
+std::string spawn(char* const argv[]);
+std::string run_piped(char* const argv[], const std::string& input);
--- a/spawn.cpp	Sun Sep 13 19:25:50 2026 +0000
+++ b/spawn.cpp	Sun Sep 13 19:40:11 2026 +0000
@@ -6,13 +6,13 @@
 #include <string>
 #include "process.h"
 extern char** environ; // idk what this does
-std::string spawn(char* const argv[], const char* path)
+std::string spawn(char* const argv[])
 {
     pid_t pid;
     int status;
-    status = posix_spawn(&pid, path, NULL, NULL, const_cast<char* const*>(argv), environ);
+    status = posix_spawnp(&pid, argv[0], NULL, NULL, const_cast<char* const*>(argv), environ);
     if (status != 0) {
-        std::cerr << "posix_spawn failed:" << strerror(status) << std::endl;
+        std::cerr << "posix_spawnp failed for " << argv[0] << ": " << strerror(status) << std::endl;
         return "error";
     }
     if (waitpid(pid, &status, 0) == -1) {
@@ -23,7 +23,7 @@
         return std::to_string(WEXITSTATUS(status));
     }
     if (WIFSIGNALED(status)) {
-        return std::to_string(WTERMSIG(status));
+        return "sig:" + std::to_string(WTERMSIG(status));
     }
     return "success";
 }