0

My code is pausing on open() whenever I use the wait function, and without it the programs dont work. There is no error code but I would like to know whats wrong.

The code will eventually be controller.c will open c1,c2,c3. Where it will wait for c1 which will get input and put it to a pipe which will then go to c2 which will print it, then c3 which will print it in a different format.

int main(int ac, char**av)
{
    int fd;
    int test;
    char * myfifo = "/tmp/myfifo";
    unlink(myfifo);                     //makes sure no fifo already exists

    /* create the FIFO (named pipe) */
    if((mkfifo(myfifo, 0666)) <0)
        perror("MKFIFO: ");



    int statval;
    pid_t pid1 = fork();                    //creates a process for c1 to run in
    wait(&statval); 
    if ( pid1 == 0)                     //makes sure to only run the program in the child process
    {   
        printf("Opening c1\n");
        int x = execvp("./c1",av);          //Runs the other file based on the array
        if (x == -1)
            exit (1);
        perror("Error");                //used for error reporting
        printf("Closing c1\n");
        exit(0);                    //ends process when finished
    }
    if (WIFEXITED(statval))                 //if there is an exit code
    printf("\nChilds exit code %d\n", WEXITSTATUS(statval));//prints the exit status of the child process

    pid_t pid2 = fork();                    //creates a process for c2 to run in
    wait(&statval); 
    if ( pid2 == 0)                     //makes sure to only run the program in the child process
    {   
        printf("Opening c2\n");
        int x = execvp("./c2",av);          //Runs the other file based on the array
        if (x == -1)
            exit (1);
        perror("Error");                //used for error reporting
        exit(0);                    //ends process when finished
    }
    if (WIFEXITED(statval))                 //if there is an exit code
    printf("\nChilds exit code %d\n", WEXITSTATUS(statval));//prints the exit status of the child process

    unlink(myfifo);

C1:

printf("TEST1\n");
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    int fd;
        char * myfifo = "/tmp/myfifo";
        char buf[BUFSIZE];

    fd = open(myfifo, O_WRONLY);
    if (fd < 0)
        perror("OPEN: ");   

    //while (1) {
        printf("Enter a line of text\n"); 
        //scanf("%s", buf);
        if ((strcmp(line,"-999"))==0){
            printf("TEST");         
            //break;
        }
        //write(fd, buf, sizeof(buf));
            write(fd, "hi", sizeof("hi"));
    //}
    close(fd);
    unlink(myfifo);
        return 0;

C2:

int fd;
    char * myfifo = "/tmp/myfifo";
    char buf[BUFSIZE];

    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);
    read(fd, buf, BUFSIZE);
    printf("Received: %s\n", buf);
    close(fd);

    return 0;

The program will open c1, print TEST and then do nothing else until I manually exit.

Anthony Drury
  • 128
  • 2
  • 12
  • Why do you need to fork and pipe data for something that is done sequentially and that you actually want to wait for? I'm not sure it deserves more than 5 seconds of attention and I already spent 2 minutes on it. – Julie Pelletier May 27 '16 at 04:30
  • Because this is what my professor wants me to do. I just follow instructions and code. – Anthony Drury May 27 '16 at 06:40

1 Answers1

2

Immediately after the first fork, both parent and child wait(). The child's call fails because it has no un-waited-for children, but you ignore the result. The child then execs program c1, which (supposing the exec succeeds) in turn opens the FIFO for writing. This blocks until the other end of the FIFO is opened, but the other end will not be opened by your program because the parent process is waiting for the child to exit before it proceeds. You have created a deadlock.

Neither child can proceed past opening the FIFO until the other (or some other program) has opened the other end of the FIFO, so the parent must fork both children before it waits for either one. Also, it is pointless for the children to wait(), though their calls to that function should fail quickly.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Well what I thought I was implementing was just making the parent wait until the child is finished. Do you have any code or a specific resource to help me please and thank you. – Anthony Drury May 27 '16 at 04:05
  • @AnthonyDrury, I'm not sure how to respond beyond what I already said. The parent must *not* wait for the first child to finish before forking the second one, because the first *won't* finish until the second, or some other process, opens the other end of the pipe. The parent should defer waiting until both children have been forked, then it should wait for both. – John Bollinger May 27 '16 at 04:09
  • Okay I think I am getting you, so for all three I should be forking for c1,c2,c3, then wait() then opening them in their child processes. I will attempt that and get back to you. – Anthony Drury May 27 '16 at 04:13