Added piped process support to Util::Procs
This commit is contained in:
parent
1a2719b01f
commit
3634a627f1
2 changed files with 87 additions and 20 deletions
|
@ -24,22 +24,11 @@ void Util::Procs::childsig_handler(int signum){
|
||||||
plist.erase(ret);
|
plist.erase(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts a new process if the name is not already active.
|
/// Attempts to run the command cmd.
|
||||||
/// \return 0 if process was not started, process PID otherwise.
|
/// Replaces the current process - use after forking first!
|
||||||
/// \arg name Name for this process - only used internally.
|
/// This function will never return - it will either run the given
|
||||||
/// \arg cmd Commandline for this process.
|
/// command or kill itself with return code 42.
|
||||||
pid_t Util::Procs::Start(std::string name, std::string cmd){
|
void Util::Procs::runCmd(std::string & cmd){
|
||||||
if (isActive(name)){return getPid(name);}
|
|
||||||
if (!handler_set){
|
|
||||||
struct sigaction new_action;
|
|
||||||
new_action.sa_handler = Util::Procs::childsig_handler;
|
|
||||||
sigemptyset(&new_action.sa_mask);
|
|
||||||
new_action.sa_flags = 0;
|
|
||||||
sigaction(SIGCHLD, &new_action, NULL);
|
|
||||||
handler_set = true;
|
|
||||||
}
|
|
||||||
pid_t ret = fork();
|
|
||||||
if (ret == 0){
|
|
||||||
//split cmd into arguments
|
//split cmd into arguments
|
||||||
//supports a maximum of 20 arguments
|
//supports a maximum of 20 arguments
|
||||||
char * tmp = (char*)cmd.c_str();
|
char * tmp = (char*)cmd.c_str();
|
||||||
|
@ -57,9 +46,28 @@ pid_t Util::Procs::Start(std::string name, std::string cmd){
|
||||||
//execute the command
|
//execute the command
|
||||||
execvp(args[0], args);
|
execvp(args[0], args);
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
std::cerr << "Error: " << strerror(errno) << std::endl;
|
std::cerr << "Error running \"" << cmd << "\": " << strerror(errno) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
_exit(42);
|
_exit(42);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Starts a new process if the name is not already active.
|
||||||
|
/// \return 0 if process was not started, process PID otherwise.
|
||||||
|
/// \arg name Name for this process - only used internally.
|
||||||
|
/// \arg cmd Commandline for this process.
|
||||||
|
pid_t Util::Procs::Start(std::string name, std::string cmd){
|
||||||
|
if (isActive(name)){return getPid(name);}
|
||||||
|
if (!handler_set){
|
||||||
|
struct sigaction new_action;
|
||||||
|
new_action.sa_handler = Util::Procs::childsig_handler;
|
||||||
|
sigemptyset(&new_action.sa_mask);
|
||||||
|
new_action.sa_flags = 0;
|
||||||
|
sigaction(SIGCHLD, &new_action, NULL);
|
||||||
|
handler_set = true;
|
||||||
|
}
|
||||||
|
pid_t ret = fork();
|
||||||
|
if (ret == 0){
|
||||||
|
runCmd(cmd);
|
||||||
}else{
|
}else{
|
||||||
if (ret > 0){
|
if (ret > 0){
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
|
@ -76,6 +84,63 @@ pid_t Util::Procs::Start(std::string name, std::string cmd){
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Starts two piped processes if the name is not already active.
|
||||||
|
/// \return 0 if process was not started, main (receiving) process PID otherwise.
|
||||||
|
/// \arg name Name for this process - only used internally.
|
||||||
|
/// \arg cmd Commandline for sub (sending) process.
|
||||||
|
/// \arg cmd2 Commandline for main (receiving) process.
|
||||||
|
pid_t Util::Procs::Start(std::string name, std::string cmd, std::string cmd2){
|
||||||
|
if (isActive(name)){return getPid(name);}
|
||||||
|
if (!handler_set){
|
||||||
|
struct sigaction new_action;
|
||||||
|
new_action.sa_handler = Util::Procs::childsig_handler;
|
||||||
|
sigemptyset(&new_action.sa_mask);
|
||||||
|
new_action.sa_flags = 0;
|
||||||
|
sigaction(SIGCHLD, &new_action, NULL);
|
||||||
|
handler_set = true;
|
||||||
|
}
|
||||||
|
pid_t ret = fork();
|
||||||
|
if (ret == 0){
|
||||||
|
int pfildes[2];
|
||||||
|
if (pipe(pfildes) == -1){
|
||||||
|
#if DEBUG >= 1
|
||||||
|
std::cerr << "Process " << name << " could not be started. Pipe creation failed." << std::endl;
|
||||||
|
#endif
|
||||||
|
_exit(41);
|
||||||
|
}
|
||||||
|
pid_t pid;
|
||||||
|
if ((pid = fork()) == -1){
|
||||||
|
#if DEBUG >= 1
|
||||||
|
std::cerr << "Process " << name << " could not be started. Second fork() failed." << std::endl;
|
||||||
|
#endif
|
||||||
|
_exit(41);
|
||||||
|
}else if (pid == 0){
|
||||||
|
close(pfildes[0]);
|
||||||
|
dup2(pfildes[1],1);
|
||||||
|
close(pfildes[1]);
|
||||||
|
runCmd(cmd);
|
||||||
|
}else{
|
||||||
|
close(pfildes[1]);
|
||||||
|
dup2(pfildes[0],0);
|
||||||
|
close(pfildes[0]);
|
||||||
|
runCmd(cmd2);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if (ret > 0){
|
||||||
|
#if DEBUG >= 1
|
||||||
|
std::cerr << "Process " << name << " started, PID " << ret << ": " << cmd << " | " << cmd2 << std::endl;
|
||||||
|
#endif
|
||||||
|
plist.insert(std::pair<pid_t, std::string>(ret, name));
|
||||||
|
}else{
|
||||||
|
#if DEBUG >= 1
|
||||||
|
std::cerr << "Process " << name << " could not be started. fork() failed." << std::endl;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/// Stops the named process, if running.
|
/// Stops the named process, if running.
|
||||||
/// \arg name (Internal) name of process to stop
|
/// \arg name (Internal) name of process to stop
|
||||||
void Util::Procs::Stop(std::string name){
|
void Util::Procs::Stop(std::string name){
|
||||||
|
|
|
@ -14,8 +14,10 @@ namespace Util{
|
||||||
static std::map<pid_t, std::string> plist; ///< Holds active processes
|
static std::map<pid_t, std::string> plist; ///< Holds active processes
|
||||||
static bool handler_set; ///< If true, the sigchld handler has been setup.
|
static bool handler_set; ///< If true, the sigchld handler has been setup.
|
||||||
static void childsig_handler(int signum);
|
static void childsig_handler(int signum);
|
||||||
|
static void runCmd(std::string & cmd);
|
||||||
public:
|
public:
|
||||||
static pid_t Start(std::string name, std::string cmd);
|
static pid_t Start(std::string name, std::string cmd);
|
||||||
|
static pid_t Start(std::string name, std::string cmd, std::string cmd2);
|
||||||
static void Stop(std::string name);
|
static void Stop(std::string name);
|
||||||
static void Stop(pid_t name);
|
static void Stop(pid_t name);
|
||||||
static void StopAll();
|
static void StopAll();
|
||||||
|
|
Loading…
Add table
Reference in a new issue