Search code examples
clinuxpipeinter-process-communicat

communication between child and parent processes in C linux: parent process not blocking


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;
}

Thanks :)


Solution

  • There are a few problems in your code:

    1.

    close(writepipe[1]);
    

    You should not close file descriptor you needed later.

    2.

    read(readpipe[0],ch,sizeof(ch));
    

    ch is NULL, which means you did not allocate any space for it to point to.

    3.

    ch1="YES";
    write(writepipe[1],ch1,sizeof(ch1));
    

    You should use strlen(ch)+1 instead of sizeof(ch) to find out how many bytes need to be written.

    4.

    There are similar problems in your code for parent process.


    Here is a fixed version based on the code in this question:

    #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;
    
        int readpipe[2];
        int writepipe[2];
        int a;
        int b;
        a=pipe(readpipe);
        b=pipe(writepipe);
        // check a and b
    
        pid=fork();
        // check pid
    
        if(pid==0)
        { //CHILD PROCESS
            close(readpipe[1]);
            close(writepipe[0]);
            read(readpipe[0],buf,sizeof(buf));
            printf("\nREAD = %s",buf);
            close(readpipe[0]);
            cp="YES\n";
            write(writepipe[1],cp,strlen(cp)+1);
            close(writepipe[1]);
        }
        else
        { //PARENT PROCESS
            close(readpipe[0]);
            close(writepipe[1]);
            cp="HI!! YOU THERE";
            write(readpipe[1],cp,strlen(cp)+1);
            close(readpipe[1]);
            read(writepipe[0],buf,sizeof(buf));
            printf("\nACK RECEIVED %s",buf);
            close(writepipe[0]);
        }
        return 0;
    }