[MLton] Temporary directories on MinGW / mlnlffigen

Vesa Karvonen vesa.a.j.k at gmail.com
Mon Apr 23 03:30:43 PDT 2007


MLton's mlnlffigen fails to create temporary files on MinGW / Windows -
except under some specific circumstances.  For some reason, on our shared
Windows dev machine, mlnlffigen works with my user account.  The reason
why it works with my account probably has something to do with me
compiling MLton, but I haven't tracked down the specifics.

Anyway, the cause of the problem is that MLton's libraries try to create
temporary files into a directory named "/tmp".  This was noted earlier by
David Hansel (http://mlton.org/pipermail/mlton/2007-March/029675.html).

Below is a patch that we're currently using to fix the problem with mlnlffigen.
While preparing the patch, I also grepped for "/tmp/" and noticed that MLton's
sources contain several other references to the directory.

-Vesa Karvonen

Index: basis-library/mlton/io.sig
===================================================================
--- basis-library/mlton/io.sig	(revision 5538)
+++ basis-library/mlton/io.sig	(working copy)
@@ -26,4 +26,6 @@
       val mkstemp: string -> string * outstream
       (* mkstemps is like mkstemp, except it has both a prefix and suffix. *)
       val mkstemps: {prefix: string, suffix: string} -> string * outstream
+      (* adds a suitable system or user specific prefix (dir) for temp files *)
+      val tempPrefix : string -> string
    end
Index: basis-library/mlton/io.fun
===================================================================
--- basis-library/mlton/io.fun	(revision 5538)
+++ basis-library/mlton/io.fun	(working copy)
@@ -33,4 +33,17 @@

 fun mkstemp s = mkstemps {prefix = s, suffix = ""}

+fun tempPrefix file =
+   case MLtonPlatform.OS.host of
+      MLtonPlatform.OS.MinGW =>
+      concat [case OS.Process.getEnv "TEMP" of
+                 SOME d => d
+               | NONE =>
+                 case OS.Process.getEnv "TMP" of
+                    SOME d => d
+                  | NONE => "C:\\temp",
+              "\\",
+              file]
+    | _ => "/tmp/" ^ file
+
 end
Index: basis-library/mlton/mlton.sml
===================================================================
--- basis-library/mlton/mlton.sml	(revision 5538)
+++ basis-library/mlton/mlton.sml	(working copy)
@@ -108,7 +108,8 @@

             fun tmpName () =
                let
-                  val (f, out) = MLton.TextIO.mkstemp "/tmp/file"
+                  val (f, out) =
+                      MLton.TextIO.mkstemp (MLton.TextIO.tempPrefix "file")
                   val _ = TextIO.closeOut out
                in
                   f
Index: basis-library/build/sources.mlb
===================================================================
--- basis-library/build/sources.mlb	(revision 5538)
+++ basis-library/build/sources.mlb	(working copy)
@@ -318,6 +318,8 @@
    ../net/unix-sock.sig
    ../net/unix-sock.sml

+   ../mlton/platform.sig
+   ../mlton/platform.sml
    ../mlton/array.sig
    ../mlton/cont.sig
    ../mlton/cont.sml
@@ -336,8 +338,6 @@
       ../mlton/ffi.sml
    end
    ../mlton/int-inf.sig
-   ../mlton/platform.sig
-   ../mlton/platform.sml
    ../mlton/proc-env.sig
    ../mlton/proc-env.sml
    ../mlton/profile.sig
Index: lib/mlton/basic/file.sml
===================================================================
--- lib/mlton/basic/file.sml	(revision 5538)
+++ lib/mlton/basic/file.sml	(working copy)
@@ -88,6 +88,7 @@
            List.foreach (sources, fn f => outputContents (f, out)))

 val temp = MLton.TextIO.mkstemps
+val tempPrefix = MLton.TextIO.tempPrefix

 fun tempName z =
    let
@@ -99,7 +100,7 @@

 fun withTemp f =
    let
-      val name = tempName {prefix = "/tmp/file", suffix = ""}
+      val name = tempName {prefix = tempPrefix "file", suffix = ""}
    in
       Exn.finally (fn () => f name, fn () => remove name)
    end
@@ -116,7 +117,7 @@
    end

 fun withTempOut (f, g) =
-   withTempOut' ({prefix = "/tmp/file", suffix = ""}, f, g)
+   withTempOut' ({prefix = tempPrefix "file", suffix = ""}, f, g)

 fun withString (s, f) =
    withTempOut (fn out => Out.output (out, s), f)



More information about the MLton mailing list