SUN Pascal: Determining if a file exists before opening

frist at ccu.umanitoba.ca frist at ccu.umanitoba.ca
Fri Mar 16 09:38:00 AEST 1990


Here's a problem that has had me beating my head against the wall:

In SUN Pascal, how do you test to see if a file exists, before 'reset'ting
or 'rewrite'ing that file? 

All other Pascal implementations I have used in the last 12 years have
either provided an explicit command (if exists(<filename>) then ...) or
provided a way of recovering from the error that occurs when you try to
open a non-existant file.  Not so on SUN.

There are two possible approaches that I can see, and both involve calling
c subroutines from Pascal.

I. Use the c 'system' function to determine if the file is present.

   system('ls <filename> > TEMPFILE');

   Now, read in TEMPFILE. If TEMPFILE contains '<filename>:not found', then
   the file doesn't exist.

   I've actually gotten this to work, but there are two important cases
   this approach misses.

   A.  If the filename contains an environment variable that is interpreted
       by the shell as a path, the program would detect a mismatch between
       the filename it sent to the system, and the name returned by 'ls'.

   eg. system('ls $HOME/seq/seq1.data > TEMPFILE')`

       would result in '/home/genrl/frist/seq/seq1.data' being written to
       TEMPFILE. You could sleaze around this problem by ignoring the
       filename in TEMPFILE and just looking for ':not found', but there
       is a lot of potential for disaster in this approach.

II. Call the c 'fopen' procedure from Pascal, and try to determine if
    the file was opened sucessfully.  I have tried this without any success
    so far, but it's possible that my very minimal knowledge of c has
    prevented me from hitting the correct form.  The following subroutine
    compiles correctly in SUN Pascal, but generates an error:


  const MAXLINE=132;
  type CHARARRAY:array[1..MAXLINE] of char;

  (* fopen and open are part of the standard c library *)
  (* They must be declared in the highest scope of the main program.*)
  function fopen(FILENAME:CHARARRAY;FILEMODE:char):char; external c;
  function open(FILENAME:CHARARRAY;ACCESS:integer):integer; external c;

  (* - - - - - - - - - - - - - - - - - - - - - - - - - - - *)
  (* =true if file exists, =false if it doesn't *)
  (* A comparable procedure is provided with ATT System V Pascal *)
  function EXISTS(FILENAME:CHARARRAY):boolean;
    var F:text;
    begin (* EXISTS *)
      F^:=fopen(FILENAME,'r');
      if open(FILENAME,0)=-1 then EXISTS:=false
      else EXISTS:=true
    end; (* EXISTS *)


    When I call EXISTS in a Pascal program, the program crashes at the fopen
    statement, giving the message

    (name unknown): Reference to an inactive file

    This is surprising to me, since even in the event that a file is not
    found, fopen should return the pointer value NULL. (What does this mean
    to Pascal?) In any event, no error should be generated.  Changing the type
    of F from text to ^text  generates the error

    Segmentation fault

    and again the program crashes.

    I have tried a number of variations on this approach with no success. The
    main problem is that the SUN Pascal documentation doesn't really go into
    any detail about how types are reconciled between the two languages. For
    example, as what type(s) should the fopen and open be declared?  

    Anyway, if anybody out there can figure this out, let me know.  I have a
    bunch of programs that depend on this procedure to protect against user
    errors.

[[Ed's Note: I haven't tried this, or looked at it extensively, but the
STAT series of file routines for C might be another approach you might
consider. They are specifically designed to return file status (without
having to open/close or redirect output). -bdg]]

Brian Fristensky                           frist at ccu.umanitoba.ca
Assistant Professor
Dept. of Plant Science
University of Manitoba
Winnipeg, MB R3T 2N2  CANADA
Office phone:                              204-474-6085
FAX:                                       204-275-5128



More information about the Comp.sys.sun mailing list