In C (not C++) for Unix/Linux Programming. Write a program that takes as an argu
ID: 640886 • Letter: I
Question
In C (not C++) for Unix/Linux Programming.
Write a program that takes as an argument an int and then creates that many child processes. All children sleep for 5 seconds, then exit. The parent process sets a signal handler or SIGCHLD then enters a loop printing a message once a second. The handler calls wait and prints out the process ID of the child and increments a counter. When the counter reaches the original number of children, the program exits.
(This problem is from textbook Understanding Unix/Linux Programming A Guide to Theory and Practice by Bruce Molay)
Sample Output should look like this:
Explanation / Answer
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#define DELAY 5
#define oops(s,x) { perror(s); exit(x); }
int num_children;
int num_died ;
main(int ac, char *av[])
{
pid_t newpid;
void child_code(), parent_code();
void get_child_status(int);
int n, i;
/*
* setup
*/
if ( ac == 1 ){
fprintf(stderr,"usage: sol08.10 numberofchildren ");
exit(1);
}
n = atoi(av[1]);
signal(SIGCHLD, get_child_status);
/*
* loop: create children
*/
num_children = n;
num_died = 0;
for(i=0; i<n; i++){
if ( (newpid = fork()) == -1 )
oops("fork",2);
if ( newpid == 0 )
child_code(DELAY,i+1);
}
parent_code();
}
/*
* new process takes a nap and then exits
*/
void child_code(int delay,int num)
{
printf("child %d here. will sleep for %d seconds ", getpid(), delay);
sleep(delay);
printf("child #%d (%d) done. about to exit ",num,getpid());
exit(num);
}
/*
* parent waits for child then prints a message
*/
void parent_code()
{
void get_child_status(int);
while(1){
printf("waiting ..%d children left ",
(num_children-num_died));
sleep(1);
}
}
void
get_child_status(int s)
{
int wait_rv; /* return value from wait() */
int child_status;
int high_8, low_7, bit_7;
signal(SIGCHLD, get_child_status); /* in case */
wait_rv = wait(&child_status);
printf("done waiting for child. Wait returned: %d ", wait_rv);
high_8 = child_status >> 8; /* 1111 1111 0000 0000 */
low_7 = child_status & 0x7F; /* 0000 0000 0111 1111 */
bit_7 = child_status & 0x80; /* 0000 0000 1000 0000 */
printf("status: exit=%d, sig=%d, core=%d ", high_8, low_7, bit_7);
num_died++;
if ( num_died == num_children )
exit(0);
}