Reputation: 113
I want parent and child processes to communicate in C linux using pipes. First I want parent to pass a string and then child to acknowledge it. I have created two file descriptors. one for parent to child i.e. readpipe and other writepipe for viceversa. The problem is its not taking my data as input. Also I want the printf statements such as "Enter your data" to be printed once but since after fork, there are two processes so they are being displayed twice. Any alternative to that??
//readpipe[0] = child read
//readpipe[1]= parent write
//writepipe[0]=parent read
//writepipe[1]=child write
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main(void)
{
pid_t pid;
int r;
/* Hope this is big enough. */
char buf[1024];
char cp[50];
char ans;
int readpipe[2];
int writepipe[2];
int a;
int b;
a=pipe(readpipe);
b=pipe(writepipe);
if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); }
if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); }
printf("\nSEND SOMETHING TO CHILD PROCESS\t");
scanf(" %c",&ans);
pid=fork();
if(pid==-1)
{
printf("pid:main");
exit(1);
}
while(ans=='y' || ans=='Y')
{
printf("\nEnter data\t"); //printed twice
fgets(cp, 50, stdin); //not taking data
printf("\n%s",cp);
if(pid==0)
{ //CHILD PROCESS
close(readpipe[1]);
close(writepipe[0]);
read(readpipe[0],buf,sizeof(buf));
printf("\nSENT\n %s",buf);
write(writepipe[1],cp,strlen(cp)+1);
}
else
{ //PARENT PROCESS
close(readpipe[0]);
close(writepipe[1]);
write(readpipe[1],cp,strlen(cp)+1);
read(writepipe[0],buf,sizeof(buf));
printf("\nRECEIVED\n %s",buf);
}
printf("\nSEND SOMETHING TO CHILD PROCESS\t");
scanf(" %c",&ans);
}
close(readpipe[1]);
close(writepipe[0]);
close(readpipe[0]);
close(writepipe[1]);
return 0;
}
Upvotes: 0
Views: 1427
Reputation: 344
Why fgets is not taking data ?
In the first scanf you are reading the single character and the new line will still be in
input buffer so this will make to skip
To solve this you should use scanf("%[^\n]%*c",&ans) - Refer this for more details
Find the modified code.. it might be helpful to you ( to break from the while i made some changes and i verified the basic function)
int main(void) {
pid_t pid;
int r;
/* Hope this is big enough. */
char buf[1024];
char cp[50];
char ans;
int readpipe[2];
int writepipe[2];
int a;
int b;
a=pipe(readpipe);
b=pipe(writepipe);
if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); }
if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); }
printf("\nSEND SOMETHING TO CHILD PROCESS\t");
scanf("%[^\n]%*c",&ans);
//ans = getchar();
fflush(stdin);
pid=fork();
if(pid==-1)
{
printf("pid:main");
exit(1);
}
while(ans=='y' || ans=='Y')
{
if(pid==0)
{
//CHILD PROCESS
close(readpipe[1]);
close(writepipe[0]);
if(read(readpipe[0],buf,sizeof(buf)) < 0)
{
break;
}
printf("\nChild Process Read: %s\n",buf);
printf("\n(child)Enter data:\t"); //printed twice
fgets(cp, 50, stdin); //not taking data
printf("\nData Written to Parent%s",cp);
if(!strncmp("Q",cp,1) || write(writepipe[1],cp,strlen(cp)+1) < 0)
{
break;
}
}
else
{
//PARENT PROCESS
close(readpipe[0]);
close(writepipe[1]);
printf("\n(Parent)Enter data\t"); //printed twice
fgets(cp, 50, stdin); //not taking data
printf("\nData Writtent to Child: %s",cp);
if(!strncmp("Q",cp,1) || write(readpipe[1],cp,strlen(cp)+1) < 0)
{
break;
}
if(read(writepipe[0],buf,sizeof(buf)) < 0)
{
break;
}
printf("\nParent Process Read: %s\n",buf);
}
ans ='y';
}
close(readpipe[1]);
close(writepipe[0]);
close(readpipe[0]);
close(writepipe[1]);
return 0;
}
Upvotes: 0
Reputation: 9894
You call
printf("\nEnter data\t"); //printed twice
fgets(cp, 50, stdin); //not taking data
before you check whether you are in the parent or the child processes. That of course causes both processes to print and both to read form standard input. So it's not clear which process reads the date you're typing.
The same problems would occur in these lines:
printf("\nSEND SOMETHING TO CHILD PROCESS\t");
scanf(" %c",&ans);
I would suggest you redesign your program to clearly seperate code that runs in the parent process afrer fork()
and code that runs in the child process.
Upvotes: 1