OSLabook Bodyfinal 2
OSLabook Bodyfinal 2
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int i, num_processes = 5;
if (pid < 0) {
fprintf(stderr, "Fork failed.\n");
return 1;
} else if (pid == 0) {
// Child process
printf("Child process %d with PID %d\n", i + 1,
getpid());
exit(0); // Exit child process
} else {
// Parent process
printf("Parent process with PID %d created child %d with
PID %d\n", getpid(), i + 1, pid);
}
}
return 0;
}
OUTPUT:
Parent process with PID 1234 created child 1 with PID 1235
Child process 1 with PID 1235
1
Parent process with PID 1234 created child 2 with PID 1236
Child process 2 with PID 1236
Parent process with PID 1234 created child 3 with PID 1237
Child process 3 with PID 1237
Parent process with PID 1234 created child 4 with PID 1238
Child process 4 with PID 1238
Parent process with PID 1234 created child 5 with PID 1239
Child process 5 with PID 1239
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t mutex;
int shared_variable = 0;
2
printf("Decremented shared variable: %d\n", shared_variable);
pthread_mutex_unlock(&mutex); // Unlock the critical section
usleep(100000); // Sleep for 100ms
}
pthread_exit(NULL);
}
int main() {
pthread_t thread1, thread2;
// Create threads
pthread_create(&thread1, NULL, increment, NULL);
pthread_create(&thread2, NULL, decrement, NULL);
return 0;
}
OUTPUT:
3
c) Create a program to demonstrate inter-process communication using shared
memory or message passing.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
struct shared_data {
int flag;
char message[SHM_SIZE];
};
int main() {
int shm_id;
key_t key = ftok(".", 'x');
struct shared_data *shared_memory;
4
shared_memory->flag = 0;
strcpy(shared_memory->message, "Hello from shared memory!");
if (pid < 0) {
perror("fork");
exit(1);
} else if (pid == 0) {
// Child process reads from shared memory
while (shared_memory->flag == 0) {
usleep(100000); // Sleep for 100ms
}
printf("Child Process: Received message from parent: %s \n",
shared_memory->message);
} else {
// Parent process writes to shared memory
printf("Parent Process: Writing message to shared memory\n");
strcpy(shared_memory->message, "Hello from parent!");
shared_memory->flag = 1; // Set flag to indicate message is
ready
wait(NULL); // Wait for child process to finish
}
return 0;
}
5
OUTPUT:
2) Memory Management
a) Develop a C program to simulate memory allocation and deallocation using
dynamic memory allocation functions like malloc() and free().
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n, i;
if (ptr == NULL) {
printf("Memory allocation failed.\n");
return 1;
}
6
}
printf("\n");
printf("Memory deallocated.\n");
return 0;
}
OUTPUT:
FIFO
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#define NUM_FRAMES 3
#define NUM_PAGES 10
int main() {
int frames[NUM_FRAMES]; // Array to store page frames
7
int pages[NUM_PAGES] = {0, 1, 2, 3, 2, 4, 5, 3, 4, 1}; //
Reference string
int page_faults = 0;
int current_frame = 0;
int i, j;
if (!found) {
page_faults++;
frames[current_frame] = page;
current_frame = (current_frame + 1) % NUM_FRAMES;
}
8
}
return 0;
}
OUTPUT:
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
struct process {
int id;
int size;
};
9
int allocated[NUM_PROCESSES] = {0}; // Keeps track of allocated
processes
int total_allocated = 0;
10
int allocated[NUM_PROCESSES] = {0}; // Keeps track of allocated
processes
int total_allocated = 0;
int main() {
struct process processes[NUM_PROCESSES] = {
{1, 20},
{2, 10},
{3, 30},
{4, 15},
{5, 25}
};
contiguousAllocation(processes);
nonContiguousAllocation(processes);
return 0;
}
11
OUTPUT:
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file;
char filename[] = "sample.txt";
char buffer[100];
// Writing to a file
file = fopen(filename, "w");
if (file == NULL) {
printf("Error opening file for writing.\n");
return 1;
}
fprintf(file, "This is a sample text file.\n");
fprintf(file, "Writing data to the file.\n");
fclose(file);
12
// Reading from a file
file = fopen(filename, "r");
if (file == NULL) {
printf("Error opening file for reading.\n");
return 1;
}
printf("Contents of %s:\n", filename);
while (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("%s", buffer);
}
fclose(file);
// Appending to a file
file = fopen(filename, "a");
if (file == NULL) {
printf("Error opening file for appending.\n");
return 1;
}
fprintf(file, "Appending data to the file.\n");
fclose(file);
return 0;
}
OUTPUT:
Contents of sample.txt:
13
This is a sample text file.
Writing data to the file.
b) Implement file access control using access permissions (read, write, execute)
and demonstrate file protection mechanisms.
#include <stdio.h>
#include <sys/stat.h>
int main() {
char filename[] = "sample.txt";
struct stat fileStat;
14
printf("Others write permission: %s\n", (fileStat.st_mode &
S_IWOTH) ? "Yes" : "No");
printf("Others execute permission: %s\n\n", (fileStat.st_mode &
S_IXOTH) ? "Yes" : "No");
return 0;
}
15
PROGRAM:
OUTPUT:
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
16
DIR *dir;
struct dirent *entry;
struct stat fileStat;
dir = opendir(dir_path);
if (dir == NULL) {
perror("Error opening directory");
return;
}
17
closedir(dir);
}
int main() {
char start_dir[] = "."; // Start traversal from the current
directory
traverseDirectory(start_dir);
return 0;
}
DIRECTORY TREE:
parent_directory/
├── subdirectory1/
│ ├── file1.txt
│ ├── file2.txt
│ └── subsubdirectory/
│ └── file3.txt
└── subdirectory2/
├── file4.txt
└── file5.txt
OUTPUT:
Directory: subdirectory1
File: file1.txt
File permissions: 644
File: file2.txt
File permissions: 644
Directory: subsubdirectory
File: file3.txt
File permissions: 644
Directory: subdirectory2
18
File: file4.txt
File permissions: 644
File: file5.txt
File permissions: 644
4) Process Scheduling
a) Implement different process scheduling algorithms like Round-Robin, First
Come First Served, and Shortest-Job-First in C.
Round-Robin
PROGRAM:
#include <stdio.h>
int time = 0;
while (1) {
int done = 1;
for (int i = 0; i < n; i++) {
if (remaining_time[i] > 0) {
done = 0;
if (remaining_time[i] > quantum) {
time += quantum;
remaining_time[i] -= quantum;
printf("Process %d executed for quantum %d\n",
processes[i], quantum);
} else {
time += remaining_time[i];
remaining_time[i] = 0;
printf("Process %d executed completely\n",
processes[i]);
}
19
}
}
if (done == 1) {
break;
}
}
}
int main() {
int processes[] = {1, 2, 3};
int n = sizeof(processes) / sizeof(processes[0]);
int burst_time[] = {10, 5, 8};
int quantum = 2;
roundRobin(processes, n, burst_time, quantum);
return 0;
}
INPUT:
OUTPUT:
PROGRAM:
#include <stdio.h>
20
void firstComeFirstServed(int processes[], int n, int burst_tim e[]) {
int waiting_time[n], turnaround_time[n];
waiting_time[0] = 0;
turnaround_time[0] = burst_time[0];
for (int i = 1; i < n; i++) {
waiting_time[i] = waiting_time[i - 1] + burst_time[i - 1];
turnaround_time[i] = waiting_time[i] + burst_time[i];
}
int main() {
int processes[] = {1, 2, 3};
int n = sizeof(processes) / sizeof(processes[0]);
int burst_time[] = {10, 5, 8};
firstComeFirstServed(processes, n, burst_time);
return 0;
}
INPUT:
OUTPUT:
Shortest-Job-First
21
PROGRAM:
#include <stdio.h>
waiting_time[0] = 0;
turnaround_time[0] = burst_time[0];
for (int i = 1; i < n; i++) {
waiting_time[i] = waiting_time[i - 1] + burst_time[i - 1];
turnaround_time[i] = waiting_time[i] + burst_time[i];
}
22
int main() {
int processes[] = {1, 2, 3};
int n = sizeof(processes) / sizeof(processes[0]);
int burst_time[] = {10, 5, 8};
shortestJobFirst(processes, n, burst_time);
return 0;
}
INPUT:
OUTPUT:
b) Write a CPU scheduler simulator that can handle a queue of processes and
schedule them based on priority or other criteria.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
struct Process {
int pid;
int priority;
};
struct Node {
struct Process process;
struct Node* next;
23
};
struct Queue {
struct Node* front;
struct Node* rear;
};
if (queue->rear == NULL) {
queue->front = queue->rear = newNode;
return;
}
queue->rear->next = newNode;
queue->rear = newNode;
}
if (queue->front == NULL) {
queue->rear = NULL;
24
}
free(temp);
return process;
}
int main() {
struct Queue* queue = createQueue();
enqueue(queue, p1);
enqueue(queue, p2);
enqueue(queue, p3);
printf("Processes in queue:\n");
printf("PID\tPriority\n");
struct Node* current = queue->front;
while (current != NULL) {
printf("%d\t%d\n", current->process.pid, current-
>process.priority);
current = current->next;
}
return 0;
}
OUTPUT:
25
Processes in queue:
PID Priority
1 3
2 1
3 2
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
struct Process {
int pid;
int arrival_time;
int burst_time;
int waiting_time;
int turnaround_time;
int remaining_time;
};
26
} else {
total_time += processes[i].remaining_time;
processes[i].turnaround_time = total_time -
processes[i].arrival_time;
processes[i].waiting_time =
processes[i].turnaround_time - processes[i].burst_time;
processes[i].remaining_time = 0;
completed++;
}
}
}
}
}
27
processes[i].turnaround_time = total_time -
processes[i].arrival_time;
processes[i].waiting_time = processes[i].turnaround_time -
processes[i].burst_time;
}
}
int main() {
int n = 4; // Number of processes
struct Process processes[n];
printf("\n");
28
printf("\n");
return 0;
}
OUTPUT:
29
5) Deadlocks
a) Write a C program to detect and handle deadlocks using resource allocation
graphs or the Banker's algorithm.
PROGRAM:
#include <stdio.h>
#include <stdbool.h>
30
// Function to initialize the need matrix based on maximum and
allocation matrices
void calculateNeed() {
for (int i = 0; i < N_PROCESSES; i++) {
for (int j = 0; j < N_RESOURCES; j++) {
need[i][j] = maximum[i][j] - allocation[i][j];
}
}
}
int safeSequence[N_PROCESSES];
int count = 0;
31
found = true;
}
}
if (!found) {
printf("Deadlock detected. System is in an unsafe
state.\n");
return;
}
}
int main() {
calculateNeed();
bankerAlgorithm();
return 0;
}
OUTPUT:
Allocation matrix:
{0, 1, 0},
{2, 0, 0},
{3, 0, 2},
{2, 1, 1},
{0, 0, 2}
32
System is in a safe state. Safe sequence: P1 P3 P4 P0 P2
PROGRAM:
#include <stdio.h>
#include <stdbool.h>
33
// Function to initialize the need matrix based on maximum and
allocation matrices
void calculateNeed() {
for (int i = 0; i < N_PROCESSES; i++) {
for (int j = 0; j < N_RESOURCES; j++) {
need[i][j] = maximum[i][j] - allocation[i][j];
}
}
}
int count = 0;
while (count < N_PROCESSES) {
bool found = false;
for (int i = 0; i < N_PROCESSES; i++) {
if (!finish[i]) {
int j;
34
for (j = 0; j < N_RESOURCES; j++) {
if (need[i][j] > work[j]) {
break;
}
}
if (j == N_RESOURCES) {
for (int k = 0; k < N_RESOURCES; k++) {
work[k] += allocation[i][k];
}
finish[i] = true;
safe = true;
found = true;
count++;
}
}
}
if (!found) {
safe = false;
break;
}
}
return safe;
}
35
printf("Request granted. Process %d can proceed safely.\n",
process);
} else {
printf("Request denied. Process %d must wait to avoid
deadlock.\n", process);
}
}
int main() {
calculateNeed();
return 0;
}
OUTPUT:
Allocation matrix:
{0, 1, 0},
{2, 0, 0},
{3, 0, 2},
{2, 1, 1},
{0, 0, 2}
First process request: {1, 0, 2}
Second process request: {3, 2, 0}
36
Process 0 is requesting resources: {1, 0, 2}
Request granted. Process 0 can proceed safely.
Process 1 is requesting resources: {3, 2, 0}
Request denied. Process 1 must wait to avoid deadlock.
PROGRAM:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#define N_PROCESSES 5
#define N_RESOURCES 3
37
};
if (safe) {
// Grant request and update allocation and available
resources
for (int i = 0; i < N_RESOURCES; i++) {
allocation[process][i] += request[i];
available[i] -= request[i];
need[process][i] -= request[i];
}
printf("Request granted. Process %d can proceed.\n",
process);
38
} else {
printf("Request denied. Process %d must wait to avoid
deadlock.\n", process);
}
}
int main() {
calculateNeed();
return 0;
}
39
OUTPUT:
Allocation matrix:
{0, 1, 0},
{2, 0, 0},
{3, 0, 2},
{2, 1, 1},
{0, 0, 2}
40
6) Input/Output Device Management
a) Develop a C program to simulate disk scheduling algorithms like FCFS,
SSTF, and SCAN.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
41
printf("SSTF Total Head Movement: %d\n", total_distance);
}
int index = 0;
while (1) {
if (direction == 1) {
while (index < n && disk[index] <= head) {
total_distance += abs(head - disk[index]);
head = disk[index];
index++;
}
if (index == n) {
total_distance += end - head;
head = end;
direction = -1; // Change direction
}
} else {
while (index >= 0 && disk[index] >= head) {
total_distance += abs(head - disk[index]);
head = disk[index];
index--;
}
if (index == -1) {
42
total_distance += head - start;
head = start;
break;
}
}
}
printf("SCAN Total Head Movement: %d\n", total_distance);
}
int main() {
int disk[] = {98, 183, 37, 122, 14, 124, 65, 67}; // Disk
requests
int head = 53; // Initial head position
int n = sizeof(disk) / sizeof(disk[0]);
return 0;
}
OUTPUT:
#include <stdio.h>
#include <stdlib.h>
43
int status; // 0 for idle, 1 for busy
};
// Simulate a process
struct Process {
int process_id;
int waiting_time;
};
int main() {
44
// Simulate processes with I/O requests
struct Process processes[] = {{1, 0}, {2, 3}, {3, 6}}; // Process
ID and waiting time
int n = sizeof(processes) / sizeof(processes[0]);
return 0;
}
OUTPUT:
45
Process 3: Continue processing after I/O
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
46
// Thread function to simulate process and I/O
void* processThread(void* arg) {
struct IODevice* io_device = (struct IODevice*)arg;
struct IORequest io_request;
io_request.process_id = rand() % 1000; // Generate a random
process ID
io_request.data = rand() % 100; // Generate random data for I/O
request
return NULL;
}
int main() {
srand(time(NULL)); // Seed the random number generator
// Join threads
for (int i = 0; i < 5; i++) {
pthread_join(threads[i], NULL);
}
return 0;
47
}
OUTPUT:
7) Security Management
a) Create a user authentication system in C using passwords and encryption
techniques.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
48
char username[50];
char password[50];
};
int main() {
registerUser("user1", "password1");
registerUser("user2", "password2");
char username[50];
char password[50];
49
scanf("%s", password);
if (authenticateUser(username, password)) {
printf("Login successful!\n");
} else {
printf("Invalid username or password.\n");
}
return 0;
}
OUTPUT:
b) Develop a program to detect and prevent common security threats like buffer
overflow or unauthorized access
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
50
return 1; // Input is within bounds
}
int main() {
char username[MAX_LENGTH];
char password[MAX_LENGTH];
51
printf("Error: Password exceeds maximum length.\n");
return 1;
}
if (validateCredentials(username, password)) {
printf("Login successful!\n");
} else {
printf("Invalid username or password.\n");
}
return 0;
}
OUTPUT:
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
52
struct UserPermission acl[10];
int aclSize = 0;
int main() {
// Add user permissions to ACL
addUserPermission("user1", 1, 1, 0); // Read and write
permissions
addUserPermission("user2", 1, 0, 1); // Read and execute
permissions
addUserPermission("user3", 1, 1, 1); // Read, write, and execute
permissions
53
char username[50];
int permission;
if (checkPermissions(username, permission)) {
printf("Permission granted.\n");
} else {
printf("Permission denied.\n");
}
return 0;
}
OUTPUT:
54