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:
commit
44fdd5d15a
2 changed files with 38 additions and 8 deletions
|
|
@ -18,11 +18,14 @@
|
||||||
#define UTILS_FILE_H
|
#define UTILS_FILE_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
bool ReadFileToString(const std::string& path, std::string* content);
|
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);
|
||||||
|
bool WriteStringToFile(const std::string& content, const std::string& path,
|
||||||
|
mode_t mode, uid_t owner, gid_t group);
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
static bool WriteStringToFd(const std::string& content, int fd) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* p = content.data();
|
const char* p = content.data();
|
||||||
size_t left = content.size();
|
size_t left = content.size();
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
|
|
@ -68,3 +61,37 @@ bool android::WriteStringToFile(const std::string& content, const std::string& p
|
||||||
TEMP_FAILURE_RETRY(close(fd));
|
TEMP_FAILURE_RETRY(close(fd));
|
||||||
return true;
|
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue