Patchwork [fortran,docs] Unformatted sequential and special files

login
register
mail settings
Submitter Thomas Koenig
Date Sept. 1, 2013, 4:53 p.m.
Message ID <5223711B.1090000@netcologne.de>
Download mbox | patch
Permalink /patch/271630/
State New
Headers show

Comments

Thomas Koenig - Sept. 1, 2013, 4:53 p.m.
Hi Janne,

I have tried to answer your points in the attached patch.

> The unformatted sequential format part looks Ok, but the special files
> section is lacking. E.g. what about
> 
> - The REWIND statement?

Not supported.

> - The ENDFILE statement?

Not supported.

> - ACCESS='stream' and the POS= specifier?

Only for inpquire.

> - ACCESS='direct'? (I suspect this should work for
> pipes/FIFO's/terminals in case REC= numbers are sequential, but is
> that a guarantee we want to make?)

I have not listed this as supported in the patch.

> - Special files which are special in other ways. E.g. block special
> files tend to allow seeking, but IO must be block aligned.

Also listed as not supported; I suspect buffering could cause grief
there.

I have updated an attached patch.  OK?

	Thomas

2013-08-30  Thomas Koenig  <tkoenig@gcc.gnu.org>

        PR fortran/30162
        * gfortran.texi:  Document unformatted sequential file format
        and I/O with special files.
ig25@linux-fd1f:~/Krempel/Unformatt
Tobias Burnus - Sept. 2, 2013, 7:45 p.m.
Thomas Koenig wrote:
> +Unformatted sequential files are stored using record markers. Each
> +full record consists of a leading record marker, the data written
> +by the user program, and a trailing record marker.  The record markers
> +are four-byte integers by default, and eight-byte integers if the
> +@option{-fmax-subrecord-length=8} option is in effect. Each record
> +marker contains the number of bytes of data in the record.

I wonder whether one should discourage the use of 
-fmax-subrecord-length=8 more explicitly here - when reading until here 
one might think that there is a 2GB limit for =4.

> +The maximum number of bytes of user data in a record is 2147483639 for
> +a four-byte record marker.

Why this number? I had expected it to be exactly  2 GiB (minus 1 Byte) = 
2**31-1 = 2147483647. Your number is one byte shorter. Why?

Actually, I had also mentioned GiB as those are simpler to remember, e.g.
"The maximal user data per record is 2 gigabytes (2147483647/2147483639 
bytes) for the four-byte record marker.

> If this is exceeded, a record is split into
> +subrecords. Each subrecord also has a leading and a trailing record
> +marker. If the leading record marker contains a negative number, the
> +number of user data bytes in the subrecord equals the absolute value
> +of this number, and another subrecord follows the current one.  If the
> +trailing record marker contains a negative number, then the number of
> +bytes of user data equals the absolute value of that number, and there
> +is a preceding subrecord.
> +
> +The format for unformatted sequential data can be duplicated using
> +unformatted stream, as shown in this example program:

(which assumes records shorter than 2 GiB)

> +
> +@smallexample
> +program main
> +  implicit none
> +  integer :: i

I wonder whether one should make this more explicit by using

use iso_fortran_env, only: int32
integer(int32) :: i

> +Unformatted sequential file access is @emph{not} supported for special
> +files.  If necessary, it can be simulated using unformatted stream,
> +see @ref{Unformatted sequential file format}.
> +
> +I/O to and from block devices are also not supported.
> +
> +@code{BACKSPACE}, @code{REWIND} and @code{ENDFILE} are not supported
> +for special files.

I think I understand what you mean but  "I/O to and from block devices 
are also not supported." sounds as if it also could apply to all I/O, 
including stream I/O.

How about adding "block devices" to the list of special files in the 
intro? You could also mention sockets, which behave similarly. The 
BACKSPACE/REWIND/ENDFILE could be moved directly after the itemize in 
the same paragraph as the POS=.

And instead of "unformatted sequential", you could write "unformatted 
sequential and directed access", which reminds me that we should also 
document that file format for the sake of completeness.

Tobias

Patch

Index: gfortran.texi
===================================================================
--- gfortran.texi	(Revision 201996)
+++ gfortran.texi	(Arbeitskopie)
@@ -1121,6 +1121,8 @@ 
 * Internal representation of LOGICAL variables::
 * Thread-safety of the runtime library::
 * Data consistency and durability::
+* Unformatted sequential file format::
+* I/O with special files::
 @end menu
 
 
@@ -1291,7 +1293,85 @@ 
 releasing @code{fcntl} file locks, if the server supports them, will
 also force cache validation and flushing dirty data and metadata.
 
+@node Unformatted sequential file format
+@section Unformatted sequential file format
+@cindex unformatted sequential files
+@cindex record marker
+@cindex subrecord
 
+Unformatted sequential files are stored using record markers. Each
+full record consists of a leading record marker, the data written
+by the user program, and a trailing record marker.  The record markers
+are four-byte integers by default, and eight-byte integers if the
+@option{-fmax-subrecord-length=8} option is in effect. Each record
+marker contains the number of bytes of data in the record.
+
+The maximum number of bytes of user data in a record is 2147483639 for
+a four-byte record marker. If this is exceeded, a record is split into
+subrecords. Each subrecord also has a leading and a trailing record
+marker. If the leading record marker contains a negative number, the
+number of user data bytes in the subrecord equals the absolute value
+of this number, and another subrecord follows the current one.  If the
+trailing record marker contains a negative number, then the number of
+bytes of user data equals the absolute value of that number, and there
+is a preceding subrecord.
+
+The format for unformatted sequential data can be duplicated using
+unformatted stream, as shown in this example program:
+
+@smallexample
+program main
+  implicit none
+  integer :: i
+  real, dimension(10) :: a, b
+  call random_number(a)
+  open (10,file='test.dat',form='unformatted',access='stream')
+  inquire (iolength=i) a
+  write (10) i, a, i
+  close (10)
+  open (10,file='test.dat',form='unformatted')
+  read (10) b
+  if (all (a == b)) print *,'success!'
+end program main
+@end smallexample
+
+@node I/O with special files
+@section I/O with special files
+@cindex special files
+@cindex pipes
+@cindex FIFO
+@cindex terminal devices
+@cindex block devices
+@cindex sockets
+@cindex BACKSPACE
+@cindex REWIND
+@cindex ENDFILE
+
+Special character-oriented files such as pipes, FIFOs or terminal
+devices are supported only for the following types of file access:
+
+@itemize
+
+@item Formatted sequential
+
+@item Formatted stream
+
+@item Unformatted stream
+
+@end itemize
+
+For special files, the @code{POS=} specifier for stream I/O can only
+be used in @code{INQUIRE} statements.
+
+Unformatted sequential file access is @emph{not} supported for special
+files.  If necessary, it can be simulated using unformatted stream,
+see @ref{Unformatted sequential file format}.
+
+I/O to and from block devices are also not supported.
+
+@code{BACKSPACE}, @code{REWIND} and @code{ENDFILE} are not supported
+for special files.
+
 @c ---------------------------------------------------------------------
 @c Extensions
 @c ---------------------------------------------------------------------