// Uebung 7 zum Fach Betriebssysteme
// Copyright Matthias Jauernig, 03IN
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdbool.h>

int i, sigi[4];
bool reset, ende;

void sigintfkt (int signr){
	printf(	"=> Aktuelle Signalzaehlerstaende:\n"
		"   SIGINT:  %d\n"
		"   SIGQUIT: %d\n"
		"   SIGUSR1: %d\n"
		"   SIGUSR2: %d\n",
		sigi[0],sigi[1],sigi[2],sigi[3]);
	sigi[0]++;
}

void sigquitfkt(int signr){
	printf("=> Verlassen des Zaehlzyklus'...\n");
	ende=true;
	sigi[1]++;
}

void sigusr1fkt(int signr){
	printf("=> Zaehlzyklus wird neu gestartet...\n");
	reset=true;
	sigi[2]++;
}

void sigusr2fkt(int signr){
	printf("=> Aktueller Zaehlzyklusstand: %d\n",i);
	sigi[3]++;
}


int main(int argc, char** argv){
	int status, id, count;
	pid_t pid;
	
	sigi[0]=0; sigi[1]=0; sigi[2]=0; sigi[3]=0;
	reset=false; ende=false; 
	
	if(argc>1){
		count=atoi(argv[1]);
		if(count==0){
			printf("Nicht-Zahl uebergeben...\n");
			exit(1);
		}
	}
	else{
		printf("Zaehlzyklenzahl eingeben: ");
		scanf("%d",&count);
	}
	
	pid = fork();
	
	sigset(SIGINT,  sigintfkt );
	sigset(SIGQUIT, sigquitfkt);
	sigset(SIGUSR1, sigusr1fkt);
	sigset(SIGUSR2, sigusr2fkt);
	
	switch(pid){
		case -1:
			perror("fork");
			exit(1);
			break;
		case 0:
			printf("Child  -> Meine PID:  %d\n",(int)getpid());
			printf("       -> Parent-PID: %d\n\n",(int)getppid());
			for(i=0; i<count; i++){
				if(reset==true){
					i=0;
					reset=false;
				}
				if(ende==true)
					break;
				if(i%(count/10) == 0)
					printf("Child -Zaehler: %d\n",i);
			}
			break;
		default:
			printf("Parent -> Meine PID:  %d\n",(int)getpid());
			do{
				id=waitpid(pid,&status,WNOHANG);
			}while(!id);
					
			printf("Child beendet: PID=%d, Status: |%x|%x|\n",
				(int)pid,(status>>8)&0xFF,status&0x7F);
			break;
	}
	
	exit(1);
}

