1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmWriteFileCommand.h"
5 #include "cmsys/FStream.hxx"
7 #include "cm_sys_stat.h"
9 #include "cmExecutionStatus.h"
10 #include "cmMakefile.h"
11 #include "cmStringAlgorithms.h"
12 #include "cmSystemTools.h"
15 bool cmWriteFileCommand(std::vector<std::string> const& args,
16 cmExecutionStatus& status)
18 if (args.size() < 2) {
19 status.SetError("called with incorrect number of arguments");
23 auto i = args.begin();
25 std::string const& fileName = *i;
26 bool overwrite = true;
29 for (; i != args.end(); ++i) {
37 if (!status.GetMakefile().CanIWriteThisFile(fileName)) {
39 "attempted to write a file: " + fileName + " into a source directory.";
41 cmSystemTools::SetFatalErrorOccurred();
45 std::string dir = cmSystemTools::GetFilenamePath(fileName);
46 cmSystemTools::MakeDirectory(dir);
49 bool writable = false;
51 // Set permissions to writable
52 if (cmSystemTools::GetPermissions(fileName.c_str(), mode)) {
53 #if defined(_MSC_VER) || defined(__MINGW32__)
54 writable = (mode & S_IWRITE) != 0;
55 mode_t newMode = mode | S_IWRITE;
57 writable = mode & S_IWUSR;
58 mode_t newMode = mode | S_IWUSR | S_IWGRP;
61 cmSystemTools::SetPermissions(fileName.c_str(), newMode);
64 // If GetPermissions fails, pretend like it is ok. File open will fail if
65 // the file is not writable
66 cmsys::ofstream file(fileName.c_str(),
67 overwrite ? std::ios::out : std::ios::app);
70 cmStrCat("Internal CMake error when trying to open file: ", fileName,
72 status.SetError(error);
75 file << message << '\n';
77 if (mode && !writable) {
78 cmSystemTools::SetPermissions(fileName.c_str(), mode);