163 OS Week4
163 OS Week4
OPERATING SYSTEMS
ASSIGNMENT-4
CODE:
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
int main( ){
pid_t rf;
int a;
rf = fork (); // Create a new child process;
if (rf < 0) {
printf("fork failed");
return 1;
} else if (rf == 0) {
printf ("child process successfully created!\n");
printf ("child_PID = %d,parent_PID = %d\n",
getpid(), getppid( ) );
printf("inside rf=%d \n",rf);
} else {
// wait(NULL);
printf ("parent process successfully created!\n");
printf ("child_PID = %d, parent_PID = %d", getpid( ), getppid( ) );
printf("rf=%d \n",rf);
}
return 0;
}
OUTPUT:
Aim: Write a program to demonstrate the use of exe system calls Parent process -->
Execute factorial of given number Child process --> Execute prime number.
Description:
fork(): The main program creates a child process. Both the parent and child processes execute
different tasks.
• execl(): Replaces the current process image with a new process image.
• execl("./prime", "./prime", (char *)NULL); replaces the child process with the prime
program.
• execl("./factorial", "./factorial", (char *)NULL); replaces the parent process with the
factorial program.
• Parent process: Waits for the child to complete using wait(NULL) before replacing
its image with the factorial calculation.
• Child process: Immediately replaces its process image with the prime number
checking program.
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
// Function to calculate factorial
long long int factorial(long long int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
// Function to check if a number is prime
int is_prime(int n) {
if (n <= 1) return 0;
if (n <= 3) return 1;
if (n % 2 == 0 || n % 3 == 0) return 0;
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) return 0;
}
return 1;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <number>\n", argv[0]);
exit(EXIT_FAILURE);
}
int num = atoi(argv[1]);
if (num < 0) {
fprintf(stderr, "Number must be non-negative.\n");
exit(EXIT_FAILURE);
}
pid_t pid = fork();
if (pid < 0) {
perror("fork failed");
exit(EXIT_FAILURE);
}
if (pid == 0) {
printf("Child Process:"); // Child process
if (is_prime(num)) {
printf("%d is a prime number.\n", num);
} else {
printf("%d is not a prime number.\n", num);
}
exit(EXIT_SUCCESS);
} else { // Parent process
wait(NULL); // Wait for the child process to complete
printf("Parent Process:\n");
printf("Factorial of %d is %lld \n", num, factorial(num));
exit(EXIT_SUCCESS);
}
return 0; }
• Replaces the current process with a new process running the program specified by
path.
• Arguments are passed as individual parameters (end with NULL).
execlp(const char *file, const char *arg, …):
• Similar to execl, but file is searched in the directories listed in PATH.
• Arguments are passed as individual parameters (end with NULL).
execle(const char *path, const char *arg, …, char *const envp[]):
• Replaces the current process with a new process running the program specified by
path.
• Arguments are passed as individual parameters (end with NULL).
• You can specify a custom environment using envp.
execv(const char *path, char *const argv[]):
• Replaces the current process with a new process running the program specified by
path.
• Arguments are passed as an array (argv), ending with NULL.
execvp(const char *file, char *const argv[]):
• Similar to execv, but file is searched in the directories listed in PATH.
• Arguments are passed as an array (argv), ending with NULL.
execvpe(const char *file, char *const argv[], char *const envp[]):
• Similar to execvp, but you can specify a custom environment using envp.
• file is searched in PATH, and arguments are passed as an array (argv), ending with
NULL.
CODE:
Exec.c
#include<stdio.h>
#include<unistd.h>
int main()
{
int i;
printf("I am Demo file
called by execvp() ");
printf("\n");
return 0;
}
Execv.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
char
*args[]={"./exec",NULL};
execv(args[0],args);
printf("Ending-----");
return 0;
}
Execvp.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
char
*args[]={"./3_6_demo",NULL
};
execvp(args[0],args);
printf("Ending-----");
return 0;
}
Aim: Write a program to demonstrate the use of vfork()
Description:
vfork():
• Creates a new process (child) but does not fully copy the parent's address space.
Instead, the child process shares the address space with the parent until it calls exec()
or _exit().
• This makes vfork() more efficient than fork() when the child process is immediately
going to execute a new program or exit.
Child Process:
• After vfork(), the child process prints its PID and the parent PID. It then uses execlp()
to replace its process image with the ls command.
• If execlp() fails, it uses _exit() to terminate immediately. Note that _exit() is used
instead of exit() to avoid flushing standard I/O buffers, which might cause issues due
to shared memory.
Parent Process:
• The parent process waits for the child to complete using wait(NULL), ensuring it
synchronizes with the child process before continuing.
CODE:
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include <stdlib.h>
int main()
{
printf(" Before fork");
int
fd1=open("kk.txt",O_RDONL
Y,742); //kk.txt is a shared
resource to parent and child
process
OUTPUT:
break;
default:
message = "This is the
parent";
n = 3;
exit_code = 0;
break;
}
for(; n > 0; n--) {
puts(message);
sleep(1);
}
}
OUTPUT:
CODE:
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t pid;
char *message;
int n;
int exit_code;
printf("fork Program
starting\n");
pid = fork();
switch(pid)
{
case -1:
perror("fork failed");
exit(1);
case 0:
message = "This is the
child";
n = 3;
exit_code = 37;
break;
default:
message = "This is the
parent";
n = 5;
exit_code = 0;
break;
}
for(; n > 0; n--) {
puts(message);
sleep(1);
}
}
Observing the Zombie Process:
To observe the zombie process:
1. Run the program and let it execute.
2. Open another terminal and use the ps -ax command to check the process status
Look for processes with the status Z (zombie).
3. Return to the original terminal and let the parent process exit. After the parent exits,
the zombie process should be cleaned up automatically.
OUTPUT: