I'm trying to make a program using the pipe communication. This is what I'm trying to do: the user sends positive integers. If the user sends a negative number the communication ends. The parent process prints the maximum number and the minimum number. This is what I tried:
#include <unistd.h>
#include <stdio.h>
main(){
int pfd[2];
int buff[200];
pipe(pfd);
if(fork()==0){
close(pfd[0]);
int n;
printf("Give a number: ");
scanf("%d",&n);
while(n >=0 ){
write(pfd[1],&n,1);
printf("Give a number: ");
scanf("%d",&n);
}
exit(0);
}
else{
close(pfd[1]);
read(pfd[0],buff,sizeof(buff));
printf("The parent read %d:",*buff);
wait(0);
}
}
This printf("The parent read %d:",*buff);
prints only the first number I gave. Can someone explain to me better what I have to do? How to print all the buffer? Am I writing only 1 number in the buffer and that's it? How do I find the maximum and the minimum number? I am very confused! :(
This is a way to do what I think you're trying to do with a very few modifications. Notice that
buff
is no longer an array and that we use the pipe itself as temporary storage as we print the numbers.It might be because
*buff
is a single integer, but you wrote more than one.If you want to print all integers sent, then you need to know how many was transfered, and then print them in a loop.
You also have a problem because you only send one byte of the integer (which is normally four bytes). You should use e.g.
This
only writes one byte. You need this:
This reads whatever is available in the pipe buffer
It blocks until there is something to read and then returns however many bytes it actually has read. The likely sequence is:
Your parent needs to keep reading until it has all the numbers it expects or end of file is reached (signified by read returning 0). Something like this:
Note that, theoretically, you might not even read all four bytes of the int in one go, although, I think, in practice with pipes, this won't happen.
I believe that you don't understand that
<stdio.h>
functions (likescanf
andfprintf
) are different of raw I/O syscalls like read(2) andwrite(2)
(actuallyprintf
andfprintf
can callwrite(2)
and you may force them to do that withfflush
)I don't understand what is the protocol you are wanting on the pipe. It seems that you want to send raw bytes (then you are restricted to 0-255). Or do you want to send each number in ASCII, one per line?
Perhaps you could do (assuming the protocol is textual, numbers in ASCII, one per line) in the parent process
and in the child process
If you want to use only low-level I/O syscalls (i.e.
read(2)
andwrite(2)
) you have to manage buffering by yourself (so, take into account the result ofread
andwrite
syscalls, which may be a partial count of bytes read or written).Don't forget to compile with
gcc -Wall -g
(all warnings and debugging information) and learn to usegdb
for debugging.