We're presented with the problem of needing to generate a unique file name.
I've had some thoughts, but also wanted to solicit suggestions from the
group.
Any suggestions for schemes, using only *standard* C++, to do this?
Dave Theese wrote:[color=blue]
> Hello all,
>
> We're presented with the problem of needing to generate a unique file
> name. I've had some thoughts, but also wanted to solicit suggestions
> from the group.
>
> Any suggestions for schemes, using only *standard* C++, to do this?[/color]
If you want to stick to standard C++ then (IMHO) the only way to do it is
trial and error. Make a random filename (if you want to be paranoid then
within the POSIX filename limits). Try to see if it is there, if not make
one if it is there, make a new random value.
If you are ready to use platform specific code, then you might be able to
ask for your own process ID (possibly thread ID as well in MT) and use
those. I am not much familiar with POSIX, but it might provide functions
for both - and that is standard, too. And portable to many platforms.
White Wolf wrote:[color=blue]
> Dave Theese wrote:
>[color=green]
>>Hello all,
>>
>>We're presented with the problem of needing to generate a unique file
>>name. I've had some thoughts, but also wanted to solicit suggestions
>>from the group.
>>
>>Any suggestions for schemes, using only *standard* C++, to do this?[/color]
>
>
> If you want to stick to standard C++ then (IMHO) the only way to do it is
> trial and error. Make a random filename (if you want to be paranoid then
> within the POSIX filename limits). Try to see if it is there, if not make
> one if it is there, make a new random value.
>
> If you are ready to use platform specific code, then you might be able to
> ask for your own process ID (possibly thread ID as well in MT) and use
> those. I am not much familiar with POSIX, but it might provide functions
> for both - and that is standard, too. And portable to many platforms.
>[/color]
There is a race condition in what you describe.
The only way to guarentee that a file is not there is to use the
"exclusive" mode (O_EXCL on unix) and create the file.
I don't think there is any way to do this using std::ftream.
Gianni Mariani wrote:[color=blue]
> White Wolf wrote:[color=green]
>> Dave Theese wrote:
>>[color=darkred]
>>> Hello all,
>>>
>>> We're presented with the problem of needing to generate a unique
>>> file name. I've had some thoughts, but also wanted to solicit
>>> suggestions
>>> from the group.
>>>
>>> Any suggestions for schemes, using only *standard* C++, to do this?[/color]
>>
>>
>> If you want to stick to standard C++ then (IMHO) the only way to do
>> it is trial and error. Make a random filename (if you want to be
>> paranoid then within the POSIX filename limits). Try to see if it
>> is there, if not make one if it is there, make a new random value.
>>
>> If you are ready to use platform specific code, then you might be
>> able to ask for your own process ID (possibly thread ID as well in
>> MT) and use those. I am not much familiar with POSIX, but it might
>> provide functions for both - and that is standard, too. And
>> portable to many platforms.
>>[/color]
>
> There is a race condition in what you describe.
>
> The only way to guarentee that a file is not there is to use the
> "exclusive" mode (O_EXCL on unix) and create the file.
>
> I don't think there is any way to do this using std::ftream.[/color]
AFAIK files being created are opened exclusive on all systems by default.
Also AFAIK fstream *only* does exclusive open, since if it did not, it
should have provided locking capabilities.
White Wolf wrote:[color=blue]
> Gianni Mariani wrote:
>[/color]
....[color=blue][color=green]
>>
>>There is a race condition in what you describe.
>>
>>The only way to guarentee that a file is not there is to use the
>>"exclusive" mode (O_EXCL on unix) and create the file.
>>
>>I don't think there is any way to do this using std::ftream.[/color]
>
>
> AFAIK files being created are opened exclusive on all systems by default.
> Also AFAIK fstream *only* does exclusive open, since if it did not, it
> should have provided locking capabilities.
>[/color]
The code below :
#include <fstream>
int main()
{
std::fstream x( "AFILE", std::ios_base:: out );
}
Produced the following system call :
open("AFILE", O_WRONLY|O_CREA T|O_TRUNC, 0666)
There is no O_EXCL flag set. Either gcc 3.3.1 is non-compliant or
you're wrong or I mis-understood what you're saying.
Gianni Mariani wrote:[color=blue]
> White Wolf wrote:[color=green]
>> Gianni Mariani wrote:
>>[/color]
> ...[color=green][color=darkred]
>>>
>>> There is a race condition in what you describe.
>>>
>>> The only way to guarentee that a file is not there is to use the
>>> "exclusive" mode (O_EXCL on unix) and create the file.
>>>
>>> I don't think there is any way to do this using std::ftream.[/color]
>>
>>
>> AFAIK files being created are opened exclusive on all systems by
>> default. Also AFAIK fstream *only* does exclusive open, since if it
>> did not, it should have provided locking capabilities.
>>[/color]
>
> The code below :
>
> #include <fstream>
>
> int main()
> {
> std::fstream x( "AFILE", std::ios_base:: out );
> }
>
>
> Produced the following system call :
>
> open("AFILE", O_WRONLY|O_CREA T|O_TRUNC, 0666)
>
>
> There is no O_EXCL flag set. Either gcc 3.3.1 is non-compliant or
> you're wrong or I mis-understood what you're saying.[/color]
One of those. :-) Last time I was checking those things (I cannot recall on
which OSes I really did) when you have _created_ a file (it was not there)
there was no way to open it not-exclusively. You had to close and reopen
it. Probably that was too long time ago and it is different nowadays. But
it made sense to me.
IMHO since fstream provides no standard way to get the file descriptor and
no interface for file locking, it strikes me as a design error to open files
for shared access inside it.
Dave Theese wrote:
[color=blue]
> Hello all,
>
> We're presented with the problem of needing to generate a unique file name.
> I've had some thoughts, but also wanted to solicit suggestions from the
> group.
>
> Any suggestions for schemes, using only *standard* C++, to do this?
>
> Thanks,
> Dave
>
>
>[/color]
std::tmpnam() is the closest thing I know of.
-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Kevin Goodsell wrote:[color=blue]
> Dave Theese wrote:
>[color=green]
>> Hello all,
>>
>> We're presented with the problem of needing to generate a unique
>> file name. I've had some thoughts, but also wanted to solicit
>> suggestions from the group.
>>
>> Any suggestions for schemes, using only *standard* C++, to do this?
>>[/color]
>
> std::tmpnam() is the closest thing I know of.[/color]
Ahh! That one I did not know... Back to the books...
White Wolf wrote:[color=blue]
> Kevin Goodsell wrote:[color=green]
>> Dave Theese wrote:
>>[color=darkred]
>>> Hello all,
>>>
>>> We're presented with the problem of needing to generate a unique
>>> file name. I've had some thoughts, but also wanted to solicit
>>> suggestions from the group.
>>>
>>> Any suggestions for schemes, using only *standard* C++, to do this?
>>>[/color]
>>
>> std::tmpnam() is the closest thing I know of.[/color]
>
> Ahh! That one I did not know... Back to the books...[/color]
In addition to this I also see tmpfile() to open it and make it sure that it
is cleaned up upon process termination.
However for tmpnam I see no quarantee in the standard that it returns a name
which attempts to be unique in the system. It only says that it will not
return the same name twice and will not return the name of an existing file.
White Wolf wrote:
[color=blue]
>
> In addition to this I also see tmpfile() to open it and make it sure that it
> is cleaned up upon process termination.[/color]
Unfortunately as a FILE *, not fstream.
[color=blue]
>
> However for tmpnam I see no quarantee in the standard that it returns a name
> which attempts to be unique in the system. It only says that it will not
> return the same name twice and will not return the name of an existing file.
>[/color]
If a file with the name doesn't exist, doesn't that imply the name is
unique?
One possible problem with tmpnam is that the file could suddenly spring
into existence after you retrieve the name, before you can create it
yourself.
-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Kevin Goodsell wrote:[color=blue]
> White Wolf wrote:
>[color=green]
>>
>> In addition to this I also see tmpfile() to open it and make it sure
>> that it is cleaned up upon process termination.[/color]
>
> Unfortunately as a FILE *, not fstream.
>[color=green]
>>
>> However for tmpnam I see no quarantee in the standard that it
>> returns a name which attempts to be unique in the system. It only
>> says that it will not return the same name twice and will not return
>> the name of an existing file.
>>[/color]
>
> If a file with the name doesn't exist, doesn't that imply the name is
> unique?[/color]
Of course not. It implies that *at the time* when the implementation has
checked it, it was not there. But at the time your code tries to create it,
it might be there. There can be several processes running on a computer.
And several comupters accessing the same disk.
[color=blue]
> One possible problem with tmpnam is that the file could suddenly
> spring
> into existence after you retrieve the name, before you can create it
> yourself.[/color]
Yes. And that is what it means "not unique in the system". There is no
bulletin board where all processes on all the computers accessing this
storage area would place a post-it: I am using this name, do not take it!
On Sun, 14 Sep 2003 03:06:19 +0300, "White Wolf" <wolof@freemail .hu>
wrote in comp.lang.c++:
[color=blue]
> Kevin Goodsell wrote:[color=green]
> > White Wolf wrote:
> >[color=darkred]
> >>
> >> In addition to this I also see tmpfile() to open it and make it sure
> >> that it is cleaned up upon process termination.[/color]
> >
> > Unfortunately as a FILE *, not fstream.
> >[color=darkred]
> >>
> >> However for tmpnam I see no quarantee in the standard that it
> >> returns a name which attempts to be unique in the system. It only
> >> says that it will not return the same name twice and will not return
> >> the name of an existing file.
> >>[/color]
> >
> > If a file with the name doesn't exist, doesn't that imply the name is
> > unique?[/color]
>
> Of course not. It implies that *at the time* when the implementation has
> checked it, it was not there. But at the time your code tries to create it,
> it might be there. There can be several processes running on a computer.
> And several comupters accessing the same disk.
>[color=green]
> > One possible problem with tmpnam is that the file could suddenly
> > spring
> > into existence after you retrieve the name, before you can create it
> > yourself.[/color]
>
> Yes. And that is what it means "not unique in the system". There is no
> bulletin board where all processes on all the computers accessing this
> storage area would place a post-it: I am using this name, do not take it![/color]
Since neither C++, nor C from which it inherits the tmpnam() library
function, define or specifically support multiple processes, it is
impossible for a library function to provide the guarantees that the
OP wants.
File systems belong to operating systems, not to C++ or any other
language. The best thing to do in a case like this is to use a
platform specific extension, if one is available.
Jack Klein wrote:
[SNIP][color=blue]
> Since neither C++, nor C from which it inherits the tmpnam() library
> function, define or specifically support multiple processes, it is
> impossible for a library function to provide the guarantees that the
> OP wants.[/color]
:-)
[color=blue]
> File systems belong to operating systems, not to C++ or any other
> language. The best thing to do in a case like this is to use a
> platform specific extension, if one is available.[/color]
So back to square one. Trial and error. tmpnam might give back a unique
name, but it is only unique at that instance - when the program has checked
the files existence. So basically we are where we were in my first post,
except that we have a standard way to generate (limited number of!) those
filenames.
Jan Rendek wrote:[color=blue][color=green]
>> std::tmpnam() is the closest thing I know of.[/color]
>
> I think it is deprecated and replaced by mkstemp()[/color]
No it is not. Neither in C99 nor in C++98 standards.
mkstemp is not a standard function. Neither in C99 nor in C++98 standards.
Comment