FORTRAN tty input/output bug
Fri Apr 23 09:02:00 GMT 1999

The following bug was discovered when porting a mixture of C and FORTRAN
software from a Solaris 2 system using the Sun Workshop compilers to a Linux box
kited out with egcs 1.0.3 release, and gcc

The problem occurs when utilising the stream mode character writing/reading
intrinsics with a FORTRAN logical unit opened on a TTY device. I have included a
small code sample which demonstrates the problem(s).  This is compiled and run
with the following commands (after puting the FORTRAN code in file fort.f and
the C code in file c.c).

cc -g -c c.c
f77 -g -w -fcase-preserve fort.f
f77 -o test fort.o c.o

Firstly, use of the perror intrinsic after a READ or WRITE to a unit opened on a
TTY device results in an error "Illegal seek", this I did not expect. This is
not the main problem, which is as follows. If the first operation on a unit
opened on a TTY device is a  read operation (either READ or fgetc), any
subsequent stream based write operation fails with a "Bad file descriptor"
error. Conversely if the first operation on the unit is a write operation (WRITE
or fputc), any subsequent stream based read operation fails with a "Bad file
descriptor" error.  Further to this, if you require to use the lower level file
descriptor based functions, read or write, in a C routine called from FORTRAN
and passed the file descriptor (obtained from fnum) you must perform an
appropriate type of i/o on the unit from the FORTRAN i/o routines (READ, WRITE,
fputc or fgetc), and again subsequent use of the opposite type of i/o operation
results in the "Bad file descriptor" error. The following code also demonstrates
this additional phenomenon.


Derry Birse

      CHARACTER*255 ERROR,NAME,ttynam

      CALL clearerr()
 5    FORMAT(A)
      CALL perror('WRITE')
      CALL clearerr()
      CALL perror('READ')
      CALL clearerr()
      CALL perror('WRITE')
      CALL clearerr()
      MK = fputc(1,'A')
      CALL perror('fputc')
      CALL flush(1)
      CALL clearerr()
      MK = fgetc(1,C)
      CALL perror('fgetc')
      CALL clearerr()
      MK = fputc(1,C)
      CALL perror('fputc')
      CALL clearerr()
      CALL readwrite(FD)
      WRITE(1,*)'The End'
      CALL flush(1)
      CALL exit(0)

The following C code provides the access to the low level read/write functions.

#include <stdio.h>
#include <errno.h>

void clearerr_()

void readwrite_(fd)
     long *fd;
  int mk;
  char c;
  do {
    mk = read(*fd, &c, 1);
  } while (mk < 0 && errno == EINTR);
  if (mk < 0) {
    fprintf(stderr,"readwrite: terminated with read error %d\n",errno);
  mk = write(*fd, &c, 1);
  if (mk < 0) {
    fprintf(stderr,"readwrite: terminated with write error %d\n",errno);


More information about the Gcc-bugs mailing list