No tempFile() in std.file

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed May 17 06:42:45 PDT 2017


On Wednesday, May 17, 2017 05:34:50 Patrick Schluter via Digitalmars-d-learn 
wrote:
> On Wednesday, 17 May 2017 at 05:30:40 UTC, Patrick Schluter wrote:
> > On Tuesday, 16 May 2017 at 13:56:57 UTC, Jonathan M Davis wrote:
> >> [...]
> >
> > As your solution doesn't inherently solve the race condition
> > associated with temporary files, you could still generate the
> > name with a wrapper around tempnam() or tmpnam() (Posix for
> > Windows I don't know). This would avoid the double open() of
> > the scenario above.
>
> But as Jonathan said above, this is not a good solution in any
> case. In Posix the use the mks*temp() family of functions is
> standard now.

As I recall, the main problem with mks*temp() is that some platforms only
support a stupidly short list af random values (something like 26 IIRC).
Regardless, it's trivial to write that functionality yourself. The key is
that you open the file with the flag that indicates that the file must not
exist when you open it. Worst case, you have to try a few times with
different file names, but if you generate something like a UUID, then the
odds of a collision are so low that that's not realistically an issue. And
AFAIK, for mks*temp() to guarantee that the file was created by the call, it
has to do basically the same thing internally. But in any case, even if we
wanted to use mks*temp() in a D program, we'd want to wrap it in a portable
D function using D's strings and not char*. So, whether mks*temp() is used
is an implementation detail.

For the use case where you actually want a file name rather than just a file
handle to play around with, you're almost certainly going to be closing and
reopening the file or closing it and handing its path off to another
program, in which case, the only real downside to having a function that
securely creates an empty temporary file and returns its path is that you
then have to open it a second time to put actual data in it, whereas a
function like scratchFile lets you start writing to it without opening it
again. Regardless, as long as a program can get the path to the file, and
has the appropriate permissions, as I understand it, there's a risk of them
screwing with it even if you have it open (at least on POSIX systems which
don't normally use file locks and where - as I understand it - obeying the
file locks is completely optional, unlike Windows which likes to lock
everything).

So, while having scratchFile would definitely be nice, maybe a good solution
would be to add function to std.file such as writeToTempFile which acted
like std.file.write except that it created a temporary file which was
guaranteed to not exist prior to the call and returned its path after it
wrote to it. If you want to use std.stdio.File with it, you're still forced
to write an empty file and then open it again with File, but for the case
where you simply want to write the data to a file and then pass the path to
something else to use it (be it something in your program or another
program), it should work well. Certainly, it would be far better than what
we have now (which would be nothing).

So, I should probably dig up my scratchFile implementation and adapt it for
std.file as something like writeToTempFile or createTempFile.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list