/* File: ~liux/public_html/courses/cop4610/examples/simple-cmd.cc Purpose: Demonstrate how to use fork and exec system calls COP4610, FSU Author: Xiuwen Liu On the web: http://www.cs.fsu.edu/~liux/courses/cop4610/examples/simple-cmd.cc Compile: g++ -o simple-cmd simple-cmd.cc */ #include #include #include #include #include #include #include #include #define MAX_ARG 50 int main(int argc, char *argv[]) { char fname[256]; pid_t pid, child_pid; char *my_argv[MAX_ARG]; int status; if (argc < 2) { cerr << "Usage: " << argv[0] << " command-to-run arg1 arg2 .... " << endl; exit(-1); } /* The following is a standard pattern to use fork and exec to run new programs */ pid = fork(); if (pid == ((pid_t)-1)) { // Something must be wrong with the system if the program gets here perror("Fork failed: "); exit(-1); } else { /* Prepare command-line arguments */ if (pid == 0) { // This is the child process cout << "Child-> This is the child process " << getpid() << " whose parent is " << getppid() << endl; if (argc <= MAX_ARG) { cout << "Child-> I will start the following command: "< Could not execute \"" << my_argv[0] << "\".\n"; perror("execvp"); exit(-1); } } else { cerr << "Child-> Too many command-line arguments\n"; exit(-1); } } else { // This is the parent process cout << "Parent-> This is the parent process " << getpid() << " whose parent is " << getppid() << endl; cout << "I created a child whose id is " << pid << endl; child_pid = wait(&status); if (child_pid == pid) { if (WIFEXITED(status)) { printf("Child %d terminated normally with status = %d.\n", pid, WEXITSTATUS(status)); } else { if (WIFSIGNALED(status)) { printf("Child %d terminated abnormally by signal %d.\n", pid, WTERMSIG(status)); } else { if (WIFSTOPPED(status)) { printf("Child %d stopped with signal %d.\n", pid, WSTOPSIG(status)); } } } } else { cerr << "Parent-> Something must be wrong. " << child_pid << " and " << pid << " should be identical.\n"; exit(-2); } } } return 0; }