I am running a subprocess call to the unix ps utility in a loop with a frequency of about 20 Hz. This works well for some time, but at some point in time, pstreams reports a weird exit status of the ps subprocess. This status does not make any sense at all to me and seems to be wrong, because I have put the same ps call into a while loop in my shell and it runs forever without errors.
This is a condensed form of what I am doing:
redi::ipstream in("ps --no-headers -eo ppid,pid",
redi::pstreams::pstdout | redi::pstreams::pstderr);
string s;
while (getline(in, s)) {
// here I do some output parsing.
}
int status = in.rdbuf()->status();
if (status != 0) {
cout << "STATUS: " << status << endl;
cout << "WIFEXITED: " << WIFEXITED(status) << endl;
cout << "WEXITSTATUS: " << WEXITSTATUS(status) << endl;
cout << "WIFSIGNALED: " << WIFSIGNALED(status) << endl;
cout << "WTERMSIG: " << WTERMSIG(status) << endl;
cout << "WIFSTOPPED: " << WIFSTOPPED(status) << endl;
cout << "WSTOPSIG: " << WSTOPSIG(status) << endl;
cout << "WIFCONTINUED: " << WIFCONTINUED(status) << endl;
// print output from stderr
in.clear();
string s;
cout << "Error:" << endl;
while (getline(in.err(), s)) {
cout << s << endl;
}
cout << "Error end" << endl;
}
As said, this works well for thousands of iterations, but with a high probability, it fails at some point in time. The output I see for the different interpretations of the status code is the following:
STATUS: -1
WIFEXITED: 0
WEXITSTATUS: 255
WIFSIGNALED: 0
WTERMSIG: 127
WIFSTOPPED: 0
WSTOPSIG: 255
WIFCONTINUED: 0
Error:
Error end
How can it be that neither there is error output, nor there was a return code from the process or anything like a TERM signal?
I just noticed that it might be necessary to call close in the ipstream instance before having the status set correctly. I implemented this strategy, but still i encounter the exact same error.
http://pstreams.sourceforge.net/doc/classredi_1_1basic__pstreambuf.html#a6b8782afacf7c7f92617798499f46702
Are you calling wait() to ensure the process has exited?
How can I call this? It is a protected method.
By calling one of the functions that call wait(), e.g. close()
I see in your second comment you say you added that. Without that your code was definitely wrong. I don't know if it's still wrong without seeing the code.
If status() returns -1 then it means you haven't waited for the process to exit.
I think I found the issue. I have created a situation where too many files were open, so starting the subprocess in the first place failed because no more pipes could be created. I probably should also check whether the stream is good before starting to read from it.
Ok, this issue can be closed. When checking the good flag of the stream, the error becomes evident.
OK, thanks for the follow-up