------------------------------------------------------------------------------
MC logo
Unix Process Creator
[^] Processes
------------------------------------------------------------------------------
runner.cpp
/*
 * Simple program to demonstrate the fork/exec/run sequence for creating
 * processes in Unix.
 */

#include <iostream>
#include <string>
using namespace std;

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

main()
{
        /* Ask for a program to run.  This is just the file name of an
           executable. */
        cout << "What shall I run? ";
        string cmd;
        getline(cin, cmd);

        /* Request a single parameter. */
        cout << "Would you like a parameter for that?  (return for none) ";
        string parm;
        getline(cin, parm);

        /* Create a child process and try to run the program in it. */
        if(fork() == 0) {
                if(parm.length() > 0)
                        execl(cmd.c_str(), cmd.c_str(), parm.c_str(), NULL);
                else
                        execl(cmd.c_str(), cmd.c_str(), NULL);
                cout << "Sorry, the exec failed." << endl;
                exit(1);
        }

        /* See what was the cause of the child processes' demise. */
        int status;
        wait(&status);
        if(WIFEXITED(status)) cout << "Exited." << endl;
        else if(WIFSIGNALED(status)) cout << "Killed." << endl;
        else cout << "Mysteriously vanished." << endl;
}

/* 
 * Note: This program really should check the return values for fork() and for
 * exec() to make sure they succeeded, and print an error message if not.
 * Failure is indicated by a negative return value.  It would also help to use
 * errno and strerror() to print a descriptive error message in place of the
 * existing exec() failure message, or for the new messages.
 *
 * It also uses uses gets() and fixed-size buffers, which creates a risk of
 * buffer overflow.
 */