Explore Linux Commands: Experiment No 1
Explore Linux Commands: Experiment No 1
Description: In this exercise, you will learn about various Linux commands and system calls
for managing files, directories, and processes.
Commands:
System Calls:
Algorithm:
Refer to the man pages of each command and system call for usage and examples.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <time.h>
void create_file() {
if (fd < 0) {
perror("open");
exit(1);
close(fd);
void write_to_file() {
int fd = open(FILENAME, O_WRONLY);
if (fd < 0) {
perror("open");
exit(1);
perror("write");
exit(1);
close(fd);
void read_from_file() {
if (fd < 0) {
perror("open");
exit(1);
char buffer[1024];
perror("read");
exit(1);
}
close(fd);
void change_directory() {
if (chdir("..") < 0) {
perror("chdir");
exit(1);
void list_directory() {
perror("system");
exit(1);
void change_file_owner() {
perror("chown");
exit(1);
}
void change_file_permissions() {
perror("chmod");
exit(1);
void change_file_group() {
perror("chgrp");
exit(1);
void display_process_info() {
perror("system");
exit(1);
}
void get_process_info() {
void sort_lines() {
perror("system");
exit(1);
void grep_pattern() {
perror("system");
exit(1);
}
void awk_script() {
perror("system");
exit(1);
int main() {
create_file();
write_to_file();
read_from_file();
change_directory();
list_directory();
change_file_owner();
change_file_permissions();
change_file_group();
display_process_info();
get_process_info();
sort_
Output:
The output will vary based on the commands and system calls used.
shell
shell
shell
shell
shell
shell
shell
EditFull ScreenCopy code
1$ echo -e "apple\nbanana\ncherry\ndate" > fruits.txt
2$ sort fruits.txt
3apple
4banana
5cherry
6date
7$ grep a fruits.txt
8apple
9banana
10$ awk '/a/ {print $1}' fruits.txt
11apple
12banana
EXPERIMENT NO 2 - Linux Shell Script
Description: In this exercise, you will write a shell script to display various system information.
Algorithm:
1. Use the uname command to display the OS type and kernel version.
2. Use the hostnamectl command to display the hostname, kernel, and OS information.
3. Use the lsb_release command to display the OS distribution and release information.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char hostname[256];
char release[256];
char kernel[256];
char architecture[256];
char hardware[256];
char domain[256];
if (gethostname(hostname, sizeof(hostname)) == 0) {
if (getlogin_r(release, sizeof(release)) == 0) {
if (uname(&kernel) == 0) {
if (get_kernel_syms(&architecture, sizeof(architecture)) == 0) {
if (get_kernel_params(&hardware, sizeof(hardware)) == 0) {
if (getdomainname(domain, sizeof(domain)) == 0) {
return 0;
FILE *fp;
fp = fopen("/proc/sys/kernel/ostype", "r");
if (fp != NULL) {
ret = 0;
fclose(fp);
return ret;
FILE *fp;
fp = fopen("/proc/sys/kernel/machine", "r");
if (fp != NULL) {
fclose(fp);
return ret;
Output:
The output will display the OS version, release number, kernel version, hostname, kernel, and OS
information, as well as the OS distribution and release information.
Hostname: my-computer
Release: my-username
Kernel: 5.13.0-30-generic
Architecture: x86_64
Hardware: x86_64
Domain: example.com
Description: In this exercise, you will write a shell script to display the top 10 processes based on CPU
usage.
Algorithm:
1. Use the ps command with the sort and head commands to display the top 10 processes based on CPU
usage.
Code:
-#!/bin/bash
Output:
top - 15:22:12 up 1 day, 22:18, 1 user, load average: 0.28, 0.32, 0.33
%Cpu(s): 0.3 us, 0.2 sy, 0.0 ni, 99.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 16379.5 total, 15545.8 free, 188.8 used, 644.9 buff/cache
MiB Swap: 20479.9 total, 20479.9 free, 0.0 used. 15644.5 avail Mem
Description: In this exercise, you will write a shell script to display processes with the highest memory
usage.
Algorithm:
1. Use the ps command with the sort and head commands to display processes with the highest memory
usage.
Code:
#!/bin/bash
for pid in $(ps -eo pid,%mem --sort=-%mem | head -n 10 | awk '{print $1}'); do
echo "---------------------------------"
done
bash
EditRunFull ScreenCopy code
1#!/bin/bash
2
3# Display processes with highest memory usage
4echo "Processes with Highest Memory Usage:"
5ps -eo pid,%mem --sort=-%mem | head -n 11
Output:
The output will display processes with the highest memory usage.
Command: google-chrome
User: your_username
PID: 2828
---------------------------------
Command: /usr/lib/firefox/firefox
User: your_username
PID: 1
---------------------------------
Command: /usr/bin/gnome-shell
User: root
PID: 2176
---------------------------------
Process ID: 2042
User: your_username
PID: 2828
---------------------------------
User: your_username
PID: 1
---------------------------------
User: your_username
PID: 2828
---------------------------------
Description: In this exercise, you will write a shell script to display various user and system
information.
Algorithm:
1. Use the whoami command to display the current logged-in user.
2. Use the logname command to display the log name.
3. Use the echo $SHELL command to display the current shell.
4. Use the echo $HOME command to display the home directory.
5. Use the uname command to display the operating system type.
6. Use the echo $PATH command to display the current path setting.
7. Use the pwd command to display the current working directory.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/wait.h>
int main() {
pid_t childPid;
int status;
if (uname(&systemInfo) != 0) {
perror("uname");
exit(1);
printf("System Information:\n");
printf(" System Name: %s\n", systemInfo.sysname);
childPid = fork();
if (childPid < 0) {
perror("fork");
exit(1);
} else if (childPid == 0) {
// Child process
} else {
// Parent process
return 0;
Output:
The output will display the current logged-in user and log name, current shell, home directory, operating
system type, current path setting, and current working directory.
System Information:
Release: 5.13.0-30-generic
Machine: x86_64
Description: In this exercise, you will implement the ls command using kernel APIs to list directory
contents.
Algorithm:
1. Use the opendir, readdir, and closedir functions to open a directory, read its contents, and close it.
2. Use the stat function to get file information, such as file type, permissions, and size.
3. Display the file name and file information.
Code:
Refer to the man pages of each function for usage and examples.
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/init.h>
#include <linux/module.h>
static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t *offset)
int bytes_read = 0;
if (!buf)
return -ENOMEM;
if (IS_ERR(dir)) {
kfree(buf);
return PTR_ERR(dir);
dir_context_init(&dc);
bytes_read += dc.pos;
kfree(buf);
filp_close(dir, NULL);
return -ENOMEM;
}
memcpy(buf + bytes_read, dc.entry->d_name.name + dc.pos, dc.entry->d_name.len - dc.pos);
kfree(buf);
filp_close(dir, NULL);
return -ENOMEM;
filp_close(dir, NULL);
kfree(buf);
return -EFAULT;
kfree(buf);
return bytes_read;
.read = device_read,
};
static int __init ls_init(void)
int result;
if (result < 0) {
return result;
return 0;
unregister_chrdev(0, "ls");
module_init(ls_init);
module_exit(ls_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
Output:
The output will display the file name and file information for each file in the specified directory.
Sure, here's an code of how to implement the ls command using kernel APIs in C:
This program uses the opendir, readdir, and closedir functions to open and iterate
through the current directory, and the stat function to get the file size.
To compile and run the program, save it to a file (e.g. myls.c), then run:
Description: In this exercise, you will create a child process in Linux using the fork system call.
Algorithm:
Code:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
if (child_pid < 0) {
return 1;
} else if (child_pid == 0) {
return 0;
Output:
The output will display the process ID of both child and parent processes, and the parent
process will wait for the child process to finish before terminating.
Description: In this exercise, you will write a program to demonstrate the concept of non-
preemptive scheduling algorithms, such as First-Come, First-Served (FCFS) and Shortest Job
Next (SJN).
Algorithm:
1. Create a process queue with a list of processes and their arrival times and burst times.
2. Implement the FCFS and SJN scheduling algorithms to schedule the processes.
3. Calculate the average waiting time and turnaround time for each algorithm.
Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_PROCESSES 5
#define MAX_TIME 20
typedef struct {
int pid;
int arrival_time;
int burst_time;
int remaining_time;
int waiting_time;
} Process;
void non_preemptive_scheduling(Process processes[]) {
int current_time = 0;
int completed_processes = 0;
int i;
current_time += processes[i].remaining_time;
processes[i].remaining_time = 0;
completed_processes++;
break;
if (i == MAX_PROCESSES) {
current_time++;
}
printf("\nWaiting time for each process:\n");
int main() {
Process processes[MAX_PROCESSES] = {
{1, 0, 4},
{2, 1, 3},
{3, 2, 1},
{4, 3, 2},
{5, 4, 5}
};
non_preemptive_scheduling(processes);
return 0;
Output:
The output will display the process ID, arrival time, burst time, waiting time, and turnaround
time for each process, as well as the average waiting time and turnaround time for each
algorithm.
Process 1: 0
Process 2: 3
Process 3: 4
Process 4: 5
Process 5: 8
Description: In this exercise, you will write a program to demonstrate the concept of
preemptive scheduling algorithms, such as Round Robin (RR) and Priority Scheduling (PS).
Algorithm:
1. Create a process queue with a list of processes and their arrival times, burst times, and
priorities.
2. Implement the RR and PS scheduling algorithms to schedule the processes.
3. Calculate the average waiting time and turnaround time for each algorithm.
Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_PROCESSES 5
#define MAX_TIME 20
typedef struct {
int pid;
int arrival_time;
int burst_time;
int remaining_time;
int waiting_time;
} Process;
int current_time = 0;
int completed_processes = 0;
int i;
current_time++;
if (processes[i].remaining_time > 1) {
processes[i].remaining_time--;
i = -1;
break;
} else {
processes[i].remaining_time = 0;
completed_processes++;
if (i == MAX_PROCESSES) {
current_time++;
int main() {
Process processes[MAX_PROCESSES] = {
{1, 0, 4},
{2, 1, 3},
{3, 2, 1},
{4, 3, 2},
{5, 4, 5}
};
preemptive_scheduling(processes);
return 0;
Output:
The output will display the process ID, arrival time, burst time, waiting time, and turnaround
time for each process, as well as the average waiting time and turnaround time for each
algorithm.
Process 1 is running at time 0
Process 2 is running at time 1
Process 3 is running at time 2
Process 4 is running at time 4
Process 5 is running at time 6
Process 2 is running at time 7
Process 5 is running at time 12
Process 3 is running at time 14
Process 4 is running at time 17
Process 1 is running at time 21
Process 5 is running at time 23
Description: In this exercise, you will write a program to implement the solution of the
Producer-Consumer problem through Semaphore to synchronize the access to a shared buffer
between a producer and a consumer.
Algorithm:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5
#define MAX_ITEMS 20
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int produced_count = 0;
int consumed_count = 0;
sem_t mutex;
sem_t full;
sem_t empty;
int item = 1;
sem_wait(&empty);
sem_wait(&mutex);
buffer[in] = item;
item++;
in = (in + 1) % BUFFER_SIZE;
produced_count++;
sem_signal(&mutex);
sem_signal(&full);
}
return NULL;
sem_wait(&full);
sem_wait(&mutex);
consumed_count++;
sem_signal(&mutex);
sem_signal(&empty);
return NULL;
}
int main() {
sem_init(&mutex, 0, 1);
sem_init(&full, 0, 0);
sem_init(&empty, 0, BUFFER_SIZE);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
sem_destroy(&mutex);
sem_destroy(&full);
sem_destroy(&empty);
return 0;
Output:
The output will display the items added and removed from the shared buffer by the producer
and consumer processes.
Produced: 1
Consumed: 1
Produced: 2
Consumed: 2
Produced: 3
Consumed: 3
Produced: 4
Consumed: 4
Produced: 5
Consumed: 5
EXPERIMENT 7- Process Management: Deadlock
Description: In this exercise, you will write a program to demonstrate the concept of deadlock
avoidance through Banker's Algorithm to allocate resources to processes without causing a
deadlock.
Algorithm:
Code:
#include <stdio.h>
#define N 5
#define M 3
{2, 0, 0},
{3, 0, 2},
{0, 0, 2},
{1, 1, 1}};
{0, 0, 1},
{2, 0, 0},
{0, 1, 0}};
int work[M];
int finish[N];
void bankers_algorithm() {
int i, j, k;
int flag = 1;
finish[i] = 0;
while (flag) {
flag = 0;
if (finish[i] == 0) {
int check = 1;
for (j = 0; j < M; j++) {
check = 0;
break;
if (check == 1) {
available[k] += allocation[i][k];
work[i] = need[i][i];
finish[i] = 1;
flag = 1;
if (finish[i] == 1) {
printf("P%d ", i);
int main() {
bankers_algorithm();
return 0;
Output:
The output will display the resource allocation and safe state for each process.
Safe sequence: P0 P1 P4 P3 P2
Description: In this exercise, you will write a program to demonstrate the concept of the
Dining Philosopher's Problem to synchronize the access to shared resources between multiple
processes.
Algorithm:
Code:
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#define N 5
#define THINKING 2
#define HUNGRY 1
#define EATING 0
int state[N];
sem_t S[N];
state[phnum] = EATING;
sleep(2);
sem_post(&S[phnum]);
}
sem_wait(&mutex);
state[phnum] = HUNGRY;
test(phnum);
sem_post(&mutex);
sem_wait(&S[phnum]);
sleep(1);
sem_wait(&mutex);
state[phnum] = THINKING;
test(RIGHT);
sem_post(&mutex);
int i;
while (1) {
sleep(1);
take_fork(phnum);
sleep(0);
put_fork(phnum);
int main() {
int i;
sem_init(&mutex, 0, 1);
sem_init(&S[i], 0, 0);
}
pthread_t id;
pthread_join(phil[i], NULL);
return 0;
}
Output -
Philosopher 0 is thinking.
Philosopher 1 is thinking.
Philosopher 2 is thinking.
Philosopher 3 is thinking.
Philosopher 4 is thinking.
Philosopher 2 is hungry.
Philosopher 2 picked up left fork.
Philosopher 2 picked up right fork.
Philosopher 2 is eating.
Philosopher 3 is hungry.
Philosopher 3 picked up left fork.
Philosopher 3 picked up right fork.
Philosopher 3 is eating.
Philosopher 1 is hungry.
Philosopher 1 picked up left fork.
Philosopher 1 picked up right fork.
Philosopher 1 is eating.
Philosopher 4 is hungry.
Philosopher 4 picked up left fork.
Philosopher 4 picked up right fork.
Philosopher 4 is eating.
Philosopher 0 is hungry.
Philosopher 0 picked up left fork.
Philosopher 0 picked up right fork.
Philosopher 0 is eating.
Philosopher 3 put down right fork.
Philosopher 3 put down left fork.
Philosopher 4 put down right fork.
Philosopher 4 put down left fork.
Philosopher 1 put down right fork.
Philosopher 1 put down left fork.
Philosopher 0 put down right fork.
Philosopher 0 put down left fork.
Philosopher 2 put down right fork.
Philosopher 2 put down left fork.
EXPERIMENT-8. Memory Management
8.1. MVT and MFT Memory Management Techniques
Aim: To write a program to demonstrate the concept of MVT and MFT memory
management techniques.
Description: In this exercise, you will write a program to demonstrate the concept
of MVT and MFT memory management techniques to manage memory allocation
and deallocation.
Algorithm:
Code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_BLOCKS 10
#define MAX_PROCESS 10
typedef struct {
int size;
int allocated;
int process_id;
} Block;
typedef struct {
int id;
int size;
int allocated;
} Process;
Block blocks[MAX_BLOCKS];
Process processes[MAX_PROCESS];
void initialize_blocks() {
int i;
blocks[i].size = 0;
blocks[i].allocated = 0;
blocks[i].process_id = -1;
void initialize_processes() {
int i;
for (i = 0; i < MAX_PROCESS; i++) {
processes[i].id = 0;
processes[i].size = 0;
processes[i].allocated = 0;
void print_blocks() {
int i;
printf("\nBlock\tSize\tAllocated\tProcess ID\n");
void print_processes() {
int i;
printf("\nProcess\tID\tSize\tAllocated\n");
}
}
int i;
return i;
return -1;
int find_free_process() {
int i;
return i;
return -1;
}
void allocate_memory_mvt(int process_id, int size) {
int i, free_block;
if (processes[i].id == process_id) {
free_block = find_free_block(size);
if (free_block != -1) {
blocks[free_block].allocated = 1;
blocks[free_block].process_id = process_id;
processes[i].allocated = 1;
break;
} else {
break;
if (processes[i].id == process_id) {
free_block = -1;
min_size = MAX_BLOCKS;
min_size = blocks[j].size;
min_index = j;
if (min_size != MAX_BLOCKS) {
free_block = min_index;
blocks[free_block].allocated = 1;
blocks[free_block].process_id = process_id;
processes[i].allocated = 1;
} else {
}
break;
int i;
if (processes[i].id == process_id) {
if (blocks[j].process_id == process_id) {
block_index = j;
break;
if (block_index != -1) {
blocks[block_index].allocated = 0;
blocks[block_index].process_id = -1;
processes[i].allocated = 0;
} else {
printf("Process %d not found\n", process_id);
break;
int main() {
initialize_blocks();
initialize_processes();
print_blocks();
print_processes();
allocate_memory_mvt(1, 10);
allocate_memory_mft(2, 5);
allocate_memory_mft(3, 20);
allocate_memory_mft(4, 30);
allocate_memory_mft(5, 10);
print_blocks();
print_processes();
deallocate_memory(2);
deallocate_memory(3);
print_blocks();
print_processes();
return 0;
Output:
The output will display the memory allocation and deallocation for each process, as
well as the memory usage and fragmentation for each technique.
Description: In this exercise, you will write a program to demonstrate the concept
of dynamic partitioning placement algorithms, such as Best Fit, First Fit, and Worst-
Fit, to allocate memory for processes.
Algorithm:
Code:
#include <stdio.h>
#include <stdlib.h>
// Function prototypes
void best_fit_placement();
void first_fit_placement();
void worst_fit_placement();
int main() {
best_fit_placement();
first_fit_placement();
worst_fit_placement();
return 0;
void best_fit_placement() {
int memory[MEMORY_SIZE] = {0}; // Represents the memory blocks
while (1) {
scanf("%d", &task_size);
if (task_size == -1)
break;
int remaining_space = 0;
remaining_space++;
i++;
min_remaining_space = remaining_space;
best_fit_index = i - remaining_space;
}
if (best_fit_index != -1) {
memory[i] = 1;
task_id++;
} else {
void first_fit_placement() {
// Implementation similar to Best Fit, except break after finding the first fit
// It traverses memory blocks linearly and allocates the task in the first available
space.
}
// Function to simulate Worst Fit placement algorithm
void worst_fit_placement() {
// Implementation similar to Best Fit, except it finds the maximum remaining space
instead of minimum.
Output:
The output will display the memory allocation and deallocation for each process, as
well as the memory usage and fragmentation for each algorithm.
Description: In this exercise, you will write a program to demonstrate the concept
of demand paging for simulation of Virtual Memory implementation to manage
memory allocation and deallocation.
Algorithm:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define NUM_FRAMES 4
#define NUM_PAGES 16
typedef struct {
int frame_number;
bool valid;
} PageTableEntry;
typedef struct {
int frame_number;
bool dirty;
} FrameTableEntry;
PageTableEntry page_table[NUM_PAGES];
FrameTableEntry frame_table[NUM_FRAMES];
void initialize_page_table() {
page_table[i].valid = false;
void initialize_frame_table() {
frame_table[i].frame_number = -1;
frame_table[i].dirty = false;
}
// Find a free frame or a victim frame using a simple FIFO replacement policy
if (frame_table[i].frame_number == -1) {
victim_frame = i;
break;
if (victim_frame == -1) {
victim_frame = 0;
if (frame_table[victim_frame].dirty) {
frame_table[victim_frame].frame_number = page_number;
frame_table[victim_frame].dirty = false;
page_table[page_number].valid = true;
page_table[page_number].frame_number = victim_frame;
if (!page_table[page_number].valid) {
handle_page_fault(page_number);
if (write) {
frame_table[frame_number].dirty = true;
int main() {
initialize_page_table();
initialize_frame_table();
return 0;
}
Output:
The output will display the memory allocation and deallocation for each process, as
well as the memory usage and page faults for each process.
Evicting frame 0
Evicting frame 1
Description: In this exercise, you will write a program to demonstrate the concept
of page replacement policies for handling page faults, such as First-In, First-Out
(FIFO), Least Recently Used (LRU), and Optimal, to manage memory allocation and
deallocation.
Algorithm:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define NUM_FRAMES 3
#define NUM_PAGES 6
typedef struct {
int page_number;
bool valid;
} PageTableEntry;
typedef struct {
int page_number;
} FrameTableEntry;
// Page replacement policy enumeration
typedef enum {
FIFO,
LRU
} ReplacementPolicy;
// Function prototypes
int main() {
PageTableEntry page_table[NUM_PAGES];
FrameTableEntry frame_table[NUM_FRAMES];
ReplacementPolicy policy;
initialize_page_table(page_table);
initialize_frame_table(frame_table);
// Simulate page faults with FIFO policy
policy = FIFO;
initialize_frame_table(frame_table);
policy = LRU;
page_table[i].valid = false;
frame_table[i].page_number = -1;
int victim_frame;
switch (policy) {
case FIFO:
victim_frame = 0;
break;
case LRU:
victim_frame = 0;
break;
frame_table[victim_frame].page_number = page_number;
page_table[page_number].valid = true;
// Print the updated frame table
print_frame_table(frame_table);
printf("\n");
Output:
The output will display the memory allocation and deallocation for each process, as
well as the memory usage and page faults for each policy.
Description: In this exercise, you will write a program to simulate file allocation
strategies, such as sequential, indexed, and linked files, to manage file storage and
retrieval.
Algorithm:
Code:
#include <stdio.h>
#include <stdlib.h>
#define NUM_BLOCKS 10
typedef enum {
CONTIGUOUS,
LINKED,
INDEXED
} AllocationStrategy;
int data;
} Block;
// Function prototypes
int main() {
int file_size;
scanf("%d", &file_size);
printf("\nContiguous Allocation:\n");
contiguous_allocation(file_size);
printf("\nLinked Allocation:\n");
linked_allocation(file_size);
printf("\nIndexed Allocation:\n");
indexed_allocation(file_size);
return 0;
return;
printf("\n");
}
// Linked allocation strategy
return;
new_block->data = i;
new_block->next = NULL;
if (head == NULL) {
head = new_block;
current = new_block;
} else {
current->next = new_block;
current = new_block;
printf("\n");
current = head;
current = current->next;
free(temp);
return;
}
int index_table[file_size];
index_table[i] = i;
printf("\n");
Output:
The output will display the file storage and retrieval for each file, as well as the
storage usage and access time for each strategy.
Contiguous Allocation:
Allocated blocks: 0 1 2 3 4
Linked Allocation:
Allocated blocks: 0 1 2 3 4
Indexed Allocation:
Index table: 0 1 2 3 4
Description: In this exercise, you will write a program to simulate file organization
of multi-level directory structure to manage file
Algorithm:
#define MAX_DEPTH 10
#define MAX_NAME_LENGTH 20
// Directory structure
typedef struct Directory {
char name[MAX_NAME_LENGTH];
struct Directory* subdirectories[MAX_DEPTH];
int num_subdirectories;
} Directory;
// Function prototypes
Directory* create_directory(const char* name);
Directory* find_subdirectory(Directory* parent, const char* name);
void add_subdirectory(Directory* parent, Directory* subdirectory);
void navigate(Directory* current_directory);
void display_path(Directory* current_directory);
int main() {
Directory* root = create_directory("root");
Directory* current_directory = root;
// Create sample directory structure
Directory* dir1 = create_directory("dir1");
Directory* dir2 = create_directory("dir2");
Directory* dir3 = create_directory("dir3");
add_subdirectory(root, dir1);
add_subdirectory(root, dir2);
add_subdirectory(dir2, dir3);
navigate(current_directory);
return 0;
}
while (1) {
printf("\nCurrent Directory: ");
display_path(current_directory);
printf("\nCommands: cd <directory_name> | exit\n");
printf("Enter command: ");
scanf("%s", input);
if (strcmp(input, "exit") == 0) {
break;
} else if (strcmp(input, "cd") == 0) {
scanf("%s", input);
Directory* new_directory = find_subdirectory(current_directory, input);
if (new_directory != NULL) {
current_directory = new_directory;
} else {
printf("Directory not found.\n");
}
} else {
printf("Invalid command.\n");
}
}
}
Output:
The output will display the disk access and retrieval for each disk request, as well as the
access time and seek time for each algorithm.