diff --git a/Foundation/include/Poco/File.h b/Foundation/include/Poco/File.h index afecf3212..a6acea46b 100644 --- a/Foundation/include/Poco/File.h +++ b/Foundation/include/Poco/File.h @@ -183,18 +183,24 @@ public: /// /// Does nothing on Windows. - void copyTo(const std::string& path) const; + void copyTo(const std::string& path, bool failOnOverwrite = false) const; /// Copies the file (or directory) to the given path. /// The target path can be a directory. /// /// A directory is copied recursively. + /// If failOnOverwrite is set the Method throws an FileExists Exception + /// if the File already exists. - void moveTo(const std::string& path); + void moveTo(const std::string& path, bool failOnOverwrite = false); /// Copies the file (or directory) to the given path and /// removes the original file. The target path can be a directory. + /// If failOnOverwrite is set the Method throws an FileExists Exception + /// if the File already exists. - void renameTo(const std::string& path); + void renameTo(const std::string& path, bool failOnOverwrite = false); /// Renames the file to the new name. + /// If failOnOverwrite is set the Method throws an FileExists Exception + /// if the File already exists. void linkTo(const std::string& path, LinkType type = LINK_SYMBOLIC) const; /// Creates a link (symbolic or hard, depending on type argument) @@ -253,7 +259,7 @@ public: /// exception for the last file-related error. protected: - void copyDirectory(const std::string& path) const; + void copyDirectory(const std::string& path, bool failOnOverwrite = false) const; /// Copies a directory. Used internally by copyTo(). }; diff --git a/Foundation/include/Poco/File_UNIX.h b/Foundation/include/Poco/File_UNIX.h index 34a15c573..d0739bf4a 100644 --- a/Foundation/include/Poco/File_UNIX.h +++ b/Foundation/include/Poco/File_UNIX.h @@ -51,8 +51,8 @@ protected: void setSizeImpl(FileSizeImpl size); void setWriteableImpl(bool flag = true); void setExecutableImpl(bool flag = true); - void copyToImpl(const std::string& path) const; - void renameToImpl(const std::string& path); + void copyToImpl(const std::string& path, bool failOnOverwrite = false) const; + void renameToImpl(const std::string& path, bool failOnOverwrite = false); void linkToImpl(const std::string& path, int type) const; void removeImpl(); bool createFileImpl(); diff --git a/Foundation/include/Poco/File_VX.h b/Foundation/include/Poco/File_VX.h index 3d66f9664..8fa884ee7 100644 --- a/Foundation/include/Poco/File_VX.h +++ b/Foundation/include/Poco/File_VX.h @@ -51,8 +51,8 @@ protected: void setSizeImpl(FileSizeImpl size); void setWriteableImpl(bool flag = true); void setExecutableImpl(bool flag = true); - void copyToImpl(const std::string& path) const; - void renameToImpl(const std::string& path); + void copyToImpl(const std::string& path, bool failOnOverwrite = false) const; + void renameToImpl(const std::string& path, bool failOnOverwrite = false); void linkToImpl(const std::string& path, int type) const; void removeImpl(); bool createFileImpl(); diff --git a/Foundation/include/Poco/File_WIN32.h b/Foundation/include/Poco/File_WIN32.h index 2d8b88807..d4f562535 100644 --- a/Foundation/include/Poco/File_WIN32.h +++ b/Foundation/include/Poco/File_WIN32.h @@ -52,8 +52,8 @@ protected: void setSizeImpl(FileSizeImpl size); void setWriteableImpl(bool flag = true); void setExecutableImpl(bool flag = true); - void copyToImpl(const std::string& path) const; - void renameToImpl(const std::string& path); + void copyToImpl(const std::string& path, bool failOnOverwrite = false) const; + void renameToImpl(const std::string& path, bool failOnOverwrite = false); void linkToImpl(const std::string& path, int type) const; void removeImpl(); bool createFileImpl(); diff --git a/Foundation/include/Poco/File_WIN32U.h b/Foundation/include/Poco/File_WIN32U.h index 835da87a1..5d1d304e0 100644 --- a/Foundation/include/Poco/File_WIN32U.h +++ b/Foundation/include/Poco/File_WIN32U.h @@ -52,8 +52,8 @@ protected: void setSizeImpl(FileSizeImpl size); void setWriteableImpl(bool flag = true); void setExecutableImpl(bool flag = true); - void copyToImpl(const std::string& path) const; - void renameToImpl(const std::string& path); + void copyToImpl(const std::string& path, bool failOnOverwrite = false) const; + void renameToImpl(const std::string& path, bool failOnOverwrite = false); void linkToImpl(const std::string& path, int type) const; void removeImpl(); bool createFileImpl(); diff --git a/Foundation/include/Poco/File_WINCE.h b/Foundation/include/Poco/File_WINCE.h index c1ba4f350..38452578e 100644 --- a/Foundation/include/Poco/File_WINCE.h +++ b/Foundation/include/Poco/File_WINCE.h @@ -52,8 +52,8 @@ protected: void setSizeImpl(FileSizeImpl size); void setWriteableImpl(bool flag = true); void setExecutableImpl(bool flag = true); - void copyToImpl(const std::string& path) const; - void renameToImpl(const std::string& path); + void copyToImpl(const std::string& path, bool failOnOverwrite = false) const; + void renameToImpl(const std::string& path, bool failOnOverwrite = false); void linkToImpl(const std::string& path, int type) const; void removeImpl(); bool createFileImpl(); diff --git a/Foundation/src/File.cpp b/Foundation/src/File.cpp index ec198d139..1c1ee015f 100644 --- a/Foundation/src/File.cpp +++ b/Foundation/src/File.cpp @@ -208,7 +208,7 @@ File& File::setExecutable(bool flag) } -void File::copyTo(const std::string& path) const +void File::copyTo(const std::string& path, bool failOnOverwrite) const { Path src(getPathImpl()); Path dest(path); @@ -219,13 +219,13 @@ void File::copyTo(const std::string& path) const dest.setFileName(src.getFileName()); } if (isDirectory()) - copyDirectory(dest.toString()); + copyDirectory(dest.toString(), failOnOverwrite); else - copyToImpl(dest.toString()); + copyToImpl(dest.toString(), failOnOverwrite); } -void File::copyDirectory(const std::string& path) const +void File::copyDirectory(const std::string& path, bool failOnOverwrite) const { File target(path); target.createDirectories(); @@ -236,22 +236,22 @@ void File::copyDirectory(const std::string& path) const DirectoryIterator end; for (; it != end; ++it) { - it->copyTo(path); + it->copyTo(path, failOnOverwrite); } } -void File::moveTo(const std::string& path) +void File::moveTo(const std::string& path, bool failOnOverwrite) { - copyTo(path); + copyTo(path, failOnOverwrite); remove(true); setPathImpl(path); } -void File::renameTo(const std::string& path) +void File::renameTo(const std::string& path, bool failOnOverwrite) { - renameToImpl(path); + renameToImpl(path, failOnOverwrite); setPathImpl(path); } diff --git a/Foundation/src/File_UNIX.cpp b/Foundation/src/File_UNIX.cpp index f345eb88b..f89a92ef3 100644 --- a/Foundation/src/File_UNIX.cpp +++ b/Foundation/src/File_UNIX.cpp @@ -326,7 +326,7 @@ void FileImpl::setExecutableImpl(bool flag) } -void FileImpl::copyToImpl(const std::string& path) const +void FileImpl::copyToImpl(const std::string& path, bool failOnOverwrite) const { poco_assert (!_path.empty()); @@ -340,8 +340,12 @@ void FileImpl::copyToImpl(const std::string& path) const handleLastErrorImpl(_path); } const long blockSize = st.st_blksize; - - int dd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, st.st_mode); + int dd; + if (failOnOverwrite) { + dd = open(path.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_WRONLY, st.st_mode); + } else { + dd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, st.st_mode); + } if (dd == -1) { close(sd); @@ -376,7 +380,7 @@ void FileImpl::copyToImpl(const std::string& path) const } -void FileImpl::renameToImpl(const std::string& path) +void FileImpl::renameToImpl(const std::string& path, bool failOnOverwrite = false) { poco_assert (!_path.empty()); diff --git a/Foundation/src/File_VX.cpp b/Foundation/src/File_VX.cpp index 9f59b478a..eeac49143 100644 --- a/Foundation/src/File_VX.cpp +++ b/Foundation/src/File_VX.cpp @@ -232,7 +232,7 @@ void FileImpl::setExecutableImpl(bool flag) } -void FileImpl::copyToImpl(const std::string& path) const +void FileImpl::copyToImpl(const std::string& path, bool failOnOverwrite) const { poco_assert (!_path.empty()); @@ -247,7 +247,13 @@ void FileImpl::copyToImpl(const std::string& path) const } const long blockSize = st.st_blksize; - int dd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, st.st_mode & S_IRWXU); + int dd; + if (failOnOverwrite) { + dd = open(path.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_WRONLY, st.st_mode & S_IRWXU); + } else { + dd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, st.st_mode & S_IRWXU); + } + if (dd == -1) { close(sd); @@ -276,7 +282,7 @@ void FileImpl::copyToImpl(const std::string& path) const } -void FileImpl::renameToImpl(const std::string& path) +void FileImpl::renameToImpl(const std::string& path, bool failOnOverwrite) { poco_assert (!_path.empty()); diff --git a/Foundation/src/File_WIN32.cpp b/Foundation/src/File_WIN32.cpp index 2c569e369..b894419cf 100644 --- a/Foundation/src/File_WIN32.cpp +++ b/Foundation/src/File_WIN32.cpp @@ -288,21 +288,27 @@ void FileImpl::setExecutableImpl(bool flag) } -void FileImpl::copyToImpl(const std::string& path) const +void FileImpl::copyToImpl(const std::string& path, bool failOnOverwrite) const { poco_assert (!_path.empty()); - if (CopyFileA(_path.c_str(), path.c_str(), FALSE) == 0) + if (CopyFileA(_path.c_str(), path.c_str(), failOnOverwrite) == 0) handleLastErrorImpl(_path); } -void FileImpl::renameToImpl(const std::string& path) +void FileImpl::renameToImpl(const std::string& path, bool failOnOverwrite) { poco_assert (!_path.empty()); - if (MoveFileExA(_path.c_str(), path.c_str(), MOVEFILE_REPLACE_EXISTING) == 0) - handleLastErrorImpl(_path); + if (failOnOverwrite) { + if (MoveFileExA(_path.c_str(), path.c_str(), NULL) == 0) + handleLastErrorImpl(_path); + } else { + if (MoveFileExA(_path.c_str(), path.c_str(), MOVEFILE_REPLACE_EXISTING) == 0) + handleLastErrorImpl(_path); + } + } diff --git a/Foundation/src/File_WIN32U.cpp b/Foundation/src/File_WIN32U.cpp index f8609f17c..b37c1f3f9 100644 --- a/Foundation/src/File_WIN32U.cpp +++ b/Foundation/src/File_WIN32U.cpp @@ -291,25 +291,30 @@ void FileImpl::setExecutableImpl(bool flag) } -void FileImpl::copyToImpl(const std::string& path) const +void FileImpl::copyToImpl(const std::string& path, bool failOnOverwrite) const { poco_assert (!_path.empty()); std::wstring upath; convertPath(path, upath); - if (CopyFileW(_upath.c_str(), upath.c_str(), FALSE) == 0) + if (CopyFileW(_upath.c_str(), upath.c_str(), failOnOverwrite) == 0) handleLastErrorImpl(_path); } -void FileImpl::renameToImpl(const std::string& path) +void FileImpl::renameToImpl(const std::string& path, bool failOnOverwrite) { poco_assert (!_path.empty()); std::wstring upath; convertPath(path, upath); - if (MoveFileExW(_upath.c_str(), upath.c_str(), MOVEFILE_REPLACE_EXISTING) == 0) - handleLastErrorImpl(_path); + if (failOnOverwrite) { + if (MoveFileExW(_upath.c_str(), upath.c_str(), NULL) == 0) + handleLastErrorImpl(_path); + } else { + if (MoveFileExW(_upath.c_str(), upath.c_str(), MOVEFILE_REPLACE_EXISTING) == 0) + handleLastErrorImpl(_path); + } } diff --git a/Foundation/src/File_WINCE.cpp b/Foundation/src/File_WINCE.cpp index ea726c4bc..f8355cd51 100644 --- a/Foundation/src/File_WINCE.cpp +++ b/Foundation/src/File_WINCE.cpp @@ -277,18 +277,18 @@ void FileImpl::setExecutableImpl(bool flag) } -void FileImpl::copyToImpl(const std::string& path) const +void FileImpl::copyToImpl(const std::string& path, bool failOnOverwrite) const { poco_assert (!_path.empty()); std::wstring upath; convertPath(path, upath); - if (CopyFileW(_upath.c_str(), upath.c_str(), FALSE) == 0) + if (CopyFileW(_upath.c_str(), upath.c_str(), failOnOverwrite) == 0) handleLastErrorImpl(_path); } -void FileImpl::renameToImpl(const std::string& path) +void FileImpl::renameToImpl(const std::string& path, bool failOnOverwrite) { poco_assert (!_path.empty());