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;
+}
+