In this programming problem, you'll practice signal (or sigaction), alarm, fork, exec*, and wait*. Your program takes command line arguments, specifying (1) a number of seconds and (2) a command to be executed. Your program will create a new process ("child") to execute the specified command. While the child is running, the original process ("parent") does nothing. When the specified seconds have passed, the parent terminates the child if the child is still running and then the parent exits. Both processes print messages to indicate the current status, as needed. Detailed program behavior and additional programming requirements are described below.
Syntax: "<your_program> <n> <command>", where <your_program> is the name of your executable program, <n> is an integer specifying the number of seconds, and <command> may contain more than one word, specifying the command to be executed.
1. If an input error occurs in the command line arguments, your program should print a meaningful error message and exit. The following are considered input errors: (1) there are not enough arguments (i.e., there are less than two arguments, not counting the program name); (2) <n> is not an integer, or <n> is less than or equal to zero.
2. Initial messages (replace the actual pid):
* When the parent process starts, it prints "Parent <pid> starts".
* When the child process starts, it prints "Child <pid> starts".
3. If the user types Ctrl-C on the terminal, the child process will be terminated (if it has not already terminated), but the parent process will NOT be affected.
4. Upon discovering the termination of the child (due to Ctrl-C or any other reason), the parent process immediately prints a message to indicate the termination of the child and continues doing nothing until the timer expires. Depending on the exit status of the child, the message should have the following format (replace the actual pid, status, and signal information):
* Case 1. The child exits normally: the parent prints a message to indicate that the child exits normally together with the exit status. For example, "Child 12345 terminated normally with exit status 0".
* Case 2. The child is terminated by a signal: the parent prints a message, showing the signal that has caused the termination; both the signal number and a description of the signal should be printed. For example, "Child 12345 terminated by signal 11: Segmentation fault".
* Any other case: the parent prints "Child 12345 has terminated abnormally".
5. When the parent's timer has expired, the parent does one of the following before it exits:
* If the child is still running, the parent will kill the child, reap the child, and print: "Parent killed child and is exiting".
* Otherwise, the parent prints "Parent is exiting".
Additional programming requirements:
* The parent process will always reap the child (by wait*).
* Use the system call alarm() to implement the parent's timer.
* As always, when making a system call (signal, alarm, fork, exec*, and wait*, etc.), check if the return value indicates an error.
Examples: Assume that your executable program is called "a.out". If a user runs your program by typing "[url removed, login to view] 5 sleep 10", your program will create a child process to execute the command "sleep 10", and the parent process will do nothing for 5 seconds, and then kill the child, and print an appropriate message and exit (see behavior V). Now suppose that the user types Ctrl-C to kill the child before the parent's timer expires, then the parent will print an appropriate message when the child terminates (see behavior IV), and continue doing nothing until the timer expires and then print a message and exit (see behavior V).