Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!cs.utexas.edu!rice!sun-spots-request From: frist@ccu.umanitoba.ca Newsgroups: comp.sys.sun Subject: SUN Pascal: Determining if a file exists before opening Keywords: Miscellaneous Message-ID: <5821@brazos.Rice.edu> Date: 15 Mar 90 23:38:00 GMT Sender: news@rice.edu Organization: Sun-Spots Lines: 96 Approved: Sun-Spots@rice.edu X-Sun-Spots-Digest: Volume 9, Issue 88, message 3 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() 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 > TEMPFILE'); Now, read in TEMPFILE. If TEMPFILE contains ':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@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