Question

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;
}
Was it helpful?

Solution 2

  1. 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

  2. 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;

}

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top