[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