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:

committed by
Brad King

parent
ee9c09548c
commit
a9c659b1b6
@@ -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);
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user