Os Lab Record
Os Lab Record
THIRUVANANTHAPURAM-695016
DEPARTMENT OF
COMPUTER SCIENCE AND ENGINEERING
Fourth Semester
CSL204 : OPERATING SYSTEMS LAB
KTU ID : TVE22CS100
DEPARTMENT OF
COMPUTER SCIENCE AND ENGINEERING
Fourth Semester
CSL204 : OPERATING SYSTEMS LAB
Certified that this a bonafide record of the work done by NAVADEEP SATHEESH
(TVE22CS100) of S4 CSE (Batch-2) class in the Operating Systems Lab during the year
2023-2024.
Faculty in Charge
External Examiner
INDEX
3 Shell Progamming-2
1
Ex.No. 1 BASIC LINUX COMMANDS
Date : 03-02-24
3. Cal
4. pwd
Purpose: To display the path of the current directory
Usage: pwd
5. ls
Purpose: To list the contents of the current directory
Usage: ls
1
2
6. ls -l
Purpose : To list the contents of the current directory in long listing format
Usage : ls -l
7. ls -a
Purpose: To list the contents of the current directory, including all hidden files
Usage: ls -a
8. mkdir
Purpose: To create a new directory
Usage: mkdir
9. cd
Purpose: Change directory to path specifed
Usage: cd <path>
3
10. rmdir
Purpose: To delete empty directories
Usage: rmdir <dir_name>
11. touch
Purpose: To change file timestamps (create file if file does not exist)
Usage: touch
4
Exp no:-2 SHELL PROGRAMMING 1
DATE:22-02-2024
temp=$1;
sum_digit=0
rev=0
while [ $temp -gt 0 ]
do
ld=$((temp%10 ))
sum_digit=$((sum_digit+ld))
rev=$((rev*10 +ld))
temp=$((temp/10))
done
echo "reverse is "
echo $rev
echo "sum is "
echo $sum_digit
Sample Output:-
5
(B) display all Armstrong number between two given numbers
Shell script:_
# aim- to display armstrong numbers between two numbers
6
for ((i = start; i <= end; i++));
do
if is_armstrong $i;then
echo "$i" fi
done
}
#Main script
read - p "Enter the starting number: "
start_num read - p "Enter the ending number: "
end_num find_armstrong_numbers $start_num $end_num
Sample Output:-
Shell script:_
.
7
bin[i]=$temp
dec=$((dec/2))
i=$((i+1))
done
echo -n "binary is :"
while [ $i -ge 0 ]
do
echo -n "${bin[i]}"
i=$((i-1))
done
echo ""
}
8
;;
esac
i=$((i+1))
dec=$((dec/16))
done
echo -n "hexa decimal is :"
while [ $i -ge 0 ]
do
echo -n "${hex[i]}"
i=$((i-1))
done
echo ""
}
#main
read -p "enter the decimal " dec
binary $dec
hexadecimal $dec
octal $dec
9
Sample Output:-
( d ) Input a date in the form dd/mm/yyyy and check whether it is a valid date in
the range 01/01/1951 to 31/12/2025.
Shell script:
10
elif [[ month -eq 4 || month -eq 6 || month -eq 9 || month -eq 11 ]]; then
if [[ day -ge 1 && day -le 30 ]]; then
echo "valid date"
else
echo "invalid date-day"
fi
elif [[ month -eq 2 ]]; then
If [[ leap ]]; then
echo $leap
if [[ day -ge 1 && day -le 29 ]]; then
echo "Valid date"
else
echo "invalid date - day"
fi
else
if [[ day -ge 1 && day -le 28 ]]; then
echo "Valid date"
else
echo "invalid date - day"
fi
fi
fi
else
echo "Invalid date - month"
fi
else
echo "invalid date - year "
fi
Sample output:
11
12
Expt. No. 4 SYSTEM CALLS 1
Date: 07-03-2024
Aim: Write programs for illustrating the working of the the following sys- tem calls
in Linux:
fork(), getpid(), getppid(), execv(), wait(), exit()
System Calls:
1. fork()
Description:-
fork() is used to create new process. Creates a copy of the parent process.
fork() returns the PID of the child process to parent and 0 to the child process.
It retruns -1 if not able to create new process. After creating new process parent
and child processes starts execution from the statement immediately followed by
fork () call.
Program code : -
/*
Exp no 4
Program to find the return value of fork() to parent and child
*/
#include <stdio.h>
#include <unistd.h>
int main ()
{
pid_t p=fork() ;
printf("Hello \n") ;
printf ("Value returned to %s by fork() = %d,processID = %d\n",(p == 0?"CHILD":"
PARENT" ),p ,getpid());
return 0 ;
}
Sample output:
13
2. execv()
Description:-
The execv() function replaces the current process image with a new process
image specifed by path . The new image is constructed from a regular,
executable file called the new process image file. No return is made because
the calling process image is replaced by the new process image.
Syntax: int execv(const char * path, char * const argv[]);
Program code : -
/*
Exp no -4
Name : Navadeep Satheesh
Roll no : 41
Program to demonstrate the function of exec() system call
*/
#include <stdio.h>
#include <unistd.h>
int main() {
char *args[] = {"./executable", "Testing", "Hullo", NULL};
return 0;
}
Child program:
#include <stdio.h>
#include <unistd.h>
return 0;
}
14
Sample output:
3. Wait()
1. Description:-
The wait() system call suspends execution of the calling thread untilone of its
children terminates. A call to wait() blocks the calling processuntil one of its child
processes exits or a signal is received. After child process terminates, parent
continues its execution after wait system call instruction.
Program code : -
/*
Exp no -4
Program to demonstrate the function of exec() system call
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main() {
if (fork() == 0) {
printf("inside child\n");
} else {
printf("inside parent\n");
// wait(NULL);
printf("child has terminated\n");
}
printf("done\n");
return 0;
}
15
Sample output:-
4. getpid(), getppid()
1. Description:-
getppid() returns the process ID of the parent of the calling process.If the calling
process was created by the fork() function and the parent process still exists at the
time of the getppid function call, this function returns the process ID of the parent
process. Otherwise, this function returns a value of 1 which is the process id for
init process.
getpid() returns the process ID of the calling process.
Program code:
/*
Exp no -4
Name : Navadeep Satheesh
Roll no : 41
Program to demonstrate the function of getpid() and getppid() system call
*/
#include <stdio.h>
#include <unistd.h>
int main()
{
int pid, ppid;
printf("Program to find process ID:\n");
pid = getpid();
printf("Process ID of running process: %d\n", pid);
ppid = getppid();
printf("Process ID of the parent process: %d\n", ppid);
return 0;
}
Sample output:-
16
17
5. exit()
Description:-
The C exit() function is a standard library function used to terminate the calling
process. When exit() is called, any open le descriptors belonging to the process
are closed and any children of the process are inherited by process 1, init, and the
process parent is sent a SIGCHLD signal.
An exit status of 0 means that the program has executed successfully, while a status
of 1 means that an error was encountered.
Program code:
/*
Exp no -4
Program to demonstrate the function of exit()system call
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void function();
int main() {
printf("Current process ID: %d\n", getpid());
function();
printf("Will not be executed\n");
return 0;
}
void function() {
printf("Inside function().\n");
printf("Current process ID: %d\n", getpid());
exit(5);
printf("This is written after exit() in the function\n");
}
Sample output:-
18
Exp no : 5 I/O SYSTEM CALLS
DATE: 15-03-2024
Aim: Write programs for illustrating the working of the the following system calls in
Linux :
opendir(), readdir(), open(), read(), stat(), write(), close()
System Calls
1. opendir(), readdir()
Description:-
The opendir() function opens a directory stream corresponding to the directory
name, and returns a pointer to the directory stream. The stream is positioned at the
first entry in the directory The readdir() function returns a pointer to a dirent
structure representing the next directory entry in the directory stream pointed to by
dirp. It returns NULL on reaching the end of the directory stream or if an error
occurred.
Program code:
/*
Exp no-5
Date:15-03-2024
Roll no : 42
Write a c program to display the content of a directory given as a command lie
argument
*/
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
if (argc == 2) {
dr = opendir(dname);
if (dr == NULL) {
printf("Could not open directory.\n");
19
} else {
printf("Contents of directory:\n");
printf("========================\n");
while ((de = readdir(dr)) != NULL) {
printf("%s\n", de->d_name);
}
closedir(dr); // Close the directory after reading its contents
}
} else {
printf("Usage: ./dir <dirname>\n");
}
}
Sample output:
2 write()
Description:-
The write() function will write the specifed number of bytes (passed to it as an
argument) from a buffer (a pointer to which is passed as an argument) into a file
specifed by a file descriptor.
It returns a value of 0 if the number of bytes is 0, -1 if there is an error, and no value
in all other cases.
Syntax: ssize_t write(int fildes, const void *buf, size_t nbyte);
20
Program code:
/*
Exp no-5
Date:15-03-2024
Write a c program writing and reading from stdout
*/
#include <unistd.h>
#include <string.h>
int main() {
char name[60];
char *str = "Name: ";
char *str1 = " Entered name: ";
int n;
// Write contents of str to stdout
write(1, str, strlen(str));
// Return the number of bytes read from stdin
n = read(0, name, 60);
write(1, str1, strlen(str1)); // Write to stdout
write(1, name, n);
return 0;
}
Sample output:
The stat() system call return information about a file, in the buffer pointed to by
statbuf.
Syntax: int fstat(int fd, struct stat *statbuf);
21
The close() closes a file descriptor, so that it no longer refers to any file and may be
reused.
Syntax: int close(int fd);
22
Program code:
/*
Exp no-5
Navadeep
Satheesh
Date:15-03-2024
Roll no : 41
Program to convert lowercase of text file to upper case and store it in another file
*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main() {
struct stat sb;
char fname[30], ch, c;
int fd1, fd2, n;
if (fd1 > 0) {
fd2 = open("file2.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
while ((n = read(fd1, &ch, 1)) > 0)
{
c = ch;
ch = (c >= 'a' && c <= 'z') ? c - 32 : c;
write(fd2, &ch, 1);
}
close(fd2);
}else {
printf("File %s not found.\n", fname);
}
stat("file2.txt", &sb);
printf("Stats of file2.txt:\n");
printf("Inode number: %lu\n", sb.st_ino);
printf("Number of hard links: %lu\n", sb.st_nlink);
close(fd1);
return 0;
23
}
Sample output:
24
Ex.No. 6 CPU SCHEDULING ALGORITHMS
Date:-22-03-2024
Aim :- Write a menu driven program for implementing the following CPU scheduling
algorithms.
(a) FCFS (b) Round Robin (c) SJF (d) Priority
For all the programs, arrival time for the processes should be considered. For each
case find the turnaround time, waiting time and display a Gantt chart. Also find the
average waiting time and average turn around time. Output should be verified with
atleast 5 processes.
Description : FCFS is one of the simplest CPU scheduling algorithms. It schedules processes
based on their arrival time, executing the earliest arriving process first. While fair and easy to
implement, FCFS may lead to the convoy effect, where long processes delay shorter ones,
causing inefficient resource utilization. It's suitable for simple systems with predictable
process behavior but may not be optimal for systems with varied process execution times.
B ) Round robin
25
D) Priority
Descripton : Priority Scheduling assigns processes a priority, executing the highest priority
process first. It can be preemptive or non-preemptive. Preemptive Priority Scheduling
switches to a higher priority process if one arrives, while Non-preemptive Priority Scheduling
lets the current process finish. It's used in real-time systems but may cause starvation for
low priority processes. Dynamic priority adjustments can address this issue.
Program code :-
/*
Name:Navadeep
Satheesh
Roll no:49
Date: 22-3-2024
To implement menu driven cpu scheduling with atleast 5 process
(a) FCFS
(b) Round Robin
(c) SJF
(d) Priority
*/
#include <stdio.h>
typedef struct //to store details related to a process
{
int pid;
int arrival;
int burst;
int completion;
int turnaround;
int waiting;
int remaining;
int priority;
} process;
26
void enqueue(int item) // functon to insert process into queue
{
if (rear == -1)
front = rear = 0;
else if (rear != 100)
rear++;
queue[rear] = item;
}
27
}
if (swap == 0)
break;
}
}
int main()
{
int n, c = 1, ch, t, i, j, swap = 0;
process p[25];
printf("Enter the number of processes: ");
scanf("%d", &n);
printf("Enter the process id, arrival time and burst time: \n");
for (i = 0; i < n; i++)
scanf("%d%d%d", &p[i].pid, &p[i].arrival, &p[i].burst);
sortprocess(p, n, 1);
sortprocess(p, n, 0);
printf("[0]\tExit\n[1]\tFCFS\n[2]\tRound Robin\n[3]\tSJF\n[4]\tPriority\n");
while (c)
{
printf("Enter your choice: ");
scanf("%d", &ch);
switch (ch)
{
case 0:
c = 0;
break;
case 1:
fcfs(p, n);
break;
case 2:
printf("Enter the time quantum: ");
scanf("%d", &t);
roundrobin(p, n, t);
break;
case 3:
sjf(p, n);
28
break;
case 4:
priority(p, n);
break;
default:
printf("Invalid input\n");
}
}
return 0;
}
29
{
printf("IDLE");
t += (p[i].start - t);
printf("%s", vl);
}
for (j = 0; j < p[i].burst - 1; j++)
printf(" ");
printf("P%d", p[i].pid);
for (j = 0; j < p[i].burst - 1; j++)
printf(" ");
t += p[i].burst;
}
printf("%s\n", vl);
t = 0;
for (i = 0; i < n; i++)
{
if (i == 0)
printf("%s", ur);
if (p[i].start != t)
{
for (j = 0; j < 4; j++)
printf("%s", hl);
t += (p[i].start - t);
printf("%s", uh);
}
for (j = 0; j < 2 * p[i].burst; j++)
printf("%s", hl);
t += p[i].burst;
if (i != n - 1)
printf("%s", uh);
else
printf("%s", ul);
}
printf("\n");
t = 0;
for (i = 0; i < n; i++)
{
if (t != p[i].start)
{
printf("%d", t);
for (j = 0; j < 4; j++)
printf(" ");
printf("%d", p[i].start);
t += (p[i].start - t);
30
}
else
printf("%d", t);
if (t % 100 < 10)
for (j = 0; j < 2 * p[i].burst; j++)
printf(" ");
else
for (j = 0; j < 2 * p[i].burst - 1; j++)
printf(" ");
t += p[i].burst;
}
printf("%d\n\n", t);
}
void display(process p[], int n) //function to display the corresponding data about the
//process
{
int i;
double avgwt = 0, avgtt = 0;
sortprocess(p, n, 1);
printf("=====================================================================
======================\n");
printf("ProcessId\tArrivalTime\tBurstTime\tCompletionTime\tTurnAroundTime\tWaitingTim
e\n");
printf("=====================================================================
======================\n");
for (i = 0; i < n; i++)
printf("%-12d\t%-12d\t%-10d\t%-15d\t%-15d\t%-12d\n", p[i].pid, p[i].arrival, p[i].burst,
p[i].completion, p[i].turnaround = p[i].completion - p[i].arrival, p[i].waiting = p[i].completion
- p[i].arrival - p[i].burst);
printf("=====================================================================
======================\n");
for (i = 0; i < n; i++)
{
avgtt += p[i].turnaround;
avgwt += p[i].waiting;
}
avgtt = avgtt / n;
avgwt = avgwt / n;
printf("Average TurnAround Time: %f\n", avgtt);
31
printf("Average Waiting Time: %f\n", avgwt);
}
void roundrobin(process p[], int n, int qt) //function for round robin scheduling
{
int i = 0, j, t = p[0].arrival, flag, cp, count = 0, gc = 0;
pstat ps[50];
front = rear = -1;
for (i = 0; i < n; i++)
{
p[i].remaining = p[i].burst; //adding the burst time as remaining time initially
if (t == p[i].arrival)
enqueue(i); //adding process to ready queue if i th process arrived at time t
}
while (count < n)
{
cp = dequeue();
if (cp != -1)
{
ps[gc].pid = p[cp].pid;
ps[gc].start = t;
if (p[cp].remaining > qt) // execute if remaining time is greater than time slice
32
{
ps[gc].burst = qt;
t += qt;
p[cp].remaining -= qt;
for (i = 0; i < n; i++)
{
flag = 0;
if (t >= p[i].arrival && p[i].remaining > 0 && i != cp)
{
for (j = front; j <= rear; j++)
if (queue[j] == i)
flag = 1;
if (flag == 0)
enqueue(i);
}
}
enqueue(cp);
}
else
// execute if remaining time is less than time slice
{
ps[gc].burst = p[cp].remaining;
t += p[cp].remaining;
p[cp].completion = t;
p[cp].remaining = 0;
count++;
}
gc++;
}
else
{
while (front == -1)
{
for (i = 0; i < n; i++)
{
if (t >= p[i].arrival && p[i].remaining > 0)
{
enqueue(i);
}
}
if (front == -1)
t++;
}
}
33
}
gantt(ps, gc);
display(p, n);
}
//function for short job first sheduling
void sjf(process p[], int n)
{
int t = 0, count = 0, cp, i, minBurstTime;
pstat ps[50];
for (i = 0; i < n; i++)
p[i].remaining = p[i].burst;
while (count != n)
{
cp = -1;
minBurstTime = 9999;
// to find process with shortest burst time at time t
for (i = 0; i < n; i++)
{
if ((p[i].arrival <= t) && (p[i].remaining > 0) && (p[i].remaining < minBurstTime))
{
minBurstTime = p[i].remaining;
cp = i;
}
}
if (cp != -1)
{
ps[count].pid = p[cp].pid;
ps[count].start = t;
ps[count].burst = p[cp].burst;
t += p[cp].burst;
p[cp].remaining = 0;
p[cp].completion = t;
count++;
}
else
t++;
}
gantt(ps, count);
display(p, n);
}
// function for priority sheduling
void priority(process p[], int n)
{
int t = 0, count = 0, cp, i, prior;
34
pstat ps[50];
printf("Enter the priorities of all the processes: \n"); //read all priorities
for (i = 0; i < n; i++)
{
printf("P%d: ", p[i].pid);
scanf("%d", &p[i].priority);
p[i].remaining = p[i].burst;
}
while (count != n)
{
cp = -1;
prior = 9999;
// to find the process priority at time t
for (i = 0; i < n; i++)
{
if ((p[i].arrival <= t) && (p[i].remaining > 0) && p[i].priority < prior)
{
prior = p[i].priority;
cp = i;
}
}
if (cp != -1)
{
ps[count].pid = p[cp].pid;
ps[count].start = t;
ps[count].burst = p[cp].burst;
t += p[cp].burst;
p[cp].remaining = 0;
p[cp].completion = t;
count++;
}
else
t++;
}
gantt(ps, count);
display(p, n);
}
35
Sample output:-
36
Result: Program is compiled and executed successfully and output is obtained.
37
38
Exp no : 7 INTER PROCESS COMMUNICATION
Date : 11-04-2023
Aim : Implement programs for Inter Process Communication using Shared Memory.
Description:
Shared memory is a form of interprocess communication (IPC) that enables multiple
processes to access the same region of memory simultaneously. In this method, a
portion of memory is shared among processes, allowing them to exchange data quickly and
efficiently without the need for complex synchronization mechanisms. Processes can read
from and write to shared memory segments, enabling fast communication and data sharing.
However, careful coordination and synchronization are necessary to prevent data corruption
and ensure consistency, as there are no built-in protections against simultaneous access by
multiple processes. Despite its speed and efficiency, shared memory IPC requires careful
management of memory allocation and deallocation to avoid memory leaks and other
resource-related issues.
Program code :
Code for sender :
/*
Renjth Rajan
int main()
{
void *shared_memory;
char buffer[100];
int shmid;
printf("Data written into shared memory: %s\n", (char *)shared_memory);
//create shared memory and get the id
39
shmid2 = shmget((key_t)1242, 1024, 0666 | IPC_CREAT);
printf("Key of shared memory is %d\n", shmid2);
40
Description:
In this program, we declare two arrays of threads: one for producers and one for
consumers. We also declare a mutex variable named `mutex` to control access to the
critical section, which is the buffer array where data is written and read. Additionally, we
declare two counting semaphores: `empty`, which tracks the number of empty locations in
the buffer, and `full`, which tracks the number of occupied locations in the buffer. The
`sem_wait()` system call is equivalent to the `wait()` function, and `sem_post()` is equivalent
to the `signal()` function. These semaphores ensure synchronized access to the buffer,
preventing race conditions between producers and consumers.
Program code:
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#include <stdlib.h>
#define buffer_size 2
#define maxItem 2
41
sem_t empty;
sem_t full;
int in = 0, out = 0;
int buffer[buffer_size];
pthread_mutex_t mutex;
int main() {
int i;
pthread_t pro[buffer_size], con[buffer_size];
pthread_mutex_init(&mutex, NULL);
sem_init(&empty, 0, buffer_size);
sem_init(&full, 0, 0);
int a[]={1,2,3,4,5};
42
for (i = 0; i < buffer_size; i++) { //create producer thread
pthread_create(&pro[i], NULL, producer, (void *)&a[i]);
}
return 0;
}
Program code:
/*
Renjth Rajan
Roll no- 49 data-29-04-2024
To solve the dinning philosophers problem using semaphore.
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
43
sem_t room; // create semaphores
sem_t chopstick[5];
int main()
{
int i, a[5];
pthread_t tid[5];
sem_init(&room, 0, 4); // initialize samaphore
for (i = 0; i < 5; i++)
sem_init(&chopstick[i], 0, 1);
for (i = 0; i < 5; i++) //create thread for philosopher
{
a[i] = i;
pthread_create(&tid[i], NULL, philosopher, (void *)&a[i]);
}
for (i = 0; i < 5; i++)
pthread_join(tid[i], NULL);
return 0;
}
44
45