OS-Labs/lab2/src/sol/part3_partitioner.cpp

136 lines
4.5 KiB
C++

#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <cstring>
using namespace std;
void handler(int signo, siginfo_t *info, void *context)
{
if(signo == SIGTERM)
{
cout <<"["<< getpid()<<"] "<<"received SIGTERM\n";
exit(0);
}
}
int main(int argc, char **argv)
{
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_sigaction = &handler;
if (sigaction(SIGTERM, &sa, NULL) == -1)
{
perror("sigaction");
return EXIT_FAILURE;
}
if (argc != 6)
{
cout << "usage: ./partitioner.out <path-to-file> <pattern> <search-start-position> <search-end-position> <max-chunk-size>\nprovided arguments:\n";
for (int i = 0; i < argc; i++)
cout << argv[i] << "\n";
return -1;
}
char *file_to_search_in = argv[1];
char *pattern_to_search_for = argv[2];
int search_start_position = atoi(argv[3]);
int search_end_position = atoi(argv[4]);
int max_chunk_size = atoi(argv[5]);
pid_t my_pid = getpid();
pid_t left_child_pid, right_child_pid, searcher_pid;
cout << "[" << my_pid << "] start position = " << search_start_position << " ; end position = " << search_end_position << "\n";
if (search_end_position - search_start_position + 1 > max_chunk_size)
{
int mid_position = (search_start_position + search_end_position) / 2;
left_child_pid = fork();
if (left_child_pid == 0)
{
// Child process
//cout << "[" << getpid() << "] forked left child " << getpid() << "\n";
char start_str[10], mid_str[10], max_str[10];
sprintf(start_str, "%d", search_start_position);
sprintf(mid_str, "%d", mid_position);
sprintf(max_str, "%d", max_chunk_size);
char *args[] = { "./part3_partitioner.out",file_to_search_in , pattern_to_search_for, start_str, mid_str, max_str, NULL };
execv("./part2_partitioner.out", args);
perror("execv left partitioner failed");
return -1;
}
else if (left_child_pid > 0)
{
// Parent process
cout << "[" << my_pid << "] forked left child " << left_child_pid << "\n";
}
else
{
perror("fork failed");
return -1;
}
right_child_pid = fork();
if (right_child_pid == 0)
{
// Child process
//cout << "[" << getpid() << "] forked right child " << getpid() << "\n";
char mid_plus_one_str[10], end_str[10], max_str[10];
sprintf(mid_plus_one_str, "%d", mid_position + 1);
sprintf(end_str, "%d", search_end_position);
sprintf(max_str, "%d", max_chunk_size);
char *args[] = { "./part3_partitioner.out", file_to_search_in, pattern_to_search_for, mid_plus_one_str, end_str, max_str, NULL };
if (execv("./part2_partitioner.out", args)==-1){
perror("execv right partitioner failed");
}
return -1;
}
else if (right_child_pid > 0)
{
// Parent process
cout << "[" << my_pid << "] forked right child " << right_child_pid << "\n";
}
else
{
perror("fork failed");
return -1;
}
waitpid(left_child_pid, NULL, 0);
cout << "[" << my_pid << "] left child returned\n";
waitpid(right_child_pid, NULL, 0);
cout << "[" << my_pid << "] right child returned\n";
}
else
{
searcher_pid = fork();
if (searcher_pid == 0)
{
// Child process
//cout << "[" << getpid() << "] forked searcher child " << getpid() << "\n";
char start_str[10], end_str[10];
sprintf(start_str, "%d", search_start_position);
sprintf(end_str, "%d", search_end_position);
char *args[] = { "./part3_searcher.out", file_to_search_in, pattern_to_search_for, start_str, end_str ,NULL};
execv("./part2_searcher.out", args);
perror("execv searcher failed");
cout << *args<< endl;
return -1;
}
else if (searcher_pid > 0)
{
// Parent process
cout << "[" << my_pid << "] forked searcher child " << searcher_pid << "\n";
}
else
{
perror("fork failed");
return -1;
}
waitpid(searcher_pid, NULL, 0);
cout << "[" << my_pid << "] searcher child returned\n";
}
return 0;
}