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

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 question

Explanation / 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().