lab2
diff --git a/Child.cpp b/Child.cpp
new file mode 100644
index 0000000..69558db
--- /dev/null
+++ b/Child.cpp
@@ -0,0 +1,210 @@
+#ifdef _MSC_VER
+
+#define _CRT_SECURE_NO_WARNINGS
+#include <cstdlib>
+#include <windows.h>
+
+#else
+
+#include <unistd.h>
+#include <stdio.h>
+#include <cstring>
+#include <sys/types.h>
+#include <signal.h>
+
+#endif
+
+#include <string>
+#include <fstream>
+#include <ctime>
+#include <cstdlib>
+#include <iostream>
+using namespace std;
+
+#define FILE_NAME "log.log"
+#define LOG_DEBUG_LEVEL 2
+#define LOG_ERROR_LEVEL 1
+#define LOG_FATAL_LEVEL 0
+int log_level = 2;
+
+void setLevel()
+{
+	switch (log_level)
+	{
+	case LOG_DEBUG_LEVEL:
+	{
+		time_t seconds = time(NULL);
+		tm* timeinfo = localtime(&seconds);
+		fstream file(FILE_NAME, ios::app);
+		file << asctime(timeinfo) << "some_debug_info" << endl;
+		file << asctime(timeinfo) << "Error: index out of range." << endl;
+		file << asctime(timeinfo) << "Error: could not find file." << endl;
+		file << asctime(timeinfo) << "Fatal_error: processes must be closed." << endl;
+		file.close();
+		cout << "some_debug_info" << endl;
+		cout << "Error: index out of range." << endl;
+		cout << "Error: could not find file." << endl;
+		cout << "Fatal_error: processes must be closed." << endl;
+		break;
+	}
+	case LOG_ERROR_LEVEL:
+	{
+		time_t seconds = time(NULL);
+		tm* timeinfo = localtime(&seconds);
+		fstream file(FILE_NAME, ios::app);
+		file << asctime(timeinfo) << "Error: could not find file." << endl;
+		file << asctime(timeinfo) << "Fatal_error: processes must be closed." << endl;
+		file.close();
+		cout << "Error: could not find file." << endl;
+		cout << "Fatal_error: processes must be closed." << endl;
+		break;
+	}
+	case LOG_FATAL_LEVEL:
+	{
+		time_t seconds = time(NULL);
+		tm* timeinfo = localtime(&seconds);
+		fstream file(FILE_NAME, ios::app);
+		file << asctime(timeinfo) << "Fatal_error: processes must be closed." << endl;
+		file.close();
+		cout << "Fatal_error: processes must be closed." << endl;
+		break;
+	}
+	}
+}
+
+#ifdef _MSC_VER
+
+#define UP_EVENT 'U'
+#define DOWN_EVENT 'D'
+#define EXIT_EVENT 'E'
+#define ACCESS_EVENT "A"
+
+#else
+
+void handler(int p)
+{
+	switch(p) 
+	{
+	case SIGINT:
+	{
+		exit(0);
+	}
+	case SIGHUP:
+	{
+		setLevel();
+		cout << "getppid() = " << getppid() << endl;
+		kill(getppid(), SIGHUP);
+		return;
+	}
+	case SIGUSR1:
+	{
+		if (log_level < 2)
+		{
+			log_level++;
+		}
+		return;
+	}	
+
+	case SIGUSR2:
+	{
+		cout << "Log level down" << endl;
+		if (log_level > 0)
+		{
+			log_level--;
+		}
+		return;
+	}
+	}
+}	
+#endif
+
+int main(int argc, char * argv[])
+{
+
+#ifdef _MSC_VER
+
+	HANDLE up_event;
+	HANDLE down_event;
+	HANDLE exit_event;
+	HANDLE access_event;
+	DWORD check;
+	char buff[3];
+	buff[0] = argv[0][0];
+	buff[2] = '\0';
+
+	buff[1] = UP_EVENT;
+	if (!(up_event = OpenEventA(EVENT_ALL_ACCESS | EVENT_MODIFY_STATE, TRUE, buff)))
+	{
+		return 0;
+	}
+
+	buff[1] = DOWN_EVENT;
+	if (!(down_event = OpenEventA(EVENT_ALL_ACCESS | EVENT_MODIFY_STATE, TRUE, buff)))
+	{
+		return 0;
+	}
+
+	buff[1] = EXIT_EVENT;
+	if (!(exit_event = OpenEventA(EVENT_ALL_ACCESS | EVENT_MODIFY_STATE, TRUE, buff)))
+	{
+		return 0;
+	}
+
+	if (!(access_event = OpenEventA(EVENT_ALL_ACCESS | EVENT_MODIFY_STATE, TRUE, ACCESS_EVENT)))
+	{
+		return 0;
+	}
+
+	while (true)
+	{
+		check = WaitForSingleObject(up_event, NULL);
+		if (check == WAIT_OBJECT_0)
+		{
+			if (log_level < 2){
+				log_level++;
+			}
+		}
+
+		check = WaitForSingleObject(down_event, NULL);
+		if (check == WAIT_OBJECT_0)
+		{
+			if (log_level > 0){
+				log_level--;
+			}
+		}
+
+		check = WaitForSingleObject(exit_event, NULL);
+		if (check == WAIT_OBJECT_0)
+		{
+			return 0;
+		}
+
+		check = WaitForSingleObject(access_event, INFINITY);
+		if (check == WAIT_OBJECT_0) 
+		{
+			setLevel();
+			SetEvent(access_event);
+		}
+		Sleep(4000);
+	}
+
+#else
+
+	struct sigaction act;
+	memset(&act, 0, sizeof(act));
+	act.sa_handler = handler;
+	sigset_t set;
+	sigemptyset(&set);
+	sigaddset(&set, SIGUSR1);
+	sigaddset(&set, SIGUSR2);
+	sigaddset(&set, SIGINT);
+	sigaddset(&set, SIGHUP);
+	act.sa_mask = set;
+	sigaction(SIGUSR1, &act, NULL);
+	sigaction(SIGUSR2, &act, NULL);
+	sigaction(SIGINT, &act, NULL);
+	sigaction(SIGHUP, &act, NULL);
+
+#endif	
+
+}
\ No newline at end of file
diff --git a/Parent.cpp b/Parent.cpp
new file mode 100644
index 0000000..3a3f373
--- /dev/null
+++ b/Parent.cpp
@@ -0,0 +1,293 @@
+#ifdef _MSC_VER
+
+#define _CRT_SECURE_NO_WARNINGS
+#include <windows.h>
+
+#else
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <cstring>
+#include <sys/wait.h>
+
+#endif
+
+#include <iostream>
+#include <stdio.h>
+#include <string>
+using namespace std;
+
+#ifdef _MSC_VER
+
+#define UP_EVENT 'U'
+#define DOWN_EVENT 'D'
+#define EXIT_EVENT 'E'
+#define ACCESS_EVENT "A"
+#define PATH "D:\\SystemProg\\labka2_spo_parent_lin\\Debug\\labka2_spo_child_lin.exe"
+
+#endif
+
+#define PROCESSCOUNT 9
+
+#ifdef _MSC_VER
+STARTUPINFOA si[PROCESSCOUNT];
+PROCESS_INFORMATION pi[PROCESSCOUNT];
+HANDLE upEvent[PROCESSCOUNT], downEvent[PROCESSCOUNT], exitEvent[PROCESSCOUNT], accessEvent;
+
+#else
+
+#define PATH "child"
+int pid[PROCESSCOUNT];
+bool fl;
+void synchandler(int p){
+	fl = false;
+}
+
+#endif
+
+bool CreateProcesses()
+{
+
+#ifdef _MSC_VER
+
+	accessEvent = CreateEventA(NULL, FALSE, TRUE, ACCESS_EVENT);
+	char buff[3];
+	for (int i = 0; i < PROCESSCOUNT; i++)
+	{
+		_itoa(i, buff, 10);
+		buff[2] = '\0';
+		buff[1] = UP_EVENT;
+		upEvent[i] = CreateEventA(NULL, FALSE, FALSE, buff);
+		buff[1] = DOWN_EVENT;
+		downEvent[i] = CreateEventA(NULL, FALSE, FALSE, buff);
+		buff[1] = EXIT_EVENT;
+		exitEvent[i] = CreateEventA(NULL, FALSE, FALSE, buff);
+
+		ZeroMemory(&si, sizeof(si));
+		ZeroMemory(&pi, sizeof(pi));
+
+		if (!CreateProcessA(PATH,
+			_itoa(i, buff, 10),
+			NULL,
+			NULL,
+			FALSE,
+			0,
+			NULL,
+			NULL,
+			&si[i],
+			&pi[i])
+			)
+		{
+			printf("CreateProcess failed (%d).\n", GetLastError());
+			system("pause");
+			return false;
+		}
+	}
+
+#else
+
+	struct sigaction act;
+	memset(&act, 0, sizeof(act));
+	act.sa_handler = synchandler;
+	sigset_t set;
+	sigemptyset(&set);
+	sigaddset(&set, SIGHUP);
+	act.sa_mask = set;
+	sigaction(SIGHUP, &act, NULL);
+	for (int i = 0; i < PROCESSCOUNT; i++)
+	{
+		pid[i] = fork();
+		switch(pid[i]){
+		case 0:
+		{
+			if (!execl(PATH, "", NULL)){
+				printf("execl failed ");
+				return false;
+			}
+			break;
+		}
+		case -1:
+		{
+			return false;
+		}
+		default:
+		{
+			continue;
+		}
+		}
+	}
+
+#endif
+
+	return true;
+}
+
+void ShowMenu()
+{
+
+#ifdef _MSC_VER
+
+	DWORD check = WaitForSingleObject(accessEvent, INFINITY);
+	if (check == WAIT_OBJECT_0)
+	{
+		cout << "1. Log level up." << endl;
+		cout << "2. Log level lower." << endl;
+		cout << "3. Exit." << endl;
+		cout << "4. Skip." << endl;
+		SetEvent(accessEvent);
+	}
+
+#else
+
+	cout << "1. Log level up." << endl;
+	cout << "2. Log level lower." << endl;
+	cout << "3. Exit." << endl;
+	cout << "4. Skip." << endl;
+
+#endif
+
+	return;
+}
+
+int ChooseMenu(int &inputNumber)
+{
+	while (true){
+		if (!(cin >> inputNumber))
+		{
+			cin.clear();
+			cin.sync();
+		}
+		else if (inputNumber < 1 || inputNumber > 4){
+			cin.clear();
+			cin.sync();
+		}
+		else {
+			return inputNumber;
+		}
+	}
+}
+
+void WaitAndClose()
+{
+
+#ifdef _MSC_VER
+
+	for (int i = 0; i < PROCESSCOUNT; i++)
+	{
+		WaitForSingleObject(pi[i].hProcess, INFINITE);
+		CloseHandle(pi[i].hProcess);
+		CloseHandle(upEvent[i]);
+		CloseHandle(downEvent[i]);
+		CloseHandle(exitEvent[i]);
+
+	}
+	CloseHandle(accessEvent);
+
+#else
+
+	for (int i = 0; i < PROCESSCOUNT; i++)
+	{
+		waitpid(pid[i], 0, 0);
+	}
+
+#endif
+
+}
+
+int main()
+{
+	if (!CreateProcesses())
+	{
+		return 0;
+	}
+
+	int inputNumber;
+
+	do {
+		ShowMenu();
+		ChooseMenu(inputNumber);
+		switch (inputNumber)
+		{
+		case 1: {
+			for (int i = 0; i < PROCESSCOUNT; i++)
+			{
+
+#ifdef _MSC_VER
+
+				SetEvent(upEvent[i]);
+
+#else
+
+				kill(pid[i], SIGUSR1);
+
+#endif
+
+			}
+			break;
+		}
+		case 2:
+		{
+			for (int i = 0; i < PROCESSCOUNT; i++)
+			{
+
+#ifdef _MSC_VER
+
+				SetEvent(downEvent[i]);
+
+#else
+
+				kill(pid[i], SIGUSR2);
+
+#endif
+			}
+			break;
+		}
+		case 3:
+		{
+			for (int i = 0; i < PROCESSCOUNT; i++)
+			{
+
+#ifdef _MSC_VER
+
+				SetEvent(exitEvent[i]);
+
+#else
+
+				kill(pid[i], SIGINT);
+
+#endif
+			}
+			break;
+		}
+		case 4:
+		{
+			break;
+		}
+		}
+#ifdef _MSC_VER
+
+#else
+
+		if(inputNumber != 3)
+		{
+			for(int i = 0; i < PROCESSCOUNT; i++) 
+			{
+				kill(pid[i], SIGHUP);
+				fl = true;
+				while (fl)
+				{
+					sleep(1);
+				}
+			}
+		}
+
+#endif
+
+	} while (inputNumber != 3);
+
+	WaitAndClose();
+	return 0;
+}
+