0% found this document useful (0 votes)
3 views10 pages

Unix Manual

The document contains various C++ programs demonstrating file operations, process management, inter-process communication, and scheduling algorithms. It includes functionalities like copying files, creating hard links, using shared memory, and implementing producer-consumer problems with semaphores. Additionally, it covers round robin and priority-based scheduling algorithms, along with message queue operations.

Uploaded by

Ankit Khedkar
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views10 pages

Unix Manual

The document contains various C++ programs demonstrating file operations, process management, inter-process communication, and scheduling algorithms. It includes functionalities like copying files, creating hard links, using shared memory, and implementing producer-consumer problems with semaphores. Additionally, it covers round robin and priority-based scheduling algorithms, along with message queue operations.

Uploaded by

Ankit Khedkar
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

perror("Error opening source file");

.31 . Check the following limits: return 1;


No. of clock ticks, Max. no. of child processes, Max. path length, Max. no. of characters in a file name, Max. no. of }
open files/ process
int dest_fd = open(destinationFile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if (dest_fd == -1) {
#include <stdio.h> perror("Error opening destination file");
#include <unistd.h> close(source_fd);
#include <limits.h> return 1;
}
int main() {
// Check and print the number of clock ticks char buffer[4096];
printf("No. of clock ticks: %ld\n", sysconf(_SC_CLK_TCK)); ssize_t bytes_read;

// Check and print the max number of child processes while ((bytes_read = read(source_fd, buffer, sizeof(buffer))) > 0) {
printf("Max. no. of child processes: %ld\n", sysconf(_SC_CHILD_MAX)); ssize_t bytes_written = write(dest_fd, buffer, bytes_read);
if (bytes_written != bytes_read) {
// Check and print the max path length perror("Error writing to destination file");
printf("Max. path length: %ld\n", pathconf("/", _PC_PATH_MAX)); close(source_fd);
close(dest_fd);
// Check and print the max number of characters in a file name return 1;
printf("Max. no. of characters in a file name: %ld\n", pathconf("/", _PC_NAME_MAX)); }
}
// Check and print the max number of open files per process
printf("Max. no. of open files/process: %ld\n", sysconf(_SC_OPEN_MAX)); // Close file descriptors
close(source_fd);
return 0; close(dest_fd);
}
std::cout << "File copied successfully!" << std::endl;
Output :
return 0;
}

b. Output the contents of the Environment list:

#include <iostream>

2. a. Copy of a file using system calls. extern char** environ;


b. Output the contents of its Environment list
int main() {
char** env = environ;

#include <iostream> while (*env != nullptr) {


#include <fstream> std::cout << *env << std::endl;
#include <cstdlib> env++;
#include <cstring> }
#include <sys/types.h>
#include <sys/stat.h> return 0;
#include <fcntl.h> }
#include <unistd.h>

int main() {
const char* sourceFile = "[Link]";
const char* destinationFile = "[Link]";

int source_fd = open(sourceFile, O_RDONLY);


if (source_fd == -1) {
// Fork a child process
child_pid = fork();

if (child_pid == -1) {
std::cerr << "Fork failed." << std::endl;
return 1;
}

for (int i = 1; i <= 5; i++) {


if (child_pid == 0) {
// Child process
std::cout << "Child Count: " << i << std::endl;
} else {
// Parent process
std::cout << "Parent Count: " << i << std::endl;
}
sleep(1); // Sleep for 1 second
}

return 0;
}
3. a. Emulate the UNIX ln command
b. Create a child from parent process using fork() and counter counts till 5 in both processes and displays.

a.
#include <iostream>
#include <unistd.h>

int main(int argc, char *argv[]) {


if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " source_file target_file" << std::endl;
return 1;
}

const char *source_file = argv[1];


const char *target_file = argv[2];
4 . Illustrate two processes communicating using shared memory
if (link(source_file, target_file) == 0) {
std::cout << "Hard link created: " << target_file << " -> " << source_file << std::endl;
return 0;
} else { #include <iostream>
perror("Error creating hard link"); #include <cstdlib>
return 2; #include <cstring>
} #include <sys/types.h>
} #include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <sys/wait.h>

// Define the shared memory key


#define SHM_KEY 1234
// Define the size of the shared memory segment
b. #define SHM_SIZE 1024
#include <iostream>
#include <unistd.h> int main() {
// Create a key for the shared memory segment
int main() { key_t key = ftok(".", SHM_KEY);
pid_t child_pid; if (key == -1) {
perror("ftok"); // Print an error message if ftok fails
exit(1);
}
5. Demonstrate producer and consumer problem using semaphores
// Create (or get) a shared memory segment
int shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget"); // Print an error message if shmget fails #include <iostream>
exit(1); #include <pthread.h>
} #include <semaphore.h>
#include <unistd.h>
// Attach the shared memory segment to the process's address space #include <vector>
char *shm_ptr = (char *)shmat(shmid, NULL, 0);
if (shm_ptr == (char *)(-1)) { #define MAX_BUFFER_SIZE 5
perror("shmat"); // Print an error message if shmat fails #define NUM_PRODUCERS 2
exit(1); #define NUM_CONSUMERS 2
}
std::vector<int> buffer; // Shared buffer
// Parent process writes a message to shared memory sem_t mutex; // Semaphore for mutual exclusion
std::string message = "Hello, shared memory!"; sem_t empty; // Semaphore for tracking empty slots in the buffer
std::strcpy(shm_ptr, message.c_str()); sem_t full; // Semaphore for tracking filled slots in the buffer

// Fork a child process void* producer(void* arg) {


pid_t child_pid = fork(); int item = *((int*)arg);
while (true) {
if (child_pid == -1) { sleep(1);
perror("fork"); // Print an error message if fork fails
exit(1); sem_wait(&empty); // Wait for an empty slot in the buffer
} sem_wait(&mutex); // Enter critical section

if (child_pid == 0) { buffer.push_back(item); // Produce an item and add it to the buffer


// Child process reads from shared memory and prints std::cout << "Produced: " << item << ", Buffer size: " << [Link]() << std::endl;
std::cout << "Child process reads: " << shm_ptr << std::endl;
sem_post(&mutex); // Exit critical section
// Detach the shared memory segment from the child process sem_post(&full); // Signal that a slot in the buffer is filled
if (shmdt(shm_ptr) == -1) { }
perror("shmdt"); // Print an error message if shmdt fails return NULL;
exit(1); }
}
} else { // Consumer function
// Parent process waits for the child to finish void* consumer(void* arg) {
wait(NULL); while (true) {
sleep(1); // Simulate time to consume an item
// Detach the shared memory segment from the parent process
if (shmdt(shm_ptr) == -1) { sem_wait(&full); // Wait for a filled slot in the buffer
perror("shmdt"); // Print an error message if shmdt fails sem_wait(&mutex); // Enter critical section
exit(1);
} int item = [Link](); // Consume an item from the buffer
buffer.pop_back();
// Remove the shared memory segment std::cout << "Consumed: " << item << ", Buffer size: " << [Link]() << std::endl;
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("shmctl"); // Print an error message if shmctl fails sem_post(&mutex); // Exit critical section
exit(1); sem_post(&empty); // Signal that a slot in the buffer is empty
} }
} return NULL;}

return 0; int main() {


} // Initialize semaphores
sem_init(&mutex, 0, 1); // Mutex semaphore
sem_init(&empty, 0, MAX_BUFFER_SIZE); // Empty semaphore (buffer slots available)
sem_init(&full, 0, 0); // Full semaphore (buffer slots filled)

// Create producer and consumer threads


pthread_t producer_threads[NUM_PRODUCERS];
pthread_t consumer_threads[NUM_CONSUMERS];
6 . Demonstrate round robin scheduling algorithm and calculates average waiting time and average turnaround
for (int i = 0; i < NUM_PRODUCERS; ++i) { time
int* item = new int(i); //dont know weather the answer is right or wrong
pthread_create(&producer_threads[i], NULL, producer, (void*)item);
} // [Link] ROBIN SCHEDULING

for (int i = 0; i < NUM_CONSUMERS; ++i) { #include <iostream>


pthread_create(&consumer_threads[i], NULL, consumer, NULL); using namespace std;
}
int main() {
// Join threads int i, limit, total = 0, x, counter = 0, time_quantum;
for (int i = 0; i < NUM_PRODUCERS; ++i) { int wait_time = 0, turnaround_time = 0, arrival_time[10], burst_time[10], temp[10];
pthread_join(producer_threads[i], NULL); float average_wait_time, average_turnaround_time;
}
cout << "Enter Total Number of Processes: ";
for (int i = 0; i < NUM_CONSUMERS; ++i) { cin >> limit;
pthread_join(consumer_threads[i], NULL); x = limit;
}
for (i = 0; i < limit; i++) {
// Destroy semaphores cout << "\nEnter Details of Process[" << i + 1 << "]\n";
sem_destroy(&mutex); cout << "Arrival Time: ";
sem_destroy(&empty); cin >> arrival_time[i];
sem_destroy(&full); cout << "Burst Time: ";
cin >> burst_time[i];
return 0; temp[i] = burst_time[i];
} }

cout << "\nEnter Time Quantum: ";


cin >> time_quantum;

cout << "\nProcess ID\tBurst Time\tTurnaround Time\tWaiting Time\n";


for (total = 0, i = 0; x != 0;) {
if (temp[i] <= time_quantum && temp[i] > 0) {
total += temp[i];
temp[i] = 0;
counter = 1;
} else if (temp[i] > 0) {
temp[i] -= time_quantum;
total += time_quantum;
}

if (temp[i] == 0 && counter == 1) {


x--;
cout << "\nProcess[" << i + 1 << "]\t\t" << burst_time[i] << "\t\t" << total - arrival_time[i] << "\t\t\t" << total -
arrival_time[i] - burst_time[i];
wait_time += total - arrival_time[i] - burst_time[i];
turnaround_time += total - arrival_time[i];
counter = 0;
}

if (i == limit - 1)
i = 0;
else if (arrival_time[i + 1] <= total)
i++;
else
total++;
}

average_wait_time = wait_time * 1.0 / limit;


average_turnaround_time = turnaround_time * 1.0 / limit;

cout << "\n\nAverage Waiting Time: " << average_wait_time;


cout << "\nAvg Turnaround Time: " << average_turnaround_time << endl; processes[i].processID = i + 1;
cout << "Enter burst time for process " << i + 1 << ": ";
return 0; cin >> processes[i].burstTime;
} cout << "Enter priority for process " << i + 1 << ": ";
Output : cin >> processes[i].priority;
}

sort([Link](), [Link](), comparePriority);

processes[0].waitingTime = 0;
processes[0].turnaroundTime = processes[0].burstTime;

for (int i = 1; i < numProcesses; i++) {


processes[i].waitingTime = processes[i - 1].waitingTime + processes[i - 1].burstTime;
processes[i].turnaroundTime = processes[i].waitingTime + processes[i].burstTime;
}

double totalWaitingTime = 0;
double totalTurnaroundTime = 0;

for (const Process &p : processes) {


totalWaitingTime += [Link];
totalTurnaroundTime += [Link];
}

double averageWaitingTime = totalWaitingTime / numProcesses;


double averageTurnaroundTime = totalTurnaroundTime / numProcesses;

cout << "Process\tBurst Time\tPriority\tWaiting Time\tTurnaround Time\n";


for (const Process &p : processes) {
cout << [Link] << "\t\t" << [Link] << "\t\t" << [Link] << "\t\t" << [Link] << "\t\t" <<
[Link] << endl;
}

7. Implement priority-based scheduling algorithm and calculates average waiting time and average turnaround time cout << "\nAverage Waiting Time: " << averageWaitingTime << endl;
cout << "Average Turnaround Time: " << averageTurnaroundTime << endl;
#include <iostream> return 0;
#include <vector> }
#include <algorithm>

using namespace std;

struct Process {
int processID;
int burstTime;
int priority;
int waitingTime;
int turnaroundTime;
};

bool comparePriority(const Process &a, const Process &b) {


return [Link] < [Link];
}

int main() { 8. Act as sender to send data in message queues and receiver that reads data from message queue.
int numProcesses;
cout << "Enter the number of processes: ";
cin >> numProcesses; [Link]
#include <iostream>
vector<Process> processes(numProcesses); #include <cstring>
#include <cstdlib>
for (int i = 0; i < numProcesses; i++) { #include <unistd.h>
#include <sys/types.h> struct Message {
#include <sys/ipc.h> long mtype;
#include <sys/msg.h> char mtext[100];
};
using namespace std;
int main() {
// Define a structure for the message data key_t key;
struct Message { int msgid;
long mtype; Message message;
char mtext[100];
}; // Step 1: Create a key for the message queue (use the same key as in the sender)
key = ftok("/tmp", '1');
int main() { if (key == -1) {
key_t key; perror("ftok");
int msgid; exit(1);
Message message; }

// Step 1: Create a key for the message queue // Step 2: Create or open the message queue
key = ftok("/tmp", '1'); msgid = msgget(key, 0666 | IPC_CREAT);
if (key == -1) { if (msgid == -1) {
perror("ftok"); perror("msgget");
exit(1); exit(1);
} }

// Step 2: Create or open the message queue // Receiver: Read data from the message queue
msgid = msgget(key, 0666 | IPC_CREAT); // Step 3: Receive a message from the queue with message type 1
if (msgid == -1) { if (msgrcv(msgid, &message, sizeof([Link]), 1, 0) == -1) {
perror("msgget"); perror("msgrcv");
exit(1); exit(1);
} }

// Sender: Send data to the message queue cout << "Data received gmessage queue: " << [Link] << endl;
[Link] = 1; // Message type (you can use different types for different purposes)
strcpy([Link], "Hello, this is a message from the sender!"); return 0;
}
// Step 3: Send the message to the queue
if (msgsnd(msgid, &message, sizeof([Link]), 0) == -1) { Output :
perror("msgsnd");
exit(1);
}
9. Where a parent writes a message to pipe and child reads message from pipe
cout << "Data sent to message queue." << endl;

return 0; #include <iostream>


} #include <unistd.h>

Output : int main() {


int pipe_fd[2]; // File descriptors for the pipe

// Create a pipe
[Link] if (pipe(pipe_fd) == -1) {
#include <iostream> perror("Pipe creation failed");
#include <cstring> return 1;
#include <cstdlib> }
#include <unistd.h>
#include <sys/types.h> pid_t child_pid = fork(); // Fork a child process
#include <sys/ipc.h>
#include <sys/msg.h> if (child_pid == -1) {
perror("Fork failed");
using namespace std; return 1;
}
// Define a structure for the message data
if (child_pid > 0) { // Parent process std::cerr << "Error creating server socket" << std::endl;
close(pipe_fd[0]); // Close the read end in the parent return -1;
}
std::string message = "Hello from parent!";
sockaddr_in server_address{};
// Write the message to the pipe server_address.sin_family = AF_INET;
if (write(pipe_fd[1], message.c_str(), [Link]()) == -1) { server_address.sin_addr.s_addr = INADDR_ANY;
perror("Write to pipe failed"); server_address.sin_port = htons(PORT);
return 1;
} if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) {
std::cerr << "Error binding to port " << PORT << std::endl;
close(pipe_fd[1]); // Close the write end in the parent close(server_socket);
} else { // Child process return -1;
close(pipe_fd[1]); // Close the write end in the child }

char buffer[50]; if (listen(server_socket, 10) == -1) {


ssize_t bytes_read; std::cerr << "Error listening on port " << PORT << std::endl;
close(server_socket);
// Read the message from the pipe return -1;
bytes_read = read(pipe_fd[0], buffer, sizeof(buffer)); }

if (bytes_read == -1) { std::cout << "Server is listening on port " << PORT << std::endl;
perror("Read from pipe failed");
return 1; while (true) {
} sockaddr_in client_address{};
socklen_t client_address_len = sizeof(client_address);
buffer[bytes_read] = '\0'; // Null-terminate the string
int client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_address_len);
std::cout << "Child process received message: " << buffer << std::endl; if (client_socket == -1) {
std::cerr << "Error accepting connection" << std::endl;
close(pipe_fd[0]); // Close the read end in the child continue;
} }

return 0; handle_request(client_socket);
} }

close(server_socket);

return 0;
}
10. Demonstrate setting up a simple web server and host website on your own Linux computer

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

const int PORT = 8080;

void handle_request(int client_socket) {


const char* response = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE
html><html><head><title>My C++ Web Server</title></head><body><h1>Hello, this is my first C++ web
server!</h1></body></html>";
send(client_socket, response, strlen(response), 0);
close(client_socket);
}

int main() {
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
const int numThreads = 2;
pthread_t threads[numThreads];

// Loop to create threads


for (int i = 0; i < numThreads; ++i) {
int* item = new int(i);
int threadCreateStatus = pthread_create(&threads[i], NULL, countTo100, (void*)item);

if (threadCreateStatus) {
std::cerr << "Error creating thread: " << threadCreateStatus << std::endl;
return -1;
}
}

// Wait for both threads to finish


for (int i = 0; i < numThreads; ++i) {
pthread_join(threads[i], NULL);
}

return 0;
}

11. a. Create two threads using pthread, where both thread counts until 100 and joins later.
b. Create two threads using pthreads. Here, main thread creates 5 other threads for 5
times and each new thread print “Hello World” message with its thread number
b.
#include <iostream>
#include <pthread.h>
a.
#include <iostream> // Function that will be executed by each thread
#include <pthread.h> void* printHello(void* threadNumber) {
int* num = static_cast<int*>(threadNumber);
// Function that will be executed by each thread std::cout << "Hello World from Thread " << *num << std::endl;
void* countTo100(void* arg) { pthread_exit(NULL);
int item = *((int*)arg); }

for (int i = 1; i <= 100; ++i) { int main() {


std::cout << "Thread " << item << ": Count " << i << std::endl; // Number of threads to create
} const int numThreads = 5;

pthread_exit(NULL); // Loop to create threads


} for (int i = 1; i <= numThreads; ++i) {
pthread_t thread;
int main() {
// Create a thread and pass the thread number as an argument return -1;
int threadNumber = i; }
int threadCreateStatus = pthread_create(&thread, NULL, printHello, &threadNumber);
std::cout << "Server listening on port 8080..." << std::endl;
if (threadCreateStatus) {
std::cerr << "Error creating thread: " << threadCreateStatus << std::endl; // Step 4: Accept a connection
return -1; sockaddr_in clientAddress;
} socklen_t clientAddrSize = sizeof(clientAddress);
int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddrSize);
// Wait for the thread to finish
pthread_join(thread, NULL); // Check for errors
} if (clientSocket == -1) {
std::cerr << "Error accepting connection." << std::endl;
return 0; close(serverSocket);
} return -1;
}

std::cout << "Connection accepted. Waiting for data..." << std::endl;

// Step 5: Receive data from the client


char buffer[1024];
ssize_t bytesRead = recv(clientSocket, buffer, sizeof(buffer), 0);

// Check for errors


if (bytesRead == -1) {
std::cerr << "Error receiving data." << std::endl;
close(serverSocket);
12. Using Socket APIs establish communication between remote and local processes close(clientSocket);
return -1;
}
//[Link]
#include <iostream> // Step 6: Print the received data
#include <cstring> std::cout << "Received data from client: " << buffer << std::endl;
#include <unistd.h>
#include <arpa/inet.h> // Step 7: Close the sockets
close(serverSocket);
int main() { close(clientSocket);
// Step 1: Create a socket
int serverSocket = socket(AF_INET, SOCK_STREAM, 0); return 0;
}
// Check for errors
if (serverSocket == -1) {
std::cerr << "Error creating socket." << std::endl;
return -1;
}

// Step 2: Bind the socket to an IP address and port


sockaddr_in serverAddress;
//[Link]
serverAddress.sin_family = AF_INET;
#include <iostream>
serverAddress.sin_addr.s_addr = INADDR_ANY;
#include <cstring>
serverAddress.sin_port = htons(8080); // Port 8080
#include <unistd.h>
#include <arpa/inet.h>
// Bind the socket
if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1) {
int main() {
std::cerr << "Error binding socket." << std::endl;
// Step 1: Create a socket
close(serverSocket);
int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
return -1;
}
// Check for errors
if (clientSocket == -1) {
// Step 3: Listen for incoming connections
std::cerr << "Error creating socket." << std::endl;
if (listen(serverSocket, 5) == -1) {
return -1;
std::cerr << "Error listening for connections." << std::endl;
}
close(serverSocket);
// Step 2: Set up the server address and port
sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(8080); // Port 8080

// Convert IP address from text to binary form


if (inet_pton(AF_INET, "[Link]", &serverAddress.sin_addr) <= 0) {
std::cerr << "Invalid address/Address not supported." << std::endl;
close(clientSocket);
return -1;
}

// Step 3: Connect to the server


if (connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1) {
std::cerr << "Connection failed." << std::endl;
close(clientSocket);
return -1;
}

std::cout << "Connected to the server. Sending data..." << std::endl;

// Step 4: Send data to the server


const char* message = "Hello from the client!";
if (send(clientSocket, message, strlen(message), 0) == -1) {
std::cerr << "Error sending data." << std::endl;
close(clientSocket);
return -1;
}

// Step 5: Close the socket


close(clientSocket);

return 0;
}

//server console

You might also like