I study the process comunications. Hello everybody. I am studying interprocess communication in C. I am using Pipes as a means of communication. Here is the exercise:
- The child process reads from the file and inserts into the buffer, the parent process reads from the buffer and prints to the screen.
My problem is the following:
I would like to insert the string "quit \ n" at the end of the reading. Unfortunately, when the father prints on the screen, the quit string is concatenated to the last element read.
This is my code :
int main(int argc, char const *argv[])
{
if(argc!=3)
{
perror(">>Error");
exit(1);
}
FILE *r_file, *w_file;
const char* filename= argv[2];
const char* word=argv[1];
int len=0;
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(1);
}
if((r_file = fdopen(pipefd[0], "r"))==NULL){
perror("reader");
exit(1);
}
if((w_file = fdopen(pipefd[1], "w"))==NULL){
perror("writer");
exit(1);
}
char buffer[BUFFER_SIZE];
if(fork()==0)//child R
{
FILE* file;
if((file=fopen(filename,"r"))==NULL)
{
perror("fopen");
exit(1);
}
close(pipefd[0]);
char* n;
while((n=(fgets(buffer,BUFFER_SIZE,file)))!=NULL)
{
printf("leggo:%s",buffer );
fputs(buffer,w_file);
}
fputs("quit\n",w_file);
fclose(file);
exit(0);
}
else
{
printf("- Sono il padre\n");
close(pipefd[1]);
while(fgets(buffer,BUFFER_SIZE,r_file)>0)
{
len=strlen(buffer);
if(buffer[len-1]=='\n') buffer[len-1]='\0';
printf("\nbuffer: %s", buffer);
}
}
}
and this is my output:
leggo:House
leggo:Hello
leggo:Car
leggo:Moto
leggo:House
leggo:Mouse
leggo:City
leggo:Alex
leggo:PC
leggo:Hello
leggo:Hello
buffer: House
buffer: Hello
buffer: Car
buffer: Moto
buffer: House
buffer: Mouse
buffer: City
buffer: Alex
buffer: PC
buffer: Hello
buffer: Helloquit%
as you see
as you see, my last line is
"buffer: Helloquit%".
But I wish that my last line will be
"buffer: quit"
Help me please !!
CodePudding user response:
That is just a problem in your file. If the last line of your file (containing "Hello") doesn't end with a \n
then the 2 last things you fputs
to your parent is "Hello" (without a \n
) and then "quit\n".
So then, the last line your parent will read (it has strictly no way to know you send those in 2 steps. What it does is just reading every till it encounter an EOF or a \n
) is "Helloquit\n"
As for the %
it is probably the prompt of your shell.
Because, in the parent, you remove the \n
from what you receive. But then print with a \n
at the beginning of the line. Reason why you still print 1 word per line. But then the last line (independently of the concatenation Hello quit problem) is printed without a ending \n
.
So, correction:
- For the concatenation Hello quit problem. Either just correct your input file. Or, do in the child the same thing you did with the parent: remove the
\n
if there is one, from the lines you read. And then add it again yourself before fputs (or fprintf, like thisfprintf(w_file, "%s\n", buffer)
). So that you know that each line is ended with a\n
in the communication with parent, whether there was one in the file or not. - For the last line ending with
%
(prompt of your shell), just add aprintf("\n")
at the end. Or, replace theprintf("\n%s", buffer)
by a more logicalprintf("%s\n", buffer)
. I suspect you've chosen this strange position of\n
because otherwise the line is sometimes concatenated with the last "Hello" that doesn't end with a newline. But we have solved that now.
Anyway, we don't really know in which order the print
will occur, since you have 2 independent process. In your demo, it occurs in an apparently orderly fashion, because w_file
is not an interactive file, so flush occurs only when buffer (not yours, the internal buffer of FILE
) is full, or when file is closed (if w_file
was interactive, as stdout is, then buffer is also flushed at each newline).
So, you can't assume anything about how printf from child and printf from parent will be intricated on the shared display they have.
But I am pretty sure, those are only debugging messages anyway, so you don't really care, do you? (you shouldn't, at least)