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