Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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);
}