[MLton-commit] r6624

Matthew Fluet fluet at mlton.org
Sat May 17 14:04:02 PDT 2008


Fix various problems with tempFileDes.

The tempFileDes function to return a fresh, temporary file handle
(used to page the heap to disk), had a number of problems.

 * using BUFSIZE 65536 causes GetTempPath to always fail, with a
   return value 0 (even on Windows XP).  Although BUFSIZE 10240 allows
   GetTempPath to succeed, CreateFile limits the file name to one less
   than MAX_PATH = 260 characters, so we use the more reasonable
   BUFSIZE 512 (as exemplified by the MSDN page).

 * The error checking of the GetTempPath return value did not signal
   an error when the return value was 0.  This allowed tempFileDes to
   proceed with a bogus lpPathBuffer, although lpPathBuffer would
   usually be initialized with '\000's, so appear to be an empty string.
   This meant that temporary files would be created in the root
   directory of the current volume (in practice, in C:/).

 * CreateFile was called with CREATE_NEW, which fails, with last-error
   code ERROR_FILE_EXISTS(80), if the specified file exists.  However,
   the documentation for GetTempFileName states: "if a unique file
   name is generated, then an empty file is created and the handle to
   it released."  So, by requesting a unique file name from
   GetTempFileName, we should *not* use CREATE_NEW.  The MSDN page
   suggests CREATE_ALWAYS, but TRUNCATE_EXISTING seems a better
   choice, as GetTempFileName should have created the file.


----------------------------------------------------------------------

U   mlton/trunk/runtime/platform/windows.c

----------------------------------------------------------------------

Modified: mlton/trunk/runtime/platform/windows.c
===================================================================
--- mlton/trunk/runtime/platform/windows.c	2008-05-15 22:07:44 UTC (rev 6623)
+++ mlton/trunk/runtime/platform/windows.c	2008-05-17 21:03:57 UTC (rev 6624)
@@ -1,30 +1,34 @@
 HANDLE fileDesHandle (int fd);
 
-/* As crazy as it is, this breaks Windows 2003&Vista: #define BUFSIZE 65536 */
-#define BUFSIZE 10240
+#define BUFSIZE 512
 
 static HANDLE tempFileDes (void) {
-  /* Based on http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/creating_and_using_a_temporary_file.asp
-   */  
-  HANDLE hTempFile; 
+  /* Based on http://msdn.microsoft.com/en-us/library/aa363875(VS.85).aspx */
+  HANDLE hTempFile;
   DWORD dwRetVal;
   DWORD dwBufSize=BUFSIZE;
   UINT uRetVal;
-  char szTempName[BUFSIZE];  
-  char lpPathBuffer[BUFSIZE];
+  TCHAR szTempName[BUFSIZE];
+  TCHAR lpPathBuffer[BUFSIZE];
 
   dwRetVal = GetTempPath(dwBufSize, lpPathBuffer);
-  if (dwRetVal >= dwBufSize)
-    die ("GetTempPath failed with error %ld\n", GetLastError());
-  uRetVal = GetTempFileName(lpPathBuffer, "TempFile", 0, szTempName);
-  if (0 == uRetVal)
-    die ("GetTempFileName in %s failed with error %ld\n", 
+  if (dwRetVal > dwBufSize || (dwRetVal == 0))
+    die ("GetTempPath(%ld,...) failed with error %ld\n", 
+         dwBufSize, GetLastError());
+  uRetVal = GetTempFileName(lpPathBuffer, TEXT("MLtonTempFile"), 0, szTempName);
+  if (uRetVal == 0)
+    die ("GetTempFileName(\"%s\",...) failed with error %ld\n", 
          lpPathBuffer, GetLastError());
-  hTempFile = CreateFile((LPTSTR) szTempName, GENERIC_READ | GENERIC_WRITE,
-    0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
-    NULL);                
+  hTempFile = CreateFile((LPTSTR) szTempName,
+                         GENERIC_READ | GENERIC_WRITE,
+                         0,
+                         NULL,
+                         TRUNCATE_EXISTING,
+                         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
+                         NULL);
   if (hTempFile == INVALID_HANDLE_VALUE)
-    die ("CreateFile failed with error %ld\n", GetLastError());
+    die ("CreateFile(\"%s\",...) failed with error %ld\n", 
+         szTempName, GetLastError());
   return hTempFile;
 }
 
@@ -131,7 +135,7 @@
                 }
 
                 fprintf(stderr, FMTPTR " %10"PRIuMAX"  %s %s\n",
-                        buf.BaseAddress, (uintmax_t)buf.RegionSize,
+                        (uintptr_t)buf.BaseAddress, (uintmax_t)buf.RegionSize,
                         state, protect);
         }
 }




More information about the MLton-commit mailing list