Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site ttrdc.UUCP Path: utzoo!linus!decvax!bellcore!ulysses!mhuxr!mhuxt!houxm!ihnp4!ltuxa!ttrdc!levy From: levy@ttrdc.UUCP (Daniel R. Levy) Newsgroups: net.lang.f77,net.bugs.usg Subject: Fix for three f77 I/O bugs Message-ID: <757@ttrdc.UUCP> Date: Mon, 24-Feb-86 19:15:04 EST Article-I.D.: ttrdc.757 Posted: Mon Feb 24 19:15:04 1986 Date-Received: Wed, 26-Feb-86 06:52:31 EST Organization: AT&T, Computer Systems Division, Skokie, IL Lines: 122 Xref: linus net.lang.f77:413 net.bugs.usg:418 Here are fixes for three apparently long-standing f77 I/O library problems in SysV f77 (and I think in BSD 4.2 and earlier--can't speak for 4.3-- someone sent me mail indicating that at least one of these was fixed in 4.3): Problem 1. Formatted floating-point input crashes (or indicates incorrect input if iostat= or err= is used) when it reads 'E-format' input data which uses an uppercase 'E'. (Lowercase 'e' works just fine.) Repeat by: program foo real a integer io read (5,10,iostat=io)a 10 format(e5.1) write(6,*)a,io stop end $ foo 1.2e4 1.200000000e+04 0 $ foo 1.2E4 1.20000005 115 Diagnosis and Fix: The input processing is failing to recognize 'E' (and 'D') as valid alternates to 'e' and 'd' in formatted input. The fix: In /usr/src/lib/libI77/rdfmt.c, approximately line 145 [function rd_F()] change if (*sp=='d' || *sp=='e') { sp++; } else nfrac-=scale; to if (*sp=='d' || *sp=='e' || *sp=='D' || *sp=='E' ) { sp++; } else nfrac-=scale; Problems 2 and 3. Explicit error checking for formatted internal input is broken in two ways. If an err= or iostat= clause is specified in the read statement, an error is indicated or a nonzero iostat variable returned if the data read was correct (consistent with the format statement used). If the data read was incorrect, then the program will die with a core dump despite the explicit error checking which was indicated in the Fortran program. Repeat by: program bar integer i character*2 cbuf 10 format(a) 20 format(i2) read(5,10)cbuf read(cbuf,20,iostat=io)i write(6,*)i,io stop end $ bar 12 12 2 $ bar ab fmt: read unexpected character apparent state: unit 5 named last format: (i2) lately reading sequential formatted internal IO abort - core dumped Diagnoses and Fixes: In the first problem (error returned even though input was correct) a value is being returned to the Fortran program from a C function that does not bother to return a value (!). The fix: In /usr/src/lib/libI77/iio.c, insert a 'return(0);' statement at the end of the function z_rnew() [approximately line 27]. (It also would be a good idea to insert a similar statement at the end of the function z_wnew() [same file] but who checks for write errors in internal I/O?) For the second problem (error checking from Fortran program is ignored, program crashes anyhow), the external pointer 'elist' to the current error-status table is never updated from the Fortran program! The result is either garbage or the table from a previous external read or write. This table, which is passed by address from the Fortran program in routine s_rsfi(), is supposed to indicate, among other thing, whether the Fortran program is trapping errors for the I/O operation. The fix: In /usr/src/lib/libI77/iio.c, approximately line 31, in the function s_rsfi(), the sequence if(n=c_si(a)) return(n); reading=1; should be changed to (one line added): if(n=c_si(a)) return(n); elist=(cilist *)a; reading=1; -- ------------------------------- Disclaimer: The views contained herein are | dan levy | yvel nad | my own and are not at all those of my em- | an engihacker @ | ployer or the administrator of any computer | at&t computer systems division | upon which I may hack. | skokie, illinois | -------------------------------- Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, vax135}!ttrdc!levy