home *** CD-ROM | disk | FTP | other *** search
/ RBBS in a Box Volume 1 #3.1 / RBBSIABOX31.cdr / scrg / safhlt.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1990-09-29  |  5.4 KB  |  190 lines

  1. (*[72457,2131]
  2. SAFHLT.PAS                27-Mar-86 5220               99
  3.  
  4.     Keywords: PCDOS MSDOS FILE ERROR SAFE HALT HANDLER HANDLE
  5.  
  6.     Demonstrates some routines to keep a list of open files in a Turbo program.
  7.     This list can be used by an error handler in order to close all open files
  8.     before halting.
  9. *)
  10.  
  11. {
  12.  a set of routines which keep track of all text files open at a given
  13.  point in program execution. This allows an error handler to close
  14.  all open files so that the Turbo internal text buffers are flushed.
  15.  
  16.  written 2/86. Kim Kokkonen.
  17.  Compuserve 72457,2131.
  18. }
  19.  
  20. PROGRAM TestSafeHalt;
  21.  
  22.   {the following or a similar version should be included into your application}
  23.   {***************************************************************************}
  24.  
  25. CONST
  26.   TextBufferSize = 512;
  27. TYPE
  28.   TextFile = Text[TextBufferSize];
  29.   TextFilePtr = ^TextFile;
  30.   TextListPtr = ^TextListRec;
  31.   TextListRec = RECORD
  32.                   fptr : TextFilePtr;
  33.                   handle : Integer; {for consistency check only}
  34.                   next : TextListPtr;
  35.                 END;
  36.   TextOpenMode = (tReset, tRewrite);
  37.   TextPathname = STRING[63];
  38.   TextFIB = RECORD
  39.               handle : Integer;
  40.               flags : Byte;
  41.               charbuff : Char;
  42.               bufofs : Integer;
  43.               bufsize : Integer;
  44.               bufpos : Integer;
  45.               bufend : Integer;
  46.               path : ARRAY[1..64] OF Char;
  47.             END;
  48. VAR
  49.   TextList : TextListPtr;
  50.  
  51.   PROCEDURE InitializeTextList;
  52.   BEGIN
  53.     TextList := NIL;
  54.   END {initializetextlist} ;
  55.  
  56.   PROCEDURE OpenTextFile(VAR f : TextFile;
  57.                          path : TextPathname;
  58.                          OpenMode : TextOpenMode;
  59.                          VAR Result : Integer);
  60.     {-shell around Assign/Reset/Rewrite to allow protected halts}
  61.   VAR
  62.     temp : TextListPtr;
  63.     fib : TextFIB ABSOLUTE f;
  64.   BEGIN
  65.     Assign(f, path);
  66.     {$I-}
  67.     CASE OpenMode OF
  68.       tReset : Reset(f);
  69.       tRewrite : Rewrite(f);
  70.     END;
  71.     {$I+}
  72.     Result := IOResult;
  73.     IF Result <> 0 THEN Exit;
  74.     {add the file to the list of open files}
  75.     temp := TextList;
  76.     New(TextList);
  77.     WITH TextList^ DO BEGIN
  78.       fptr := Ptr(Seg(f), Ofs(f));
  79.       handle := fib.handle;
  80.       next := temp;
  81.     END;
  82.   END {opentextfile} ;
  83.  
  84.   PROCEDURE CloseTextFile(VAR f : TextFile;
  85.                           VAR Result : Integer);
  86.     {-shell around Close to allow protected halts}
  87.   VAR
  88.     prevfile, curfile : TextListPtr;
  89.     foundit : Boolean;
  90.   BEGIN
  91.     {$I-}
  92.     Close(f);
  93.     {$I+}
  94.     Result := IOResult;
  95.     IF Result <> 0 THEN Exit;
  96.     {remove the record from the text file list}
  97.     foundit := False;
  98.     curfile := TextList;
  99.     prevfile := NIL;
  100.     WHILE NOT(foundit) AND (curfile <> NIL) DO BEGIN
  101.       foundit := (curfile^.fptr = Ptr(Seg(f), Ofs(f)));
  102.       IF foundit THEN BEGIN
  103.         IF prevfile = NIL THEN
  104.           {file was first in the list}
  105.           TextList := curfile^.next
  106.         ELSE
  107.           {file is in middle of list}
  108.           prevfile^.next := curfile^.next;
  109.         Dispose(curfile);
  110.       END ELSE BEGIN
  111.         prevfile := curfile;
  112.         curfile := curfile^.next;
  113.       END;
  114.     END;
  115.     IF NOT(foundit) THEN
  116.       WriteLn('PROGRAM ERROR: closed file not found in text file list....');
  117.   END {closetextfile} ;
  118.  
  119.   PROCEDURE FlushAllTextFiles;
  120.     {-call from a shutdown procedure to flush Turbo's text buffers}
  121.   VAR
  122.     curfile : TextListPtr;
  123.     fib : TextFIB;
  124.     i : Byte;
  125.   BEGIN
  126.     curfile := TextList;
  127.     WHILE curfile <> NIL DO BEGIN
  128.       {consistency check - make sure handle matches what it was opened to}
  129.       Move(curfile^.fptr^, fib, SizeOf(TextFIB));
  130.       WITH fib DO
  131.         IF handle <> curfile^.handle THEN BEGIN
  132.           WriteLn('PROGRAM ERROR: file and list handles do not match');
  133.           Write('filename: ');
  134.           i := 1;
  135.           WHILE path[i] <> #0 DO BEGIN
  136.             Write(path[i]);
  137.             i := Succ(i);
  138.           END;
  139.           WriteLn;
  140.         END;
  141.       {close the file, this automatically flushes it}
  142.       {at this point, error checking the close is superfluous}
  143.       {$I-}
  144.       Close(curfile^.fptr^);
  145.       {$I+}
  146.       curfile := curfile^.next;
  147.     END;
  148.   END {flushalltextfiles} ;
  149.  
  150.   PROCEDURE SafeHalt(ReturnCode : Integer);
  151.     {-call instead of Turbo's Halt procedure to really clean up at halt time}
  152.   BEGIN
  153.     {assure Turbo's text buffers are clean}
  154.     {DOS will close all typed and untyped files, which Turbo doesn't buffer}
  155.     FlushAllTextFiles;
  156.     {restore trapped interrupts, if any - here}
  157.     {let Turbo restore its own interrupts and return the return code}
  158.     Halt(ReturnCode);
  159.   END {safehalt} ;
  160.  
  161.  
  162.   {*********half-hearted demonstration follows********************}
  163.  
  164. VAR
  165.   f1, f2, f3 : TextFile;
  166.   Result : Integer;
  167.  
  168.   PROCEDURE WriteGarbage(VAR f : TextFile);
  169.   VAR
  170.     i : Integer;
  171.   BEGIN
  172.     FOR i := 1 TO 20 DO
  173.       WriteLn(f, i, ' garbage ', i);
  174.   END {writegarbage} ;
  175.  
  176. BEGIN
  177.   InitializeTextList;
  178.   OpenTextFile(f1, 'tmp1.tmp', tRewrite, Result);
  179.   OpenTextFile(f2, 'tmp2.tmp', tRewrite, Result);
  180.   OpenTextFile(f3, 'tmp3.tmp', tRewrite, Result);
  181.   WriteGarbage(f1);
  182.   WriteGarbage(f2);
  183.   WriteGarbage(f3);
  184.   CloseTextFile(f1, Result);
  185.   CloseTextFile(f3, Result);
  186.   {safehalt gets all text into TMP2.TMP}
  187.   {if not called, TMP2.TMP will be an empty file}
  188.   SafeHalt(0);
  189. END.
  190.