cmake/Source/cmWriteFileCommand.cxx

83 lines
2.2 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWriteFileCommand.h"
2016-07-09 11:21:54 +02:00
2017-07-20 19:35:53 +02:00
#include "cmsys/FStream.hxx"
2017-07-20 19:35:53 +02:00
#include "cm_sys_stat.h"
2017-04-14 19:02:05 +02:00
2020-02-01 23:06:01 +01:00
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
2017-04-14 19:02:05 +02:00
// cmLibraryCommand
2020-02-01 23:06:01 +01:00
bool cmWriteFileCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
2016-07-09 11:21:54 +02:00
if (args.size() < 2) {
2020-02-01 23:06:01 +01:00
status.SetError("called with incorrect number of arguments");
return false;
2016-07-09 11:21:54 +02:00
}
std::string message;
2020-02-01 23:06:01 +01:00
auto i = args.begin();
2017-07-20 19:35:53 +02:00
std::string const& fileName = *i;
bool overwrite = true;
i++;
2016-07-09 11:21:54 +02:00
for (; i != args.end(); ++i) {
if (*i == "APPEND") {
overwrite = false;
2016-07-09 11:21:54 +02:00
} else {
message += *i;
}
2016-07-09 11:21:54 +02:00
}
2020-02-01 23:06:01 +01:00
if (!status.GetMakefile().CanIWriteThisFile(fileName)) {
2016-07-09 11:21:54 +02:00
std::string e =
"attempted to write a file: " + fileName + " into a source directory.";
2020-02-01 23:06:01 +01:00
status.SetError(e);
2022-08-04 22:12:04 +02:00
cmSystemTools::SetFatalErrorOccurred();
return false;
2016-07-09 11:21:54 +02:00
}
std::string dir = cmSystemTools::GetFilenamePath(fileName);
2018-04-23 21:13:27 +02:00
cmSystemTools::MakeDirectory(dir);
2010-06-23 01:18:35 +03:00
mode_t mode = 0;
2018-10-28 12:09:07 +01:00
bool writable = false;
// Set permissions to writable
2016-07-09 11:21:54 +02:00
if (cmSystemTools::GetPermissions(fileName.c_str(), mode)) {
#if defined(_MSC_VER) || defined(__MINGW32__)
2019-11-11 23:01:05 +01:00
writable = (mode & S_IWRITE) != 0;
2018-10-28 12:09:07 +01:00
mode_t newMode = mode | S_IWRITE;
#else
2018-10-28 12:09:07 +01:00
writable = mode & S_IWUSR;
mode_t newMode = mode | S_IWUSR | S_IWGRP;
#endif
2018-10-28 12:09:07 +01:00
if (!writable) {
cmSystemTools::SetPermissions(fileName.c_str(), newMode);
}
2016-07-09 11:21:54 +02:00
}
// If GetPermissions fails, pretend like it is ok. File open will fail if
// the file is not writable
2014-08-03 19:52:23 +02:00
cmsys::ofstream file(fileName.c_str(),
2016-07-09 11:21:54 +02:00
overwrite ? std::ios::out : std::ios::app);
if (!file) {
2020-02-01 23:06:01 +01:00
std::string error =
cmStrCat("Internal CMake error when trying to open file: ", fileName,
" for writing.");
status.SetError(error);
return false;
2016-07-09 11:21:54 +02:00
}
2020-08-30 11:54:41 +02:00
file << message << '\n';
file.close();
2018-10-28 12:09:07 +01:00
if (mode && !writable) {
2010-06-23 01:18:35 +03:00
cmSystemTools::SetPermissions(fileName.c_str(), mode);
2016-07-09 11:21:54 +02:00
}
return true;
}