Unique file name generation

D

Dave Theese

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
 
W

White Wolf

Dave said:
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?

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.
 
G

Gianni Mariani

White said:
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.

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.
 
W

White Wolf

Gianni said:
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.

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.
 
G

Gianni Mariani

White said:
Gianni Mariani wrote:
....


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.

The code below :

#include <fstream>

int main()
{
std::fstream x( "AFILE", std::ios_base::eek:ut );
}


Produced the following system call :

open("AFILE", O_WRONLY|O_CREAT|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.
 
W

White Wolf

Gianni said:
The code below :

#include <fstream>

int main()
{
std::fstream x( "AFILE", std::ios_base::eek:ut );
}


Produced the following system call :

open("AFILE", O_WRONLY|O_CREAT|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.

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.
 
K

Kevin Goodsell

Dave said:
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

std::tmpnam() is the closest thing I know of.

-Kevin
 
W

White Wolf

White said:
Ahh! That one I did not know... Back to the books...

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.
 
K

Kevin Goodsell

White said:
In addition to this I also see tmpfile() to open it and make it sure that it
is cleaned up upon process termination.

Unfortunately as a FILE *, not fstream.
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.

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
 
W

White Wolf

Kevin said:
Unfortunately as a FILE *, not fstream.


If a file with the name doesn't exist, doesn't that imply the name is
unique?

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.
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.

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!
 
J

Jack Klein

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.


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!

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
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
W

White Wolf

Jack Klein wrote:
[SNIP]
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.

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.
 
J

Jan Rendek

std::tmpnam() is the closest thing I know of.

I think it is deprecated and replaced by mkstemp()
Like this:

#include <cstdlib>

int main() {
char _tmpFileName[] = "MYAPPXXXXXX";
mkstemp(_tmpFileName);

_tmpfile.open(_tmpFileName, ios::eek:ut | ios::in | ios::trunc);
}
 
A

Attila Feher

Jan said:
I think it is deprecated and replaced by mkstemp()

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.

Please refrain from posting wild guesses.
 
F

Frank Schmitt

Attila Feher said:
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.

I guess Jan got confused by the (Linux?) manpage for tmpnam and/or the gcc
compiler; both state that tmpnam() is deprecated and mkstemp() should be used
instead.
Of course, given that tmpnam() is standard and mkstemp() is not, this
advice is quite unfortunate.

kind regards
frank
 
A

Attila Feher

Frank said:
I guess Jan got confused by the (Linux?) manpage for tmpnam and/or
the gcc compiler; both state that tmpnam() is deprecated and
mkstemp() should be used instead.
Of course, given that tmpnam() is standard and mkstemp() is not, this
advice is quite unfortunate.

Hm. Then I guess if some of you know how to report bugs regarding those
manpages it would be a good idea to report this. I mean they can of course
say in the manpage that in our environment we have mkstemp what is far
superior to the language standard tmpnam function and we suggest you use
ours... but is I understand you the current wording is very misleading.
 
J

Jan Rendek

mkstemp is not a standard function. Neither in C99 nor in C++98 standards.

My mistake. I was ideed mislead by the linux man pages.
 
A

Attila Feher

Jan said:
My mistake. I was ideed mislead by the linux man pages.

First time in my life that Linux is actually blamed not Mircosoft! Let's
remember the date. :)
 
G

Gianni Mariani

Attila said:
Hm. Then I guess if some of you know how to report bugs regarding those
manpages it would be a good idea to report this. I mean they can of course
say in the manpage that in our environment we have mkstemp what is far
superior to the language standard tmpnam function and we suggest you use
ours... but is I understand you the current wording is very misleading.

I think there is a security vulnerability with tmpnam.

Standard or not, it is highly reccomended NOT to add security
vulnerabilities. I'd have to agree with the GNU guys on this - (if my
sentence above is true).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top