home *** CD-ROM | disk | FTP | other *** search
- MODULE tsigtimer;
- __IMP_SWITCHES__
- __DEBUG__
- #ifdef HM2
- #ifdef __LONG_WHOLE__
- (*$!i+: Modul muss mit $i- uebersetzt werden! *)
- (*$!w+: Modul muss mit $w- uebersetzt werden! *)
- #else
- (*$!i-: Modul muss mit $i+ uebersetzt werden! *)
- (*$!w-: Modul muss mit $w+ uebersetzt werden! *)
- #endif
- #endif
-
- #if (defined MM2) && (defined __DEBUG_CODE__)
- IMPORT Debug;
- #endif
-
- VAL_INTRINSIC
- CAST_IMPORT
-
- (* Programm ist nur mit MiNT oder MultiTOS sinnvoll.
- *
- * Test und Anwendungsbeispiel fuer Signalfunktionen, die mit der Zeit
- * zu tun haben.
- *
- * Hier treten zwar "alarm()" und "sleep()" gemeinsam in einem Programm
- * auf (siehe Hinweise in 'sig'), da sie aber nicht zur gleichen Zeit
- * aktiv sind, gibt es hoffentlich keine Probleme.
- *
- * 29-Mai-94, Holger Kleinschmidt
- *)
-
- FROM SYSTEM IMPORT
- (* PROC *) ADR;
-
- FROM PORTAB IMPORT
- (* CONST*) NULL,
- (* TYPE *) UNSIGNEDLONG;
-
- IMPORT e;
-
- FROM OSCALLS IMPORT
- (* PROC *) Cconis, Cnecin;
-
- FROM cstr IMPORT
- (* PROC *) strerror, AssignCToM2;
-
- FROM sig IMPORT
- (* CONST*) SIGINT, SIGQUIT, SIGALRM,
- (* TYPE *) SigactionRec, SigBlockType, SaFlags, sigsetT,
- (* PROC *) alarm, sleep, usleep, sigemptyset, sigaddset, pause, sigaction,
- sigsuspend, sigpause, sigmask;
-
- FROM InOut IMPORT
- (* PROC *) WriteCard, WriteInt, WriteString, WriteLn;
-
- FROM pOUT IMPORT
- (* PROC *) PutCard;
-
- (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
-
- VAR new : SigactionRec;
- mask : sigsetT;
- c : CHAR;
- AlrmHandled : BOOLEAN;
- IntHandled : BOOLEAN;
- QuitHandled : BOOLEAN;
- key : UNSIGNEDLONG;
- rems : CARDINAL;
- remus : UNSIGNEDLONG;
- void : INTEGER;
- errmsg : ARRAY [0..40] OF CHAR;
-
- (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
-
- #ifdef HM2
- (*$E+,$K+*)
- #endif
- PROCEDURE CatchSigAlrm (sig : UNSIGNEDLONG);
- BEGIN
- AlrmHandled := TRUE;
- END CatchSigAlrm;
-
- PROCEDURE CatchSigInt (sig : UNSIGNEDLONG);
- BEGIN
- IntHandled := TRUE;
- END CatchSigInt;
-
- PROCEDURE CatchSigQuit (sig : UNSIGNEDLONG);
- BEGIN
- QuitHandled := TRUE;
- END CatchSigQuit;
- #ifdef HM2
- (*$E=,$K-*)
- #endif
-
- (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
-
- BEGIN
- (* 'CatchSigInt' als Signalhandler fuer SIGINT (= CTRL-C) installieren. *)
- WITH new DO
- saHandler.proc := CatchSigInt;
- sigemptyset(saMask);
- saFlags := SaFlags{};
- END;
- IF sigaction(SIGINT, ADR(new), NULL) < 0 THEN
- AssignCToM2(strerror(e.errno), 0, errmsg);
- WriteString("***: "); WriteString(errmsg);
- END;
-
- (* Fuer fuenf Sekunden selbst suspendieren. Falls waehrend dieser Zeit
- * ein SIGINT auftritt, wird der Signalhandler ausgefuehrt, und 'IntHandled'
- * auf TRUE gesetzt.
- *)
- WriteString('"sleep()" für 5 Sekunden. Vorzeitiger Abbruch mit SIGINT-Signal (CTRL-C)...');
- WriteLn;
- IntHandled := FALSE;
- rems := sleep(5);
- WriteString('..."sleep()" wurde ');
- IF IntHandled THEN
- WriteString('nach ');
- WriteCard(5 - rems, 0);
- WriteString(" Sekunden vorzeitig durch SIGINT abgebrochen.");
- ELSE
- WriteString('nicht vorzeitig durch SIGINT abgebrochen.');
- END;
- WriteLn;
- WriteLn;
-
- (*
- (* Wie oben. Nur mit MiNT 1.10 ! *)
- WriteString('"usleep()" für 5 Sekunden. Vorzeitiger Abbruch mit SIGINT-Signal (CTRL-C)... ');
- WriteLn;
- IntHandled := FALSE;
- remus := usleep(LC(5000000)); (* ab MiNT 1.10 *)
- WriteString('..."usleep()" wurde ');
- IF IntHandled THEN
- WriteString('durch SIGINT nach ');
- PutCard(LC(5000000) - remus, 0);
- WriteString(" Mikrosekunden vorzeitig durch SIGINT abgebrochen.");
- ELSE
- WriteString('nicht vorzeitig durch SIGINT abgebrochen.');
- END;
- WriteLn;
- WriteLn;
- *)
-
- (* 'CatchSigAlrm' als Signalhandler fuer SIGALRM installieren. *)
- WITH new DO
- saHandler.proc := CatchSigAlrm;
- sigemptyset(saMask);
- saFlags := SaFlags{};
- END;
- IF sigaction(SIGALRM, ADR(new), NULL) < 0 THEN
- AssignCToM2(strerror(e.errno), 0, errmsg);
- WriteString("***: "); WriteString(errmsg);
- END;
-
- (* In fuenf Sekunden ein SIGALRM-Signal generieren. Falls waehrend dieser
- * Zeit keine Taste gedrueckt wird, wird der Signalhandler ausgefuehrt und
- * 'AlrmHandled' auf TRUE gesetzt, sonst wird der Alarm geloescht.
- *)
- WriteString('"alarm()" nach 5 Sekunden. Vorzeitiger Abbruch durch Tastendruck... ');
- WriteLn;
- AlrmHandled := FALSE;
- rems := alarm(5);
- REPEAT
- UNTIL AlrmHandled OR Cconis();
- rems := alarm(0); (* Noch ausstehenden Alarm loeschen *)
- IF AlrmHandled THEN
- WriteString("...Keine Taste innerhalb von 5");
- ELSE
- WriteString("...Taste nach ");
- WriteCard(5 - rems, 0);
- END;
- WriteString(" Sekunden gedrückt.");
- WriteLn;
- WriteLn;
-
- (* In fuenf Sekunden ein SIGALRM-Signal generieren und mit "pause" auf
- * ein Signal warten. Falls waehrend dieser Zeit ein SIGINT auftritt,
- * wird der SIGINT-Signalhandler ausgefuehrt und 'SigHandled' auf TRUE
- * gesetzt, sonst wird der Alarm ausgeloest.
- *)
- WriteString('"alarm()" nach 5 Sekunden. Warten mit "pause", vorz. Abbruch mit SIGINT...');
- WriteLn;
- IntHandled := FALSE;
- rems := alarm(5);
- pause;
- rems := alarm(0); (* Noch ausstehenden Alarm loeschen *)
- WriteString('..."pause" wurde');
- IF NOT IntHandled THEN
- WriteString(" nicht");
- END;
- WriteString(" vorzeitig durch SIGINT unterbrochen.");
- WriteLn;
- WriteLn;
-
- (* 'CatchSigQuit' als Signalhandler fuer SIGQUIT installieren. *)
- WITH new DO
- saHandler.proc := CatchSigQuit;
- sigemptyset(saMask);
- saFlags := SaFlags{};
- END;
- IF sigaction(SIGQUIT, ADR(new), NULL) < 0 THEN
- AssignCToM2(strerror(e.errno), 0, errmsg);
- WriteString("***: "); WriteString(errmsg);
- END;
-
-
- (* In fuenf Sekunden ein SIGALRM-Signal generieren und mit "sigsuspend" auf
- * ein Signal warten, wobei SIGINT blockiert ist. Falls waehrend dieser Zeit
- * ein SIGQUIT (= CTRL-\ bzw. SHIFT + CONTROL + ALT + ü) gesendet wird,
- * wird der SIGQUIT-Signalhandler ausgefuehrt und 'QuitHandled' auf TRUE
- * gesetzt, sonst wird der Alarm ausgeloest.
- * Falls waehrend dieser Zeit ein SIGINT auftritt, wird es nicht sofort
- * gesendet, sondern nur vermerkt und erst nach dem Ende von "sigsuspend()"
- * gesendet, wodurch der SIGINT-Handler ausgefuehrt und 'SigHandled' auf TRUE
- * gesetzt wird.
- *)
- WriteString('"alarm()" nach 5 Sekunden. Warten mit "sigsuspend()", SIGINT blockiert');
- WriteLn;
- WriteString('(ausprobieren!). Vorzeitiger Abbruch mit SIGQUIT (CTRL-\)...');
- WriteLn;
- IntHandled := FALSE;
- QuitHandled := FALSE;
- sigemptyset(mask);
- void := sigaddset(mask, SIGINT);
- rems := alarm(5);
- sigsuspend(mask);
- rems := alarm(0); (* Noch ausstehenden Alarm loeschen *)
- WriteString('..."sigsuspend()" wurde');
- IF NOT QuitHandled THEN
- WriteString(" nicht");
- END;
- WriteString(" vorzeitig durch SIGQUIT unterbrochen."); WriteLn;
- WriteString("...SIGINT wurde");
- IF NOT IntHandled THEN
- WriteString(" nicht");
- END;
- WriteString(" ausprobiert");
- WriteLn;
- WriteLn;
-
- (* Das gleiche mit "sigpause()": *)
- WriteString('"alarm()" nach 5 Sekunden. Warten mit "sigpause()", SIGINT blockiert');
- WriteLn;
- WriteString('(ausprobieren!). Vorzeitiger Abbruch mit SIGQUIT (CTRL-\)...');
- WriteLn;
- IntHandled := FALSE;
- QuitHandled := FALSE;
-
- rems := alarm(5);
- sigpause(sigmask(SIGINT));
- rems := alarm(0); (* Noch ausstehenden Alarm loeschen *)
- WriteString('..."sigpause()" wurde');
- IF NOT QuitHandled THEN
- WriteString(" nicht");
- END;
- WriteString(" vorzeitig durch SIGQUIT unterbrochen."); WriteLn;
- WriteString("...SIGINT wurde");
- IF NOT IntHandled THEN
- WriteString(" nicht");
- END;
- WriteString(" ausprobiert");
- WriteLn;
- WriteLn;
-
- key := Cnecin();
- END tsigtimer.
-