Reputation: 137
I am trying to send two messages from the parent to the receiver. Only one is received. Receiver uses stdin and stdout for the pipe, and outputs its results into std err. Here is my code.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
int main(int argc,char * argv[])
{
char buffer[100]; // The pipe's buffer
int pipes[2];
pid_t childpid;
if ( pipe(pipes) ){
fprintf(stderr,"FATAL ERROR IN PIPE");
}
if((childpid = fork()) == -1){
perror("fork");
exit(1);
}
if(childpid == 0){
close(pipes[1]);
dup2(pipes[0],STDIN_FILENO);
scanf("%s\n",buffer);
fprintf(stderr,"REC: %s\n",buffer);
scanf("%s\n",buffer);
fprintf(stderr,"REC: %s\n",buffer);
sleep(50);
}
else
{
close(pipes[0]);
// Read in a string from the pipe
char* arr = "HelloWorld\n";
write(pipes[1],arr,strlen(arr)+1);
write(pipes[1],arr,strlen(arr)+1);
sleep(50);
}
return 0;
}
Upvotes: 4
Views: 1022
Reputation: 26800
One problem is with the following line:
scanf("%s\n",buffer);
scanf
does not read trailing white space (including new-line characters) unless matched by a directive. But the directive exists here. So it waits for another new line after the usual new line which follows the input.
Remove the \n
in both the scanf
statements.
Secondly, you have to modify your fprintf
statements to add the \n
in them.
fprintf(stderr,"REC: %s\n",buffer);
Thirdly, don't add 1 to the strlen(arr)
in write
. Modify it to:
write(pipes[1],arr,strlen(arr));
It works. See live demo:
Output:
REC: HelloWorld
REC: HelloWorld
Real time: 2.082 s
User time: 0.043 s
Sys. time: 0.037 s
CPU share: 3.85 %
Exit code: 0
Upvotes: 0
Reputation: 60107
The problem is the strlen(arr)+1
part. You're sending the terminating nul
as well and that nul
ends up making up the second "string" read by scanf
:
REC: HelloWorld
REC:
If you remove the +1
, you'll get both lines (I've also decreased the sleep times because I'm not patient enough to wait 50 seconds for the result):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
int main(int argc,char * argv[])
{
char buffer[100]; // The pipe's buffer
int pipes[2];
pid_t childpid;
if ( pipe(pipes) ){ fprintf(stderr,"FATAL ERROR IN PIPE"); }
if((childpid = fork()) == -1){ perror("fork"); exit(1); }
if(childpid == 0){
close(pipes[1]);
dup2(pipes[0],STDIN_FILENO);
scanf("%s\n",buffer);
fprintf(stderr,"REC: %s\n",buffer);
scanf("%s\n",buffer);
fprintf(stderr,"REC: %s\n",buffer);
sleep(2);
}
else
{
close(pipes[0]);
// Read in a string from the pipe
char* arr = "HelloWorld\n";
write(pipes[1],arr,strlen(arr)); // << NO +1
write(pipes[1],arr,strlen(arr)); // << NO +1
sleep(2);
}
return 0;
}
Upvotes: 3