0% found this document useful (0 votes)
3 views

[OS] LAB 4 template

Uploaded by

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

[OS] LAB 4 template

Uploaded by

khoinguyenpkn
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 10

Name: Phạm Khôi Nguyên

Student ID: 23521055


Class: CTTT2023

OS
LAB 4

CHECKLIST
1. Homework
1 2 3 4 5 6
Explanation
Your code
Results and discussions

Mark: 9.5

*Notice: Export PDF file, name format:


<MSSV>_LAB4.pdf

1
2. Lab 4
1. Write a program time.cpp that measures the execution time of a shell command.
The program will be executed with the syntax ./time <command> where
<command> is the shell command you want to measure the execution time for.
Example:

Answer:

Compile the program with: g++ time.cpp -o time

2
Result:

3
Explaination:
#include <iostream> // For input and output (cin, cout, cerr)
#include <chrono> // For high-resolution clocks to measure time
#include <cstdlib> // For system() function to execute shell commands
int main(int argc, char* argv[]) {
// Check if the user has provided a command as an argument
if (argc < 2) {
std::cerr << "Usage: ./time <command>" << std::endl;
return 1; // Exit with error if no command is provided
}
// Start measuring the time before executing the command
auto start = std::chrono::high_resolution_clock::now();
// Execute the shell command passed as an argument
// system() runs the command specified by argv[1]
int result = std::system(argv[1]);
// Stop measuring the time after the command execution
auto end = std::chrono::high_resolution_clock::now();
// Calculate the time difference in seconds
std::chrono::duration<double> duration = end - start;

// Display the execution time


if (result == 0) { // Check if the command executed successfully (0 means success)
std::cout << "Command executed in: " << duration.count() << " seconds." <<
std::endl;
} else { // If there was an error in executing the command
std::cerr << "Error executing the command." << std::endl;
return 1; // Exit with error code if command execution failed
}
return 0; // Successfully executed, return 0
}
2. Design a file-copying program named filecopy.cpp using ordinary pipes. This
program will be passed two parameters: the name of the file to be copied and the
name of the destination file. The program will then create an ordinary pipe and
write the contents of the file to be copied to the pipe. The child process will read this

4
file from the pipe and write it to the destination file. For example, if we invoke the
program as follows:
./filecopy input.txt copy.txt
The file input.txt will be written to the pipe. The child process will read the contents
of this file and write it to the destination file copy.txt.
Answer:

5
6
Compile the program with: g++ filecopy.cpp -o filecopy
Create input.txt and copy.txt for demonstration:

Result:

Check the copy.txt:

Copied succesfully.

7
Explaination:
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <cstring>
#define BUFFER_SIZE 1024 // Define buffer size for copying data
int main(int argc, char* argv[]) {
// Check if the correct number of arguments are passed
if (argc != 3) {
std::cerr << "Usage: ./filecopy <source_file> <destination_file>" << std::endl;
return 1; // Exit if arguments are incorrect
}
const char* sourceFile = argv[1]; // Source file name from arguments

8
const char* destinationFile = argv[2]; // Destination file name from arguments
// Create a pipe (an array of two file descriptors)
int pipefd[2];
if (pipe(pipefd) == -1) {
std::cerr << "Error creating pipe: " << strerror(errno) << std::endl;
return 1; // Exit if pipe creation fails
}
// Fork the process to create a child process
pid_t pid = fork();
if (pid == -1) { // Error occurred during fork
std::cerr << "Error forking process: " << strerror(errno) << std::endl;
return 1; // Exit if forking fails
}
if (pid > 0) { // Parent process
close(pipefd[0]); // Close the read end of the pipe in the parent process
// Open the source file for reading (in binary mode)
std::ifstream source(sourceFile, std::ios::binary);
if (!source) {
std::cerr << "Error opening source file: " << sourceFile << std::endl;
close(pipefd[1]); // Close the write end of the pipe in case of error
return 1; // Exit if the source file cannot be opened
}
char buffer[BUFFER_SIZE]; // Create a buffer to hold the data
while (source.read(buffer, BUFFER_SIZE)) { // Read data from the source file in
chunks
write(pipefd[1], buffer, source.gcount()); // Write data to the pipe
}
// Write any remaining data if the file is not an exact multiple of
BUFFER_SIZE
if (source.gcount() > 0) {
write(pipefd[1], buffer, source.gcount());
}
close(pipefd[1]); // Close the write end of the pipe after writing all data
// Wait for the child process to finish
wait(NULL);

9
}
else { // Child process
close(pipefd[1]); // Close the write end of the pipe in the child process
// Open the destination file for writing (create if it doesn't exist)
int destFd = open(destinationFile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (destFd == -1) {
std::cerr << "Error opening destination file: " << destinationFile << std::endl;
close(pipefd[0]); // Close the read end of the pipe in case of error
return 1; // Exit if the destination file cannot be opened
}
char buffer[BUFFER_SIZE]; // Buffer to hold data from the pipe
ssize_t bytesRead;
while ((bytesRead = read(pipefd[0], buffer, sizeof(buffer))) > 0) { // Read data
from the pipe
write(destFd, buffer, bytesRead); // Write data to the destination file
}
close(pipefd[0]); // Close the read end of the pipe in the child process
close(destFd); // Close the destination file
}
return 0; // Exit successfully
}

10

You might also like