116 lines
2.5 KiB
C++
116 lines
2.5 KiB
C++
#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);
|
|
}
|
|
}
|