1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

KWSys 2022-11-15 (6c92b9b0)

Code extracted from:

    https://gitlab.kitware.com/utils/kwsys.git

at commit 6c92b9b0e7a57380a86c5dc4a50fe633b72fe66a (master).

Upstream Shortlog
-----------------

Brad King (1):
      30e10c87 SystemTools: Report with copy operation failures which path failed
This commit is contained in:
KWSys Upstream
2022-11-15 07:51:35 -05:00
committed by Brad King
parent ee9c09548c
commit a9c659b1b6
2 changed files with 66 additions and 38 deletions

View File

@@ -2290,8 +2290,8 @@ static std::string FileInDir(const std::string& source, const std::string& dir)
return new_destination + '/' + SystemTools::GetFilenameName(source);
}
Status SystemTools::CopyFileIfDifferent(std::string const& source,
std::string const& destination)
SystemTools::CopyStatus 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
@@ -2308,7 +2308,7 @@ Status SystemTools::CopyFileIfDifferent(std::string const& source,
}
}
// at this point the files must be the same so return true
return Status::Success();
return CopyStatus{ Status::Success(), CopyStatus::NoPath };
}
#define KWSYS_ST_BUFFER 4096
@@ -2434,13 +2434,13 @@ bool SystemTools::TextFilesDiffer(const std::string& path1,
return false;
}
Status SystemTools::CopyFileContentBlockwise(std::string const& source,
std::string const& destination)
SystemTools::CopyStatus 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 Status::POSIX_errno();
return CopyStatus{ Status::POSIX_errno(), CopyStatus::SourcePath };
}
// try and remove the destination file so that read only destination files
@@ -2452,7 +2452,7 @@ Status SystemTools::CopyFileContentBlockwise(std::string const& source,
kwsys::ofstream fout(destination.c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
if (!fout) {
return Status::POSIX_errno();
return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
// This copy loop is very sensitive on certain platforms with
@@ -2481,10 +2481,10 @@ Status SystemTools::CopyFileContentBlockwise(std::string const& source,
fout.close();
if (!fout) {
return Status::POSIX_errno();
return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
return Status::Success();
return CopyStatus{ Status::Success(), CopyStatus::NoPath };
}
/**
@@ -2499,13 +2499,13 @@ Status SystemTools::CopyFileContentBlockwise(std::string const& source,
* - The underlying filesystem does not support file cloning
* - An unspecified error occurred
*/
Status SystemTools::CloneFileContent(std::string const& source,
std::string const& destination)
SystemTools::CopyStatus 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 Status::POSIX_errno();
return CopyStatus{ Status::POSIX_errno(), CopyStatus::SourcePath };
}
SystemTools::RemoveFile(destination);
@@ -2513,14 +2513,14 @@ Status SystemTools::CloneFileContent(std::string const& 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();
CopyStatus status{ Status::POSIX_errno(), CopyStatus::DestPath };
close(in);
return status;
}
Status status = Status::Success();
CopyStatus status{ Status::Success(), CopyStatus::NoPath };
if (ioctl(out, FICLONE, in) < 0) {
status = Status::POSIX_errno();
status = CopyStatus{ Status::POSIX_errno(), CopyStatus::NoPath };
}
close(in);
close(out);
@@ -2532,40 +2532,41 @@ Status SystemTools::CloneFileContent(std::string const& source,
// be updated by `copy_file_if_different` and `copy_file`.
if (copyfile(source.c_str(), destination.c_str(), nullptr,
COPYFILE_METADATA | COPYFILE_CLONE) < 0) {
return Status::POSIX_errno();
return CopyStatus{ Status::POSIX_errno(), CopyStatus::NoPath };
}
# if KWSYS_CXX_HAS_UTIMENSAT
// utimensat is only available on newer Unixes and macOS 10.13+
if (utimensat(AT_FDCWD, destination.c_str(), nullptr, 0) < 0) {
return Status::POSIX_errno();
return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
# else
// fall back to utimes
if (utimes(destination.c_str(), nullptr) < 0) {
return Status::POSIX_errno();
return CopyStatus{ Status::POSIX_errno(), CopyStatus::DestPath };
}
# endif
return Status::Success();
return CopyStatus{ Status::Success(), CopyStatus::NoPath };
#else
(void)source;
(void)destination;
return Status::POSIX(ENOSYS);
return CopyStatus{ Status::POSIX(ENOSYS), CopyStatus::NoPath };
#endif
}
/**
* Copy a file named by "source" to the file named by "destination".
*/
Status SystemTools::CopyFileAlways(std::string const& source,
std::string const& destination)
SystemTools::CopyStatus SystemTools::CopyFileAlways(
std::string const& source, std::string const& destination)
{
Status status;
CopyStatus status;
mode_t perm = 0;
Status perms = SystemTools::GetPermissions(source, perm);
std::string real_destination = destination;
if (SystemTools::FileIsDirectory(source)) {
status = SystemTools::MakeDirectory(destination);
status = CopyStatus{ SystemTools::MakeDirectory(destination),
CopyStatus::DestPath };
if (!status.IsSuccess()) {
return status;
}
@@ -2590,7 +2591,8 @@ Status SystemTools::CopyFileAlways(std::string const& source,
// Create destination directory
if (!destination_dir.empty()) {
status = SystemTools::MakeDirectory(destination_dir);
status = CopyStatus{ SystemTools::MakeDirectory(destination_dir),
CopyStatus::DestPath };
if (!status.IsSuccess()) {
return status;
}
@@ -2606,13 +2608,15 @@ Status SystemTools::CopyFileAlways(std::string const& source,
}
}
if (perms) {
status = SystemTools::SetPermissions(real_destination, perm);
status = CopyStatus{ SystemTools::SetPermissions(real_destination, perm),
CopyStatus::DestPath };
}
return status;
}
Status SystemTools::CopyAFile(std::string const& source,
std::string const& destination, bool always)
SystemTools::CopyStatus SystemTools::CopyAFile(std::string const& source,
std::string const& destination,
bool always)
{
if (always) {
return SystemTools::CopyFileAlways(source, destination);

View File

@@ -565,12 +565,35 @@ public:
static Status MakeDirectory(std::string const& path,
const mode_t* mode = nullptr);
/**
* Represent the result of a file copy operation.
* This is the result 'Status' and, if the operation failed,
* an indication of whether the error occurred on the source
* or destination path.
*/
struct CopyStatus : public Status
{
enum WhichPath
{
NoPath,
SourcePath,
DestPath,
};
CopyStatus() = default;
CopyStatus(Status s, WhichPath p)
: Status(s)
, Path(p)
{
}
WhichPath Path = NoPath;
};
/**
* Copy the source file to the destination file only
* if the two files differ.
*/
static Status CopyFileIfDifferent(std::string const& source,
std::string const& destination);
static CopyStatus CopyFileIfDifferent(std::string const& source,
std::string const& destination);
/**
* Compare the contents of two files. Return true if different
@@ -588,13 +611,13 @@ public:
/**
* Blockwise copy source to destination file
*/
static Status CopyFileContentBlockwise(std::string const& source,
std::string const& destination);
static CopyStatus CopyFileContentBlockwise(std::string const& source,
std::string const& destination);
/**
* Clone the source file to the destination file
*/
static Status CloneFileContent(std::string const& source,
std::string const& destination);
static CopyStatus CloneFileContent(std::string const& source,
std::string const& destination);
/**
* Return true if the two files are the same file
@@ -604,16 +627,17 @@ public:
/**
* Copy a file.
*/
static Status CopyFileAlways(std::string const& source,
std::string const& destination);
static CopyStatus CopyFileAlways(std::string const& source,
std::string const& destination);
/**
* Copy a file. If the "always" argument is true the file is always
* copied. If it is false, the file is copied only if it is new or
* has changed.
*/
static Status CopyAFile(std::string const& source,
std::string const& destination, bool always = true);
static CopyStatus CopyAFile(std::string const& source,
std::string const& destination,
bool always = true);
/**
* Copy content directory to another directory with all files and