Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ tstate(3F) — Sun WorkShop 3.0.1

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

ioctl(2)

mtio(4s)

perror(3f)

read(2)

st(4s)

write(2)

TOPEN(3F)  —  FORTRAN LIBRARY ROUTINES

NAME

topen, tclose, tread, twrite, trewin, tskipf, tstate − FORTRAN tape I/O

OVERVIEW

You can manipulate magnetic tape from FORTRAN using these functions. 
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. The tlu has no relationship at all to any normal FORTRAN logical unit. 
Note that before you use one of these functions, its name must be in an INTEGER statement. 

DESCRIPTION

topen — Associate a device name with a tape logical unit (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 islabeled to true.  Note: 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 displayed output is
topen ok:  0  1   /dev/rst0

tclose — Write EOF and close tape device channel and remove its association 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. 
Note: tclose() places an EOF marker immediately after the current location 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 displayed 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 will be the size of buffer.

Example: Write a 2-record file.

        CHARACTER devnam∗9 / ’/dev/rst0’ /, rec1∗512 / "abcd" /, 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 displayed 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 displayed 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 2-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 displayed output is
  1 abcd
  2 wxyz
  3 wxyz
trewin ok:   0   1  /dev/rst0
abcd

tskipf — Skip foreward over files and/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 physical records.  If the current file is at EOF, this counts as 1 file to skip.  This also resets the EOF status.  See tstate below. 

Example: Typical fragment -- Skip 4 files and then skip 1 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.  It 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. 

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 3 files written in the previous example. 

        CHARACTER devnam∗10 / ’/dev/nrst0’ /, onerec∗512 / " " /
        INTEGER f, n / 0 /, tlu / 1 /, tcsr, topen, tread, trewin, 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, 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 displayed 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 & EOT Summary

1. If at either EOF or EOT, then

a.  Any tread() will just return; it will not read the tape. 
b.  A tskipf( tlu, 1, 0 ) resets the EOF status to false, and returns; it does not advance the tape pointer. 

2. A successfull twrite() resets the EOF and EOT status flags to false. 
3. 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 thrown away. This behavior of tclose() is inherited from the Berkeley code. 

FILES

libF77.a

SEE ALSO

ioctl(2), mtio(4s), perror(3f), read(2), st(4s), write(2). 

Sun Release 4.1  —  Last change: 28 October 1991

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026