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