resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmWriteFileCommand.cxx
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"
4
5 #include "cmsys/FStream.hxx"
6
7 #include "cm_sys_stat.h"
8
9 #include "cmExecutionStatus.h"
10 #include "cmMakefile.h"
11 #include "cmStringAlgorithms.h"
12 #include "cmSystemTools.h"
13
14 // cmLibraryCommand
15 bool cmWriteFileCommand(std::vector<std::string> const& args,
16                         cmExecutionStatus& status)
17 {
18   if (args.size() < 2) {
19     status.SetError("called with incorrect number of arguments");
20     return false;
21   }
22   std::string message;
23   auto i = args.begin();
24
25   std::string const& fileName = *i;
26   bool overwrite = true;
27   i++;
28
29   for (; i != args.end(); ++i) {
30     if (*i == "APPEND") {
31       overwrite = false;
32     } else {
33       message += *i;
34     }
35   }
36
37   if (!status.GetMakefile().CanIWriteThisFile(fileName)) {
38     std::string e =
39       "attempted to write a file: " + fileName + " into a source directory.";
40     status.SetError(e);
41     cmSystemTools::SetFatalErrorOccurred();
42     return false;
43   }
44
45   std::string dir = cmSystemTools::GetFilenamePath(fileName);
46   cmSystemTools::MakeDirectory(dir);
47
48   mode_t mode = 0;
49   bool writable = false;
50
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;
56 #else
57     writable = mode & S_IWUSR;
58     mode_t newMode = mode | S_IWUSR | S_IWGRP;
59 #endif
60     if (!writable) {
61       cmSystemTools::SetPermissions(fileName.c_str(), newMode);
62     }
63   }
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);
68   if (!file) {
69     std::string error =
70       cmStrCat("Internal CMake error when trying to open file: ", fileName,
71                " for writing.");
72     status.SetError(error);
73     return false;
74   }
75   file << message << '\n';
76   file.close();
77   if (mode && !writable) {
78     cmSystemTools::SetPermissions(fileName.c_str(), mode);
79   }
80
81   return true;
82 }