Running external program using C and read the result output
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Running external program using C and read the result output
I am running some external executable inside C and getting the output from the executable using pipe like below:
1. create pipe
2. fork a child process to execute the program
3. parent reads from pipe
I know in Perl there is something pretty easy like:
my $result = qx (command);
Scalar $result will contain all std output from the command, just wondering if C has the same thing ? A pipe reads is working but seems too much work ?
Before anyone suggests it, don't use popen. You'll need to fork at the very least so that you can replace standard out for the command to be executed. Look at the manpages for pipe, dup2, fork, system, and execv. I haven't told you how to set it up because I'm not quite sure the context; e.g. is it a one-time thing, do you need continued communication with the command, does your program need to do something else in the meantime, does your program need to wait until the other command finishes, does your program need to kill the command when it exits, does the command need terminal access, is it merely a command name and arguments or does it have shell operators, does it need to run under the same user or a different one? I'm sure I've forgotten something.
Kevin Barry
I got confused about that too... was pipe a mostly used way (if not only) for that ? I guess it might also be the low-level behaviors behind that perl 'qw' command ?
Quote:
Originally Posted by Hko
Why's that?
It would be the easiest way to do it, and would be closest to the perl example the OP mentioned.
Why's that?
It would be the easiest way to do it, and would be closest to the perl example the OP mentioned.
I'm not dead-set against it, but you don't have control over the process when you use it (especially the pipe direction you didn't choose,) and I've seen implementations that didn't account for already having a lot of files open.
Kevin Barry
I got confused about that too... was pipe a mostly used way (if not only) for that ? I guess it might also be the low-level behaviors behind that perl 'qw' command ?
pipe is usually used to create a descriptor pair before forking. After forking, dup2 is often used to replace standard input or output with the pipe, followed by system or execv, allowing the parent to communicate with the child using its standard input and output.
Kevin Barry
The system( ) function does not return until there is an exit from the
command string. This is why folks have mentioned fork() and execv() --
both of which will return to the caller before the command exits.
Also, Just because the command passed to system(...) does a write does not mean that a file is visible to the subsequent fopen(...). As I recall, you need open+write+close before a following fopen will see a file that exists. An alternative requires that there is enough written to force a buffer flush, or an explicit call to flush() or similar in the code.
It has been a long time since I coded at this detail level, so I'm sure there are things forgotten. I hope these comments give you helpful things to think about.
The called "popen()/fgets ()/pclose()" are probably the ideal solution to your problem.
No tool is right for every job - but I'm frankly not aware of any issues or problems of any kind with "popen()". Certainly none that you wouldn't ALSO face if you did the "fork()/exec()/pipe()/etc" all yourself.
funnily enough I've been playing with this today,
a function helper that runs like execlp(3)
after which you can read the output from stdin.
(not tidied up yet)
Distribution: Damn Small Linux, KateOs, M$ Ickdows Vista, My own OS
Posts: 2,094
Rep:
Quote:
Originally Posted by SaintDanBert
The system( ) function does not return until there is an exit from the
command string. This is why folks have mentioned fork() and execv() --
both of which will return to the caller before the command exits.
Also, Just because the command passed to system(...) does a write does not mean that a file is visible to the subsequent fopen(...). As I recall, you need open+write+close before a following fopen will see a file that exists. An alternative requires that there is enough written to force a buffer flush, or an explicit call to flush() or similar in the code.
It has been a long time since I coded at this detail level, so I'm sure there are things forgotten. I hope these comments give you helpful things to think about.
~~~ 0;-Dan
But maybe its better to wait for the child to finish before your read the output?
But maybe its better to wait for the child to finish before your read the output?
Better depends on the context. It sounds like the OP wants his parent process to interact with the child. That is the whole point of having popen(). The downside of popen() versus pipe()+fork()+exec() is that popen() launches a shell, which may be useless.
A couple of websites provide useful samples and tutorials for contrast:
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.