PDA

View Full Version : software that can't be run from a terminal



Gh0str1d3r
7th October 2010, 10:51
Hi,

I have written a qt program that is designed to perform the communication with another console program, which I otherwise would have to do myself. It is very simple:


QProcess process;
process.start("<external terminal program>");
process.waitForStarted();
QString processOutput;

// read the program's output and react appropriately
while( process.state() == QProcess::Running )
{
// the information could be either in the stout or sterr channel,
// so we need to poll these
QString stout;
QString sterr;
for(int i=0; i<100; i++)
{
process.setReadChannel(QProcess::StandardOutput);
process.waitForReadyRead(10);
stout = process.readAllStandardOutput();
if( !stout.isEmpty() )
break;

process.setReadChannel(QProcess::StandardError);
process.waitForReadyRead(10);
sterr = process.readAllStandardError();
if( !sterr.isEmpty() )
break;
}

processOutput += stout + sterr;

if(processOutput.contains("successfully"))
{
qDebug("success");
process.waitForFinished(1000);
return 0;
}

if( stout.isEmpty() && sterr.isEmpty() )
{
qDebug("process does not answer. terminating.");
process.waitForFinished(1000);
return 1;
}

if(stout.contains("[y/n]"))
{
process.write("y\n");
}

if(stout.contains("Username:"))
{
process.write("<Username>\n");
}

if(sterr.contains("Password:"))
{
process.write("<Password>");
}
}

Before someone starts a discussion about security and that one should not circumvent password prompt: This is not the topic here!

So the topic is, why this software does not run in a terminal. there, it keeps on waiting for a true user input, and ignores the pipe from the program. Is there a way to fix this?

The program runs fine in kdevelop, or when "clicking on the icon", and even when it is executed by a daemon (start-stop-daemon in an init script).

wysota
7th October 2010, 11:16
Before someone starts a discussion about security and that one should not circumvent password prompt: This is not the topic here!
Is it the topic here that you are reinventing the wheel?

http://expect.sourceforge.net/


So the topic is, why this software does not run in a terminal.
What does "does not run in a terminal" mean?

Gh0str1d3r
7th October 2010, 11:50
yes, probably I reinvented the wheel. Sometimes it requires more effort to search for an existing solution rather than quickly solve it yourself.

"does not run in a terminal" means that the automatic answering of the prompts is not performed when I run the software from a shell. That is, it still waits for a true user input, which is not what it should do.

wysota
7th October 2010, 11:54
yes, probably I reinvented the wheel. Sometimes it requires more effort to search for an existing solution rather than quickly solve it yourself.
I guess the "quickly" idea backfired then :) It's not hard to do something "quickly wrong" and when facing a similar problem in future do it "quickly wrong" again but effectively you waste more time than if you did a proper reaseach first looking for a ready solution that would work in both cases.


"does not run in a terminal" means that the automatic answering of the prompts is not performed when I run the software from a shell.
So the software runs but it does not work the way you want it, yes?


That is, it still waits for a true user input, which is not what it should do.
Maybe the process you spawn detects it has a terminal available and expects the input to come from the terminal and not stdin.

Gh0str1d3r
7th October 2010, 12:13
I guess the "quickly" idea backfired then :) It's not hard to do something "quickly wrong" and when facing a similar problem in future do it "quickly wrong" again but effectively you waste more time than if you did a proper reaseach first looking for a ready solution that would work in both cases.

Maybe you are write. Still, this way I may as well learn something about Qt. The reason why I am asking is because I don't want to do it wrong.


So the software runs but it does not work the way you want it, yes?

yes.


Maybe the process you spawn detects it has a terminal available and expects the input to come from the terminal and not stdin.

I guess so. So the original question could equally have been "how do I have to modify my code to force the external process to expect its input from stdin?"

btw: why does the biggest and most highlighted button (i.e. "Reply to Thread") irreversibly delete the text that one has written using "quick reply"?? very frustrating...

wysota
7th October 2010, 12:54
So the original question could equally have been "how do I have to modify my code to force the external process to expect its input from stdin?"
Detach your program from the terminal (using native api) before spawning the child process.


btw: why does the biggest and most highlighted button (i.e. "Reply to Thread") irreversibly delete the text that one has written using "quick reply"?? very frustrating...
True.

Gh0str1d3r
7th October 2010, 13:10
thanks, running


# ./a.out&

(i.e. with the &) works!

EDIT: no, it doesn't, it only looks good at first glance.

wysota
7th October 2010, 13:21
That's not the most straightforward way. Use fork(), daemon(), setsid() or something similar in your program.

Gh0str1d3r
7th October 2010, 13:29
many thanks, these commands were completely new to me. now it really works (with the &, this was not true).