/* File: ~liux/public_html/courses/cop4610/examples/simple-cmd.cc Purpose: Demonstrate how to use fork, dup and exec system calls for I/O redictions, COP4610, FSU Author: Xiuwen Liu On the web: http://www.cs.fsu.edu/~liux/courses/cop4610/examples/simple-cmd-redirect.cc Compile: g++ -o simple-cmd-redirect simple-cmd-redirect.cc */ #include #include #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; int fd; if (argc < 2) { cerr << "Usage: " << argv[0] << " command-to-run [redirect-in [redirect-out]] " << 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: "<= 3) { /* Redirect the Input */ fd = open(argv[2], O_RDONLY); if (fd < 0) { cout << "Could not open file \"" << argv[2] << " input rediction." <= 4) { /* Redirect the output */ fd = open(argv[3], O_WRONLY|O_CREAT|O_TRUNC); if (fd < 0) { cout << "Could not open file \"" << argv[3] << " output rediction." < 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; }