[Back to FILES SWAG index]  [Back to Main SWAG index]  [Original]

{
>>DOS will automatically close all open files that belong to your
>>process upon termination.  The only way I know of to do it manually,
>>if you don't know what the actual file variables will be, is to search
>>your PSP

>   I was doing fine until this point, what's a psp?
PSP stands for Program Segment Prefix.  It contains a lot of information
about your program that is important to DOS.  Some of the things it
contains is the file handle table for open files, the command line tail,
information carried over from CP/M, an ISR table, a pointer to a copy of
the master environment, and more.

>for any open file handles, then explicitly call DOS, passing
>>each file handle number. If nobody has a better suggestion, I could
>>probably think up some code to do that.

>   at least psuedo code would be appreciated..
Here is some code that will close all of the files that your program
actually opened.  It won't clear the run-time error; you'll have to
put that code into the exit-proc, or write your own.

{ FCLOSALL.PAS
  file close unit
  12-5-93
  (c) 1993 Brian Pape

  This code may be distributed freely.  However, I would appreciate it
  if modifications made to the code would be noted with the name of the
  modifier and the date.

  This program will demonstrate how to close all open files in
  your program without knowing what the names of the associated
  file variables are.  All that you need to do in order to implement
  this code is put the statement USES FCLOSALL in your main program.

  When your program ends, whether through a run-time error or through
  normal termination, this procedure will attempt to close all open files
  that were opened by your program.  It will not close the standard i/o
  file handles that are maintained by DOS.  In fact, the Turbo RTL will
  automatically close the INPUT and OUTPUT standard files in the standard
  exit procedure.  The other DOS standard I/O files are StdErr, AUX,
  and PRN.

  This code does not clear the ExitCode variable, so if your program is
  terminating with a run-time error, the turbo ExitProc will still
  print the "Runtime Error at xxxx:xxxx" message.  If you want to
  prevent this message from occuring, then write another exitproc to
  clear the ExitCode variable in certain cases.

  This code requires TP 6.0 or greater since it uses BASM
}

unit fclosall;
interface
implementation
var
  saveexit:pointer;

procedure close_files_exit_proc; far;
var
  numhandles : byte;
  hp : ^byte;
begin

  exitproc := saveexit;

  { get number of file handles available }
  numhandles := byte(ptr(prefixseg,$32)^);

  { get the location of the fht, in case it is moved }
  hp := pointer(ptr(prefixseg,$34)^);
  inc(hp,5);

  { skip the first 5 handles because they are standard DOS handles }
  for numhandles := 5 to pred(numhandles) do
    begin
      asm
        mov  ah,3eh
        xor  bh,bh
        push ds
        lds  si,hp
        mov  bl,[si]
        cmp  bl,0ffh  { don't close invalid handle; it will close INPUT }
        je   @invalidhandle
        int  $21
        @invalidhandle:
        pop ds
      end;
      inc(hp);
    end;
end;

begin
  saveexit := exitproc;
  exitproc := @close_files_exit_proc;
end.  { FCLOSALL }


{ tests the FCLOSALL unit }
program test_fcloseall;
uses fclosall;
var
  f : file;
  i : byte;
begin
  for i := 1 to 16 do
    begin
      assign(f,'a.a');
      rewrite(f);
    end;  { for }
end.


[Back to FILES SWAG index]  [Back to Main SWAG index]  [Original]