TOPEN(3F)TOPEN(3F)NAME
topen, tclose, tread, twrite, trewin, tskipf, tstate - FORTRAN tape I/O
(OBSOLETE)
NOTICE: OBSOLETE
This man page is provided for historical reasons only. This functional‐
ity is not implemented in Fortran 95 (f95).
OVERVIEW
You can use these functions to manipulate magnetic tapes from FORTRAN.
On any one unit, do not mix these functions with standard FORTRAN I/O.
You must first use topen() to open a tape logical unit, tlu, for the
specified device. Then you do all other operations on the specified
tlu. tlu has no relationship at all to any normal FORTRAN logical
unit.
Before you use one of these functions, its name must be in an INTEGER
statement.
DESCRIPTIONtopen — Associate a device name with a tape logical unit, that is, does
not move tape.
Syntax: n = topen( tlu, devnam, islabeled )
tlu is the tape logical unit. It is an integer input argument and
must be in the range 0 to 7.
islabeled indicates whether the tape is labeled. It is a logical
input argument.
If you know the tape contains a tape label, then you set isla‐
beled to true. A label is the first file on the tape.
n is the return value: n=0 indicates OK. n<0 indicates an error.
See perror(3f) for details.
Example: Open a 1/4" tape file:
CHARACTER devnam*9 / '/dev/rst0' /
INTEGER n / 0 /, tlu / 1 /, topen
LOGICAL islabeled / .false. /
n = topen ( tlu, devnam, islabeled )
IF ( n .LT. 0 ) STOP "topen: cannot open"
WRITE(*,'("topen ok:", 2I3, 1X, A10)') n, tlu, devnam
END
The output is:
topen ok: 0 1 /dev/rst0
tclose — Write EOF and close tape device channel and remove its associ‐
ation with tlu.
Syntax: n = tclose ( tlu )
tlu is the tape logical unit. It is an integer input argument in
range 0 to 7.
n is the integer return value. n=0 indicates OK. n<0 indicates
an error.
tclose() places an EOF marker immediately after the current loca‐
tion of the unit pointer, and then closes the unit. So if you
trewin() a unit before you use tclose() it, its contents are
thrown away.
Example: Close an opened 1/4" tape file:
CHARACTER devnam*9 / '/dev/rst0' /
INTEGER n / 0 /, tlu / 1 /, tclose, topen
LOGICAL islabeled / .false. /
n = topen ( tlu, devnam, islabeled )
n = tclose ( tlu )
IF ( n .LT. 0 ) STOP "tclose: cannot close"
WRITE(*, '("tclose ok:", 2I3, 1X, A10)') n, tlu, devnam
END
The output is:
tclose ok: 0 1 /dev/rst0
twrite — Write the next physical record from buffer to tape.
Syntax: n = twrite ( tlu, buffer )
tlu is the tape logical unit. It is an integer input argument and
must be in the range 0 to 7.
buffer must be of type character and must be sized at a multiple
of 512.
n is the return value.
n >0 indicates OK, and n = number of bytes written.
n =0 indicates end of tape
n <0 indicates an error.
The physical record length is the size of buffer.
Example: Write a two-record file:
CHARACTER devnam*9 / '/dev/rst0' /, rec1*512 / "abcd" /
CHARACTER rec2*512 / "wxyz" /
INTEGER n / 0 /, tlu / 1 /, tclose, topen, twrite
LOGICAL islabeled / .false. /
n = topen ( tlu, devnam, islabeled )
IF ( n .LT. 0 ) STOP "topen: cannot open"
n = twrite ( tlu, rec1 )
IF ( n .LT. 0 ) STOP "twrite: cannot write 1"
n = twrite ( tlu, rec2 )
IF ( n .LT. 0 ) STOP "twrite: cannot write 2"
WRITE(*, '("twrite ok:", 2I4, 1X, A10)') n, tlu, devnam
END
The output is:
twrite ok: 512 1 /dev/rst0
tread — Read next physical record from tape into buffer. If at EOF or
EOT, return; do not read tape.
Syntax: n = tread ( tlu, buffer )
tlu is the tape logical unit. It is an integer input argument,
and must be in the range 0 to 7.
buffer must be of type character and must be sized at a multiple
of 512.
The size of buffer should be large enough to hold the largest
physical record to be read.
n is the return value. n <0 indicates an error. n =0 indicates
the end-of-file.
If n >0, then n is the actual number of bytes read.
Example: Read the first record of the file written above.
CHARACTER devnam*9 / '/dev/rst0' /, onerec*512 / " " /
INTEGER n / 0 /, tlu / 1 /, topen, tread
LOGICAL islabeled / .false. /
n = topen ( tlu, devnam, islabeled )
IF ( n .LT. 0 ) STOP "topen: cannot open"
n = tread ( tlu, onerec )
IF ( n .LT. 0 ) STOP "tread: cannot read"
WRITE(*,'("tread ok:", 2I4, 1X, A10)') n, tlu, devnam
WRITE(*,'( A4)') onerec
END
The output is:
tread ok: 512 1 /dev/rst0
abcd
trewin — Rewind the tape to the beginning of the first data file.
Syntax: n = trewin ( tlu )
tlu is the tape logical unit. It is an integer input argument,
and must be in the range 0 to 7.
n is the return value. n =0 indicates OK. n <0 indicates an
error.
If the tape is labeled (see topen above), then the label is
skipped over after rewinding.
Example 1: Typical fragment:
CHARACTER devnam*9 / '/dev/rst0' /
INTEGER n /0/, tlu /1/, tclose, topen, tread, trewin
...
n = trewin ( tlu )
IF ( n .LT. 0 ) STOP "trewin: cannot rewind"
WRITE(*, '("trewin ok:", 2I4, 1X, A10)') n, tlu, devnam
...
END
Example 2: In a two-record file, try to read 3 records, then rewind and
read 1 record.
CHARACTER devnam*9 / '/dev/rst0' /, onerec*512 / " " /
INTEGER n / 0 /, r, tlu / 1 /, topen, tread, trewin
LOGICAL islabeled / .false. /
n = topen ( tlu, devnam, islabeled )
IF ( n .LT. 0 ) STOP "topen: cannot open"
DO r = 1, 3
n = tread ( tlu, onerec )
WRITE(*,'(1X, I2, 1X, A4)') r, onerec
END DO
n = trewin ( tlu )
IF ( n .LT. 0 ) STOP "trewin: cannot rewind"
WRITE(*, '("trewin ok:" 2I4, 1X, A10)') n, tlu, devnam
n = tread ( tlu, onerec )
IF ( n .LT. 0 ) STOP "tread: cannot read after rewind"
WRITE(*,'(A4)') onerec
END
The output is:
1 abcd
2 wxyz
3 wxyz
trewin ok: 0 1 /dev/rst0
abcd
tskipf — Skip forward over files or records, and reset EOF status. It
does not skip backward.
Syntax: n = tskipf( tlu, nf, nr )
tlu is the tape logical unit. It is an integer input argument.
It must be in the range 0 to 7.
nf is the integer number of end-of-file marks to skip over first.
nr is the integer number of physical records to skip over after
skipping files.
n is the integer return value. n=0 indicates OK. n<0 indicates
an error.
First, it skips nf end-of-file marks. Then it skips over nr phys‐
ical records. If the current file is at EOF, this counts as one
file to skip. This function also resets the EOF status. See
tstate below.
Example: Typical fragment (\m skip four files and then skip one record.
See also tstate, second example.
INTEGER nfiles / 4 /, nrecords / 1 /, tskipf, tlu / 1 /
...
n = tskipf( tlu, nfiles, nrecords )
IF ( n .LT. 0 ) STOP "tskipf: cannot skip"
tstate — Determine the logical state of the tape I/O channel.
Syntax: n = tstate ( tlu, fileno, recno, errf, eoff, eotf, tcsr )
tlu is the tape logical unit. It is an integer input argument,
and must be in the range 0 to 7.
fileno is an integer output argument indicating the current file
number.
recno is an integer output argument indicating the current record
number.
errf is a logical output argument indicating an error occurred.
eoff is a logical output argument indicating the current file is
at EOF.
While eoff is true, you cannot read from that tlu. You can set
this EOF status flag to false by using tskipf() to skip one file
and zero records: n=tskipf( tlu, 1, 0 ). Then you can read any
valid record that follows.
eotf is a logical output argument indicating the tape has reached
logical end-of-tape.
EOT is indicated by an empty file, often referred to as a double
EOF mark. You cannot read past EOT, but you can write past EOT.
tcsr is an integer output argument for hardware errors on the
device. It contains the tape drive control status register. If
the error is software, then tcsr is returned as zero. The values
returned in this status register vary grossly with the brand and
size of tape drive. For details, see st(4s).
Example: Write 3 files of 2 records each. The next example uses
tstate() to trap eof and get at all files:
CHARACTER devnam*10 / '/dev/nrst0' /,
& f0rec1*512 / "eins" /, f0rec2*512 / "zwei" /,
& f1rec1*512 / "ichi" /, f1rec2*512 / "ni__" /,
& f2rec1*512 / "un__" /, f2rec2*512 / "deux" /
INTEGER n / 0 /, tlu / 1 /, tclose, topen, trewin, twrite
LOGICAL islabeled / .false. /
n = topen ( tlu, devnam, islabeled )
n = trewin ( tlu )
n = twrite ( tlu, f0rec1 )
n = twrite ( tlu, f0rec2 )
n = tclose ( tlu )
n = topen ( tlu, devnam, islabeled )
n = twrite ( tlu, f1rec1 )
n = twrite ( tlu, f1rec2 )
n = tclose ( tlu )
n = topen ( tlu, devnam, islabeled )
n = twrite ( tlu, f2rec1 )
n = twrite ( tlu, f2rec2 )
n = tclose ( tlu )
END
Example: Use tstate() in a loop that reads all records of the three
files written in the previous example:
CHARACTER devnam*10 / '/dev/nrst0' /, onerec*512 / " " /
INTEGER f, n / 0 /, tlu / 1 /, tcsr, topen, tread, trewin
INTEGER tskipf, tstate
LOGICAL errf, eoff, eotf, islabeled / .false. /
n = topen ( tlu, devnam, islabeled )
n = tstate ( tlu, fn, rn, errf, eoff, eotf, tcsr )
WRITE(*,1) 'open:', fn, rn, errf, eoff, eotf, tcsr
1 FORMAT(1X, A10, 2I2, 1X, 1L, 1X, 1L,1X, 1L, 1X, I2 )
2 FORMAT(1X, A10, 1X, A4, 1X, 2I2, 1X, 1L, 1X, 1L,1X, 1L, 1X, I2)
n = trewin ( tlu )
n = tstate ( tlu, fn, rn, errf, eoff, eotf, tcsr )
WRITE(*,1) 'rewind:', fn, rn, errf, eoff, eotf, tcsr
DO f = 1, 3
eoff = .false.
DO WHILE ( .NOT. eoff )
n = tread ( tlu, onerec )
n = tstate ( tlu, fn, rn, errf, eoff, eotf, tcsr )
IF (.NOT. eoff) WRITE(*,2) 'read:', onerec, fn, rn, errf,
1 eoff, eotf, tcsr
END DO
n = tskipf ( tlu, 1, 0 )
n = tstate ( tlu, fn, rn, errf, eoff, eotf, tcsr )
WRITE(*,1) 'tskip: ', fn, rn, errf, eoff, eotf, tcsr
END DO
END
The output is:
open: 0 0 F F F 0
rewind: 0 0 F F F 0
read: eins 0 1 F F F 0
read: zwei 0 2 F F F 0
tskip: 1 0 F F F 0
read: ichi 1 1 F F F 0
read: ni__ 1 2 F F F 0
tskip: 2 0 F F F 0
read: un__ 2 1 F F F 0
read: deux 2 2 F F F 0
tskip: 3 0 F F F 0
EOF and EOT Summary:
If at either EOF or EOT, then:
· Any tread() just returns; it does not read the tape.
· A tskipf( tlu, 1, 0 ) resets the EOF status to false, and returns; it
does not advance the tape pointer.
A successfull twrite() resets the EOF and EOT status flags to false.
A succesfull tclose() resets all those flags to false.
tclose() truncates. tclose() places an EOF marker immediately after
the current location of the unit pointer and then closes the unit. So
if you use trewin() to rewind a unit before you use tclose() to close
it, its contents are discarded. This behavior of tclose() is inherited
from the Berkeley code.
NOTICE: OBSOLETE
This man page is provided for historical reasons only. This functional‐
ity is not implemented in Fortran 95 (f95).
29 September 1995 TOPEN(3F)