Bug 47439

Summary: Fun with scratch files on Windows MKTEMP only allows for 26 files
Product: gcc Reporter: Tobias Burnus <burnus>
Component: libfortranAssignee: Francois-Xavier Coudert <fxcoudert>
Status: RESOLVED FIXED    
Severity: normal CC: fxcoudert, hjl.tools, jb, jvdelisle2
Priority: P3 Keywords: patch
Version: 4.6.0   
Target Milestone: ---   
URL: http://gcc.gnu.org/ml/fortran/2011-03/msg00102.html
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2011-03-12 15:22:42

Description Tobias Burnus 2011-01-24 17:05:13 UTC
Reported by Claude Simone at http://groups.google.com/group/comp.lang.fortran/msg/b1bf5ce50080e89e

Thread: http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/8843f2317cb565cd


A) Not more than 26 temporary files are possible

To generate a temporay file, libgfortran/io/unix.c's tempfile calls the system's mktemp, which according to Microsoft's API has the following property:

http://msdn.microsoft.com/en-us/library/34wc6k1f%28v=VS.80%29.aspx

"_mktemp preserves base and replaces the first trailing X with an alphabetic character. _mktemp replaces the following trailing X's with a five-digit value; this value is a unique number identifying the calling process, or in multithreaded programs, the calling thread."

Hence, there are only "a" to "z" = 26 temporary files possible - at least concurrently. Thus, for Windows systems, gfortran needs an own implementation for mk(s)temp, which supports more. One possibility would be to change the BASE handed to "mktemp".



B) Files are not unlinked

Newer Windows support for FILE_FLAG_DELETE_ON_CLOSE; cf. CreateFile Function at http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx

See also http://msdn.microsoft.com/en-us/library/yeby3zcb%28v=VS.80%29.aspx for "D" and "_O_TEMPORARY" in fopen and _wfopen.


However, in principle on exit libgfortran's
  static void __attribute__((destructor))
  cleanup (void)
should be called, which should delete files.
Comment 1 Janne Blomqvist 2011-01-25 09:28:14 UTC
Seems the reason for Windows _mktemp() behavior is due to replicating some age-old BSD behavior. From the Linux mktemp(3) manpage:

BUGS
       Never use mktemp().  Some implementations follow 4.3BSD and replace XXXXXX by the current process ID and a  single
       letter,  so  that  at most 26 different names can be returned.  Since on the one hand the names are easy to guess,
       and on the other hand there is a race between testing whether the name exists and opening the file, every  use  of
       mktemp() is a security risk.  The race is avoided by mkstemp(3).

(Needless to say, libgfortran use mkstemp() ifavailable, mktemp() is just a fallback.)
Comment 2 Francois-Xavier Coudert 2011-03-12 15:22:42 UTC
A patch for the first half of the PR can be found here: http://gcc.gnu.org/ml/fortran/2011-03/msg00102.html
Comment 3 Francois-Xavier Coudert 2011-03-19 12:09:34 UTC
Author: fxcoudert
Date: Sat Mar 19 12:09:27 2011
New Revision: 171178

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171178
Log:
	PR libfortran/47439

	* io/unix.c (tempfile): Work around poor mktemp() implementations.

	* gfortran.dg/scratch_1.f90: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/scratch_1.f90
Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/libgfortran/ChangeLog
    trunk/libgfortran/io/unix.c
Comment 4 H.J. Lu 2011-03-19 14:30:37 UTC
On Linux/ia32, revision 171179 gave:

FAIL: gfortran.dg/scratch_1.f90  -O0  execution test
FAIL: gfortran.dg/scratch_1.f90  -O1  execution test
FAIL: gfortran.dg/scratch_1.f90  -O2  execution test
FAIL: gfortran.dg/scratch_1.f90  -O3 -fomit-frame-pointer  execution test
FAIL: gfortran.dg/scratch_1.f90  -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions  execution test
FAIL: gfortran.dg/scratch_1.f90  -O3 -fomit-frame-pointer -funroll-loops  execution test
FAIL: gfortran.dg/scratch_1.f90  -O3 -g  execution test
FAIL: gfortran.dg/scratch_1.f90  -Os  execution test
Comment 5 Francois-Xavier Coudert 2011-03-19 14:35:12 UTC
Author: fxcoudert
Date: Sat Mar 19 14:35:05 2011
New Revision: 171180

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171180
Log:
	PR libfortran/47439
	* gfortran.dg/scratch_1.f90: Adjust test.

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/scratch_1.f90
Comment 6 Francois-Xavier Coudert 2011-03-19 14:36:13 UTC
(In reply to comment #4)
> FAIL: gfortran.dg/scratch_1.f90  -O0  execution test

Must be a limit on the number of concurrently open files (the test checks for 3000). Next commit fixed it.