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