/src/CMake/Source/cmWriteFileCommand.cxx
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst 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 | 0 | { |
18 | 0 | if (args.size() < 2) { |
19 | 0 | status.SetError("called with incorrect number of arguments"); |
20 | 0 | return false; |
21 | 0 | } |
22 | 0 | std::string message; |
23 | 0 | auto i = args.begin(); |
24 | |
|
25 | 0 | std::string const& fileName = *i; |
26 | 0 | bool overwrite = true; |
27 | 0 | i++; |
28 | |
|
29 | 0 | for (; i != args.end(); ++i) { |
30 | 0 | if (*i == "APPEND") { |
31 | 0 | overwrite = false; |
32 | 0 | } else { |
33 | 0 | message += *i; |
34 | 0 | } |
35 | 0 | } |
36 | |
|
37 | 0 | if (!status.GetMakefile().CanIWriteThisFile(fileName)) { |
38 | 0 | std::string e = |
39 | 0 | "attempted to write a file: " + fileName + " into a source directory."; |
40 | 0 | status.SetError(e); |
41 | 0 | cmSystemTools::SetFatalErrorOccurred(); |
42 | 0 | return false; |
43 | 0 | } |
44 | | |
45 | 0 | std::string dir = cmSystemTools::GetFilenamePath(fileName); |
46 | 0 | cmSystemTools::MakeDirectory(dir); |
47 | |
|
48 | 0 | mode_t mode = 0; |
49 | 0 | bool writable = false; |
50 | | |
51 | | // Set permissions to writable |
52 | 0 | 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 | 0 | writable = mode & S_IWUSR; |
58 | 0 | mode_t newMode = mode | S_IWUSR | S_IWGRP; |
59 | 0 | #endif |
60 | 0 | if (!writable) { |
61 | 0 | cmSystemTools::SetPermissions(fileName.c_str(), newMode); |
62 | 0 | } |
63 | 0 | } |
64 | | // If GetPermissions fails, pretend like it is ok. File open will fail if |
65 | | // the file is not writable |
66 | 0 | cmsys::ofstream file(fileName.c_str(), |
67 | 0 | overwrite ? std::ios::out : std::ios::app); |
68 | 0 | if (!file) { |
69 | 0 | std::string error = |
70 | 0 | cmStrCat("Internal CMake error when trying to open file: ", fileName, |
71 | 0 | " for writing."); |
72 | 0 | status.SetError(error); |
73 | 0 | return false; |
74 | 0 | } |
75 | 0 | file << message << '\n'; |
76 | 0 | file.close(); |
77 | 0 | if (mode && !writable) { |
78 | 0 | cmSystemTools::SetPermissions(fileName.c_str(), mode); |
79 | 0 | } |
80 | |
|
81 | 0 | return true; |
82 | 0 | } |