On Tue, 18 Nov 2025, Pali Rohár wrote:
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.
Ok, great! Then this patch should be fine - I'll try to push it soon.
// Martin
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public