#include <signal.h>
#include <stdio.h>

static volatile int event = 0;

static void handleSIGUSR2(int signal)
{
	event = 2;
}

static void handleSIGUSR1(int signal)
{
	event = 1;
}

int main(int argc, char* argv[])
{
	puts("Waiting for SIGUSR1 or SIGUSR2");
	struct sigaction action = {
		.sa_handler = handleSIGUSR1
	};
	sigemptyset(&action.sa_mask);
	sigaddset(&action.sa_mask, SIGUSR2);
	sigaction(SIGUSR1, &action, NULL);

	struct sigaction sigusr1Handler = {
		.sa_handler = handleSIGUSR2
	};
	sigemptyset(&sigusr1Handler.sa_mask);
	/*
	 * der SIGUSR1 und SIGUSR2 Handler greifen beide auf den gleichen Zustand
	 * zu. Deshalb muss das jeweils andere Signal während der Behandlung
	 * blockiert werden, sonst ist der Zustand nicht eindeutig definiert.
	 */
	sigaddset(&sigusr1Handler.sa_mask, SIGUSR1);
	sigaction(SIGUSR2, &sigusr1Handler, NULL);

	/*
	 * das Signal muss explizit blockiert werden.
	 * Sonst könnte es zwischen dem event == 0 und dem Schlafen legen auftreten
	 */
	sigset_t blockSigusr;
	sigemptyset(&blockSigusr);
	sigaddset(&blockSigusr, SIGUSR1);
	sigaddset(&blockSigusr, SIGUSR2);
	sigprocmask(SIG_BLOCK, &blockSigusr, NULL);

	/*
	 * Hier werden dann während sigsuspend alle Signale bis auf die 2
	 * blockiert. Das ist generell aber nicht was man tun will. Lieber
	 * möglichst wenig Signale blockieren und stattdessen ein while um die
	 * Bedingung packen.
	 */
	sigset_t mask;
	sigfillset(&mask);
	sigdelset(&mask, SIGUSR1);
	sigdelset(&mask, SIGUSR2);

	while (event == 0) {
		sigsuspend(&mask);
	}
	puts("Done");
}
