[comp.lang.fortran] File handling in Fortran 77

ravi@earth.ce.nwu.edu (Ravi Sinha) (08/23/90)

Hi,

I have been wondering for a while about how certain aspects of
file handling are supposed to be in Fortran 77 standard.  Maybe
someone can shed some light on it.

(i)  If you open an OLD file using status=UNKNOWN and write
     less no. of lines to it than is already there, should the
     new file have only the stuff written when it was opened
     last.  Or should the write statement just overwrite
     the old file, thereby leaving rest of the old contents
     untouched.  I have seen implementations of compilers
     which do either and I am not sure which is the expected
     behavior.
			    
(ii) Can you open a file with status=NEW if the file already
     exists.  Again I have seen implementations which don't
     allow this (most unix), and others which allow you
     to open existing files with status=NEW (vax/vms).
						    
(iii) (i) if an old file is opened with status=NEW qualifier.
						     
(iv) Are any of these issues dependent on whether your
     file is binary or ASCII.  I remember that there were
     some discussions a few months ago about how to change
     only portions of an existing file through selective 
     read/write.  I can't recall the details, though.

Thanks.

---------------------------------------------------------------------
Ravi Sinha			|  As usual, the opinions here 
Northwestern University		|  are mine, and only mine.
ravi@earth.ce.nwu.edu		|  Who'd want to claim these anyway?

fwebb@bbn.com (Fred Webb) (08/23/90)

In article <11191@accuvax.nwu.edu> ravi@earth.ce.nwu.edu (Ravi Sinha) writes:
>Hi,
>
>I have been wondering for a while about how certain aspects of
>file handling are supposed to be in Fortran 77 standard.  Maybe
>someone can shed some light on it.
>
>  (questions deleted to keep my mailer happy)

According to the standard:

i.,iii.: If a file is opened for sequential access, and a record is written
         to the file, that record "becomes the last record of the file"
         (ANSI X3.9-1978, 12.9.4.1, 12.9.6). Records in files opened for
         direct access can be written or rewritten without affecting any
         other records in the same file (ANSI X3.9, 12.2.4.2).

ii.:     If OLD is specified, the file must exist. If NEW is specified,
         the file must not exist. (ANSI X3.9-1978, 12.10.1)

iv.:     Fortran doesn't know from binary or ASCII. Records and files
         are foramtted (ASCII) or unformatted (binary. None of these issues
         are connected in any way to the issue of formatted or unformatted
         files. If you want to change a record in a file without truncating
         the file you must use direct access (ACCESS=DIRECT).

					-- Fred

andyo@masscomp.ccur.com (Andy Oram) (08/29/90)

Questions about standard Fortran 77, from ravi@earth.ce.nwu.edu (Ravi Sinha):

> (i)  If you open an OLD file using status=UNKNOWN and write
>      less no. of lines to it than is already there, should the
>      new file have only the stuff written when it was opened
>      last.  Or should the write statement just overwrite
>      the old file, thereby leaving rest of the old contents
>      untouched.

This depends on whether you use ACCESS='SEQUENTIAL' or ACCESS='DIRECT'.

Sequential access positions the file at the beginning (the standard seems to
leave some leeway here, but paragraph 12.2.4.1 says that files are opened at
the first record).  Furthermore, sequenitial access causes each write to be
last record (paragraph 12.9.4.1).  Add it up and you can say "bye-bye old
data."

(Although this behavior is reasonable, it annoys me that the standard prevents
systems with back-up and versioning systems, like VAX/VMS, from providing that
feature when FORTRAN programs overwrite old files.)

Under direct access, untouched records keep their old contents.

		    
> (ii) Can you open a file with status=NEW if the file already
>      exists.

No (paragraph 12.10.1, under STATUS specifier).

> others which allow you
> to open existing files with status=NEW (vax/vms).
	.
	.
	.
> (iii) (i) if an old file is opened with status=NEW qualifier.

I haven't worked on VAX/VMS for a while, but I bet what it's doing is giving
you a new, higher-numbered version of the file.

> (iv) Are any of these issues dependent on whether your
>      file is binary or ASCII.

Not officially.  I can't think of any circumstances where you'd see
differences -- a record is a record is a record, and that's the granularity
with which FORTRAN I/O operates.  (For instance, you can't change one part of
an existing record and leave another part intact.)

Disclaimer:  I've used the standard a lot while writing a FORTRAN manual.  I
answered the posting in the hope of saving time for busier people with more
expertise in the standard.  Please forgive me if I have slipped up, either
because the standard has a subtle loophole, or because I got too loose trying
to map formal requirements (the standard) onto useful, real-life operation.

mcdonald@aries.scs.uiuc.edu (Doug McDonald) (08/30/90)

In article <46016@masscomp.ccur.com> andyo@masscomp.UUCP (Andy Oram) writes:
>Not officially.  I can't think of any circumstances where you'd see
>differences -- a record is a record is a record, and that's the granularity
>with which FORTRAN I/O operates.  (For instance, you can't change one part of
>an existing record and leave another part intact.)
>
This has always bothered me. A file is just a sequence of it, usually
organized as bytes - a text file must be in "bytes".

So how, in standard Fortran, do you dothe exact analog of the most primitive
file operations - those expressed in C as flavors of get, put, and seek.
It HAS to be possible to do this, as C requires it.

Doug MCDonald

burley@world.std.com (James C Burley) (08/30/90)

In article <1990Aug29.173235.9405@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:

   This has always bothered me. A file is just a sequence of it, usually
   organized as bytes - a text file must be in "bytes".

   So how, in standard Fortran, do you dothe exact analog of the most primitive
   file operations - those expressed in C as flavors of get, put, and seek.
   It HAS to be possible to do this, as C requires it.

   Doug MCDonald

You don't.  Standard Fortran is built on older and more baroque/primitive
file storage technology than C/UNIX.  Fortran allows systems to implement
files as consisting of zero or more fixed-length records, in particular.
So while, in C, you can (or could if ANSI C and its libraries ran on such
a system) read and write to arbitrary bytes in the file, in Fortran you
can't do it without using system calls, tricks, or nonstandard usage.

In Fortran, you can "seek" to a given record (if you've specified this
desire in the OPEN statement, I think), but not to a given byte.

As far as "HAS to be possible...as C requires it", this statement suggest you
think C is written in Fortran?  Or maybe I misunderstand what is meant by
this.  Generally speaking, Fortran demands a lot less from the operating system
it runs on in terms of file support than C, even if it demands more from the
run-time library to implement all its "features".  For example, I remember
that PRIMOS couldn't exactly implement C files, since PRIMOS bytes were 8 bits
but its file system (like the internal memory organization) was based on
16-bit chunks.  If you wrote 21 bytes to a new file, closed it, and later
read it, you'd get 22 bytes.  Unless they did some trick like check for a zero
in the final byte, in which case if you wrote 22 bytes to a new file, the last
one being zero, and later read it, you'd get 21 bytes.  (If any circa-1982
PRIMOS experts read this and know any different, please let me know how they
got around this problem.)  To do C correctly, PRIMOS would have needed a
change to its file system to add the ability to track file length down to
byte granularity.  Fortran support, however, rarely requires any changes to
any file system, no matter how primitive.

In Fortran, you can "seek" to a given record (if you've specified this
desire in the OPEN statement, I think), but not to a given byte.

James Craig Burley, Software Craftsperson    burley@world.std.com

mcdonald@aries.scs.uiuc.edu (Doug McDonald) (08/30/90)

In article <BURLEY.90Aug30024743@world.std.com> burley@world.std.com (James C Burley) writes:
>In article <1990Aug29.173235.9405@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:
>
>   This has always bothered me. A file is just a sequence of it, usually
                                                              ^^
                                                   my typo - I meant bits
>   organized as bytes - a text file must be in "bytes".
>
>   So how, in standard Fortran, do you dothe exact analog of the most primitive
>   file operations - those expressed in C as flavors of get, put, and seek.
>   It HAS to be possible to do this, as C requires it.
>
>   Doug MCDonald
>
>You don't.  Standard Fortran is built on older and more baroque/primitive
>file storage technology than C/UNIX.  Fortran allows systems to implement
>files as consisting of zero or more fixed-length records, in particular.
>So while, in C, you can (or could if ANSI C and its libraries ran on such
>a system) read and write to arbitrary bytes in the file, in Fortran you
>can't do it without using system calls, tricks, or nonstandard usage.
>
>In Fortran, you can "seek" to a given record (if you've specified this
>desire in the OPEN statement, I think), but not to a given byte.
>
>As far as "HAS to be possible...as C requires it", this statement suggest you
>think C is written in Fortran?  Or maybe I misunderstand what is meant by
>this. 

I meant that a computer that can't run C is a joke. If it can run C,
it must be physically possible, and possible by some sort of OS calls.


> Generally speaking, Fortran demands a lot less from the operating system
>it runs on in terms of file support than C, even if it demands more from the
>run-time library to implement all its "features".  For example, I remember
>that PRIMOS couldn't exactly implement C files, since PRIMOS bytes were 8 bits
>but its file system (like the internal memory organization) was based on
>16-bit chunks.  If you wrote 21 bytes to a new file, closed it, and later
>read it, you'd get 22 bytes.  Unless they did some trick like check for a zero
>in the final byte, in which case if you wrote 22 bytes to a new file, the last
>one being zero, and later read it, you'd get 21 bytes.  (If any circa-1982
>PRIMOS experts read this and know any different, please let me know how they
>got around this problem.)  To do C correctly, PRIMOS would have needed a
>change to its file system to add the ability to track file length down to
>byte granularity.  Fortran support, however, rarely requires any changes to
>any file system, no matter how primitive.
>
In other words, you are saying Primes are (were?) so deficient that
they could not even tell how long a file was? 


>In Fortran, you can "seek" to a given record (if you've specified this
>desire in the OPEN statement, I think), but not to a given byte.
>

I still don't understand why not. A file IS a sequence of bits.  Why can't the
OS simply move those bits (as needed, or all at once, if the address
space is big enough) into memory and present them to the program?  If 
you had written the file with some arcane internal organization, you
would then SEE that organization, and could deal with as you pleased.


Incidentally, how do the OS's with the arcane file types get all that
arcana installed in the files? Not even in the CISC-yist  architectures
is it done in hardware is it? What language IS it done in? Certainly not
Fortran --- C? assembly? The point is that any language is joke if it is
severly limited in how it can use files. The "byte" model (or, even 
moreso the bit model) is general. The "record model" is a hindrance -
if it is the ONLY model a language or OS supports. A "record" model
would be OK as a language specific overlay of a basic general model.

But to have it stuffed deep down inside the OS as in VMS and IBM mainframes
is a disaster. 

Doug MCDonald

bomgard@copper.ucs.indiana.edu (Tim Bomgardner) (08/31/90)

In article <BURLEY.90Aug30024743@world.std.com> burley@world.std.com (James C Burley) writes:
>In article <1990Aug29.173235.9405@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:
>
>   This has always bothered me. A file is just a sequence of it, usually
>   organized as bytes - a text file must be in "bytes".
>
>   So how, in standard Fortran, do you dothe exact analog of the most primitive
>   file operations - those expressed in C as flavors of get, put, and seek.
>   It HAS to be possible to do this, as C requires it.
>
>   Doug MCDonald
>
>You don't.  Standard Fortran is built on older and more baroque/primitive
>file storage technology than C/UNIX.  Fortran allows systems to implement
>files as consisting of zero or more fixed-length records, in particular.
>So while, in C, you can (or could if ANSI C and its libraries ran on such
>a system) read and write to arbitrary bytes in the file, in Fortran you
>can't do it without using system calls, tricks, or nonstandard usage.
>
Rubbish.  The answer is right there in front of you.  Set RECL=1,
ACCESS='DIRECT' in the open statement.  For those of you who don't
believe me, I'll be happy to email you fortran implementations of get,
put, and seek that use no tricks whatsoever.

Tim Bomgardner


(sorry about this:)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

achille@cernvax.UUCP (achille petrilli) (08/31/90)

In article <55875@iuvax.cs.indiana.edu> bomgard@copper.ucs.indiana.edu (Tim Bomgardner) writes:
>In article <BURLEY.90Aug30024743@world.std.com> burley@world.std.com (James C Burley) writes:
>>In article <1990Aug29.173235.9405@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:
>>
>>   This has always bothered me. A file is just a sequence of it, usually
>>   organized as bytes - a text file must be in "bytes".
>>		...
>>
>>You don't.  Standard Fortran is built on older and more baroque/primitive
>>file storage technology than C/UNIX.  Fortran allows systems to implement
>>		...
>>
>Rubbish.  The answer is right there in front of you.  Set RECL=1,
>ACCESS='DIRECT' in the open statement.  For those of you who don't
>believe me, I'll be happy to email you fortran implementations of get,
>put, and seek that use no tricks whatsoever.
>
A few comments about this method:
1) Some fortran implementation I know of put control information into the
	DIRECT access file to record the record length (e.g. Apollo's ftn at sr9.x).
	In this case you could generate easily a huge overhead (In the Apollo the
	overhead per record is a couple of bytes, 4 or 8 I don't remember).
2) If I remember correctly, the f77 standard does NOT specify in which units the
	RECL is specified. I just tried to write 3 direct/unformatted records on
	Ultrix with f77 and fort (the VAX/VMS compiler running under Ultrix), each record
	having a RECL=4. I include the source for people who want to try this:

        program main
        open(1,file='/tmp/jkl',
     +  form='unformatted',access='direct',recl=4,status='new')
        write(1,rec=1) 1
        write(1,rec=2) 2
        write(1,rec=3) 3
        close(1)
        end

	f77 produced a 12 bytes output file, fort a 48 bytes one. You can extrapolate
	what your RECL=1 would have produced in the 2 cases.
3) For DIRECT access, you have to specify the record number every record you
	read/write. That's not exactly a byte stream.
4) I'd guess the overhead WRT an equivalent C program should be enormous, given that
	every byte (or longword in the case of VAX fortran) written is treated as a record.

I wouldn't really bend fortran that way to do these sort of things, it's not meant
to do it simply.

Achille Petrilli
Management Information Systems

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (08/31/90)

In article <1990Aug30.132335.20164@ux1.cso.uiuc.edu>, mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:
> I meant that a computer that can't run C is a joke.

Hmm, I used such a machine for years.  It was *lovely*.  Moving to UNIX/C
was a *huge* step down in terms of ease of programming/debugging.

> If it can run C,
> it must be physically possible, and possible by some sort of OS calls.

Well yes, but it doesn't have to be _easy_.  Consider System 370.  That
can run UNIX (Amdahl's UTS, IBM's AIX, even, I've heard, SunOS 4.0).  So
it is physically possible for the computer to run C.  Indeed, there are
several C compilers (SAS/Lattice, NorCroft, Waterloo, IBM) for MVS and CMS.
With files made of fixed length records, the C RTL can "fake" seeking to an
arbitrary byte.  With files made of variable length records, although CMS
allows you to seek to an arbitrary record (nice one!) you have to know
which record, which would mean having to add up the lengths of all the
records in the file starting at the beginning until you found the right one.
Physically possible, yes.  Fast, no.

The interesting thing about the reference to C is that it doesn't actually
put much of a constraint on the operating system at all.  There is no
requirement that a C program be able to read or write every file format
that the operating system supports.  It is quite conceivable that C and
Fortran might have no formats in common.  One method that has been used
by some C compilers is to make C files out of fixed length records, where
the length of each record is 1.  So it can be the case that an operating
system may be able to support C in full conformance with the ANSI standard,
and yet may have additional file formats that Fortran can use but C can't.

> In other words, you are saying Primes are (were?) so deficient that
> they could not even tell how long a file was? 

No, he said they could tell, but only in units of 16-bit words.
Why is that more reprehensible than UNIX not being able to tell
how long a file is in bits?

> I still don't understand why not.  A file IS a sequence of bits.

No.  A file *IS* (part of) a state of a storage device.  That storage
device may have special characteristics (such as IBM's old count-key-data
stuff) that show up in the structure of a file.  There are some bits in
there, sure, but the physical structure of the device may also be relevant.

> What language IS it done in?  Certainly not Fortran --- C? assembly?

Why _not_ Fortran?  When I knew it, PR1MOS _was_ written in Fortran.

> The point is that any language is joke if it is
> severly limited in how it can use files.

Right.  So C must be a joke because it has no built in support for VSAM.
C must be a joke because it cannot address files at the bit level.
C must be a joke because it has no standard record locking facilities.
And so on and so on.

But C can call subroutines to do these things?  Why, so can Fortran!

> But to have it stuffed deep down inside the OS as in VMS and IBM mainframes
> is a disaster. 

VMS supports UNIX-like Stream-LF files, also Mac-like Stream-CR files,
and fixed-length and variable-length records a la IBM, and a couple more.
As for IBM, their operating system was such a disaster that they've
been crying their way to the bank ever since.  (I loathe MVS and CMS
myself.  With respect to MVS, "loathe" doesn't begin to express it.  But
MVS is taking a remarkbly long time to disappear...)

-- 
You can lie with statistics ... but not to a statistician.

whit@milton.u.washington.edu (John Whitmore) (08/31/90)

In article <1990Aug30.132335.20164@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:
>
>>In Fortran, you can "seek" to a given record (if you've specified this
>>desire in the OPEN statement, I think), but not to a given byte.
>>
>
>I still don't understand why not. A file IS a sequence of bits. 

	No, it most certainly is NOT.  A file has a name; where is that name,
in the sequence?  A file has a creation date; where is that date?

	A file is a data structure, nothing less.  

	It MAY have, as its CONTENTS, a sequence of bits, but there is 
NOTHING in the concept of a file that requires sequence.  Nothing.
	Macintosh files, for instance, have header information, an indexed
array of subfiles (the RESOURCE FORK, containing RESOURCES like fonts,
I/O drivers, floating point packages, pictures, sounds, etc.) and a
sequential subfile (the DATA FORK).  There may be significant sequential
information in the DATA fork, but the other two parts (header and
resource fork) have well-defined structure which is not sequential.
There are many useful files which have zero-length DATA fork,
and retrieving information from these files requires asking the
resource manager for the resources, by resource ID and type.
This manager will load the whole resource into memory; there's
no way to just grab a small part (certainly not to select a byte).
To the extent that FORTRAN deals with such files, it does so
with nonstandard constructions.  C is no better in this regard.
	
	There are a number of things that FORTRAN simply doesn't bother
with; RENAMING a file is a good example.  Our FORTRAN code that
needs that capability ends up calling on the C or Basic function
library.  If the structure has parts that you can't manipulate
within the standard, you just have to have nonstandard manipulations,
or do without.

		John Whitmore

burley@world.std.com (James C Burley) (08/31/90)

In article <1990Aug30.132335.20164@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:

   I meant that a computer that can't run C is a joke. If it can run C,
   it must be physically possible, and possible by some sort of OS calls.

If I create a language called "X" with an I/O model expecting files to be
composed of a given number of bits, does that make "jokes" out of all existing
computers that measure file lengths in granularities down to only 8-bit
bytes?  Hardly.

Meanwhile, yes, Fortran programmers can make direct OS calls to do things not
provided directly by the language's I/O specification.

   In other words, you are saying Primes are (were?) so deficient that
   they could not even tell how long a file was? 

Primes had all sorts of problems dealing with C.  C is a language designed
to closely match the machine-code architecture of a particular kind of system;
Primes were designed with another standard in mind (Multics, PL/I).  Of course
they knew how long a file was -- down to a granularity of 16 bits, not 8 bits
as C demands.

I'd like to see contemporary systems that do C well compete against Primes
running demanding PL/I applications using dynamic linking and such.  Prime
50 series machines were built largely around a PL/I model; the OS call
interface tended to be Fortran-oriented, but the OS in general was evolving
towards a PL/I and Multics model during the late 70s and early 80s.

   I still don't understand why not. A file IS a sequence of bits.  Why can't the
   OS simply move those bits (as needed, or all at once, if the address
   space is big enough) into memory and present them to the program?  If 
   you had written the file with some arcane internal organization, you
   would then SEE that organization, and could deal with as you pleased.

The idea of C is to allow the programmer to see the exact internal organization
of the file.  The idea of Fortran is to hide the internal organization of the
file from the programmer to improve portability.  Fortran has a different
design goal than C.  Fortran can run (or run reasonably efficiently) on some
machines that standard C (with I/O libraries) cannot.  C can run more
efficiently on many machines under circumstances than Fortran; and it is
often easier to implement a C compiler system than a Fortran one because you
don't have to implement so many "insulating" levels.  A Fortran compiler
system is easily implemented entirely within the ANSI standard C environment
(I think; I'm doing one now), but the converse is not true.  However, in an
environment where standard C cannot be provided, Fortran can still be
implemented in another language and/or assembler.  Aside from the sheer size
of a Fortran compiler, it is hard to imagine any computer architecture on which
a Fortran system could not be placed (at least a run-time environment, if
compiling could take place on a different machine due to the size of the
compiler).

Most of these statements about Fortran can be applied to C if you forget about
the standard run-time library, especially I/O, but possibly including things
like setjmp/longjmp.  Even then, one must contend with character pointers
(which Fortran does not have) and recursion, which C implementations require
but not all systems can provide (or provide at "base level", i.e. without an
omnipresent extra layer of processing to simulate a different machine).

   Incidentally, how do the OS's with the arcane file types get all that
   arcana installed in the files? Not even in the CISC-yist  architectures
   is it done in hardware is it? What language IS it done in? Certainly not
   Fortran --- C? assembly? The point is that any language is joke if it is
   severly limited in how it can use files. The "byte" model (or, even 
   moreso the bit model) is general. The "record model" is a hindrance -
   if it is the ONLY model a language or OS supports. A "record" model
   would be OK as a language specific overlay of a basic general model.

   But to have it stuffed deep down inside the OS as in VMS and IBM mainframes
   is a disaster. 

   Doug MCDonald

The OSes do whatever they want in assembly, at worst.  PRIMOS was originally
written in Fortran and assembler; yet it could just as well have been
implemented in C, because it never used Fortran I/O statements to do anything,
just system calls, which is the C model.  (I.e. C has no "built in" I/O at all;
it all happens via function calls to the library.  Fortran is more like Pascal
and Basic in the sense that it has built-in I/O statements.)  There is nothing
magic about any of the OS's I/O when you think of it this way.

In fact PRIMOS was more true to the UNIX model of files than VAX/VMS (the
offspring of PDP-11 systems on which C/UNIX was kind of born), because a PRIMOS
file was essentially just a sequence of zero or more 16-bit chunks.  Change
that to 8-bit chunks and you (almost) have the UNIX file system model.  VMS,
on the other hand, offers so many different ways to represent similar file
concepts (stream-LF, stream-CR, stream-CRLF, variable record with CR, var w/o
CR, just to name a few), it can drive you crazy.  C implementations default to
picking the lowest-level format (I think it's stream-LF), which many system
utilities don't support well.

No special hardware support is needed.  At the lowest level, one is simply
writing bits.  Disk subsystems deal primarily in fixed-size blocks (1024 16-bit
words, as I recall, on Primes); so their lowest level of granularity for
storing bits is their block size.  To write anything other than a block of
bits at a module-block bit address on a disk (i.e. anything other than "write
block number x" or "write block numbers x through y"), the OS must first read
the block(s), then overlay the data and rewrite them.  Most OS's I've seen
provide special optimization paths when user software asks to write one or
more complete blocks at block boundaries.  I think early drum-based systems
had blocks more the size of old-style records (72 or 80 bytes or something)
so Fortran evolved from that.  If the Fortran programmer wanted to rewrite
a given portion of the record, let him write the code to first read the entire
record, overlay, then rewrite; the performance implications are clearer that
way.  This was probably the thinking; plus some devices (like line printers)
couldn't deal with partial records at all, and they didn't have the ability
(or the understanding) to do buffering in an I/O library (or maybe they just
didn't have libraries at the time, and generated the I/O instructions directly
at compile time?).

The same goes for C when you want to write an arbitrary number of bits at
an arbitrary bit address in a file.  C is "deficient" in this sense.  (And
of course reading is an issue too, but has less performance reduction.)

8-bit bytes are only magic to you because that is what you're used to.  Some
of us got used to 16-bit, 36-bit, 32-bit, 12-bit, 18-bit, 64-bit, or 24-bit
chunks as the granularity for addressing in memory and/or files.  So 8-bit
bytes is just another value to us.  For C programmers, character addressing
and reading/writing is important: Fortran programmers only got at all excited
about character data around 12 years ago.  Until then, and this is still true
to a large extent, Fortran cared only about numbers and, for efficiency,
grouping sequences of numbers into records.

Early file systems didn't have much info on files; sometimes none.  So a file
simply started at a block address on a disk and went on for so many blocks,
perhaps controlled by an index block(s) or perhaps not if contiguous files
were always used.  Adding something as innocuous as "here's the logical
length of the file" was a big thing; getting the granularity "right" still
hasn't happened.  So PRIMOS' concept of logical length was 16-bit chunks; but
most systems still do it in 8-bit chunks, and that is "wrong" since a new
language might want to use 1-bit chunks.

Your questions and comments suggest to me that you are interested in learning
about operating systems and file systems (their histories, design, and
implementation).  It is hard to sum up this field in response to these issues,
though I've tried to provide some highlights from my own experience.  I
suggest you go out and find a book on implementation of some OS over 10 years
old that isn't UNIX; best if it includes information on why certain design
tradeoffs were made.  That might give you more insight not only on why old
systems weren't built to run C (which should be obvious to anyone), but why
current systems might well not be adequate for future languages that don't
add any real exciting new "features" but simply demand a more general machine
model (like the 1-bit granularity for memory and/or files), and why systems
that are designed for such new languages might well be worse, in terms of
amount of complexity to achieve a given performance, in terms of running
today's C programs.

Further, it might be revealing to think through what kinds of optimizations
are available when doing language-level record-blocking and how they might be
made available to languages (like C) that don't provide it.

Ultimately, the point I wish to make is that, if a given machine isn't well
suited to hosting a standard C environment, the only thing you can say with
certainty about that system is that it isn't well suited to C.  You can't
really say it's generally "deficient".  After all, it might be better at
running Fortran than an equivalent machine that fits C like hand-in-glove!

James Craig Burley, Software Craftsperson    burley@world.std.com

burley@world.std.com (James C Burley) (08/31/90)

In article <55875@iuvax.cs.indiana.edu> bomgard@copper.ucs.indiana.edu (Tim Bomgardner) writes:

   In article <BURLEY.90Aug30024743@world.std.com> burley@world.std.com (James C Burley) writes:
   >In article <1990Aug29.173235.9405@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:
   >
   >   This has always bothered me. A file is just a sequence of it, usually
   >   organized as bytes - a text file must be in "bytes".
   >
   >   So how, in standard Fortran, do you dothe exact analog of the most primitive
   >   file operations - those expressed in C as flavors of get, put, and seek.
   >   It HAS to be possible to do this, as C requires it.
   >
   >You don't.  Standard Fortran is built on older and more baroque/primitive
   >file storage technology than C/UNIX.  Fortran allows systems to implement
   >files as consisting of zero or more fixed-length records, in particular.
   >So while, in C, you can (or could if ANSI C and its libraries ran on such
   >a system) read and write to arbitrary bytes in the file, in Fortran you
   >can't do it without using system calls, tricks, or nonstandard usage.
   >
   Rubbish.  The answer is right there in front of you.  Set RECL=1,
   ACCESS='DIRECT' in the open statement.  For those of you who don't
   believe me, I'll be happy to email you fortran implementations of get,
   put, and seek that use no tricks whatsoever.

   Tim Bomgardner

What you talk about allows you to read/write a file AS IF it was individually
accessible on a character-by-character level.

However, it does NOT guarantee you that you're accessing the contents of the
file itself on that basis.

In fact on most systems on which I've used Fortran, what you get from using
the above technique to write, say, 80 bytes, is 240 bytes or some such thing:
two bytes to specify some kind of record information (length, type, formatting,
whatever) and one byte of data.  Some systems even pad to an even byte, so you
get 320 bytes.

The original questions seemed to be asking about base-level file access on
a byte-by-byte basis, which is either promised by standard C or simply
implemented by nearly everybody.  I haven't been concerned with justifying
"joke" or "deficient" systems by pointing out that they can always simulate
C's byte-level access by providing a higher layer on top of the system's
native layer -- as PRIMOS could (and may) have.  C programmers usually demand
access to the lowest level organization of files and want to use that level
to implement their own organizations.

In other words, I doubt you can consistently use the solution you show above
to implement the exact same behavior as C's byte-level access on the SAME FILE.
Any (or almost any) standard C (with library) implementation can fully
implement all Fortran's I/O formats, but I don't think the opposite is true.

James Craig Burley, Software Craftsperson    burley@world.std.com

mac@harris.cis.ksu.edu (Myron A. Calhoun) (08/31/90)

In article <1990Aug30.132335.20164@ux1.cso.uiuc.edu>, mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:

   [most lines deleted]

> I meant that a computer that can't run C is a joke.

I hope no one is confusing computers (hardware) with systems (software).
--Myron.
--
# Myron A. Calhoun, Ph.D. E.E.; Associate Professor   (913) 539-4448 home
# INTERNET: mac@harris.cis.ksu.edu   (129.130.10.2)         532-6350 work
# UUCP: ...{rutgers, texbell}!ksuvax1!harry!mac             532-7004 fax
# AT&T Mail:  attmail!ksuvax1!mac

lamson@sierra.crd.ge.com (scott h lamson) (08/31/90)

In article <55875@iuvax.cs.indiana.edu> bomgard@copper.ucs.indiana.edu (Tim Bomgardner) writes:

>   From: bomgard@copper.ucs.indiana.edu (Tim Bomgardner)

>   >   So how, in standard Fortran, do you dothe exact analog of the most primitive
>   >   file operations - those expressed in C as flavors of get, put, and seek.
>   >   It HAS to be possible to do this, as C requires it.
>   Rubbish.  The answer is right there in front of you.  Set RECL=1,
>   ACCESS='DIRECT' in the open statement.  For those of you who don't
>   believe me, I'll be happy to email you fortran implementations of get,
>   put, and seek that use no tricks whatsoever.

Not bad.  I have used RECL=# bytes I wanted to write to a file,
                      ACCESS='DIRECT',
                      FORM='UNFORMATTED'

and wrote the files all in one write statement with record # = 1
to produce a binary files readable by a C program, or to produce a
file that was readable by C as part ASCII and part binary  (Stardent's
AVS field files to be specific).  I don't know how universal this is,
but it seems to work on convex, stardent and sun (all unix) without
having any end-of-record or record length stuff tacked on.  The ascii
part of the AVS file was character data, and I needed to put
line-feeds in the character strings explicitly (so that at least is
not too portable).


--
        Scott|  ARPA:      lamson@crd.ge.com
       Lamson|  UUCP:      uunet!crd.ge.com!lamson
(518)387-5795|  UUCP:      uunet!sierra.crd.ge.com!lamson
General Electric Corporate Research and Development

bomgard@copper.ucs.indiana.edu (Tim Bomgardner) (09/01/90)

In article <BURLEY.90Aug31003136@world.std.com> burley@world.std.com
(James C Burley) writes:
>In article <55875@iuvax.cs.indiana.edu> bomgard@copper.ucs.indiana.edu
(Tim Bomgardner) writes:
>
>   In article <BURLEY.90Aug30024743@world.std.com> burley@world.std.com
(James C Burley) writes:
>   >In article <1990Aug29.173235.9405@ux1.cso.uiuc.edu>
mcdonald@aries.scs.uiuc.edu (Doug McDonald) writes:
>   >
>   >   This has always bothered me. A file is just a sequence of it,
usually
>   >   organized as bytes - a text file must be in "bytes".
>   >
>   >   So how, in standard Fortran, do you dothe exact analog of the
most primitive
>   >   file operations - those expressed in C as flavors of get, put,
and seek.>   >   It HAS to be possible to do this, as C requires it.
>   >
>   >You don't.  Standard Fortran is built on older and more
baroque/primitive
>   >file storage technology than C/UNIX.  Fortran allows systems to
implement
>   >files as consisting of zero or more fixed-length records, in
particular.
>   >So while, in C, you can (or could if ANSI C and its libraries ran
on such
>   >a system) read and write to arbitrary bytes in the file, in Fortran
you
>   >can't do it without using system calls, tricks, or nonstandard
usage.
>   >
>   Rubbish.  The answer is right there in front of you.  Set RECL=1,
>   ACCESS='DIRECT' in the open statement.  For those of you who don't
>   believe me, I'll be happy to email you fortran implementations of
get,
>   put, and seek that use no tricks whatsoever.
>
>   Tim Bomgardner
>

>What you talk about allows you to read/write a file AS IF it was
individually
>accessible on a character-by-character level.

Accessing a file AS IF it was individually accessible on a char-by-char
level is the ONLY way a (disk) file CAN be accessed.  Files are accessed
by blocks, and SOME layer of software SOMEWHERE peels off the chars for
you one at a time.  It may be in the operating system (unix), or in
another dimension (VMS), or in the language runtime library.

>However, it does NOT guarantee you that you're accessing the contents
of the
>file itself on that basis.

I guarantee you're NOT accessing the (disk) file on char-by-char basis.

>In fact on most systems on which I've used Fortran, what you get from
using
>the above technique to write, say, 80 bytes, is 240 bytes or some such
thing:
>two bytes to specify some kind of record information (length, type,
formatting,>whatever) and one byte of data.  Some systems even pad to an
even byte, so you
>get 320 bytes.

Like you said, it depends on the system.  My system stores 80 bytes in
80 bytes.  How you open the file will also affect this.  See my other
post containing the promised source code.

>The original questions seemed to be asking about base-level file access
on
>a byte-by-byte basis, which is either promised by standard C or simply
>implemented by nearly everybody.  I haven't been concerned with
justifying
>"joke" or "deficient" systems by pointing out that they can always
simulate
>C's byte-level access by providing a higher layer on top of the
system's
>native layer -- as PRIMOS could (and may) have.  C programmers usually
demand
>access to the lowest level organization of files and want to use that
level
>to implement their own organizations.

I draw a finer distinction between the language and the OS.  The lowest
level of (disk) file organization is the block, and that's usually NOT
what C (or any other) programmers want.  C's "byte-level access" is
itself a "higher layer on the system's native layer."

>In other words, I doubt you can consistently use the solution you show
above
>to implement the exact same behavior as C's byte-level access on the
SAME FILE.>Any (or almost any) standard C (with library) implementation
can fully
>implement all Fortran's I/O formats, but I don't think the opposite is
true.

Well, sure, since C doesn't HAVE any I/O formats.  The library is simply
an interface to the Unix (style) file system.  In any case, take a look
at my other post and tell me what you think.

>James Craig Burley, Software Craftsperson    burley@world.std.com

Tim Bomgardner, Software Contortionist

(sorry about this:)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

bomgard@copper.ucs.indiana.edu (Tim Bomgardner) (09/01/90)

Wow.  I got a lot more responses to that post than I expected.  I'm
going to simply include the code here for anyone who wants it.  In
general, no, I don't know if it works on your particular machine, but
it should.  One writer claimed it would not work on VAX/VMS because
a VMS record length (RECL) is 4.  This is only partly true.  RECL 
denotes record length in processor dependent units for _unformatted_
files (4 on the VAX), but in _characters_ for formatted files.  I 
erroneously left FORM='FORMATTED' out of the list of open statement 
parameters because it doesn't matter on my system.

This code was compiled using Ryan-McFarland Fortran on a 386 PC running
DOS 3.3.  As far as I can tell, it works perfectly.  I uploaded it to
a VAX/VMS system, where it worked as is with the following caveat.
The file system (which insists on doing more for you than you may
want or need) created the file with the "Fortran carriage control"
attribute set.  This made it impossible to TYPE the output file.
Setting CARRIAGECONTROL='NONE' in the open statement cured this
problem.  In practical terms, this means the program is not portable.
We can argue about whether this is a Fortran problem or a problem
with VMS's file system philosophy.

c======================================================================
c The following (stripped down) routines provide a simple character-
c oriented file i/o facility modeled after C's getc, putc, etc.
c They are intended for illustrative purposes only.  They require 
c direct access to the file; if the operating system won't allow it, 
c that's not Fortran's fault.
c======================================================================
c
c Open a file in a specified mode.  Only 'r' mode is implemented
c here.  Only one file at a time can be opened.  No error checking is 
c performed.
c
      integer function fopen(filename, mode)
      character filename*(*), mode*(*)
      common /cio/ fileptr
      integer fileptr

      lun = 99
      open(unit=lun, file=filename, status='old', access='direct',
     &     form='formatted', recl=1)
      fileptr = 0
      fopen = lun
      return
      end

c======================================================================
c
c Position the file pointer.  Only C's SEEK_SET (beginning of file) is
c implemented.  No error checking is performed.
c
      integer function fseek(lun, offset, whence)
      integer lun, offset, whence
      common /cio/ fileptr
      integer fileptr

      fileptr = 0
      fseek = 0
      return
      end

c======================================================================
c
c Get a character from an open file.  No error checking is performed.
c
      integer function getc(lun)
      integer lun
      common /cio/ fileptr
      integer fileptr
      character*1 khar

      read(unit=lun, fmt=7, rec=fileptr) khar
7     format(a)
      fileptr = fileptr + 1
      getc = ichar(khar)
      return
      end

c======================================================================
c
c Write a character to an open file.  No error checking is performed.
c
      integer function putc(khar, lun)
      character*1 khar
      integer lun
      common /cio/ fileptr
      integer fileptr

      write(unit=lun, fmt=7, rec=fileptr) khar
7     format(a)
      fileptr = fileptr + 1
      putc = ichar(khar)
      return
      end

burley@world.std.com (James C Burley) (09/01/90)

I think this discussion kind of fragmented from what I thought the original
intention was.  I perceived the original issue as whether systems that couldn't
"natively" represent files in a manner perfectly suited to C's standard I/O
library were a "joke" and/or "deficient".  So a system (PRIMOS) that could
only remember the # of 16-bit words, rather than 8-bit bytes, was deficient.

Sure, the C implementation could throw in an extra 16-bit word at the end of
every file containing an indicator of whether the preceding word contained one
or two bytes.

But even Fortran I/O COULD implement C's low-level approach by throwing each
character in a separate record, thus incurring the huge overhead of transacting
Fortran records just to deal with low-level bytes.  So your suggestion about
possible solutions is fine in some ways, especially on systems where it truly
writes only one byte each time.

But that won't work on all, or perhaps even many, systems; how would PRIMOS
track the number of records written if it only wrote one byte per one-byte
record, given that it had only a count of 16-bit words available?  Thus EOF
would be potentially inaccurate.

Agreed that ultimately we're all talking about gathering bits into blocks
into characters and back again, but to keep the discussion on track, I think
it is worthwhile to focus on the issue of what is native, or natural, for
a file system.  PRIMOS could (and does) implement per-record or per-file
information in the data portion of a file that helps it cope with Fortran I/O.
Thus one cannot use Fortran I/O to read a file in its raw, byte-by-byte,
form; a file written by a C program might thus be unreadable, unless that
C program was specifically designed for the task (and hence is not portable).

Obviously one is not accessing the disk file itself on a char-by-char
basis; I was pointing out that using RECL=1 does not, according to the
Fortran standard and many implementations as well, give you byte-by-byte
access to the lowest level (normally permitted user programs) of access
to a file's data.  Using C's fputc, fgetc, and so on, also does not make
such guarantees, but many more systems grant you that low-level access,
and historically, I believe, a larger percentage of C programs have been
written as general utilities (read/write files to be accessed by other
programs written in other languages) than Fortran programs.

When you say "The lowest level of (disk) file organization is the block, and
that's usually NOT what C (or any other) programmers want.  C's 'byte-level
access' is itself a 'higher layer on the system's native layer.'", I feel
the need to point out that the issue concerned systems whose OS's imposed
a HIGHER layer on the disk file than desired by a particular LANGUAGE.  So
I agree there is a distinction between the language and the OS: the lowest
layer of access provided by an OS is the lowest layer of access that can
be provided by a particular language running on that OS while using "natural"
(i.e. no extra coding) access.

So operating/file systems written with lowest-layer access being sufficient
for contemporary languages like Fortran, PL/I, and Pascal, should not be
considered "jokes" and "deficient" just because some new language, C, comes
around and asks for yet a lower layer, requiring changes to file system code,
on-disk file format changes, and resulting upheavals at customer sites having
to run some kind of conversion program on all their disks.

And this scenario would apply if my made-up language "X" came along and
became popular and required bit-layer access to files (so a file could
contain, say, exactly 3 bits), and its zealots claimed any system that didn't
support that in native mode was a "joke" and "deficient".  In fact, this
scenario would, to my knowledge, apply to ALL commonly used systems today.

Somebody else correctly pointed out earlier in this discussion that even
the view put forth, which I agreed with, that a file is simply a string
of bits, is overly constraining.  I defer to that more generally correct
point of view: just because a Macintosh file has both a data fork and a
resource fork does not mean it is NOT a file in any useful sense of the
word.  Yet one cannot view it in its natural form as a string of bits;
perhaps two strings, but even then, one string really contains resources,
not bits.  The internal representations of the resources, and the way the
resources themselves are hung together, are generally of no concern to the
ordinary users of the file (including the applications that define the file
and manage its resources).  Obviously, C's view of files is inadequate in
this case, and C programmers must resort (much like Fortran programmers
naturally do) to calling on functions that impose a "higher" organization
on a file than simply a stream of bytes (or bits).

James Craig Burley, Software Craftsperson    burley@world.std.com

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (09/02/90)

In article <56017@iuvax.cs.indiana.edu>, bomgard@copper.ucs.indiana.edu (Tim Bomgardner) writes:
> c Position the file pointer.  Only C's SEEK_SET (beginning of file) is
> c implemented.  No error checking is performed.
> c
>       integer function fseek(lun, offset, whence)
>       integer lun, offset, whence
>       common /cio/ fileptr
>       integer fileptr
> 
>       fileptr = 0
>       fseek = 0
>       return
>       end

This is always equivalent to rewind(), which is hardly what
we were expecting!  A slightly better implementation would be

	integer function fseek(lun, offset, whence)
	    integer lun, offset, whence
	    integer filpos
	    common /cio/ filpos
	    integer temp

	    if (whence .eq. 0) then
C		absolute positioning
		temp = offset
	    else if (whence .eq. 1) then
C		relative positioning
		temp = filpos + offset
	    else
C		relative to end (not supported) or invalid
		temp = -1
	    end if
	    if (temp .ge. 0) then
		filpos = temp
		fseek = 0
	    else
C		error
		fseek = -1
	    end if
	    return
	end

On the other hand, aren't records numbered from 1?
The cleanest way to handle that would be in getc() and putc().

-- 
You can lie with statistics ... but not to a statistician.

jf@threel.co.uk (John Fisher) (09/03/90)

In article <1990Aug30.132335.20164@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu
(Doug McDonald) writes:
 
> I meant that a computer that can't run C is a joke.

I get really worried about remarks like this.   People just come popping
along, ignorant of the whole history of computing and of everything outside
their C/UNIX ghetto;  ignorant too, of developments like functional languages
and of the whole realm of what computers are actually *used*for*, and make
remarks like this, and everybody laughs and says how very iconoclastic and
progressive it is.

The trouble is, it's evidence of a closed, rigid and dogmatic frame of
mind.   And in twenty or thirty years, when these folk are in charge of
the whole computer industry, anybody who comes along with a new idea is
going to have a hard time of it.

No, a computer that can't run C is not necessarily a joke, any more than a
kitchen appliance that can't whisk eggs is a joke.   A computer is either
good or bad at the job is was designed to do.   That's all.   There are no
transcendentally determined criteria for what makes a good computer. 

--John

mcdonald@aries.scs.uiuc.edu (Doug McDonald) (09/05/90)

In article <26e23059@ThreeL.co.uk> jf@threel.co.uk (John Fisher) writes:
>In article <1990Aug30.132335.20164@ux1.cso.uiuc.edu> mcdonald@aries.scs.uiuc.edu
>(Doug McDonald) writes:
> 
>> I meant that a computer that can't run C is a joke.
>
>I get really worried about remarks like this.   People just come popping
>along, ignorant of the whole history of computing and of everything outside
>their C/UNIX ghetto; 

Sorry, bub, I'm not a member of that getto. I'm a member of, in rough
chronological order, the gettos of the IBM 1620 and 704, the
IBM 7094, the IBM 360, the Sigma (later Xerox) 5, the PDP8,
the PDP11 (RT11), the PDP 10, the CDC Cyber 175, the Illiac IV,
the VAX/VMS, the IBM-PC, and then at the tail end, Unix.   

>ignorant too, of developments like functional languages
>and of the whole realm of what computers are actually *used*for*, and make
>remarks like this, and everybody laughs and says how very iconoclastic and
>progressive it is.
>
I am aware of what computers are used for. I actually USE them!!!
I'm even aware of how COBOL uses records. I just contend that 
the records belong in the COBOL, not in the OS itself.  

>The trouble is, it's evidence of a closed, rigid and dogmatic frame of
>mind.   And in twenty or thirty years, when these folk are in charge of
>the whole computer industry, anybody who comes along with a new idea is
>going to have a hard time of it.
I doubt it, if they have a better idea. The rigidified record-oriented
mindset ruled for a long while (outside if the mini-computer real-time
world) and then it now seems that it is being superceded.

>
>No, a computer that can't run C is not necessarily a joke, 
I contend that it is. Remember that X3J11 bent over backwards to
accomodate things like special Lisp computers.


I was always befuddled by the concept of "records". Even on the 
7094 I found them odd. And on the 360, both odd and supremely irritating.
I honestly think 360-style JCL was the stupidist idea I have ever seen
on a computer. VMS was a big improvement over that, and Unix over VMS.

Doug McDonald

jerry@violet.berkeley.edu (Jerry Berkman) (09/13/90)

In article <46016@masscomp.ccur.com> andyo@masscomp.UUCP (Andy Oram) writes:
>Questions about standard Fortran 77, from ravi@earth.ce.nwu.edu (Ravi Sinha):
>
>> (i)  If you open an OLD file using status=UNKNOWN and write
>>      less no. of lines to it than is already there, should the
>>      new file have only the stuff written when it was opened
>>      last.  Or should the write statement just overwrite
>>      the old file, thereby leaving rest of the old contents
>>      untouched.
>
>This depends on whether you use ACCESS='SEQUENTIAL' or ACCESS='DIRECT'.
>
>Sequential access positions the file at the beginning (the standard seems to
>leave some leeway here, but paragraph 12.2.4.1 says that files are opened at
>the first record).  Furthermore, sequenitial access causes each write to be
>last record (paragraph 12.9.4.1).  Add it up and you can say "bye-bye old
>data."

The standard does not state, in general, whether files are opened at
the beginning or end.

For many years, the VAX UNIX f77 opened files at their end.  The logic
was that if you wanted to start at the beginning, you could issue a
'rewind'.  However, if the file was opened at the beginning, there
would be no easy way to get to the end.  This caused endless confusion
among users.   In early 1983, a number of us managed to convince the
BSD people to change the library to open disk files at their beginning.
Even several years later, I heard of other system who opened files
at their end.

12.2.4.1 says files discusses files which have both direct access
and sequential access in the set of allowed access methods, which
is not all files.

Even though I would love the Fortran standard to specify opening
disk files at their beginning, the Fortran standard makes no
distinction between types of files.  Thus it could only say
all files are opened at their beginning.  This would be a mess
on tapes.  What if I have positioned the tape at the 10,000 record
of the 30th file on the tape.  What would open at the beginning
mean?

	- Jerry Berkman, U.C. Berkeley, (415)642-4804
	  jerry@violet.berkeley.edu

(normal disclaimers: opinions are my own, not my employers, etc.)

staff@cadlab.sublink.ORG (Alex Martelli) (09/14/90)

jerry@violet.berkeley.edu (Jerry Berkman) writes:
	...
>Even several years later, I heard of other system who opened files
>at their end.
	...
Even TODAY, the IBM XL Fortran compiler on their new RISC-6000 
workstation OPEN's the file at end.  It does have an escape clause,
though - if the first operation right after an OPEN is a READ, then
an "implicit" rewind is performed.  However, OPEN then WRITE will
"append" the record, while on most other systems the first record
is being over-written.  Pity the standard could not be more rigid on
this point, it would help portability.  What does Fortran-90 say?

-- 
Alex Martelli - CAD.LAB s.p.a., v. Stalingrado 45, Bologna, Italia
Email: (work:) staff@cadlab.sublink.org, (home:) alex@am.sublink.org
Phone: (work:) ++39 (51) 371099, (home:) ++39 (51) 250434; 
Fax: ++39 (51) 366964 (work only; any time of day or night).

sjc@key.COM (Steve Correll) (09/25/90)

In article <271@cadlab.sublink.ORG>, staff@cadlab.sublink.ORG (Alex Martelli) writes:
> Even TODAY, the IBM XL Fortran compiler on their new RISC-6000 
> workstation OPEN's the file at end...What does Fortran-90 say?

Fortran 90 permits you to specify POSITION='REWIND', POSITION='APPEND', or
POSITION='ASIS' in the OPEN statement. The latter leaves the file position
unchanged if the file exists and was already connected.
-- 
sjc@key.com or ...{sun,pyramid}!pacbell!key!sjc 		Steve Correll

hirchert@harriett.ncsa.uiuc.edu (Kurt Hirchert) (10/02/90)

In article <2144@key.COM> sjc@key.COM (Steve Correll) writes:
>Fortran 90 permits you to specify POSITION='REWIND', POSITION='APPEND', or
>POSITION='ASIS' in the OPEN statement. The latter leaves the file position
>unchanged if the file exists and was already connected.

Steve's description of POSITION='ASIS' is not entire correct.  ASIS provides
processor-dependent positioning.  I.e., it provides what FORTRAN 77 provided
(although the FORTRAN 77 standard was not as explicit about this).  What might
this mean?
o  In the simplest case, ASIS might mean the same as APPEND (as in the original
   f77 implementation of FORTRAN 77) or REWIND (as is the default on most
   systems not based on f77).
o  ASIS might mean APPEND or REWIND based on some external system information.
   For example, users of OS/360 and its successors could use JCL to choose
   between adding to the end of an existing file (DISP=MOD) and overwriting
   an existing file (DISP=OLD).  ASIS could be interpreted as taking the
   positioning from the DISP field of the JCL.
o  ASIS might mean the current physical positioning of a device such as a
   magnetic tape drive.
o  ASIS might mean a position retained by the Fortran I/O library for the
   duration of the execution of a Fortran program.  (I think this is what
   Steve was describing.)
o  ASIS might mean a position retained by the I/O library or the system for
   a period of time longer than the execution of a single program.

In other words, POSITION='ASIS' allows the Fortran processor to provide access
to whatever extended positioning capabilities a system may provide, but the
existence of POSITION='ASIS' should not be construed as a requirement that
such extended positioning capabilities must be provided.
--
Kurt W. Hirchert     hirchert@ncsa.uiuc.edu
National Center for Supercomputing Applications

sjc@key.COM (Steve Correll) (10/03/90)

In article <1990Oct1.174040.16208@ux1.cso.uiuc.edu>, hirchert@harriett.ncsa.uiuc.edu (Kurt Hirchert) writes:
> In article <2144@key.COM> sjc@key.COM (Steve Correll) writes:
> >Fortran 90 permits you to specify POSITION='REWIND', POSITION='APPEND', or
> >POSITION='ASIS' in the OPEN statement. The latter leaves the file position
> >unchanged if the file exists and was already connected.
> 
> Steve's description of POSITION='ASIS' is not entire correct.  ASIS provides
> processor-dependent positioning.  I.e., it provides what FORTRAN 77 provided
> ...

My description had better be correct, because the last ten words of it are
copied directly from lines 31 and 32 of section 9.3.4.7 of the S8.115 draft
standard! ASIS behaves as I described when the file was already connected, but
behaves as Kurt described (i.e. processor-dependent, like Fortran 77) when the
file was not connected.

Kurt's case is admittedly the more common. What is my case for? You can use
OPEN a second time on an already-connected file/unit pair so as to change the
attributes BLANK=, PAD=, or DELIM=. When you do, the default is
POSITION='ASIS', which is defined (mercifully enough) not to mess up the file
position in the process.

Rather than multiplexing two different meanings onto ASIS, it might be less
confusing to have two different attributes ASIS and PROCESSORDEPENDENT, but
it's probably good enough as is (sic).
-- 
sjc@key.com or ...{sun,pyramid}!pacbell!key!sjc 		Steve Correll

ndeng@euler.Berkeley.EDU (10/03/90)

In article <2144@key.COM> sjc@key.COM (Steve Correll) writes:

 >Fortran 90 permits you to specify POSITION='REWIND', POSITION='APPEND', or
 >POSITION='ASIS' in the OPEN statement. The latter leaves the file position
 >unchanged if the file exists and was already connected.
                                       ^^^^^^^ ^^^^^^^^^
Correct me if I am wrong. But how could one CONNECT to a file before OPEN it?
 
>sjc@key.com or ...{sun,pyramid}!pacbell!key!sjc 		Steve Correll

Mike 
ndeng@euler.berkeley.edu

tholen@uhccux.uhcc.Hawaii.Edu (David Tholen) (10/03/90)

In article <28454@pasteur.Berkeley.EDU>, ndeng@euler.Berkeley.EDU writes:
                                      
> Correct me if I am wrong. But how could one CONNECT to a file before OPEN it?
  
Simple.  OPEN it twice without CLOSEing it in between.  The file will be
connected before the second OPEN.  Many systems preconnect some or all units.
For example, many compilers do not require you to OPEN the keyboard to
accept input or OPEN the screen (or printer) to print output.  UNIX systems
preconnect logical units 0, 5, and 6, to standard error, standard input, and
standard output, respectively.  Some UNIX FORTRANS preconnect all other units
to files with names 'fort.N', where N corresponds to the logical unit number.
Thus if you WRITE to a logical unit number that hasn't been explicitly
OPENed, the output will go to the file 'fort.N'.  Any file that has been
preconnected will be connected at the time of an explicit OPEN statement.

So why would somebody want to OPEN a file that is already OPENed?  Simply to
change the connection properties, such as BLANK='NULL' to BLANK='ZERO'.

hirchert@harriett.ncsa.uiuc.edu (Kurt Hirchert) (10/03/90)

In article <2153@key.COM> sjc@key.COM (Steve Correll) writes:
>In article <1990Oct1.174040.16208@ux1.cso.uiuc.edu>, hirchert@harriett.ncsa.uiuc.edu (Kurt Hirchert) writes:
>> In article <2144@key.COM> sjc@key.COM (Steve Correll) writes:
>> >Fortran 90 permits you to specify POSITION='REWIND', POSITION='APPEND', or
>> >POSITION='ASIS' in the OPEN statement. The latter leaves the file position
>> >unchanged if the file exists and was already connected.
>> 
>> Steve's description of POSITION='ASIS' is not entire correct.  ASIS provides
>> processor-dependent positioning.  I.e., it provides what FORTRAN 77 provided
>> ...
>
>My description had better be correct, because the last ten words of it are
>copied directly from lines 31 and 32 of section 9.3.4.7 of the S8.115 draft
>standard! ASIS behaves as I described when the file was already connected, but
>behaves as Kurt described (i.e. processor-dependent, like Fortran 77) when the
>file was not connected.

If those are literally the words in /S8.115 (I don't have my copy handy to
check), then I have a bone to pick with the people who did the editorial
work on that section.  The use of the past tense ("was connected") would
suggest that this is intended to apply to the case of a program opening a file,
reading part of it, closing it, and then opening it again later.  There was
never any intent of requiring positioning to be retained on files that are
closed, only on files that are currently connected (present tense!).
--
Kurt W. Hirchert     hirchert@ncsa.uiuc.edu
National Center for Supercomputing Applications

karl@uts.amdahl.com (Karl Rowley) (10/05/90)

In article <28454@pasteur.Berkeley.EDU> ndeng@euler.Berkeley.EDU.UUCP () writes:
>In article <2144@key.COM> sjc@key.COM (Steve Correll) writes:
>
> >Fortran 90 permits you to specify POSITION='REWIND', POSITION='APPEND', or
> >POSITION='ASIS' in the OPEN statement. The latter leaves the file position
> >unchanged if the file exists and was already connected.
>                                       ^^^^^^^ ^^^^^^^^^
>Correct me if I am wrong. But how could one CONNECT to a file before OPEN it?
> 

Look at COS (the Cray Operating System) as an example.  A dataset has a 
position (like a tape on a tape drive) that it retains between the execution
of various programs.  The "REWIND" statement can be used in the job control
language to rewind a dataset outside of a program.  Datasets are "connected",
positioned, and even assigned to particular Fortran unit numbers before 
an application is run.

The same basic model holds true for VSOS on the Cyber 205 (and I suspect
for some other systems too).  Cray and Cyber experts please forgive me
if I have messed up any details here.

Does the Fortran standard say what the default position of a file is when
it is OPENed?  I think this is vendor-dependent.

There are other models for handling files that differ from what Unix
provides -- Fortran attempts to accomodate them.

				Karl Rowley
				Amdahl Corp.
				Santa Clara, California
				karl@uts.amdahl.com
				...!ames!amdahl!karl