[Dune] [#912] Dune on MinGW
Jö Fahlke
jorrit at jorrit.de
Tue May 10 13:40:24 CEST 2011
Am Tue, 10. May 2011, 12:19:52 +0200 schrieb Dr. Olaf Ippisch:
> The Problem is that the file needs to be directly opened for the method
> to be safe. So it would be necessary to have a function which directly
> opens the file with mkstemp and returns a file pointer. This would be
> safe. For Posix compatibility one could divert to a less safe version
> using tmpnam.
If I followed the discussion correctly we have the following requirements for
the temporary file after the function returns:
* It must exists, so no other process will use a file of the same name [1].
* We're not going to delete and recreate it [2].
* Creating it must not clobber any other existing file.
* We need the file name, so we can pass it along to other library routines.
* We're not interested in a file descriptor, file pointer, or fstream opened
to the file.
Then the correct procedure is as follows:
1. Generate a filename containing some random characters.
2. Open the file with O_CREAT|O_EXCL.
3. If opening fails with errno==EEXIST, go back to 1.
4. If opening fails for other reasons, error out.
5. Close the file.
6. Return the filename.
An implementation is given below.
Bye,
Jö.
[1] assuming the other process creates temporary files correctly itself.
[2] If we have to do that, the only race-safe way is to create a temporary
directory and use a file inside that directory.
#include <cstdlib>
#include <sstream>
#include <string>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
std::string tempfileByName(const std::string &prefix) {
int save_errno = errno;
while(true) {
// 1. Generate a filename containing some random characters
std::ostringstream name;
name << prefix;
name << std::rand();
// 2. Open the file with O_CREAT|O_EXCL.
int fd = open(name.str().c_str(), O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
// 3. If opening fails with errno==EEXISTS, go back to 1.
if(fd < 0 && errno == EEXIST)
continue;
// 4. If opening fails for other reasons, error out.
if(fd < 0) {
std::ostringstream msg;
msg << "Can't create temporary file, errno=" << errno;
errno = save_errno;
throw msg.str();
}
// 5. Close the file.
close(fd);
// 6. Return the filename.
errno = save_errno;
return(name.str());
}
}
--
If God had intended Man to Smoke, He would have set him on Fire.
-- fortune
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 828 bytes
Desc: Digital signature
URL: <https://lists.dune-project.org/pipermail/dune/attachments/20110510/309b88a6/attachment.sig>
More information about the Dune
mailing list