/* Source: https://riptutorial.com/posix/example/15876/create-child-process-and-wait-until-it-exits */

#include <unistd.h>     /* for fork(), getpid() */
#include <sys/types.h>  /* for waitpid() */
#include <sys/wait.h>   /* for waitpid() */
#include <stdlib.h>     /* for exit() */
#include <stdio.h>      /* for printf(), perror() */

int main(int argc, char *argv[]) {

    /* Create child process.
     * On success, fork() returns the process ID of the child (> 0) to the
     * parent and 0 to the child. On error, -1 is returned. */

    pid_t child_pid = fork();

    if (child_pid < 0) {
        perror("fork() failed");
        exit(EXIT_FAILURE);
    } else if (child_pid == 0) {

        /* Print message from child process.
         * getpid() returns the PID (process identifier) of current process,
         * which is typically int but doesn't have to be, so we cast it.
         * getppid() returns the PID of the parent process. */
         
        printf("from child: pid=%d, parent_pid=%d\n", (int) getpid(), (int) getppid());

        /* We can do something here, e.g. load another program using exec(). */
        exit(33);
        
    } else if (child_pid > 0) {
    
        /* Print message from parent process.  */
        printf("from parent: pid=%d child_pid=%d\n", (int) getpid(), (int) child_pid); 
        
        /* Wait until child process exits or terminates. 
         * The return value of waitpid() is PID of the child process, while
         * its argument is filled with exit code and termination reason. */

        int status;
        pid_t waited_pid = waitpid(child_pid, &status, 0);

        if (waited_pid < 0) {
            perror("waitpid() failed");
            exit(EXIT_FAILURE);
        } else if (waited_pid == child_pid) {

            if (WIFEXITED(status)) {
                /* WIFEXITED(status) returns true if the child has terminated 
                 * normally. In this case WEXITSTATUS(status) returns child's
                 * exit code. */
                printf("from parent: child exited with code %d\n", WEXITSTATUS(status));
            }
        }
    }

    exit(EXIT_SUCCESS);
}
