On Tuesday 18 November 2025 20:53:12 Martin Storsjö wrote:
> On Tue, 18 Nov 2025, Pali Rohár wrote:
> 
> > > presume this is new in msvcr110/UCRT or newer? As the behaviour you 
> > > describe
> > > of tmpnam() is that it only generates a string "\<random>", right?
> > 
> > Yes, in my tests I saw only "\<random>" in buffer returned by tmpnam().
> > 
> > > As the
> > > old tmpnam() doesn't see the full string, only the name subset, does it do
> > > anything to check that the returned names are unique already? As the 
> > > current
> > > docs say "Each of these functions returns the name of a file that doesn't
> > > currently exist. " - but that can't be proven if it doesn't even see the
> > > full path?
> > 
> > Seems that the tmpnam() generates fixed string pattern followed by some
> > number which is increased by every call.
> 
> Ok, so if it is incremented after each call, then we should be good here.
> 
> > But because tmpnam() function does not create a file (it just generates
> > filename), there can be still a race condition between tmpnam() and
> > creat() calls. For example another process could generate by its own
> > same filename and create file earlier.
> 
> Yes, I know that we must check that we actually get an unique file opened
> here.
> 
> > > The patch looks ok, if old versions of tmpnam() behave in the way of just
> > > returning a random string and not trying to check if the file is unique 
> > > (ok,
> > > we can't know what it does internally) without a full path, just starting
> > > with a backslash.
> > 
> > For our mingw-w64 tmpfile() implementation it does not matter if the
> > tmpnam() returned existing or non-existing filename in the root C:\.
> 
> It _could_ be an issue, depending on the implementation of tmpfile(). If
> tmpfile returns an entirely random name, or an always incrementing number
> (with a counter that is shared between calls), then we are good.
> 
> But consider the following implementation of tmpnam():
> 
>     int idx = 0;
>     while (true) {
>         sprintf(buf, "\tmp%03d", idx);
>         if (!exists(buf))
>             return buf; // Found a non-existing filename
>         idx++;
>     }
> 
> Then we would have a problem! Because tmpnam() could each time return a
> filename like "\tmp000", because it internally checks that "\tmp000" does
> not exist, and only proceeds to "tmp001" if "\tmp000" exists. But in our
> case, after tmpnam returns that, we check "<GetTempPath>\tmp000" which does
> exist, so we call tmpnam() again, and again and essentially hang there.
> 
> But if you say that we don't get this behaviour, then I think we're safe.
> 
> // Martin

Now I see what you mean. I run tmpnam() in the loop without creating the
file and I always got different filename from tmpnam(). So I think that
we should not hit the above issue.

Also in the documentation pages linked in previous email is written:

msvcrt40, msvcrt (5) and msvcrt (6):
"The function generates unique filenames for up to TMP_MAX calls."

msvcr70-msvcr120:
"The name generated by tmpnam consists of a program-generated file name
and, after the first call to tmpnam, a file extension of sequential
numbers in base 32 (.1-.vvu, when TMP_MAX in STDIO.H is 32,767)."

So it matches my observation.


_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to