Fork() with grandchildren using C This assignment requires you to experiment wit
ID: 3863544 • Letter: F
Question
Fork() with grandchildren using C
This assignment requires you to experiment with the creation, termination and handling of processes in UNIX by writing small C programs. First, let's make sure we can write a program using calls such as fork and exec, and get it to compile and run. Write a program X that creates two child processes Y and 2, and write a program A that creates a child process B such that the child B loads and executes the program X. To test such a program, you should make each of the processes to do some I/O e.g. write something to the output, or wait for some input) at appropriate places. For each of the questions below, design a test experiment by modifying the programs you have written so that the result of test justifies the answer to the questionExplanation / Answer
Please find the program "X.c" below
#include<stdio.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
int main()
{
pid_t pid;
pid = fork();
if(pid == -1){
printf("Process X : Unable to launch child process Y ");
exit(-1);
}
if(pid == 0)//Child process
{
printf("Process Y : <Process id = %d> ",getpid());
printf("Process Y : <My parent process id = %d> ",getppid());
}
else{
pid = fork();
if(pid == -1){
printf("Process X : Unable to launch child process Z ");
exit(-1);
}
if(pid == 0){
printf("Process Z : <Process id = %d> ",getpid());
printf("Process Z : <My parent process id = %d> ",getppid());
}
else{
printf("Process X : <Process id = %d> ",getpid());
wait(-1, NULL, 0);
}
}
return 0;
}
Please find the program "A.c" below
#include<stdio.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
int main()
{
pid_t pid;
char* argv[] = {"X",NULL};
int ret = 0;
pid = fork();
if(pid == -1){
printf("Process A : Unable to launch child process B ");
exit(-1);
}
if(pid == 0)//Child process
{
printf("Process B : <Process id = %d> ",getpid());
ret = execl("./X",argv[0] , argv[1]);
if(ret == -1){
printf("Process B : Unable to exec process X ");
exit(-1);
}
}
else{
printf("Process A : <Process id = %d> ",getpid());
wait(-1,NULL,0); // Waiting for child process to exit
}
return 0;
}
Compile the program X.c using following command :
gcc -o X X.c
Compile the program A.c using following command :
gcc -o A A.c
Change in program X.c to show it can kill process Y . Compile it and execute the program "X"
#include<stdio.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<signal.h>
int main()
{
pid_t pid2;
pid_t pid3;
pid2 = fork();
if(pid2 == -1){
printf("Process X : Unable to launch child process Y ");
exit(-1);
}
if(pid2 == 0)//Child process
{
sleep(20); // Sleeping fpr 20 sec (Letting the parent process 'X' to kill )
printf("Process Y : <Process id = %d> ",getpid());
printf("Process Y : <My parent process id = %d> ",getppid());
}
else{
pid3 = fork();
if(pid3 == -1){
printf("Process X : Unable to launch child process Z ");
exit(-1);
}
if(pid3 == 0){
printf("Process Z : <Process id = %d> ",getpid());
printf("Process Z : <My parent process id = %d> ",getppid());
}
else{
printf("Process X : <Process id = %d> ",getpid());
kill(pid2,SIGQUIT);
wait(-1, NULL, 0);
}
}
return 0;
}
To kill process Y specifically using process 'A' .
It is possible for the process 'A' to kill process 'Y' specifically if it knows its process id.. For that you need to create a pipe to communicate the process id.
I have used files to do the same thing.
Following are the modified code for A.c and X.c
A.c
#include<stdio.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<signal.h>
int main()
{
pid_t pid;
char* argv[] = {"X",NULL};
int ret = 0;
int fd;
FILE* fp = NULL;
int processId = 0;
pid = fork();
if(pid == -1){
printf("Process A : Unable to launch child process B ");
exit(-1);
}
if(pid == 0)//Child process
{
printf("Process B : <Process id = %d> ",getpid());
ret = execl("./X",argv[0] , argv[1]);
if(ret == -1){
printf("Process B : Unable to exec process X ");
exit(-1);
}
}
else{
printf("Process A : <Process id = %d> ",getpid());
sleep(3);
fp =fopen("./pid.txt","r");
fscanf(fp,"%d",&processId);
fclose(fp);
kill(processId, SIGQUIT);
wait(pid,NULL,0); // Waiting for child process to exit
}
return 0;
}
X.c
#include<stdio.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<signal.h>
#include<string.h>
int main()
{
pid_t pid2;
pid_t pid3;
char id[10] = {''};
FILE* fp = fopen("./pid.txt","w+");
pid2 = fork();
if(pid2 == -1){
printf("Process X : Unable to launch child process Y ");
exit(-1);
}
if(pid2 == 0)//Child process
{
fprintf(fp,"%d",getpid());
fclose(fp);
sleep(20); // Sleeping for 3 sec (Letting the parent process 'A' to kill )
printf("Process Y : <Process id = %d> ",getpid());
printf("Process Y : <My parent process id = %d> ",getppid());
}
else{
pid3 = fork();
if(pid3 == -1){
printf("Process X : Unable to launch child process Z ");
exit(-1);
}
if(pid3 == 0){
printf("Process Z : <Process id = %d> ",getpid());
printf("Process Z : <My parent process id = %d> ",getppid());
}
else{
printf("Process X : <Process id = %d> ",getpid());
wait(pid2, NULL, 0);
wait(pid3, NULL, 0);
}
}
return 0;
}
You need to compile both files and execute program A only. Since the process 'Y' doesn't prints any output means that it got killed while in sleep().