forwarded message from Stephen Weeks
Stephen Weeks
MLton@sourcelight.com
Thu, 21 Jun 2001 14:54:33 -0700
Return-Path: <sweeks@eponym.epr.com>
Received: (from sweeks@localhost)
by eponym.epr.com (8.11.2/8.11.2) id f5LLs3e27613;
Thu, 21 Jun 2001 14:54:03 -0700
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Message-ID: <15154.27899.351541.970585@eponym.epr.com>
In-Reply-To: <200106212127.f5LLRHJ29946@syzygy.sourcelight.com>
References: <200106212127.f5LLRHJ29946@syzygy.sourcelight.com>
X-Mailer: VM 6.89 under 21.1 (patch 14) "Cuyahoga Valley" XEmacs Lucid
From: Stephen Weeks <sweeks@intertrust.com>
To: Henry Cejtin <henry@sourcelight.com>
Subject: mkstemp
Date: Thu, 21 Jun 2001 14:54:03 -0700
> As to directories, only the mdir system call can meke them, and it doesn't
> have the fancy options that open has. On the other hand, mkdir will fail if
> the file already exists, even if it is a symlink to something that doesn't
> exist. Thus there are no race conditions.
OK.
> As you say, mkstemp is all just using the correct open options, so I would
> definitely do it using the posix stuff. If you need files with particular
> suffixes, then you can't use mkstemp(), but you can, of course, get the same
> effect using the correct open modes by hand. The key point is O_CREAT and
> O_EXCL. They indicate that you want to create the file, and that you want
> the call to fail if the file exists, even if it is a symlink to a file that
> does not exist. You also have to supply the mode argument, which should be
> octal 666 (any one can read and write, no execute), which is automatically
> adjusted by the umask removing some of these bits. If the file is going to
> be executable you should use octal 777 instead.
Linux mkstemp does 0600, not 0666.
How do you propose allowing flexibility for the mode? I think having the simple
function with the hardwired mode is nice. Should we have a separate function
mkstemp' that takes an extra argument of type Posix.FileSys.S.mode? Or leave
that for hackers who know what's going on to do themselves, since it can be done
as pure SML code.
I am hesitating about putting mkstemp in MLton.TextIO instead of my libraries.
What's pushing me to is the fact that OS.FileSys.tmpName causes that link time
warning, and I want a ready answer for questions, like "oh, just use
MLton.TextIO.mkstemp".
Anyways, here is the latest sig ...
val MLton.TextIO.mkstemp:
{prefix: string, suffix: string} -> string * TextIO.outstream
and implementation ...
local
val chars =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
val n = Word.fromInt (String.size chars)
val r: word ref = ref 0w0
in
fun tempName {prefix, suffix} =
let
val _ = r := Random.seed ()
val unique =
String.tabulate
(6, fn _ =>
let
val w = !r
val c = String.sub (chars,
Word.toInt (Word.mod (w, n)))
val _ = r := Word.div (w, n)
in c
end)
in
concat [prefix, unique, suffix]
end
end
fun mkstemp arg: string * outstream =
let
fun loop (i: int) =
if i = 0
then raise Fail "MLton.TextIO.temp"
else
let
val name = tempName arg
open Posix.FileSys
in
(name,
newOut (createf (name, O_WRONLY, O.flags [O.excl],
let open S
in flags [irusr, iwusr]
end)))
end handle PosixError.SysErr _ => loop (i - 1)
in
loop 100 (* max num trials *)
end