Reputation: 29
Let‘s assume we have a pipe int InPipe[2];
. How can you read the input until the pipe is empty without blocking when the whole available Data input was read?
I know this question has been asked several times, but I couldn’t assemble a suitable function.
This is my Code so far:
int InPipe[2];
char buffer[1024];
int rc;
while (true){
read(InPipe[0], buffer, sizeof(buffer));
fprintf(stdout, “%s“, buffer);
bzero(&buffer, sizeof(buffer)); // Clearing Buffer
}
Any Ideas, Suggestions, Code Snippets
Upvotes: 1
Views: 1383
Reputation: 23228
There are a couple of key things mentioned in the comments, i.e. non-blocking IO, and performing the read in its own thread, along with some other suggestions. The example here goes into detail explaining its architecture. Only the code section is reproduced below as I believe it to be a decent illustration of several of these comments. The example code is commented throughout. Read them, they serve as a good tutorial:
// C program to demonstrate use of fork() and pipe()
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<string.h>
#include<sys/wait.h>
int main()
{
// We use two pipes
// First pipe to send input string from parent
// Second pipe to send concatenated string from child
int fd1[2]; // Used to store two ends of first pipe
int fd2[2]; // Used to store two ends of second pipe
char fixed_str[] = "forgeeks.org";
char input_str[100];
pid_t p;
if (pipe(fd1)==-1)
{
fprintf(stderr, "Pipe Failed" );
return 1;
}
if (pipe(fd2)==-1)
{
fprintf(stderr, "Pipe Failed" );
return 1;
}
scanf("%s", input_str);
p = fork(); //Note - the return of fork can be less than, greater
// than or equal to zero. Each is significant in
// knowing how to direct program flow, as shown
// in this section...
if (p < 0)
{
fprintf(stderr, "fork Failed" );
return 1;
}
// Parent process
else if (p > 0)
{
char concat_str[100];
close(fd1[0]); // Close reading end of first pipe
// Write input string and close writing end of first
// pipe.
write(fd1[1], input_str, strlen(input_str)+1);
close(fd1[1]);
// Wait for child to send a string
wait(NULL);
close(fd2[1]); // Close writing end of second pipe
// Read string from child, print it and close
// reading end.
read(fd2[0], concat_str, 100);
printf("Concatenated string %s\n", concat_str);
close(fd2[0]);
}
// child process
else
{
close(fd1[1]); // Close writing end of first pipe
// Read a string using first pipe
char concat_str[100];
read(fd1[0], concat_str, 100);
// Concatenate a fixed string with it
int k = strlen(concat_str);
int i;
for (i=0; i<strlen(fixed_str); i++)
concat_str[k++] = fixed_str[i];
concat_str[k] = '\0'; // string ends with '\0'
// Close both reading ends
close(fd1[0]);
close(fd2[0]);
// Write concatenated string and close writing end
write(fd2[1], concat_str, strlen(concat_str)+1);
close(fd2[1]);
exit(0);
}
}
Upvotes: 3
Reputation: 2940
Reading from a pipe
Attempts to read from a
pipe
that is currently emptyblock
until at least one byte has been written to thepipe
. If the write end of a pipe is closed, then a process reading from the pipe will seeend-of-file
(i.e.,read()
returns 0) once it has read all remaining data in thepipe
.
taken from linux interface programming.
You cant! the process reading from the pipe will be blocked in this situation.
Due to people comments, i am adding this section:
we can use a pipe
to allow communication between two processes. To con-nect two processes using a pipe, we follow the pipe()
call with a call to fork()
. immediately after the fork()
, one process closes its descriptor for the write end of the pipe, and the other closes its descriptor for the read end. For example, if the parent is to send data to the child, then it would close its read descriptor for the pipe, filedes[0]
, while the child would close its write descriptor for the pipe, filedes[1]
, then the code for this will be:
int filedes[2];
if (pipe(filedes) == -1) /* Create the pipe */
errExit("pipe");
switch (fork()) /* Create a child process */
{
case -1:
errExit("fork");
case 0: /* Child */
if (close(filedes[1]) == -1) /* Close unused write end */
errExit("close");
/* Child now reads from pipe */
break;
default: /* Parent */
if (close(filedes[0]) == -1) /* Close unused read end */
errExit("close");
/* Parent now writes to pipe */
break;
}
Upvotes: 3