a firstworks project
Rudiments
About Documentation Download Licensing News

Using the signal classes

Signals allow one processes to interrupt the execution of another process.

Signal handlers allow processes to intercept and react to the signals sent to them.

Rudiments provides 3 classes for working with signals: signalset, signalmanager and signalhandler.

A signal set is just a collection of signals. The signalset class allows a programmer to build up a collection of signals.

The signalmanager class provides methods for sending signals, ignoring signals, waiting for signals and examining blocked signals.

The signalhandler class provides methods for catching and handling signals.

This program illustrates the use of all three classes.

// Copyright (c) 1999-2018 David Muse
// See the file COPYING for more information

#include <rudiments/signalclasses.h>
#include <rudiments/stdio.h>

bool	gotsigterm=false;

void handleSigterm(int32_t sig) {
	stdoutput.printf("Got a SIGTERM!\n");
	gotsigterm=true;
}

#ifdef SIGALRM
void handleAlarm(int32_t sig) {
	stdoutput.printf("alarm!\n");
}
#endif

int main(int argc, const char **argv) {

	// ignore all signals except SIGTERM and SIGALRM
	signalset	ignoreset;
	ignoreset.addAllSignals();
	ignoreset.removeSignal(SIGTERM);
	#ifdef SIGALRM
	ignoreset.removeSignal(SIGALRM);
	#endif
	signalmanager::ignoreSignals(&ignoreset);

	// run handleSigterm() when a SIGTERM is received
	signalhandler	termhandler;
	termhandler.setHandler(handleSigterm);
	termhandler.handleSignal(SIGTERM);

	// run handleAlarm() when a SIGALRM is received
	#ifdef SIGALRM
	signalhandler	alarmhandler;
	alarmhandler.setHandler(handleAlarm);
	alarmhandler.handleSignal(SIGALRM);
	#endif

	// Loop forever, waiting to receive a signal that we are not ignoring.
	signalmanager::alarm(2);
	while (!gotsigterm) {
		signalmanager::waitForSignals(&ignoreset);
		signalmanager::alarm(2);
	}
}

It should print out "alarm!" every 2 seconds and, if killed, should print out "Got a SIGTERM!" before exiting. If killed with a signal other than SIGTERM (the default), then it will ignore the signal.

Windows systems don't have signals or the kill program. Signals are more-or-less simulated on Windows platforms though, and the following program provides an approximation of the kill program as found on unix-like systems, that should work on Windows.

#include <rudiments/process.h>
#include <rudiments/charstring.h>
#include <rudiments/error.h>
#include <rudiments/stdio.h>

int main(int argc, const char **argv) {

	if (argc<3) {
		stdoutput.printf("usage: kill signal processid\n");
		process::exit(1);
	}

	int32_t	sig=SIGTERM;
	if (!charstring::compare(argv[1],"SIGINT")) {
		sig=SIGINT;
	} else if (!charstring::compare(argv[1],"SIGABRT")) {
		sig=SIGABRT;
	} else if (!charstring::compare(argv[1],"SIGFPE")) {
		sig=SIGFPE;
	} else if (!charstring::compare(argv[1],"SIGILL")) {
		sig=SIGILL;
	} else if (!charstring::compare(argv[1],"SIGSEGV")) {
		sig=SIGSEGV;
	} else if (!charstring::compare(argv[1],"SIGKILL")) {
		sig=SIGKILL;
	}

	pid_t	pid=charstring::convertToInteger(argv[2]);

	if (!process::sendSignal(pid,sig)) {
		stdoutput.printf("kill failed: %s\n",error::getErrorString());
		process::exit(1);
	}
	process::exit(0);
}
Copyright 2017 - David Muse - Contact