QProcess not reading process output
-
Hi all,
I have built a GUI to monitor the results of a test on a Linux machine. On this GUI I have a text browser that I want text to be appended to as the test runs. The program that runs the actual test is a console based application. As it runs, text will output to the Linux terminal. First I declare a new QProcess in the private section of the header file of the class like below.
QProcess *exec = new QProcess(this);
Then here is my code for the rest of the QProcess.
void TestStart::testRunning() { exec->setProcessChannelMode(QProcess::MergedChannels); connect(exec, &QProcess::readyReadStandardOutput, [=] {ui->textBrowser_3->append(exec->readAllStandardOutput());}); connect(exec, &QProcess::readyReadStandardError, [=] {ui->textBrowser_3->append(exec->readAllStandardError());}); QStringList params; params << "google.com"; QString ping = "ping"; QString program = "/home/personal/code/CODE/Example/SigqueueHandling/Program/ReceiveSig"; //exec->start(ping, params); //exec->setWorkingDirectory("/home/personal/code/CODE/Example/SigqueueHandling/Program"); exec->start(program); }
When I uncomment exec->start(ping, params) and comment exec->start(program), the GUI works exactly like it should. That is, the ping command works exactly how I would want my test program to work.
When I uncomment exec->start(program) and comment exec->start(ping, params) and run the GUI, there is no output to my text browser like I expect. When I close the GUI I get the message in the QT Console that QProcess: destroyed while running for program. So I THINK that the program ReceiveSig is at least starting.
I have verified that the directory in program is correct, as when I put that command to the terminal it runs my ReceiveSig program just fine. I am at a loss and any hints would be greatly appreciated. Why is my ReceiveSig program's output not being read by QProcess?
-
@camtheman99
May depend on howReceiveSig
sends its output, for example it might buffer its output so it doesn't arrive till program end. We don't know. -
ReceiveSig should send out hello world via std::cout every second, while the program is running. After ReceiveSig receives a signal from another program, the text will change to say something else.
I figured the ping command works similar to what I have going on in ReceiveSig, so I expected the same behavior. I should also mention that when I close the GUI without stopping the process, I get the error message in the QT console that the process at /home/personal/code/CODE/Example/SigqueueHandling/Program/ReceiveSig was destroyed while running. This tells me that the process ReceiveSig should be running.
Does std::cout buffer the output somehow?
-
@camtheman99 said in QProcess not reading process output:
Does std::cout buffer the output somehow?
It's always buffered ...
See https://en.cppreference.com/w/cpp/io/manip/endl -
Here is the code for ReceiveSig:
//includes below #include <stdlib.h> #include <iostream> #include <unistd.h> #include <stdlib.h> #include <signal.h> void myHandler(int signum, siginfo_t *info, void *extra) { int SigVal = info->si_value.sival_int; if(signum == SIGUSR1) { if(SigVal == 1) { std::cout << "This is signal 1!\n"; } else if(SigVal == 2) { std::cout << "This is signal 2!\n"; } else if(SigVal == 3) { std::cout << "This is signal 3!\n"; } } } int main(){ struct sigaction act; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; act.sa_sigaction = &myHandler; sigaction(SIGUSR1, &act, 0); std::cout << "I am right before the while loop\n"; sleep(1); while(1) //this loop repeats forever only to be interrupted by SIGUSR1 { std::cout << "Hello World!\n"; sleep(1); } }
I will reiterate that ReceiveSig works perfectly when I run ./ReceiveSig from the terminal. Should I use something else instead of std::cout? QProcess should work with an infinite loop right? I do not want to waitForFinished, as that will just block the rest of the program forever.
-
@camtheman99 said in QProcess not reading process output:
Should I use something else instead of std::cout?
Did you actually read my post and the links I poosted?
-
@camtheman99
The usual behaviour for stdout buffering is: when outputting to terminal line buffered, so sending\n
flushes the buffer, but when outputting to a file or pipe (like when run as a sub-process not connected to a terminal) block buffered, meaning output not flushed until a fair amount has been sent (4k?) or process flushes on exit. Could this describe what you are seeing?UPDATE In any case, why don't you put
endl
s into your client code like @Christian-Ehrlicher says and see if that gives you what you are asking for? -
Hey guys, I updated my code to include std::endl instead of "\n" and it worked how I expected! I had no idea there was such a distinction between the two as I hadn't run into this before. Thank you both for your input.
-
@camtheman99
That is interesting, thanks to @Christian-Ehrlicher.