#include <string> #include <unistd.h> #include <sys/wait.h> #include "services/logger.hpp" #include "utils/macros.hpp" #include "utils/proc.hpp" #include "utils/string.hpp" namespace proc { pid_t get_process_id() { return getpid(); } // pid_t get_parent_process_id() { // return getppid(); // } bool in_parent_process(pid_t pid) { return pid != -1 && pid != 0; } bool in_forked_process(pid_t pid) { return pid == 0; } pid_t fork() { pid_t pid = ::fork(); if (pid < 0) { log_error("Failed to fork process: "+ StrErrno() +" ("+ std::to_string(errno) +")"); return -1; } if (in_parent_process(pid)) log_trace("Forked process (pid: "+ std::to_string(pid) +")"); return pid; } bool pipe(int fds[2]) { if (::pipe(fds) != 0) { log_error("Failed to allocate memory for pipe channels"); return false; } log_trace("Successfully created pipe channels"); return true; } void exec(const std::string& cmd) { // log_trace(string::replace_all(cmd, "\n", " ")); std::vector<char *> c_args; std::vector<std::string> args; auto pos = cmd.find('\n'); if (pos != std::string::npos) string::split_into(cmd, '\n', args); else string::split_into(cmd, ' ', args); for (auto const &a : args) c_args.emplace_back(const_cast<char *>(a.c_str())); c_args.emplace_back(nullptr); // get_logger()->debug("Executing: \""+ string::join(args, " ") +"\""); ::execvp(c_args[0], c_args.data()); throw ExecFailure("Failed to execute command:\n-> "+ StrErrno()+ " ("+ std::to_string(errno) + ")"); } bool kill(pid_t pid, int sig) { return ::kill(pid, sig) != -1; } pid_t wait(int *status) { return ::wait(status); } pid_t wait_for_completion(pid_t pid, int *status, int options) { int saved_errno = errno; pid_t retval = waitpid(pid, status, options); errno = saved_errno; return retval; } pid_t wait_for_completion(int *status, int options) { return wait_for_completion(-1, status, options); } pid_t wait_for_completion(pid_t pid) { int status; return wait_for_completion(pid, &status); } pid_t wait_for_completion_nohang(pid_t pid, int *status) { return wait_for_completion(pid, status, WNOHANG); } pid_t wait_for_completion_nohang(int *status) { return wait_for_completion_nohang(-1, status); } pid_t wait_for_completion_nohang() { int status; return wait_for_completion_nohang(-1, &status); } }