int Performer shExecuteExperimenta const char stringToExecute const na

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
int Performer::shExecuteExperimental(const char* stringToExecute) const {
namespace ba = boost::algorithm;
string s(stringToExecute);
vector<string> fields;
ba::split(fields, s, ba::is_any_of(" "));
const char* argumentsArray[fields.size()+1];
for (unsigned int i = 0; i < fields.size(); ++i) {
argumentsArray[i] = fields[i].c_str();
}
/* NEXT:
* We need whitespace at the end of any argument ov execv(), but boost::split
* erased it, of course, so lets restore */
argumentsArray[fields.size()] = NULL;
pid_t child_pid, w;
int status;
child_pid = fork();
if ( child_pid == 0 ) {
/* NOTE:
* This is done by the child process because child_pid for it will be 0
* but for parent child_pid will have the value of PID if the child
*/
*pLog << pLog->date() << "[INFO]: Child process PID is: " << (long)getpid();
execv(argumentsArray[0], const_cast<char** const>(argumentsArray));
/* NOTE:
* If execv returns, it must have failed */
throw std::runtime_error(strerror(errno));
} else { // got not error but "the return status of the command"
do {
/* INFO:
* This is run by the parent. Wait for the child
to terminate
*/
/* INFO:
* The waitpid() system call suspends execution of the calling process until a child specified by pid argument has changed state.
* By default, waitpid() waits only for terminated children, but this behavior is modifiable via the options argument.
*
* WUNTRACED also return if a child has stopped (but not traced via ptrace(2))
* WCONTINUED also return if a stopped child has been resumed by delivery of SIGCONT
*
* The value of pid can be:
* < -1 meaning wait for any child process whose process group ID is equal to the absolute value of pid.
* -1 meaning wait for any child process.
* 0 meaning wait for any child process whose process group ID is equal to that of the calling process.
* > 0 meaning wait for the child whose process ID is equal to the value of pid.
*/
w = waitpid(child_pid, &status, WUNTRACED | WCONTINUED); // waiting the child process to perform requested actions
if (w == -1) {
throw std::runtime_error(strerror(errno));
}
/* NOTE:
* This macro queries the child termination status provided by the wait() and waitpid() functions, and determines whether the child process ended normally
*/
if (WIFEXITED(status)) {
*pLog << pLog->date() << "[INFO]: Child process Exited, status=" << WEXITSTATUS(status) << (long)getpid();
} else if (WIFSIGNALED(status)) {
*pLog << pLog->date() << "[WARNING]: Child process Killed by signal " << WTERMSIG(status);
} else if (WIFSTOPPED(status)) {
*pLog << pLog->date() << "[WARNING]: Child process Stopped by signal" << WSTOPSIG(status);
} else if (WIFCONTINUED(status)) {
*pLog << pLog->date() << "[INFO]: Child process Continued";
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
*pLog << pLog->date() << "[INFO]: Child process Completed";
return(EXIT_SUCCESS);
}
}