Hello I have seen some solutions on the internet, all of them are basically creating a file, however I want to store them in an array of char. Speed is really important for me and I don't want to spend any time for working on hard drive. So popen() is not a real solution for me.
5 Answers
Here is a working code snippet:
char bash_cmd[256] = "ls -l";
char buffer[1000];
FILE *pipe;
int len;
pipe = popen(bash_cmd, "r");
if (NULL == pipe) {
perror("pipe");
exit(1);
}
fgets(buffer, sizeof(buffer), pipe);
len = strlen(buffer);
buffer[len-1] = '\0';
pclose(pipe);
1 Comment
buffer variable not bash_cmd after fgetsIf you would read the manpage of popen, you would notice the following:
The popen() function opens a process by creating a pipe, forking, and invoking the shell. [...] The return value from popen() is a normal standard I/O stream in all respects save that it must be closed with pclose() rather than fclose(3). [...] reading from a "popened" stream reads the command's standard output, and the command's standard input is the same as that of the process that called popen().
(emphasis mine)
As you can see, a call to popen results in the stdout of the command being piped into your program through an I/O stream, which has nothing to do with disk I/O at all, but rather with interprocess communication managed by the operating system.
(As a sidenote: It's generally a good idea to rely on the basic functionality of the operating system, within reason, to solve common problems. And since popen is part of POSIX.1-2001 you can rely on it to be available on all standards compliant operarting systems, even windows)
EDIT: if you want to know more, read this: http://linux.die.net/man/3/popen
Comments
Never forget Knuth's saying that "premature optimization is the root of all evil". Don't worry about performance until it matters, and then measure before doing anything. Except for very rare situations, the value of your time is much higher than the cost of the program runs.
Jon Bentley's "Writing efficient programs" (sadly out of print, in his "Programming Pearls" one chapter is a summary) is a detailed discussion on how to make programs run faster (if it is worthwhile); and only as the very last measure, to squeeze out the last possible 2% of performance (after cutting run time down by half) it recommends using changes like you propose. The cited book includes some very entertaining war stories of "performance optimizations" that were a complete waste (optimize code that isn't ever used, oprimize the code run while the operating system twiddles its thumbs, ...).
Comments
If speed is important to you, you can write your own version of popen.
It may make sense, since popen() - creates a pipe - forks - executes the shell (very expensive!) - the shell than creates a pipe, forks, executes your program
Your customized version could reduce the procedure to: - creates a pipe - forks - executes your program
You could even extend popen to control the commands STDOUT, STDERR and STDIN seperately. I wrote such a routine, see https://github.com/rockdaboot/mget/blob/master/libmget/pipe.c It is GPL'ed.
You call mget_popen3() with FILE pointers or mget_fd_popen3() with file descriptors. At least, it should give you an idea on how to do it.
Comments
Do you mind having more than one C programs?If you don't ,you can make use of the command line arguments. In the fist C program you can do the following
system("YourCommand | SecondProgram");
The SecondProgram will be the "executable" of the second C program you will be writing. In the second C program you can receive the output of the command YourCommand as a command line argument in the SecondProgram. For that purpose you may begin the main() of second C program as below
main(int argc,char *argv[])
The array argv will have the output of the YourCommand and argc will contain the number of elements in the array argv.
popendoesn't open a file. It runs a program and connects the output directly to a C input stream. I know the stream's type is calledFILE*but it's not really a file.popen? That would be the normal way to do this.man 3 popenit contains everything you need to know, including whypopenis the way to go here.