Re: [pstreams-users] Empty process output
Brought to you by:
redi
From: Jonathan W. <pst...@ka...> - 2013-02-06 13:19:32
|
On 6 February 2013 11:04, Johannes Wienke wrote: > Hi, > > I am trying to use pstreams to get the output from a system call to the > Unix pstree command. On stackoverflow I found the following post: > http://stackoverflow.com/questions/5309020/how-to-get-the-full-stream-output-with-pstreams/5309174 > > So what I am currently using is this code to read the output: > > redi::ipstream in(boost::str(boost::format("pstree -pa %d") % pid)); > std::stringstream ss; > ss << in.rdbuf(); > std::string pstreeOut = ss.str(); > > if (pstreeOut.empty()) { > throw NoSuchProcessException(pid); > } > > Most of the time this works, but sometimes the exception is triggered. I > had the suspicion that this code actually doesn't wait for pstree to > finish. Is anything wrong with the way I us pstrees? Hi, The expression 'ss << in.rdbuf()' will read from the pstreambuf until End-Of-File is reached, which will only happen when the child process closes its end of the pipe, which in your program will happen after 'pstree' exits. So it should always wait for 'pstree' to finish, as demonstrated by this program which takes 5 seconds to print the output, because it has to wait for the child to finish sleeping and exit: #include <pstreams/pstream.h> #include <sstream> #include <iostream> int main(int argc, char** argv) { std::string pid = argc > 1 ? argv[1] : "1"; redi::ipstream in("pstree -pa " + pid + " && sleep 5"); std::stringstream ss; ss << in.rdbuf(); std::string pstreeOut = ss.str(); if (pstreeOut.empty()) { throw std::runtime_error("No such process: " + pid); } std::cout << pstreeOut << '\n'; } My guess would be that the process you are trying to inspect has exited and so pstree produces no output. On my GNU/Linux system 'pstree' doesn't print an error or exit with non-zero status for a non-existent PID, which isn't very helpful. If the processes you are trying to view are owned by you then you could use this command: boost::format("kill -s 0 %d 2>&1 && pstree -pa %d") % pid % pid The kill command will not send a signal, but will print an error and exit with a non-zero status if the process doesn't exist. |