This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

The semantics of `truncate'.


L.S.,

I'm trying to resolve the problem the GAMESS-developers have with the
g77/f2c run-time library, specifically the implementation of endfile.c
in libI77.

According to Fortran semantics, ENDFILE would write an END-OF-FILE
record (that can be conceptual).  On output this means the file ends
there.

After output has been written to a file, when REWIND is issued for that
file, an implicit ENDFILE is assumed.  This means that the sequence:

      WRITE(..) 'something'
      REWIND(..)
      READ(..) char-var
      READ(.., END=10) char-var
      PRINT*,'HELP - SHOULDN''T GET HERE'
   10 END

would get an end-of-file indication on the second read and would jump
around the 'HELP ...' print.

So far, so good.  .../gcc/gcc/teststuite/g77.f-torture/execute/io1.f
ensures us that these semantics will be obeyed, short of invoking test
suite regressions.

The point of this mail is that I can't get it to work if I implement
ENDFILE using truncate [ the present implementation copies the file to
be ENDFILE'd to a /tmp file and back, which upset the GAMESS users ]

Somehow, truncate does work in that if I cat the temporary file created
by io1.f just before the two reads, it indeed only contains one line -
however, the test still fails because the second read succeeds in spite
of the END= line.

One of the reasons for this could be that the file is open while
truncate is being called - would this be a problem ?

I'll attach the patch I'm currently using for those interested.

Thanks for any insight offered or pointers for further reading ...

-- 
Toon Moene - mailto:toon@moene.indiv.nluug.nl - phoneto: +31 346 214290
Saturnushof 14, 3738 XG  Maartensdijk, The Netherlands
Maintainer, GNU Fortran 77: http://gcc.gnu.org/onlinedocs/g77_news.html
Join GNU Fortran 95: http://g95.sourceforge.net/ (under construction)
*** configure.in.orig	Sat Feb 24 16:56:03 2001
--- configure.in	Sat Feb 24 16:55:28 2001
*************** else
*** 135,138 ****
--- 135,139 ----
  fi
  
+ AC_CHECK_FUNCS(truncate)
  AC_CHECK_FUNCS(mkstemp)
  AC_CHECK_FUNCS(tempnam)
*** endfile.c.orig	Sun Mar 12 20:20:47 2000
--- endfile.c	Sat Feb 24 22:38:34 2001
***************
*** 2,5 ****
--- 2,9 ----
  #include "fio.h"
  
+ #ifdef HAVE_TRUNCATE
+ #include <unistd.h>
+ #endif /* defined(HAVE_TRUNCATE) */
+ 
  #ifdef KR_headers
  extern char *strcpy();
*************** integer f_end(alist *a)
*** 39,42 ****
--- 43,47 ----
  }
  
+ #ifndef HAVE_TRUNCATE
   static int
  #ifdef KR_headers
*************** copy(FILE *from, register long len, FILE
*** 57,60 ****
--- 62,66 ----
  	return 0;
  	}
+ #endif /* !defined(HAVE_TRUNCATE) */
  
   int
*************** t_runc(alist *a)
*** 67,72 ****
  	long loc, len;
  	unit *b;
! 	FILE *bf, *tf;
! 	int rc = 0;
  
  	b = &f__units[a->aunit];
--- 73,81 ----
  	long loc, len;
  	unit *b;
! 	int rc;
! 	FILE *bf;
! #ifndef HAVE_TRUNCATE
! 	FILE *tf;
! #endif /* !defined(HAVE_TRUNCATE) */
  
  	b = &f__units[a->aunit];
*************** t_runc(alist *a)
*** 78,81 ****
--- 87,92 ----
  	if (loc >= len || b->useek == 0 || b->ufnm == NULL)
  		return(0);
+ #ifndef HAVE_TRUNCATE
+ 	rc = 0;
  	fclose(b->ufd);
  	if (!loc) {
*************** done1:
*** 119,122 ****
--- 130,136 ----
  done:
  	f__cf = b->ufd = bf;
+ #else  /* !defined(HAVE_TRUNCATE) */
+ 	rc = truncate(b->ufnm, loc);
+ #endif /* !defined(HAVE_TRUNCATE) */
  	if (rc)
  		err(a->aerr,111,"endfile");

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]