linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jason <lcprog@lakedaemon.net>
To: Michele Mondelli <mithenks.ml@gmail.com>, jai.unix@gmail.com
Cc: linux-c-programming@vger.kernel.org
Subject: Re: command output to variables
Date: Sat, 10 Jan 2009 09:57:07 -0500	[thread overview]
Message-ID: <4968B743.5080005@lakedaemon.net> (raw)
In-Reply-To: <dbe330bd0901070533g4b49d451u12c70eed805e145b@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1573 bytes --]

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 <mithenks@siena.linux.it>
>  *
>  */
> #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.

[-- Attachment #2: pipe.c --]
[-- Type: text/plain, Size: 1055 bytes --]

/*
 * Run the 'ls' command and print the output to stdout.
 * 
 * Compile with 
 * 		gcc -Wall pipe.c -o pipe
 * 
 * 
 * Mithenks <mithenks@siena.linux.it>
 * Changes added by Jason <lcprog@lakedaemon.net>
 * 
 */
#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);
}

  parent reply	other threads:[~2009-01-10 14:57 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-07 12:35 command output to variables Jai Sharma
2009-01-07 12:54 ` Xin Zou
2009-01-07 13:33 ` Michele Mondelli
2009-01-07 14:59   ` Jai Sharma
2009-01-10 14:57   ` Jason [this message]
2009-01-07 14:31 ` Bert Wesarg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4968B743.5080005@lakedaemon.net \
    --to=lcprog@lakedaemon.net \
    --cc=jai.unix@gmail.com \
    --cc=linux-c-programming@vger.kernel.org \
    --cc=mithenks.ml@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).