I have written an application that does a popen call to get results from a linux system command (string) that I pass on the command line.
Example:
./myapp ls -l /home/someuser
Results:
As expected I get the same output as if I ran the "ls -l /home/someuser" command right on the shell.
The code works well for all tests except one so far... If I try to pass a command string which is an init script restart as follows:
./myapp /sbin/service tomcat restart
The command is only half processed!
Tomcat stops and does not start.
The issue (I believe) is that the init script issues a stop and then a seperate start. The initial stop exits with and exit code as expected and this is caught by popen and interpreted as the command finishing when in fact the start part has still not run.
If I run it seperately:
./myapp /sbin/service tomcat stop
and then
./myapp /sbin/service tomcat start
All works fine, which is what makes me think it is the init script returning an exit code before all sides of the "restart" are done.
anyway here is a snippet of my code that is in the child fork:
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
|
// Start processing the command
string send_data = "", start_time = get_time_date();
int MAXBUF = 256;
size_t n = 0;
FILE *stream;
char cmd_buff[MAXBUF];
// I want ALL output to come back to me in the output string!
cmd.append(" 2>&1");
time_t tm_start = Str2DateTime(start_time);
stream = popen(cmd.c_str(), "r");
pid_t proc_pid = getpid();
if (!stream){
exit(1);
}
string curr_time;
double curr_dif = 0.00;
memset(cmd_buff, 0, MAXBUF + 1);
// in case you are wondering
// I am using curr_diff as a means to "time out" the command if 10 seconds
// or more has elapsed
while ((fgets(cmd_buff, MAXBUF, stream) != NULL) && (curr_dif < 10.00)){
curr_time = get_time_date();
time_t tm_curr = Str2DateTime(curr_time);
curr_dif = difftime (tm_curr,tm_start);
n = write( cli_sock, cmd_buff, MAXBUF );
if (n < 0) {
string msg = "";
msg.append(get_time_date());
msg.append(" - ERROR writing to socket.");
WriteLogFile(msg, logfile);
}
}
pclose(stream);
shutdown(cli_sock, 2);
close(cli_sock);
// Now kill the child process
waitpid(proc_pid, NULL, 0);
kill (proc_pid, 9);
|
Can anyone see why this might fail or at least give me some pointers on a better (more ellegant) solution?
If this all looks ok and I am correct that the init script is returning an exit code, is there a way to combat that issue?
Maybe make the popen wait for the true end of the system command and not the first half exiting?
EDIT:
Sorry I pasted code from an earlier revision before, this is the latest and does still have the issue above.