#include "runner.h" #include #include #include #include #include #include int execute_cmd( const std::string& command, const std::vector& args, const std::string& working_dir, const std::map& env, bool silent, bool interactive, sSSHInfo* sshinfo, std::string* output ) { // SSH execution is not implemented in this demo if (sshinfo) { std::cerr << "Remote SSH execution is not implemented in this demo.\n"; return -1; } int pipefd[2]; if (output && pipe(pipefd) == -1) { perror("pipe"); return -1; } pid_t pid = fork(); if (pid == -1) { perror("fork"); return -1; } if (pid == 0) { // Child process if (!working_dir.empty()) { if (chdir(working_dir.c_str()) != 0) { perror("chdir"); exit(-1); } } // Set environment variables for (const auto& kv : env) { setenv(kv.first.c_str(), kv.second.c_str(), 1); } if (output) { close(pipefd[0]); dup2(pipefd[1], STDOUT_FILENO); dup2(pipefd[1], STDERR_FILENO); close(pipefd[1]); } else if (silent) { int devnull = open("/dev/null", O_WRONLY); dup2(devnull, STDOUT_FILENO); dup2(devnull, STDERR_FILENO); close(devnull); } if (!interactive) { // Detach from terminal if not interactive setsid(); } std::vector argv; argv.push_back(const_cast(command.c_str())); for (const auto& arg : args) { argv.push_back(const_cast(arg.c_str())); } argv.push_back(nullptr); execvp(command.c_str(), argv.data()); perror("execvp"); exit(-1); } else { // Parent process if (output) { close(pipefd[1]); std::ostringstream oss; char buf[4096]; ssize_t n; while ((n = read(pipefd[0], buf, sizeof(buf))) > 0) { oss.write(buf, n); } close(pipefd[0]); *output = oss.str(); } int status = 0; waitpid(pid, &status, 0); if (WIFEXITED(status)) { return WEXITSTATUS(status); } else { return -1; } } }