000
14.11.2009, 20:17 Uhr
~Sne11ius
Gast
|
Hallo zusammen!
ich muss als Aufgabe für die Uni ein Programm schreiben, dass empfangene Signale auf der Konsole ausgibt. Ich bin damit auch recht erfolgreich... Allerdings macht die letzte while-Schleife nicht das, was ich von ihr erwarte: nach der dritten Benutzung von CTRL+C das Programm auf jeden Fall beenden. Auch wenn er etwas lang ist zeig euch besser den Kompletten Quelltext, sonst lass ich noch aus versehen was wichtiges weg.
Vielen Dank natürlich im Vorraus!
C++: |
#include <iostream> // für cout
#include <cstdio> // für getchar() #include <cstdlib> // für exit() #include <csignal> // für signal(), SIGABRT, SIGFPE... #include <csetjmp> // für setjmp() und longjmp()
using namespace std;
// Diese Variable wird abgefragt, befor eine Anweisung ausgeführt wird, // die zum Senden eines Signales führt. volatile bool do_Bad_Things(false);
// In diese Struktur wird mittels setjmp() die aktuelle 'Programmumgebung' // gespeichert (z. B. Werte von Registern, Program-Counter) jmp_buf save_Env;
// Diese Funktion gibt eine zum jeweiligen Signal passende Meldung aus. // Außerdem setzt sie 'do_Bad_Things' auf false. // Die Funktion wird in main() mittels signal() als Signal-Handler für hier // aufgeführten Signale gesetzt. void signal_Handler(int SIG) { // Meldung machen: switch (SIG) { case (SIGABRT) : cout << "SIGABRT"; break; case (SIGFPE) : cout << "SIGFPE"; break; case (SIGILL) : cout << "SIGILL"; break; case (SIGSEGV) : cout << "SIGSEGV"; break; case (SIGTERM) : cout << "SIGTERM"; break; default : cout << "unknown signal"; }
cout << "(" << SIG << ") received." << endl;
// Dafür sorgen, dass nicht das gleiche Signal sofort wieder ausgelöst // wird do_Bad_Things = false;
signal(SIG, &signal_Handler); // Zu 'sicherer' Position springen longjmp(save_Env, 1); }
volatile int repeat(3);
void INT_Handler(int SIG) { --repeat; cout << endl << "SIGINT(" << SIG << ") receieved." << endl; cout.flush(); cout << "Wirklich beenden? [j/n] " << endl; char c(getchar()); if ('j' == c || 'J' == c) exit(0); else longjmp(save_Env, 1); }
// Aktuellen Status sichern und Auslösen eines Signals erlauben int save_State() { do_Bad_Things = true; return setjmp(save_Env); }
int main(int argc, char** argv) { // Persönlichen Handler für Signale registrieren signal(SIGABRT, signal_Handler); signal(SIGABRT, signal_Handler); signal(SIGFPE, signal_Handler); signal(SIGILL, signal_Handler); signal(SIGSEGV, signal_Handler); signal(SIGTERM, signal_Handler); signal(SIGKILL, signal_Handler); signal(SIGINT, INT_Handler);
// Status sichern save_State(); if (do_Bad_Things) int i(0/0); // Division durch 0 => SIGFPE
save_State(); if (do_Bad_Things) { int* p(0); // Pointer zeigt auf Adresse 0 *p = 0; // In Adresse 0 schreiben => SIGSEGV }
while(true) { save_State(); cout << "Druecke CTRL-C zum Beenden des Programms." << endl; if (repeat == 0) exit(0); pause(); } }
|
|