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