Skip to content

Instantly share code, notes, and snippets.

@alherd-by
Created April 14, 2016 12:22
Show Gist options
  • Save alherd-by/312d08a229ea24744124252be1ac055b to your computer and use it in GitHub Desktop.
Save alherd-by/312d08a229ea24744124252be1ac055b to your computer and use it in GitHub Desktop.
#include <curses.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#define MAX_COUNT 20
char processStorage[20][30] =
{
{"\r\nFirst process"},
{"\r\nSecond process"},
{"\r\nThird process"},
{"\r\nFourth process"},
{"\r\nFifth process"},
{"\r\nSixth process"},
{"\r\nSeventh process"},
{"\r\nEighth process"},
{"\r\nNinth process"},
{"\r\nTenth process"},
{"\r\nEleventh process"},
{"\r\nTwelfth process"},
{"\r\nThirteenth process"},
{"\r\nFourteenth process"},
{"\r\nFifteenth process"},
{"\r\nSixteenth process"},
{"\r\nSeventeenth process"},
{"\r\nEighteenth process"},
{"\r\nNineteenth process"},
{"\r\nTwentieth process"},
};
pid_t child_pid[MAX_COUNT];
int flagEnd = 1;
int cur = 1;
int currentProcCount = 0;
int flagPrint = 0;
struct sigaction printSignal, endSignal;
void checkEnd() {
if (flagEnd) {
kill(getppid(), SIGUSR2); //signal to parent about finish of printing
exit(0);
}
}
void canPrint(int signo) {
flagPrint = 1;
}
void setEndFlag(int signo) {
flagEnd = 1;
}
int main(void) {
clear();
noecho();
refresh();
printSignal.sa_handler = canPrint;
sigaction(SIGUSR1, &printSignal, NULL);
endSignal.sa_handler = setEndFlag;
sigaction(SIGUSR2, &endSignal, NULL);
char c = NULL;
int index = 0;
child_pid[0] = getpid();
while (c != 'q') {
switch (c = getchar()) {
case '=': {
if (currentProcCount < MAX_COUNT) {
currentProcCount++;
child_pid[currentProcCount] = fork();
}
switch (child_pid[currentProcCount]) {
case 0: //child process
{
flagEnd = 0;
while (!flagEnd) {
usleep(10000);
if (flagPrint) {
for (index = 0; index < strlen(processStorage[currentProcCount - 1]); index++) {
checkEnd();
printf("%c", processStorage[currentProcCount - 1][index]);
refresh();
usleep(40000);
}
checkEnd();
refresh();
flagPrint = 0;
kill(getppid(), SIGUSR2); //signal to parent about finish of printing
}
checkEnd();
}
exit(0);
}
break;
case -1: {
printf("Child process[%d] failed!\n", currentProcCount);
}
break;
}
}
break;
case '-': {
if (currentProcCount == 0) {
break;
}
kill(child_pid[currentProcCount], SIGUSR2); //finishing last child process
waitpid(child_pid[currentProcCount], NULL, 0);
if (cur == currentProcCount) {
cur = 1;
}
currentProcCount--;
}
break;
}
if (flagEnd && currentProcCount > 0) //if current process has finished printing
{
flagEnd = 0;
kill(child_pid[cur++], SIGUSR1); //signal to child process about printing of string; at the begining cur=1
if (cur > currentProcCount) // if current number > amount of processes,
cur = 1; //then begin from the start
}
refresh();
}
if (child_pid[currentProcCount] != 0) {
for (; currentProcCount > 0; currentProcCount--) {
kill(child_pid[currentProcCount], SIGUSR2);
waitpid(child_pid[currentProcCount], NULL, 0);
}
}
clear();
endwin();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment