re PR libfortran/47439 (Fun with scratch files on Windows MKTEMP only allows for...
authorFrancois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Sat, 19 Mar 2011 12:09:27 +0000 (12:09 +0000)
committerFrançois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Sat, 19 Mar 2011 12:09:27 +0000 (12:09 +0000)
PR libfortran/47439

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

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

From-SVN: r171178

gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/scratch_1.f90 [new file with mode: 0644]
libgfortran/ChangeLog
libgfortran/io/unix.c

index 1a30a107a745d30d9f7ddc9687347e659be663b1..7ac4d78a77d6251e1e2d3d4981d8174c412b7c41 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-16  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
+
+       PR libfortran/47439
+       * gfortran.dg/scratch_1.f90: New test.
+
 2011-03-18  Joseph Myers  <joseph@codesourcery.com>
 
        * gcc.dg/c1x-typedef-1.c: Expect errors for redefinitions of
diff --git a/gcc/testsuite/gfortran.dg/scratch_1.f90 b/gcc/testsuite/gfortran.dg/scratch_1.f90
new file mode 100644 (file)
index 0000000..32bf0c4
--- /dev/null
@@ -0,0 +1,8 @@
+! { dg-do run }
+! Check that we can open more than 26 scratch files concurrently
+  integer :: i
+  do i = 1, 3000
+    print *, i
+    open(100+i,status="scratch")
+  end do
+end
index 9723efe21ee45cf9e29185dfdb04a3067cc61f94..70cf85b42a6371f9a09fc2e741da5c2dfdc45d02 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-19  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
+
+       PR libfortran/47439
+       * io/unix.c (tempfile): Work around poor mktemp() implementations.
+
 2011-03-16  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
        PR libfortran/47883
index 12536ca5cbeafd897c9e92745ce2e08730a82c9d..edccdd6397a3f002e26c6b06891dc0d0989a1874 100644 (file)
@@ -1022,6 +1022,12 @@ tempfile (st_parameter_open *opp)
   char *template;
   const char *slash = "/";
   int fd;
+  size_t tempdirlen;
+
+#ifndef HAVE_MKSTEMP
+  int count;
+  size_t slashlen;
+#endif
 
   tempdir = getenv ("GFORTRAN_TMPDIR");
 #ifdef __MINGW32__
@@ -1046,16 +1052,19 @@ tempfile (st_parameter_open *opp)
   if (tempdir == NULL)
     tempdir = DEFAULT_TEMPDIR;
 #endif
+
   /* Check for special case that tempdir contains slash
      or backslash at end.  */
-  if (*tempdir == 0 || tempdir[strlen (tempdir) - 1] == '/'
+  tempdirlen = strlen (tempdir);
+  if (*tempdir == 0 || tempdir[tempdirlen - 1] == '/'
 #ifdef __MINGW32__
-      || tempdir[strlen (tempdir) - 1] == '\\'
+      || tempdir[tempdirlen - 1] == '\\'
 #endif
      )
     slash = "";
 
-  template = get_mem (strlen (tempdir) + 20);
+  // Take care that the template is longer in the mktemp() branch.
+  template = get_mem (tempdirlen + 23);
 
 #ifdef HAVE_MKSTEMP
   sprintf (template, "%s%sgfortrantmpXXXXXX", tempdir, slash);
@@ -1064,11 +1073,30 @@ tempfile (st_parameter_open *opp)
 
 #else /* HAVE_MKSTEMP */
   fd = -1;
+  count = 0;
+  slashlen = strlen (slash);
   do
     {
-      sprintf (template, "%s%sgfortrantmpXXXXXX", tempdir, slash);
+      sprintf (template, "%s%sgfortrantmpaaaXXXXXX", tempdir, slash);
+      if (count > 0)
+       {
+         int c = count;
+         template[tempdirlen + slashlen + 13] = 'a' + (c% 26);
+         c /= 26;
+         template[tempdirlen + slashlen + 12] = 'a' + (c % 26);
+         c /= 26;
+         template[tempdirlen + slashlen + 11] = 'a' + (c % 26);
+         if (c >= 26)
+           break;
+       }
+
       if (!mktemp (template))
-       break;
+      {
+       errno = EEXIST;
+       count++;
+       continue;
+      }
+
 #if defined(HAVE_CRLF) && defined(O_BINARY)
       fd = open (template, O_RDWR | O_CREAT | O_EXCL | O_BINARY,
                 S_IREAD | S_IWRITE);