From fd074aa05df58fd60d490bb4e367aa2c82338741 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 28 Sep 2012 01:02:38 +0300 Subject: [PATCH] Add an exclusive create flag to IO::File This flag is important in creating temp files, as it allows atomic creation of a new file. It also completes the set of create modes available on Win32. --- source/io/file.cpp | 11 ++++++++++- source/io/file.h | 9 ++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/source/io/file.cpp b/source/io/file.cpp index 862b607..208371d 100644 --- a/source/io/file.cpp +++ b/source/io/file.cpp @@ -17,7 +17,9 @@ File::File(const string &fn, Mode m, CreateMode cm) { if(!(m&M_RDWR)) throw invalid_argument("File::File mode"); - if(cm&~(C_CREATE|C_TRUNCATE)) + if(cm&~(C_CREATE|C_TRUNCATE|C_EXCLUSIVE)) + throw invalid_argument("File::File create"); + if((cm&C_EXCLUSIVE) && (!(cm&C_CREATE) || (cm&C_TRUNCATE))) throw invalid_argument("File::File create"); mode = m; @@ -38,6 +40,7 @@ File::File(const string &fn, Mode m, CreateMode cm) case C_CREATE: create_flags = OPEN_ALWAYS; break; case C_TRUNCATE: create_flags = TRUNCATE_EXISTING; break; case C_CREATE+C_TRUNCATE: create_flags = CREATE_ALWAYS; break; + case C_CREATE+C_EXCLUSIVE: create_flags = CREATE_NEW; break; } } @@ -47,6 +50,8 @@ File::File(const string &fn, Mode m, CreateMode cm) int err = GetLastError(); if(err==ERROR_FILE_NOT_FOUND) throw file_not_found(fn); + else if(err==ERROR_FILE_EXISTS) + throw file_already_exists(fn); else throw system_error(format("CreateFile(%s)", fn), err); } @@ -66,6 +71,8 @@ File::File(const string &fn, Mode m, CreateMode cm) flags |= O_CREAT; if(cm&C_TRUNCATE) flags |= O_TRUNC; + if(cm&C_EXCLUSIVE) + flags |= O_EXCL; } if(mode&M_APPEND) flags |= O_APPEND; @@ -78,6 +85,8 @@ File::File(const string &fn, Mode m, CreateMode cm) int err = errno; if(err==ENOENT) throw file_not_found(fn); + else if(err==EEXIST) + throw file_already_exists(fn); else throw system_error(format("open(%s)", fn), err); } diff --git a/source/io/file.h b/source/io/file.h index 430571f..4f8e5dd 100644 --- a/source/io/file.h +++ b/source/io/file.h @@ -17,6 +17,12 @@ public: file_not_found(const std::string &fn): std::runtime_error(fn) { } }; +class file_already_exists: public std::runtime_error +{ +public: + file_already_exists(const std::string &fn): std::runtime_error(fn) { } +}; + /** A class for reading and writing files. @@ -30,7 +36,8 @@ public: { C_NONE = 0, C_CREATE = 1, - C_TRUNCATE = 2 + C_TRUNCATE = 2, + C_EXCLUSIVE = 4 }; private: -- 2.45.2