2016-11-02 15:22:45 -04:00
|
|
|
#include <sys/wait.h>
|
2016-11-20 17:04:31 -05:00
|
|
|
#include <unistd.h>
|
2016-11-02 15:22:45 -04:00
|
|
|
|
2016-11-25 07:55:15 -05:00
|
|
|
#include "errors.hpp"
|
2016-12-03 14:52:42 -05:00
|
|
|
#include "utils/env.hpp"
|
2016-11-02 15:22:45 -04:00
|
|
|
#include "utils/process.hpp"
|
|
|
|
#include "utils/string.hpp"
|
|
|
|
|
2016-11-19 00:22:44 -05:00
|
|
|
POLYBAR_NS
|
2016-11-02 15:22:45 -04:00
|
|
|
|
|
|
|
namespace process_util {
|
|
|
|
/**
|
|
|
|
* Check if currently in main process
|
|
|
|
*/
|
|
|
|
bool in_parent_process(pid_t pid) {
|
|
|
|
return pid != -1 && pid != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if currently in subprocess
|
|
|
|
*/
|
|
|
|
bool in_forked_process(pid_t pid) {
|
|
|
|
return pid == 0;
|
|
|
|
}
|
|
|
|
|
2016-12-03 09:46:48 -05:00
|
|
|
/**
|
2016-12-03 14:52:42 -05:00
|
|
|
* Execute command
|
2016-12-03 09:46:48 -05:00
|
|
|
*/
|
|
|
|
void exec(char* cmd, char** args) {
|
2016-12-14 09:02:56 -05:00
|
|
|
if (cmd != nullptr) {
|
|
|
|
execvp(cmd, args);
|
|
|
|
throw system_error("execvp() failed");
|
|
|
|
}
|
2016-12-03 09:46:48 -05:00
|
|
|
}
|
|
|
|
|
2016-11-02 15:22:45 -04:00
|
|
|
/**
|
2016-12-03 14:52:42 -05:00
|
|
|
* Execute command using shell
|
2016-11-02 15:22:45 -04:00
|
|
|
*/
|
2016-12-03 14:52:42 -05:00
|
|
|
void exec_sh(const char* cmd) {
|
2016-12-14 21:30:41 -05:00
|
|
|
static const string shell{env_util::get("SHELL", "/bin/sh")};
|
2016-12-14 09:02:56 -05:00
|
|
|
|
|
|
|
if (cmd != nullptr) {
|
|
|
|
execlp(shell.c_str(), shell.c_str(), "-c", cmd, nullptr);
|
|
|
|
throw system_error("execvp() failed");
|
|
|
|
}
|
2016-11-02 15:22:45 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wait for child process
|
|
|
|
*/
|
|
|
|
pid_t wait_for_completion(pid_t process_id, int* status_addr, int waitflags) {
|
|
|
|
int saved_errno = errno;
|
|
|
|
auto retval = waitpid(process_id, status_addr, waitflags);
|
|
|
|
errno = saved_errno;
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wait for child process
|
|
|
|
*/
|
|
|
|
pid_t wait_for_completion(int* status_addr, int waitflags) {
|
|
|
|
return wait_for_completion(-1, status_addr, waitflags);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wait for child process
|
|
|
|
*/
|
|
|
|
pid_t wait_for_completion(pid_t process_id) {
|
|
|
|
int status = 0;
|
|
|
|
return wait_for_completion(process_id, &status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Non-blocking wait
|
|
|
|
*
|
|
|
|
* @see wait_for_completion
|
|
|
|
*/
|
|
|
|
pid_t wait_for_completion_nohang(pid_t process_id, int* status) {
|
|
|
|
return wait_for_completion(process_id, status, WNOHANG);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Non-blocking wait
|
|
|
|
*
|
|
|
|
* @see wait_for_completion
|
|
|
|
*/
|
|
|
|
pid_t wait_for_completion_nohang(int* status) {
|
|
|
|
return wait_for_completion_nohang(-1, status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Non-blocking wait
|
|
|
|
*
|
|
|
|
* @see wait_for_completion
|
|
|
|
*/
|
|
|
|
pid_t wait_for_completion_nohang() {
|
|
|
|
int status = 0;
|
|
|
|
return wait_for_completion_nohang(-1, &status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Non-blocking wait call which returns pid of any child process
|
|
|
|
*
|
|
|
|
* @see wait_for_completion
|
|
|
|
*/
|
|
|
|
bool notify_childprocess() {
|
|
|
|
return wait_for_completion_nohang() > 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-19 00:22:44 -05:00
|
|
|
POLYBAR_NS_END
|