LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-01-2008, 11:26 AM   #1
aw_wolfe
Member
 
Registered: Apr 2005
Posts: 50

Rep: Reputation: 15
Question C++ popen return EOF second time


I have a function that uses popen to read output of shell command and return in a string...note: there are many examples of this out there on the web, I've tried several, so below is only the latest used and may not be the best one, however, the problem occurs with every example I've used.

Function works great(all multiple versions of it) the first time used. The second time however, the first read on the stream causes an EOF and thus exits (whether fgetc or fgets --not shown in the current version). Note at no time are any errors detected...perror("after eof") produces success message.

Note::I've validated that the cmd is valid and should infact return something.

Is something not getting reset? Hold over from previous popen that the fflush(NULL) isn't getting? How do I need to ensure a clean read?

Thanks,

Tony

string readpopen(string cmd)
{
fflush(NULL);

string data;
FILE *stream;
char buffer[1];
data.reserve(1024);

stream = popen(cmd.c_str(), "r");
if(stream==NULL)
{
perror("popen");
return "";

}
while (true)
{
int c=fgetc(stream);
if(c==EOF) //second time used, always first read is EOF
{
perror("after eof");
break;
}


data.push_back((char)c);

}
if(ferror(stream))
{
perror("Read stream:");
}
pclose(stream);

if (data.empty())
{
data="";
}

return data;
}

Last edited by aw_wolfe; 09-01-2008 at 11:28 AM. Reason: more information
 
Old 09-01-2008, 02:05 PM   #2
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
The command's return doesn't transmit through the pipe. I don't think you can get the return using popen, just its standard output. Normally you'd get the return with system, but then you don't get standard output unless you fork and replace file descriptors. It can be very complicated.

What do you mean by "second time"? Does that mean a second call to readpopen from the same process instance, or the second iteration of the while loop? I don't understand the error.
ta0kira

PS I find it difficult to read your code. Please 1) enclose it in [code][/code] and 2) incrementally indent your nested {} so it's easy to tell the level of scope. Thank you.

PPS popen doesn't have anything to do with C++, or even standard C. It's a part of POSIX C, so you'd have this problem even in a C program.

Last edited by ta0kira; 09-01-2008 at 02:13 PM.
 
Old 09-01-2008, 04:22 PM   #3
aw_wolfe
Member
 
Registered: Apr 2005
Posts: 50

Original Poster
Rep: Reputation: 15
Sorry about the readability issue of the code. 1) It's been a long day and I'm skipping in my thoughts. 2) code really wasn't the issue, I know the code 'works'. It's really an 'environment issue/question'.

So let me try and slow down a bit....

I have a function that reads from a popen (cmd)...an example cmd might be "ps axo pid,cmd|grep 'app -k something -c somethingelse'" (please don't get hung up on this). This is defined in a common.h file.

It works fine if called from a straight c application. I getline(cin,cmd)--so clean string-nothing hidden in it-- and call function with cmd. Works multiple times.
It was failing the second time the function was called from within a c++ class. I've broken the pipes down and apart....so not doing "ps ....|grep" rather just one at a time. So if I do a "ps axo pid,cmd" for example and read the lines one at a time using a fgets

//keep in mind I'm looking for this in this example..... app -k something -c somethingelse

In the straight c code it reads this fine and finds what I'm looking for....eventually one of the strings is 'app -k something -c somethingelse'
In the C++ code that calls the exact same function in the exact same header file only returns "app -k something -c". So it would seem that something about the C++ environment is causing the read (fgets) on the pipe to think the "-c" is at the end of line or end of read or potentially something else (but what I'm not sure).
 
Old 09-01-2008, 09:46 PM   #4
aw_wolfe
Member
 
Registered: Apr 2005
Posts: 50

Original Poster
Rep: Reputation: 15
Well figured it out...
so just to let anyone else know if they didn't already.

Seems from the c++ application the environment was set for a width of 80 chars. So when the popen ('ps...') was trying to read it was failing because the string we were trying to match was over 80 chars. For some reason when popen ('ps ...') from c application (even though exact same function from exact same header file) the environment width was wider, so there wasn't an issue finding the strings because they were not truncated. Solution was to manually increase the width of the ps output with '-w -w' flags. I have no idea why there was the environmental difference but that was what was causing the problem.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Help using popen and execl cdog Linux - Software 3 02-28-2007 06:44 PM
popen for windows csfalcon Programming 6 11-30-2005 08:21 AM
C Popen gold5angel Programming 2 04-17-2004 07:07 PM
After some hard time, a script to return your IP frandalla LinuxQuestions.org Member Success Stories 3 01-29-2004 01:15 PM
dash every time i hit enter (carriage return) in gnome (rh 9) lynchmob09 Linux - Software 1 09-18-2003 12:38 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:11 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration