diff options
author | Brad King <brad.king@kitware.com> | 2021-04-14 16:13:59 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2021-04-14 16:13:59 (GMT) |
commit | eef585efaa49d546a9af2939a147c971c76de03e (patch) | |
tree | 35125ce532848216258f06ff643b1cde6090c3b2 /Source/kwsys/SystemTools.cxx | |
parent | ff9e922902834a68d7872fa2d7476f28c865decd (diff) | |
parent | a790167101290eaf77d7a3ef8fd807160af1b9a9 (diff) | |
download | CMake-eef585efaa49d546a9af2939a147c971c76de03e.zip CMake-eef585efaa49d546a9af2939a147c971c76de03e.tar.gz CMake-eef585efaa49d546a9af2939a147c971c76de03e.tar.bz2 |
Merge branch 'upstream-KWSys' into update-kwsys
# By KWSys Upstream
* upstream-KWSys:
KWSys 2021-04-14 (7ab1c601)
Diffstat (limited to 'Source/kwsys/SystemTools.cxx')
-rw-r--r-- | Source/kwsys/SystemTools.cxx | 300 |
1 files changed, 166 insertions, 134 deletions
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 4d974a8..2518845 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -882,21 +882,24 @@ FILE* SystemTools::Fopen(const std::string& file, const char* mode) #endif } -bool SystemTools::MakeDirectory(const char* path, const mode_t* mode) +Status SystemTools::MakeDirectory(const char* path, const mode_t* mode) { if (!path) { - return false; + return Status::POSIX(EINVAL); } return SystemTools::MakeDirectory(std::string(path), mode); } -bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode) +Status SystemTools::MakeDirectory(std::string const& path, const mode_t* mode) { - if (SystemTools::PathExists(path)) { - return SystemTools::FileIsDirectory(path); - } if (path.empty()) { - return false; + return Status::POSIX(EINVAL); + } + if (SystemTools::PathExists(path)) { + if (SystemTools::FileIsDirectory(path)) { + return Status::Success(); + } + return Status::POSIX(EEXIST); } std::string dir = path; SystemTools::ConvertToUnixSlashes(dir); @@ -914,15 +917,11 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode) ++pos; } topdir = dir; - if (Mkdir(topdir, mode) != 0) { - // if it is some other error besides directory exists - // then return false - if (errno != EEXIST) { - return false; - } + if (Mkdir(topdir, mode) != 0 && errno != EEXIST) { + return Status::POSIX_errno(); } - return true; + return Status::Success(); } // replace replace with with as many times as it shows up in source. @@ -1411,18 +1410,18 @@ int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf) #endif } -bool SystemTools::Touch(const std::string& filename, bool create) +Status SystemTools::Touch(std::string const& filename, bool create) { if (!SystemTools::FileExists(filename)) { if (create) { FILE* file = Fopen(filename, "a+b"); if (file) { fclose(file); - return true; + return Status::Success(); } - return false; + return Status::POSIX_errno(); } else { - return true; + return Status::Success(); } } #if defined(_WIN32) && !defined(__CYGWIN__) @@ -1430,31 +1429,32 @@ bool SystemTools::Touch(const std::string& filename, bool create) FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if (!h) { - return false; + return Status::Windows_GetLastError(); } FILETIME mtime; GetSystemTimeAsFileTime(&mtime); if (!SetFileTime(h, 0, 0, &mtime)) { + Status status = Status::Windows_GetLastError(); CloseHandle(h); - return false; + return status; } CloseHandle(h); #elif KWSYS_CXX_HAS_UTIMENSAT // utimensat is only available on newer Unixes and macOS 10.13+ if (utimensat(AT_FDCWD, filename.c_str(), nullptr, 0) < 0) { - return false; + return Status::POSIX_errno(); } #else // fall back to utimes if (utimes(filename.c_str(), nullptr) < 0) { - return false; + return Status::POSIX_errno(); } #endif - return true; + return Status::Success(); } -bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2, - int* result) +Status SystemTools::FileTimeCompare(std::string const& f1, + std::string const& f2, int* result) { // Default to same time. *result = 0; @@ -1462,11 +1462,11 @@ bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2, // POSIX version. Use stat function to get file modification time. struct stat s1; if (stat(f1.c_str(), &s1) != 0) { - return false; + return Status::POSIX_errno(); } struct stat s2; if (stat(f2.c_str(), &s2) != 0) { - return false; + return Status::POSIX_errno(); } # if KWSYS_CXX_STAT_HAS_ST_MTIM // Compare using nanosecond resolution. @@ -1504,17 +1504,17 @@ bool SystemTools::FileTimeCompare(const std::string& f1, const std::string& f2, WIN32_FILE_ATTRIBUTE_DATA f2d; if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f1).c_str(), GetFileExInfoStandard, &f1d)) { - return false; + return Status::Windows_GetLastError(); } if (!GetFileAttributesExW(Encoding::ToWindowsExtendedPath(f2).c_str(), GetFileExInfoStandard, &f2d)) { - return false; + return Status::Windows_GetLastError(); } // Compare the file times using resolution provided by system call. *result = (int)CompareFileTime(&f1d.ftLastWriteTime, &f2d.ftLastWriteTime); #endif - return true; + return Status::Success(); } // Return a capitalized string (i.e the first letter is uppercased, all other @@ -2129,8 +2129,8 @@ static std::string FileInDir(const std::string& source, const std::string& dir) return new_destination + '/' + SystemTools::GetFilenameName(source); } -bool SystemTools::CopyFileIfDifferent(const std::string& source, - const std::string& destination) +Status SystemTools::CopyFileIfDifferent(std::string const& source, + std::string const& destination) { // special check for a destination that is a directory // FilesDiffer does not handle file to directory compare @@ -2147,7 +2147,7 @@ bool SystemTools::CopyFileIfDifferent(const std::string& source, } } // at this point the files must be the same so return true - return true; + return Status::Success(); } #define KWSYS_ST_BUFFER 4096 @@ -2273,13 +2273,13 @@ bool SystemTools::TextFilesDiffer(const std::string& path1, return false; } -bool SystemTools::CopyFileContentBlockwise(const std::string& source, - const std::string& destination) +Status SystemTools::CopyFileContentBlockwise(std::string const& source, + std::string const& destination) { // Open files kwsys::ifstream fin(source.c_str(), std::ios::in | std::ios::binary); if (!fin) { - return false; + return Status::POSIX_errno(); } // try and remove the destination file so that read only destination files @@ -2291,7 +2291,7 @@ bool SystemTools::CopyFileContentBlockwise(const std::string& source, kwsys::ofstream fout(destination.c_str(), std::ios::out | std::ios::trunc | std::ios::binary); if (!fout) { - return false; + return Status::POSIX_errno(); } // This copy loop is very sensitive on certain platforms with @@ -2320,10 +2320,10 @@ bool SystemTools::CopyFileContentBlockwise(const std::string& source, fout.close(); if (!fout) { - return false; + return Status::POSIX_errno(); } - return true; + return Status::Success(); } /** @@ -2338,13 +2338,13 @@ bool SystemTools::CopyFileContentBlockwise(const std::string& source, * - The underlying filesystem does not support file cloning * - An unspecified error occurred */ -bool SystemTools::CloneFileContent(const std::string& source, - const std::string& destination) +Status SystemTools::CloneFileContent(std::string const& source, + std::string const& destination) { #if defined(__linux) && defined(FICLONE) int in = open(source.c_str(), O_RDONLY); if (in < 0) { - return false; + return Status::POSIX_errno(); } SystemTools::RemoveFile(destination); @@ -2352,38 +2352,42 @@ bool SystemTools::CloneFileContent(const std::string& source, int out = open(destination.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (out < 0) { + Status status = Status::POSIX_errno(); close(in); - return false; + return status; } - int result = ioctl(out, FICLONE, in); + Status status = Status::Success(); + if (ioctl(out, FICLONE, in) < 0) { + status = Status::POSIX_errno(); + } close(in); close(out); - if (result < 0) { - return false; - } - - return true; + return status; #else (void)source; (void)destination; - return false; + return Status::POSIX(ENOSYS); #endif } /** * Copy a file named by "source" to the file named by "destination". */ -bool SystemTools::CopyFileAlways(const std::string& source, - const std::string& destination) +Status SystemTools::CopyFileAlways(std::string const& source, + std::string const& destination) { + Status status; mode_t perm = 0; - bool perms = SystemTools::GetPermissions(source, perm); + Status perms = SystemTools::GetPermissions(source, perm); std::string real_destination = destination; if (SystemTools::FileIsDirectory(source)) { - SystemTools::MakeDirectory(destination); + status = SystemTools::MakeDirectory(destination); + if (!status) { + return status; + } } else { // If destination is a directory, try to create a file with the same // name as the source in that directory. @@ -2400,30 +2404,34 @@ bool SystemTools::CopyFileAlways(const std::string& source, } // If files are the same do not copy if (SystemTools::SameFile(source, real_destination)) { - return true; + return status; } // Create destination directory - - SystemTools::MakeDirectory(destination_dir); - - if (!SystemTools::CloneFileContent(source, real_destination)) { - // if cloning did not succeed, fall back to blockwise copy - if (!SystemTools::CopyFileContentBlockwise(source, real_destination)) { - return false; + if (!destination_dir.empty()) { + status = SystemTools::MakeDirectory(destination_dir); + if (!status) { + return status; } } + + status = SystemTools::CloneFileContent(source, real_destination); + // if cloning did not succeed, fall back to blockwise copy + if (!status) { + status = SystemTools::CopyFileContentBlockwise(source, real_destination); + } + if (!status) { + return status; + } } if (perms) { - if (!SystemTools::SetPermissions(real_destination, perm)) { - return false; - } + status = SystemTools::SetPermissions(real_destination, perm); } - return true; + return status; } -bool SystemTools::CopyAFile(const std::string& source, - const std::string& destination, bool always) +Status SystemTools::CopyAFile(std::string const& source, + std::string const& destination, bool always) { if (always) { return SystemTools::CopyFileAlways(source, destination); @@ -2436,18 +2444,21 @@ bool SystemTools::CopyAFile(const std::string& source, * Copy a directory content from "source" directory to the directory named by * "destination". */ -bool SystemTools::CopyADirectory(const std::string& source, - const std::string& destination, bool always) +Status SystemTools::CopyADirectory(std::string const& source, + std::string const& destination, bool always) { + Status status; Directory dir; - if (dir.Load(source) == 0) { - return false; + status = dir.Load(source); + if (!status) { + return status; } - size_t fileNum; - if (!SystemTools::MakeDirectory(destination)) { - return false; + status = SystemTools::MakeDirectory(destination); + if (!status) { + return status; } - for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) { + + for (size_t fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) { if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 && strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..") != 0) { std::string fullPath = source; @@ -2457,18 +2468,20 @@ bool SystemTools::CopyADirectory(const std::string& source, std::string fullDestPath = destination; fullDestPath += "/"; fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum)); - if (!SystemTools::CopyADirectory(fullPath, fullDestPath, always)) { - return false; + status = SystemTools::CopyADirectory(fullPath, fullDestPath, always); + if (!status) { + return status; } } else { - if (!SystemTools::CopyAFile(fullPath, destination, always)) { - return false; + status = SystemTools::CopyAFile(fullPath, destination, always); + if (!status) { + return status; } } } } - return true; + return status; } // return size of file; also returns zero if no file exists @@ -2550,26 +2563,26 @@ std::string SystemTools::GetLastSystemError() return strerror(e); } -bool SystemTools::RemoveFile(const std::string& source) +Status SystemTools::RemoveFile(std::string const& source) { #ifdef _WIN32 std::wstring const& ws = Encoding::ToWindowsExtendedPath(source); if (DeleteFileW(ws.c_str())) { - return true; + return Status::Success(); } DWORD err = GetLastError(); if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) { - return true; + return Status::Success(); } if (err != ERROR_ACCESS_DENIED) { - return false; + return Status::Windows(err); } /* The file may be read-only. Try adding write permission. */ mode_t mode; if (!SystemTools::GetPermissions(source, mode) || !SystemTools::SetPermissions(source, S_IWRITE)) { SetLastError(err); - return false; + return Status::Windows(err); } const DWORD DIRECTORY_SOFT_LINK_ATTRS = @@ -2578,26 +2591,29 @@ bool SystemTools::RemoveFile(const std::string& source) if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & DIRECTORY_SOFT_LINK_ATTRS) == DIRECTORY_SOFT_LINK_ATTRS && RemoveDirectoryW(ws.c_str())) { - return true; + return Status::Success(); } if (DeleteFileW(ws.c_str()) || GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_PATH_NOT_FOUND) { - return true; + return Status::Success(); } /* Try to restore the original permissions. */ SystemTools::SetPermissions(source, mode); SetLastError(err); - return false; + return Status::Windows(err); #else - return unlink(source.c_str()) == 0 || errno == ENOENT; + if (unlink(source.c_str()) != 0 && errno != ENOENT) { + return Status::POSIX_errno(); + } + return Status::Success(); #endif } -bool SystemTools::RemoveADirectory(const std::string& source) +Status SystemTools::RemoveADirectory(std::string const& source) { // Add write permission to the directory so we can modify its // content to remove files and directories from it. - mode_t mode; + mode_t mode = 0; if (SystemTools::GetPermissions(source, mode)) { #if defined(_WIN32) && !defined(__CYGWIN__) mode |= S_IWRITE; @@ -2607,8 +2623,13 @@ bool SystemTools::RemoveADirectory(const std::string& source) SystemTools::SetPermissions(source, mode); } + Status status; Directory dir; - dir.Load(source); + status = dir.Load(source); + if (!status) { + return status; + } + size_t fileNum; for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) { if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 && @@ -2618,18 +2639,23 @@ bool SystemTools::RemoveADirectory(const std::string& source) fullPath += dir.GetFile(static_cast<unsigned long>(fileNum)); if (SystemTools::FileIsDirectory(fullPath) && !SystemTools::FileIsSymlink(fullPath)) { - if (!SystemTools::RemoveADirectory(fullPath)) { - return false; + status = SystemTools::RemoveADirectory(fullPath); + if (!status) { + return status; } } else { - if (!SystemTools::RemoveFile(fullPath)) { - return false; + status = SystemTools::RemoveFile(fullPath); + if (!status) { + return status; } } } } - return (Rmdir(source) == 0); + if (Rmdir(source) != 0) { + status = Status::POSIX_errno(); + } + return status; } /** @@ -3023,44 +3049,49 @@ bool SystemTools::FileIsFIFO(const std::string& name) } #if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::CreateSymlink(const std::string&, const std::string&) +Status SystemTools::CreateSymlink(std::string const&, std::string const&) { - return false; + return Status::Windows(ERROR_NOT_SUPPORTED); } #else -bool SystemTools::CreateSymlink(const std::string& origName, - const std::string& newName) +Status SystemTools::CreateSymlink(std::string const& origName, + std::string const& newName) { - return symlink(origName.c_str(), newName.c_str()) >= 0; + if (symlink(origName.c_str(), newName.c_str()) < 0) { + return Status::POSIX_errno(); + } + return Status::Success(); } #endif #if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::ReadSymlink(const std::string&, std::string&) +Status SystemTools::ReadSymlink(std::string const&, std::string&) { - return false; + return Status::Windows(ERROR_NOT_SUPPORTED); } #else -bool SystemTools::ReadSymlink(const std::string& newName, - std::string& origName) +Status SystemTools::ReadSymlink(std::string const& newName, + std::string& origName) { char buf[KWSYS_SYSTEMTOOLS_MAXPATH + 1]; int count = static_cast<int>( readlink(newName.c_str(), buf, KWSYS_SYSTEMTOOLS_MAXPATH)); - if (count >= 0) { - // Add null-terminator. - buf[count] = 0; - origName = buf; - return true; - } else { - return false; + if (count < 0) { + return Status::POSIX_errno(); } + // Add null-terminator. + buf[count] = 0; + origName = buf; + return Status::Success(); } #endif -int SystemTools::ChangeDirectory(const std::string& dir) +Status SystemTools::ChangeDirectory(std::string const& dir) { - return Chdir(dir); + if (Chdir(dir) < 0) { + return Status::POSIX_errno(); + } + return Status::Success(); } std::string SystemTools::GetCurrentWorkingDirectory() @@ -3957,7 +3988,8 @@ bool SystemToolsStatic::FileIsFullPath(const char* in_name, size_t len) return false; } -bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath) +Status SystemTools::GetShortPath(std::string const& path, + std::string& shortPath) { #if defined(_WIN32) && !defined(__CYGWIN__) std::string tempPath = path; // create a buffer @@ -3977,14 +4009,14 @@ bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath) } if (ret == 0) { - return false; + return Status::Windows_GetLastError(); } else { shortPath = Encoding::ToNarrow(&buffer[0]); - return true; + return Status::Success(); } #else shortPath = path; - return true; + return Status::Success(); #endif } @@ -4085,21 +4117,21 @@ int SystemTools::GetTerminalWidth() return width; } -bool SystemTools::GetPermissions(const char* file, mode_t& mode) +Status SystemTools::GetPermissions(const char* file, mode_t& mode) { if (!file) { - return false; + return Status::POSIX(EINVAL); } return SystemTools::GetPermissions(std::string(file), mode); } -bool SystemTools::GetPermissions(const std::string& file, mode_t& mode) +Status SystemTools::GetPermissions(std::string const& file, mode_t& mode) { #if defined(_WIN32) DWORD attr = GetFileAttributesW(Encoding::ToWindowsExtendedPath(file).c_str()); if (attr == INVALID_FILE_ATTRIBUTES) { - return false; + return Status::Windows_GetLastError(); } if ((attr & FILE_ATTRIBUTE_READONLY) != 0) { mode = (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6)); @@ -4122,27 +4154,27 @@ bool SystemTools::GetPermissions(const std::string& file, mode_t& mode) #else struct stat st; if (stat(file.c_str(), &st) < 0) { - return false; + return Status::POSIX_errno(); } mode = st.st_mode; #endif - return true; + return Status::Success(); } -bool SystemTools::SetPermissions(const char* file, mode_t mode, - bool honor_umask) +Status SystemTools::SetPermissions(const char* file, mode_t mode, + bool honor_umask) { if (!file) { - return false; + return Status::POSIX(EINVAL); } return SystemTools::SetPermissions(std::string(file), mode, honor_umask); } -bool SystemTools::SetPermissions(const std::string& file, mode_t mode, - bool honor_umask) +Status SystemTools::SetPermissions(std::string const& file, mode_t mode, + bool honor_umask) { if (!SystemTools::PathExists(file)) { - return false; + return Status::POSIX(ENOENT); } if (honor_umask) { mode_t currentMask = umask(0); @@ -4155,10 +4187,10 @@ bool SystemTools::SetPermissions(const std::string& file, mode_t mode, if (chmod(file.c_str(), mode) < 0) #endif { - return false; + return Status::POSIX_errno(); } - return true; + return Status::Success(); } std::string SystemTools::GetParentDirectory(const std::string& fileOrDir) |