blob: 3a3f3731b6054f4932257b21f460c0941994612d [file] [log] [blame]
#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;
}