Reputation: 263
I'm trying to write simple c function which would give me possibility to see progress of data transfer from one stream to other stream and display it on my char LCD.
I manage to transfer the data and indicate the progress but how to get result of the piping?
So basically i want to do in c corresponds to shell command:
/home/image.img | md5sum > result
The problem i have i with the stdout. I would like to get it to a char * result.
In other words the md5sum returns a string on the screen like this "5193fd9ebfa30bcb914e7af4760deb15" but i would like to get it to my char * result for further usage in the function.
FILE *in_stream, *out_stream;
#define TRANSFER_BLOCK_SIZE 1048576 //one MB
int n=0;
int i=0;
long int input_size=0;
unsigned char buffer[TRANSFER_BLOCK_SIZE];
if((out_stream=popen("md5sum","w"))==NULL)
{
perror(output_pipe_name);
return 1;
}
if((in_stream=fopen("/home/gregorek/image.img","r"))==NULL)
{
perror(input_file_name);
return 1;
}
//check total size of the input file
fseek(in_stream,0,SEEK_END);
input_size=(ftell(in_stream)/TRANSFER_BLOCK_SIZE)+1;
fseek(in_stream,0,SEEK_SET);
//
do
{
i++;
memset(buffer,'\0',TRANSFER_BLOCK_SIZE);
n=fread(buffer,sizeof(unsigned char),TRANSFER_BLOCK_SIZE,in_stream);
lcd_display(i); //this is my progress indicator
fwrite(buffer,sizeof(unsigned char),n,out_stream);
}
while(!feof(in_stream));
fclose(in_stream);
pclose(out_stream);
return 0;
}
thanks
Upvotes: 0
Views: 1155
Reputation: 263
Thanks Henrik, Here is the code for all of you who wonder how to do it:
int fd_pipe[2], nbytes, status;
char pipe_buffer[1000];
memset(pipe_buffer,'\0',1000);
if(pipe(fd_pipe)!=0)
{
perror("fd_pipe:");
exit(EXIT_FAILURE);
}
pid = fork();
if (pid == -1)
{
perror("Fork failed");
exit(EXIT_FAILURE);
}
else
{
if(pid>0) //The parent's part
{
// Parent process closes output side of the pipe
close(fd_pipe[1]);
//Parent wait's untill the child is done
wait(&status);
// Read in a string from the pipe's input side
nbytes = read(fd_pipe[0], pipe_buffer, sizeof(pipe_buffer));
printf("Received %d chars, string: %s \n", nbytes, pipe_buffer);
//on the end close the other side of pipe
close(fd_pipe[0]);
}
else
{ // The child's part
/* Child process closes input side of the pipe */
close(fd_pipe[0]);
//redirect the stdout(1) to the fd_pipe and then close the sdtout
dup2(fd_pipe[1],1);
//Do the thing which creates the result message
system("/image/"IMAGE_NAME | md5sum");
//on the end close the other side of pipe
close(fd_pipe[1]);
exit(0);
}
}
Upvotes: 1
Reputation: 4314
popen
doesn't really give you what you want here, as it's a specialized library function. Use the system calls fork
and pipe
directly instead.
You use fork
to create a child process and pipe
to redirect stdout
back to the parent process.
See this example for details.
This is incidentally exactly what the shell does when you command it to do this:
cat /home/image.img | md5sum > result
Upvotes: 2