| 102 | |
| 103 | #if !defined(_WIN32) |
| 104 | bool WriteStringToFile(const std::string& content, const std::string& path, |
| 105 | mode_t mode, uid_t owner, gid_t group, |
| 106 | bool follow_symlinks) { |
| 107 | int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_BINARY | |
| 108 | (follow_symlinks ? 0 : O_NOFOLLOW); |
| 109 | android_lkchan::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode))); |
| 110 | if (fd == -1) { |
| 111 | PLOG(ERROR) << "android_lkchan::WriteStringToFile open failed"; |
| 112 | return false; |
| 113 | } |
| 114 | |
| 115 | // We do an explicit fchmod here because we assume that the caller really |
| 116 | // meant what they said and doesn't want the umask-influenced mode. |
| 117 | if (fchmod(fd, mode) == -1) { |
| 118 | PLOG(ERROR) << "android_lkchan::WriteStringToFile fchmod failed"; |
| 119 | return CleanUpAfterFailedWrite(path); |
| 120 | } |
| 121 | if (fchown(fd, owner, group) == -1) { |
| 122 | PLOG(ERROR) << "android_lkchan::WriteStringToFile fchown failed"; |
| 123 | return CleanUpAfterFailedWrite(path); |
| 124 | } |
| 125 | if (!WriteStringToFd(content, fd)) { |
| 126 | PLOG(ERROR) << "android_lkchan::WriteStringToFile write failed"; |
| 127 | return CleanUpAfterFailedWrite(path); |
| 128 | } |
| 129 | return true; |
| 130 | } |
| 131 | #endif |
| 132 | |
| 133 | bool WriteStringToFile(const std::string& content, const std::string& path, |
nothing calls this directly
no test coverage detected