am 27d28d3b: Merge "Add a WriteStringToFile overload that cares about permissions."

* commit '27d28d3baff860d1fd936a5fcf2d920577c52575':
  Add a WriteStringToFile overload that cares about permissions.
This commit is contained in:
Elliott Hughes 2015-02-05 02:31:31 +00:00 committed by Android Git Automerger
commit 44fdd5d15a
2 changed files with 38 additions and 8 deletions

View File

@ -18,11 +18,14 @@
#define UTILS_FILE_H
#include <string>
#include <sys/stat.h>
namespace android {
bool ReadFileToString(const std::string& path, std::string* content);
bool WriteStringToFile(const std::string& content, const std::string& path);
bool WriteStringToFile(const std::string& content, const std::string& path,
mode_t mode, uid_t owner, gid_t group);
} // namespace android

View File

@ -46,14 +46,7 @@ bool android::ReadFileToString(const std::string& path, std::string* content) {
}
}
bool android::WriteStringToFile(const std::string& content, const std::string& path) {
int fd = TEMP_FAILURE_RETRY(open(path.c_str(),
O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
DEFFILEMODE));
if (fd == -1) {
return false;
}
static bool WriteStringToFd(const std::string& content, int fd) {
const char* p = content.data();
size_t left = content.size();
while (left > 0) {
@ -68,3 +61,37 @@ bool android::WriteStringToFile(const std::string& content, const std::string& p
TEMP_FAILURE_RETRY(close(fd));
return true;
}
static bool CleanUpAfterFailedWrite(const std::string& path) {
// Something went wrong. Let's not leave a corrupt file lying around.
int saved_errno = errno;
unlink(path.c_str());
errno = saved_errno;
return false;
}
bool android::WriteStringToFile(const std::string& content, const std::string& path,
mode_t mode, uid_t owner, gid_t group) {
int fd = TEMP_FAILURE_RETRY(open(path.c_str(),
O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
mode));
if (fd == -1) {
return false;
}
// We do an explicit fchmod here because we assume that the caller really meant what they
// said and doesn't want the umask-influenced mode.
if (fchmod(fd, mode) != -1 && fchown(fd, owner, group) == -1 && WriteStringToFd(content, fd)) {
return true;
}
return CleanUpAfterFailedWrite(path);
}
bool android::WriteStringToFile(const std::string& content, const std::string& path) {
int fd = TEMP_FAILURE_RETRY(open(path.c_str(),
O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
DEFFILEMODE));
if (fd == -1) {
return false;
}
return WriteStringToFd(content, fd) || CleanUpAfterFailedWrite(path);
}