Re: command output to variables

Jason <[email protected]>
Newsgroups org.kernel.vger.linux-c-programming
Message-ID <[email protected]>
Michele Mondelli wrote:
> A simple example of using pipe in Linux.
>
> /*
>  * Run the 'ls' command and print the output to stdout.
>  *
>  * Compile with
>  * 		gcc -Wall pipe.c -o pipe
>  *
>  *
>  * Mithenks <[email protected]>
>  *
>  */
> #include <stdio.h>
> #include <stdlib.h>
>
> int main() {
> 	
> 	FILE *pipe;
> 	char buffer[1024];
> 	
>	if ( (pipe = popen("ls","r") ) < 0 ) {

This should be:
	if ( (pipe = popen("ls","r") ) == NULL ) {

> 		perror("popen(): ");
> 		exit(-1);
>	}
> 	
> 	

Don't forget to clear the buffer, printf requires NULL terminated strings.
	memset(buffer, 0, sizeof(buffer));

> 	fread(buffer,sizeof(buffer),1,pipe);

In a real implementation, you'll be looping on fread(), and you'll want
to check the return value, like so:

	int rlen=0;
	if ( (rlen = fread(buffer,sizeof(buffer),1,pipe) ) != 1 ) {
		/*we have a short read or error*/
		if( feof(pipe) != 0 ) {
			printf("Finished\n");
			exit(0);
		}
		else if ( ferror(pipe) != 0 ) {
			printf("Error reading from pipe.\n");
			exit(-1);
		}
	}

> 	printf("Output:\n%s\n",buffer);
> 	
> 	pclose(pipe);
> 	
> 	return 0;
> }

So, that got a little messy, I've attached a re-write.  It's not the
most efficient thing in the world, but it should get you started.

When in doubt, 'man function_name'.  For example, 'man popen' told me I
should be checking for a NULL return value, and 'man fread' told me I
should be checking the number of items returned, _not_ the number of
bytes.  'man brain' returned NULL for me, so any errors are solely my
responsibility.  ;-)

hth,

Jason.
pipe.c (text/plain, 1 KB)
/*
 * Run the 'ls' command and print the output to stdout.
 * 
 * Compile with 
 * 		gcc -Wall pipe.c -o pipe
 * 
 * 
 * Mithenks <[email protected]>
 * Changes added by Jason <[email protected]>
 * 
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
	
	FILE *pipe=NULL;
	char buffer[1024];
	int  rlen=0;
	int  blen=0;
	
	if ( (pipe = popen("ls","r") ) == NULL ) {
		perror("popen(): ");
		exit(-1);
	}

	/*we subtract 1 so there is always a NULL terminator*/
	blen = sizeof(buffer) - 1;

	while (1) { 
		memset(buffer,0,sizeof(buffer));

		if ( (rlen = fread(buffer,blen,1,pipe) ) != 1 ) {
			/*we have a short read or an error*/
			if ( feof(pipe) != 0 ) {
				fprintf(stderr,"Finished");
				printf("%s",buffer);
				break;
			}
			else if ( ferror(pipe) != 0 ) {
				fprintf(stderr,"Error reading from pipe.\n");
				break;
			}
			else {
				/*short read*/
				printf("%s",buffer);
			}
		}
		else {
			/*we got a full buffer*/
			printf("%s",buffer);
		}
	}

	if(pipe != NULL) {	
		pclose(pipe);
	}
	
	exit(0);
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.