[net.lang.f77] binary i/o problem

rbd@lamont.UUCP (Roger Davis) (05/07/85)

Does anyone know how to get a Fortran program to read
a binary file through standard input? (Or why it's not
possible, if such is the case?) The following test
program, and an infinite number of variations thereon,
will not work, while a similar program that reads formatted
input through standard input works fine.

% cat rdbinary.f
c	program rdbinary
c
c	read binary input from stdin
c
	integer number
c
	close(5)
	open(5, status='old', form='unformatted', err=80)
	write(6, '("stdin opened")')
c
	read(5, err=90) number
	write(6, '("number = ", i5)') number
	goto 100
c
c	error messages
80	write(6, '("open error")')
	goto 100
90	write(6, '("read error")')
	goto 100
c 
100	stop
	end

This program produces the following output
when supplied with a binary input: 
  
% rdbinary <binaryfile
stdin opened
read sue: [-1] end of file
logical unit 5, named 'fort.5'
lately: reading sequential unformatted external IO
IOT trap (core dumped)

				Roger Davis
				lamont!rbd

UUCP: {decvax, ihnp4, cmc12} philabs!lamont!rbd

therneau@ur-msbvax.UUCP (05/09/85)

  You forgot to rewind the file (I think).  The BSD fortran always opens
files at the end - assuming that you want to append to them.  Hence the
immediate end-of-file


		Terry Therneau
		Statistics Dept.  U of Rochester

paul@gargoyle.UChicago.UUCP (Paul Schinder) (05/11/85)

In article <> therneau@ur-msbvax.UUCP writes:
>
>  You forgot to rewind the file (I think).  The BSD fortran always opens
>files at the end - assuming that you want to append to them.  Hence the
>immediate end-of-file
>
>
>		Terry Therneau
>		Statistics Dept.  U of Rochester


That's true in 4.1 BSD, but not 4.2, where f77 opens files at the
beginning.  I *think* the problem in the original posting is caused
by the fact that the open statement doesn't include a "file = ...".
When there is no filename, the filename defaults
to "fort.unitnumber", which explains the error message (fort.5 does
not exist, hence is empty, so the first read gets EOF).  I almost
replied saying to  "open(5, file='/dev/tty',form='unformatted',...)",
but I don't think this will work if you use a pipe to enter the data.
I think in all cases /dev/tty is connected to the
terminal.  Does anyone have any other ideas?
-- 


				Paul Schinder
				Astronomy and Astrophysics Center
				University of Chicago
				uucp: ..!ihnp4!oddjob!paul

dlw@ucbtopaz.CC.Berkeley.ARPA (David Wasley) (05/14/85)

The example posted closed unit 5, thus releasing Unix stdin.
It then opened unit 5, thus getting the default file: fort.5
Since there was no data in fort.5, it then got EOF.
To redeclare unit 5 "unformatted", simply issue the 'open'
statement without the preceding 'close'. You don't have to
'rewind' unit 5 if it is attached to stdin since stdin can't
be positioned.
	David Wasley
	...!ucbvax!dlw

woods@hao.UUCP (Greg Woods) (05/14/85)

> When there is no filename, the filename defaults
> to "fort.unitnumber", which explains the error message (fort.5 does
> not exist, hence is empty, so the first read gets EOF).  I almost
> replied saying to  "open(5, file='/dev/tty',form='unformatted',...)",
> but I don't think this will work if you use a pipe to enter the data.
> I think in all cases /dev/tty is connected to the
> terminal.  Does anyone have any other ideas?

  Yes. Use the isatty(3F) function which tells you whether standard
input is a terminal or not. If so, your open will work fine. If
not, don't ever close unit 5.

--Greg

P.S. I gave up on FORTRAN I/O a long time ago. We solved this problem here
by implementing a library of trivial C functions to give us access to the 
system calls we needed. For example:

int uread_(fd,addr,bytes) int *fd; char *addr; int *bytes;
{ return(read(*fd,addr,*bytes); }

  This can now be called from FORTRAN under BSD just like a read call in C.
Deals directly with file descriptors so no messing with FORTRAN I/O 
conventions. The disadvantage, of course, is that it's not meaningless
on a non-UNIX system and non-portable to systems that don't allow FORTRAN
and C to call each other.
-- 
{ucbvax!hplabs | allegra!nbires | decvax!noao | harpo!seismo | ihnp4!noao}
       		        !hao!woods

CSNET: woods@NCAR  ARPA: woods%ncar@CSNET-RELAY
   
     "...I may not be right but I've never been wrong
      It seldom turns out the way it does in the song..."