home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / m2posx14 / test / tsigtime.mpp < prev    next >
Encoding:
Text File  |  1994-05-29  |  7.7 KB  |  271 lines

  1. MODULE tsigtimer;
  2. __IMP_SWITCHES__
  3. __DEBUG__
  4. #ifdef HM2
  5. #ifdef __LONG_WHOLE__
  6. (*$!i+: Modul muss mit $i- uebersetzt werden! *)
  7. (*$!w+: Modul muss mit $w- uebersetzt werden! *)
  8. #else
  9. (*$!i-: Modul muss mit $i+ uebersetzt werden! *)
  10. (*$!w-: Modul muss mit $w+ uebersetzt werden! *)
  11. #endif
  12. #endif
  13.  
  14. #if (defined MM2) && (defined __DEBUG_CODE__)
  15. IMPORT Debug;
  16. #endif
  17.  
  18. VAL_INTRINSIC
  19. CAST_IMPORT
  20.  
  21. (* Programm ist nur mit MiNT oder MultiTOS sinnvoll.
  22.  *
  23.  * Test und Anwendungsbeispiel fuer Signalfunktionen, die mit der Zeit
  24.  * zu tun haben.
  25.  *
  26.  * Hier treten zwar "alarm()" und "sleep()" gemeinsam in einem Programm
  27.  * auf (siehe Hinweise in 'sig'), da sie aber nicht zur gleichen Zeit
  28.  * aktiv sind, gibt es hoffentlich keine Probleme.
  29.  *
  30.  * 29-Mai-94, Holger Kleinschmidt
  31.  *)
  32.  
  33. FROM SYSTEM IMPORT
  34. (* PROC *) ADR;
  35.  
  36. FROM PORTAB IMPORT
  37. (* CONST*) NULL,
  38. (* TYPE *) UNSIGNEDLONG;
  39.  
  40. IMPORT e;
  41.  
  42. FROM OSCALLS IMPORT
  43. (* PROC *) Cconis, Cnecin;
  44.  
  45. FROM cstr IMPORT
  46. (* PROC *) strerror, AssignCToM2;
  47.  
  48. FROM sig IMPORT
  49. (* CONST*) SIGINT, SIGQUIT, SIGALRM,
  50. (* TYPE *) SigactionRec, SigBlockType, SaFlags, sigsetT,
  51. (* PROC *) alarm, sleep, usleep, sigemptyset, sigaddset, pause, sigaction,
  52.            sigsuspend, sigpause, sigmask;
  53.  
  54. FROM InOut IMPORT
  55. (* PROC *) WriteCard, WriteInt, WriteString, WriteLn;
  56.  
  57. FROM pOUT IMPORT
  58. (* PROC *) PutCard;
  59.  
  60. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  61.  
  62. VAR new         : SigactionRec;
  63.     mask        : sigsetT;
  64.     c           : CHAR;
  65.     AlrmHandled : BOOLEAN;
  66.     IntHandled  : BOOLEAN;
  67.     QuitHandled : BOOLEAN;
  68.     key         : UNSIGNEDLONG;
  69.     rems        : CARDINAL;
  70.     remus       : UNSIGNEDLONG;
  71.     void        : INTEGER;
  72.     errmsg      : ARRAY [0..40] OF CHAR;
  73.  
  74. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  75.  
  76. #ifdef HM2
  77. (*$E+,$K+*)
  78. #endif
  79. PROCEDURE CatchSigAlrm (sig : UNSIGNEDLONG);
  80. BEGIN
  81.  AlrmHandled := TRUE;
  82. END CatchSigAlrm;
  83.  
  84. PROCEDURE CatchSigInt (sig : UNSIGNEDLONG);
  85. BEGIN
  86.  IntHandled := TRUE;
  87. END CatchSigInt;
  88.  
  89. PROCEDURE CatchSigQuit (sig : UNSIGNEDLONG);
  90. BEGIN
  91.  QuitHandled := TRUE;
  92. END CatchSigQuit;
  93. #ifdef HM2
  94. (*$E=,$K-*)
  95. #endif
  96.  
  97. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  98.  
  99. BEGIN
  100.  (* 'CatchSigInt' als Signalhandler fuer SIGINT (= CTRL-C) installieren. *)
  101.  WITH new DO
  102.    saHandler.proc := CatchSigInt;
  103.    sigemptyset(saMask);
  104.    saFlags := SaFlags{};
  105.  END;
  106.  IF sigaction(SIGINT, ADR(new), NULL) < 0 THEN
  107.    AssignCToM2(strerror(e.errno), 0, errmsg);
  108.    WriteString("***: "); WriteString(errmsg);
  109.  END;
  110.  
  111.  (* Fuer fuenf Sekunden selbst suspendieren. Falls waehrend dieser Zeit
  112.   * ein SIGINT auftritt, wird der Signalhandler ausgefuehrt, und 'IntHandled'
  113.   * auf TRUE gesetzt.
  114.   *)
  115.  WriteString('"sleep()" für 5 Sekunden. Vorzeitiger Abbruch mit SIGINT-Signal (CTRL-C)...');
  116.  WriteLn;
  117.  IntHandled := FALSE;
  118.  rems       := sleep(5);
  119.  WriteString('..."sleep()" wurde ');
  120.  IF IntHandled THEN
  121.    WriteString('nach ');
  122.    WriteCard(5 - rems, 0);
  123.    WriteString(" Sekunden vorzeitig durch SIGINT abgebrochen.");
  124.  ELSE
  125.    WriteString('nicht vorzeitig durch SIGINT abgebrochen.');
  126.  END;
  127.  WriteLn;
  128.  WriteLn;
  129.  
  130. (*
  131. (* Wie oben. Nur mit MiNT 1.10 ! *)
  132.  WriteString('"usleep()" für 5 Sekunden. Vorzeitiger Abbruch mit SIGINT-Signal (CTRL-C)... ');
  133.  WriteLn;
  134.  IntHandled := FALSE;
  135.  remus      := usleep(LC(5000000)); (* ab MiNT 1.10 *)
  136.  WriteString('..."usleep()" wurde ');
  137.  IF IntHandled THEN
  138.    WriteString('durch SIGINT nach ');
  139.    PutCard(LC(5000000) - remus, 0);
  140.    WriteString(" Mikrosekunden vorzeitig durch SIGINT abgebrochen.");
  141.  ELSE
  142.    WriteString('nicht vorzeitig durch SIGINT abgebrochen.');
  143.  END;
  144.  WriteLn;
  145.  WriteLn;
  146. *)
  147.  
  148.  (* 'CatchSigAlrm' als Signalhandler fuer SIGALRM installieren. *)
  149.  WITH new DO
  150.    saHandler.proc := CatchSigAlrm;
  151.    sigemptyset(saMask);
  152.    saFlags := SaFlags{};
  153.  END;
  154.  IF sigaction(SIGALRM, ADR(new), NULL) < 0 THEN
  155.    AssignCToM2(strerror(e.errno), 0, errmsg);
  156.    WriteString("***: "); WriteString(errmsg);
  157.  END;
  158.  
  159.  (* In fuenf Sekunden ein SIGALRM-Signal generieren. Falls waehrend dieser
  160.   * Zeit keine Taste gedrueckt wird, wird der Signalhandler ausgefuehrt und
  161.   * 'AlrmHandled' auf TRUE gesetzt, sonst wird der Alarm geloescht.
  162.   *)
  163.  WriteString('"alarm()" nach 5 Sekunden. Vorzeitiger Abbruch durch Tastendruck... ');
  164.  WriteLn;
  165.  AlrmHandled := FALSE;
  166.  rems        := alarm(5);
  167.  REPEAT
  168.  UNTIL AlrmHandled OR Cconis();
  169.  rems := alarm(0); (* Noch ausstehenden Alarm loeschen *)
  170.  IF AlrmHandled THEN
  171.    WriteString("...Keine Taste innerhalb von 5");
  172.  ELSE
  173.    WriteString("...Taste nach ");
  174.    WriteCard(5 - rems, 0);
  175.  END;
  176.  WriteString(" Sekunden gedrückt.");
  177.  WriteLn;
  178.  WriteLn;
  179.  
  180.  (* In fuenf Sekunden ein SIGALRM-Signal generieren und mit "pause" auf
  181.   * ein Signal warten. Falls waehrend dieser Zeit ein SIGINT auftritt,
  182.   * wird der SIGINT-Signalhandler ausgefuehrt und 'SigHandled' auf TRUE
  183.   * gesetzt, sonst wird der Alarm ausgeloest.
  184.   *)
  185.  WriteString('"alarm()" nach 5 Sekunden. Warten mit "pause", vorz. Abbruch mit SIGINT...');
  186.  WriteLn;
  187.  IntHandled := FALSE;
  188.  rems       := alarm(5);
  189.  pause;
  190.  rems := alarm(0); (* Noch ausstehenden Alarm loeschen *)
  191.  WriteString('..."pause" wurde');
  192.  IF NOT IntHandled THEN
  193.    WriteString(" nicht");
  194.  END;
  195.  WriteString(" vorzeitig durch SIGINT unterbrochen.");
  196.  WriteLn;
  197.  WriteLn;
  198.  
  199.  (* 'CatchSigQuit' als Signalhandler fuer SIGQUIT installieren. *)
  200.  WITH new DO
  201.    saHandler.proc := CatchSigQuit;
  202.    sigemptyset(saMask);
  203.    saFlags := SaFlags{};
  204.  END;
  205.  IF sigaction(SIGQUIT, ADR(new), NULL) < 0 THEN
  206.    AssignCToM2(strerror(e.errno), 0, errmsg);
  207.    WriteString("***: "); WriteString(errmsg);
  208.  END;
  209.  
  210.  
  211.  (* In fuenf Sekunden ein SIGALRM-Signal generieren und mit "sigsuspend" auf
  212.   * ein Signal warten, wobei SIGINT blockiert ist. Falls waehrend dieser Zeit
  213.   * ein SIGQUIT (= CTRL-\ bzw. SHIFT + CONTROL + ALT + ü) gesendet wird,
  214.   * wird der SIGQUIT-Signalhandler ausgefuehrt und 'QuitHandled' auf TRUE
  215.   * gesetzt, sonst wird der Alarm ausgeloest.
  216.   * Falls waehrend dieser Zeit ein SIGINT auftritt, wird es nicht sofort
  217.   * gesendet, sondern nur vermerkt und erst nach dem Ende von "sigsuspend()"
  218.   * gesendet, wodurch der SIGINT-Handler ausgefuehrt und 'SigHandled' auf TRUE
  219.   * gesetzt wird.
  220.   *)
  221.  WriteString('"alarm()" nach 5 Sekunden. Warten mit "sigsuspend()", SIGINT blockiert');
  222.  WriteLn;
  223.  WriteString('(ausprobieren!). Vorzeitiger Abbruch mit SIGQUIT (CTRL-\)...');
  224.  WriteLn;
  225.  IntHandled  := FALSE;
  226.  QuitHandled := FALSE;
  227.  sigemptyset(mask);
  228.  void := sigaddset(mask, SIGINT);
  229.  rems := alarm(5);
  230.  sigsuspend(mask);
  231.  rems := alarm(0); (* Noch ausstehenden Alarm loeschen *)
  232.  WriteString('..."sigsuspend()" wurde');
  233.  IF NOT QuitHandled THEN
  234.    WriteString(" nicht");
  235.  END;
  236.  WriteString(" vorzeitig durch SIGQUIT unterbrochen."); WriteLn;
  237.  WriteString("...SIGINT wurde");
  238.  IF NOT IntHandled THEN
  239.    WriteString(" nicht");
  240.  END;
  241.  WriteString(" ausprobiert");
  242.  WriteLn;
  243.  WriteLn;
  244.  
  245.  (* Das gleiche mit "sigpause()": *)
  246.  WriteString('"alarm()" nach 5 Sekunden. Warten mit "sigpause()", SIGINT blockiert');
  247.  WriteLn;
  248.  WriteString('(ausprobieren!). Vorzeitiger Abbruch mit SIGQUIT (CTRL-\)...');
  249.  WriteLn;
  250.  IntHandled  := FALSE;
  251.  QuitHandled := FALSE;
  252.  
  253.  rems := alarm(5);
  254.  sigpause(sigmask(SIGINT));
  255.  rems := alarm(0); (* Noch ausstehenden Alarm loeschen *)
  256.  WriteString('..."sigpause()" wurde');
  257.  IF NOT QuitHandled THEN
  258.    WriteString(" nicht");
  259.  END;
  260.  WriteString(" vorzeitig durch SIGQUIT unterbrochen."); WriteLn;
  261.  WriteString("...SIGINT wurde");
  262.  IF NOT IntHandled THEN
  263.    WriteString(" nicht");
  264.  END;
  265.  WriteString(" ausprobiert");
  266.  WriteLn;
  267.  WriteLn;
  268.  
  269.  key := Cnecin();
  270. END tsigtimer.
  271.