/* 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;
}