Search code examples
cpipeparentcommand-line-arguments

parent send command line arguments to child


I am writing a program that creates a pipe, forks, then the parent sends the command line arguments to the child one char at a time. The child is supposed to count them, and then the parent reaps the child and prints out how many arguments there were. Here is what I have so far:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>

int main(int argc, char **argv)
{
    pid_t   pid;
    int     status;
    int     comm[2];
    char    buffer[BUFSIZ];

    // set up pipe
    if (pipe(comm)) {
        printf("pipe error\n");
        return -1;
        }


    // call fork()
    pid = fork();

    // fork failed
    if (pid < 0) {
        printf("fork error %d\n", pid);
        return -1;
        }

    else if (pid == 0) {
        // -- running in child process --
        int     nChars = 0;
        close(comm[1]);

        // Receive characters from parent process via pipe
        // one at a time, and count them.

        while(read(comm[0], buffer, sizeof(buffer)) != '\n')
            nChars++;

        // Return number of characters counted to parent process.
        return nChars;
        }
    else {
        // -- running in parent process --
        int     nChars = 0;
        close(comm[0]);

        // Send characters from command line arguments starting with
        // argv[1] one at a time through pipe to child process.

        char endl='\n';
        for (int a = 1; a < argc; a++) {
            for (int c = 0; c < strlen(argv[a]); c++) {
                write(comm[1], &argv[a][c], 1);
            }
        }
        write(comm[1], &endl, 1);

        // Wait for child process to return. Reap child process.
        // Receive number of characters counted via the value
        // returned when the child process is reaped.

        waitpid(pid, &status, 0);

        printf("child counted %d chars\n", nChars);
        return 0;
        }
}

It seems to run endlessly. It must be stuck in one of the loops. What is going wrong?


Solution

  • Code:

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <string.h>
    
    int main(int argc, char *argv[])
    {
        pid_t   pid;
        int     status;
        int     comm[2];
        char    buffer[BUFSIZ];
    
        // set up pipe
        if (pipe(comm) < 0) {
            printf("pipe error\n");
            return -1;
        }
        // call fork()
        if((pid = fork()) <0)
        {
            printf("fork error %d\n", pid);
            return -1;
        }
        else if (pid == 0) {
            // -- running in child process --
            int     nChars = 0;
            close(comm[1]);
            //printf("%d \n",BUFSIZ);
            // Receive characters from parent process via pipe
            // one at a time, and count them.
            int n;
            while( (n =read(comm[0], buffer, BUFSIZ)) >0)
        {
          buffer[n] = 0;
          int oneChar, i = 0,endflag = 0;
          while((oneChar = buffer[i])!=0)
          {
           // printf("%d\n",oneChar);
            if(oneChar!=EOF)
              nChars++;
            else
            {
              endflag = 1;
              break;
            }
            i++;
          }
          //printf("%s\n",buffer);
          if(endflag)
            break;
        }
        printf("nChar : %d",nChars);
            // Return number of characters counted to parent process.
            return nChars;
        }
        else {
            // -- running in parent process --
            //int     nChars = 0;
            close(comm[0]);
    
            // Send characters from command line arguments starting with
            // argv[1] one at a time through pipe to child process.
            int a,c;
            char endl='\n';
            for ( a = 1; a < argc; a++) {
                for ( c = 0; c < strlen(argv[a]); c++) {
                    write(comm[1], &argv[a][c], 1);
                }
            }
        printf("write end\n");
        int end = EOF;
        write(comm[1],&end,4);
    
    
            waitpid(pid, &status, 0);
    
            printf("child counted %d chars\n", WEXITSTATUS(status));
            return 0;
            }
    }