0

Here is how my program articulates: there is a parent that forks a child and this child forks itself another child. So There is a parent, a child and a subchild (i.e. the parent of this subchild is the child).

The child execute a command with execlp(), let's say date to make it simple. The subchild do the same.

Of course the child forks the subchild before executing the command.

I am looking for the subchild to execute the command AFTER the child executed its own command. Moreover after the child and subchild executed their command, I would like the parent to continue its own process.

I have 2 problems:

  • I don't know how to make the parent to wait for the subchild execution
  • I can't make the subchild wait for the child execution (does the child lose its pid when using execlp?)

Here is my current implementation:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main (int argc, char **argv){
    pid_t pid1, pid2;

    pid1 = fork();

    if (pid1 > 0)
    {
        int status;

        // Wait child
        printf("Parent waiting for child\n");
        waitpid(pid1, &status, 0);
        printf("Parent has waited child\n");

        // Wait subchild
        printf("Parent waiting for subchild\n");
        // Wait sub-child here?
        printf("Parent has waited subchild\n");

        // End
        printf("parent end\n");
    }
    else
    {
        pid2 = fork();

        // Subchild
        if (pid2 == 0) {
            waitpid(getppid(), NULL, 0); // wait child? it doesn't work
            execlp("/bin/date", "date", "+Subchild:\"%d-%m-%y\"", (char *) 0);
            _exit(EXIT_FAILURE);
        }
        // Child
        else {
            execlp("/bin/date", "date", "+Child:\"%d-%m-%y\"", (char *) 0);
            _exit(EXIT_FAILURE);
        }
    }

    return 0;
}

My two "problems" are line 21 and 33.

The output is the following:

Parent waiting for child
Subchild:"03-10-17"
Child:"03-10-17"
Parent has waited child
Parent waiting for subchild
Parent has waited subchild
parent end

The subchild executes itself as fast as it can... I resolved this by using shared variable but it felt like a workaround and I still had issues with the parent waiting for the subchild.

SugarMouse
  • 131
  • 3
  • 9
  • It's a bit hard to give advice, despite the clarity of your question. If you want things done sequentially, forking sub-processes seems like the wrong way to go. Why fork? What are you trying to do that you wand separate processes, but sequential execution? If you weren't exec'ing programs, you could use signals to signal back and forth between parent and process group, but when you exec, you lose that option. – Leonard Oct 03 '17 at 04:25
  • Another good read on the subject (with example) is [**man 2 wait**](https://linux.die.net/man/2/wait) – David C. Rankin Oct 03 '17 at 04:31
  • Thank you for your comment. This is more like an educational program where the difficulty is this architecture with which I have to find a way to create a sequential execution. I tried several solutions but as you said the exec() makes it quite hard (shared variable/semaphore/...). – SugarMouse Oct 03 '17 at 04:36
  • The commonly used names are parent, child, grandchild (and sometimes grandparent). These are usefully gender neutral, too. – Jonathan Leffler Oct 03 '17 at 05:32
  • You parent process cannot wait directly for the grandchild to die; it can only wait for its own direct children to die. This is true regardless of the use of `exec*()` functions. Your best bet might be to create a pair of pipes, one for use by the child and one for use by the grandchild. The parent opens both pipes and closes both write ends. The child forks; the child then closes both ends of the grandchild's pipe, and the read end of the child's pipe; meanwhile, the grandchild closes both ends of the child's pipe and closes the read end of the grandchild's pipe. _[…continued…]_ – Jonathan Leffler Oct 03 '17 at 05:35
  • _[…continuation…]_ Then the grandchild can exec a program, and when the program terminates, the write end of the grandchild's pipe will be closed. The parent will be attempting to read from the grandchild's pipe and will get EOF when there is no grandchild (or child) with the write end of the grandchild's pipe open, so it knows the grandchild has finished, and can now wait for the child to finish in the same general way. – Jonathan Leffler Oct 03 '17 at 05:37

1 Answers1

0

Thanks to @JonathanLeffler I could solve the problem by creating pipes. It took time since I didn't know how pipes work but in the end it was much more easier than I thought.

@DavidC.Rankin I read the documentation about the wait function but it doesn't seem to be of any help in that situation.

Thank you.

SugarMouse
  • 131
  • 3
  • 9