1dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes/* 2dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * Copyright (C) 2015 The Android Open Source Project 3dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * 4dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * you may not use this file except in compliance with the License. 6dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * You may obtain a copy of the License at 7dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * 8dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * 10dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * Unless required by applicable law or agreed to in writing, software 11dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * See the License for the specific language governing permissions and 14dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes * limitations under the License. 15dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes */ 16dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes 17c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert#include "base/file.h" 18dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes 19dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes#include <errno.h> 20dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes#include <fcntl.h> 21dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes#include <sys/stat.h> 22dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes#include <sys/types.h> 23dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes 24c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert#include <string> 25c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert 2676d9cad62c19eef99b61f95d3a7c256804c6ad80Dan Albert#include "base/macros.h" // For TEMP_FAILURE_RETRY on Darwin. 27c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert#define LOG_TAG "base.file" 28c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert#include "cutils/log.h" 2994d1360f7eacd52771fb7030b26aeb722a584bd5Dan Albert#include "utils/Compat.h" 30af4885a4a83ed28c3194131e80bd3b40bc03a2ccElliott Hughes 31c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albertnamespace android { 32c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albertnamespace base { 33c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert 34c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albertbool ReadFdToString(int fd, std::string* content) { 35f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes content->clear(); 36f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes 37f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes char buf[BUFSIZ]; 38f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes ssize_t n; 39f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) { 40f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes content->append(buf, n); 41f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes } 42f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes return (n == 0) ? true : false; 43f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes} 44f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes 45c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albertbool ReadFileToString(const std::string& path, std::string* content) { 46dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes content->clear(); 47dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes 48c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert int fd = 49c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW)); 50dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes if (fd == -1) { 51dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes return false; 52dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes } 53f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes bool result = ReadFdToString(fd, content); 5412c67f4dfe1daf975e4c3f04211008b470206526Nick Kralevich close(fd); 55f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes return result; 56dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes} 57dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes 58c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albertbool WriteStringToFd(const std::string& content, int fd) { 59dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes const char* p = content.data(); 60dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes size_t left = content.size(); 61dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes while (left > 0) { 62dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, left)); 63dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes if (n == -1) { 64dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes return false; 65dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes } 66dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes p += n; 67dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes left -= n; 68dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes } 69dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes return true; 70dec12b2b71ec73483f9a2267ee5717d7eb0cdf6dElliott Hughes} 71202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes 72202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughesstatic bool CleanUpAfterFailedWrite(const std::string& path) { 73202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes // Something went wrong. Let's not leave a corrupt file lying around. 74202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes int saved_errno = errno; 75202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes unlink(path.c_str()); 76202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes errno = saved_errno; 77202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes return false; 78202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes} 79202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes 8031fa09c1c611633c8c9bdc2f1466d8de47ca95e6Elliott Hughes#if !defined(_WIN32) 81c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albertbool WriteStringToFile(const std::string& content, const std::string& path, 82c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert mode_t mode, uid_t owner, gid_t group) { 83c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert int fd = TEMP_FAILURE_RETRY( 84c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW, 85c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert mode)); 86202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes if (fd == -1) { 879d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes ALOGE("android::WriteStringToFile open failed: %s", strerror(errno)); 88202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes return false; 89202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes } 90f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes 91c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert // We do an explicit fchmod here because we assume that the caller really 92c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert // meant what they said and doesn't want the umask-influenced mode. 939d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes if (fchmod(fd, mode) == -1) { 949d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes ALOGE("android::WriteStringToFile fchmod failed: %s", strerror(errno)); 959d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes return CleanUpAfterFailedWrite(path); 969d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes } 979d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes if (fchown(fd, owner, group) == -1) { 989d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes ALOGE("android::WriteStringToFile fchown failed: %s", strerror(errno)); 999d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes return CleanUpAfterFailedWrite(path); 1009d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes } 1019d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes if (!WriteStringToFd(content, fd)) { 1029d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes ALOGE("android::WriteStringToFile write failed: %s", strerror(errno)); 1039d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes return CleanUpAfterFailedWrite(path); 1049d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes } 10512c67f4dfe1daf975e4c3f04211008b470206526Nick Kralevich close(fd); 1069d1f515ed1066d095b923c538e8ac19c73e045f4Elliott Hughes return true; 107202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes} 10831fa09c1c611633c8c9bdc2f1466d8de47ca95e6Elliott Hughes#endif 109202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes 110c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albertbool WriteStringToFile(const std::string& content, const std::string& path) { 111c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert int fd = TEMP_FAILURE_RETRY( 112c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW, 113c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert DEFFILEMODE)); 114202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes if (fd == -1) { 115202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes return false; 116202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes } 117f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes 118f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes bool result = WriteStringToFd(content, fd); 11912c67f4dfe1daf975e4c3f04211008b470206526Nick Kralevich close(fd); 120f682b4786a4093efb23bf80d69bf80eb274b145bElliott Hughes return result || CleanUpAfterFailedWrite(path); 121202f024dee8a450b92b17b2a4b90d412879321bdElliott Hughes} 122c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert 12356085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughesbool ReadFully(int fd, void* data, size_t byte_count) { 12456085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes uint8_t* p = reinterpret_cast<uint8_t*>(data); 12556085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes size_t remaining = byte_count; 12656085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes while (remaining > 0) { 12756085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes ssize_t n = TEMP_FAILURE_RETRY(read(fd, p, remaining)); 12856085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes if (n <= 0) return false; 12956085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes p += n; 13056085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes remaining -= n; 13156085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes } 13256085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes return true; 13356085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes} 13456085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes 13556085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughesbool WriteFully(int fd, const void* data, size_t byte_count) { 13656085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes const uint8_t* p = reinterpret_cast<const uint8_t*>(data); 13756085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes size_t remaining = byte_count; 13856085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes while (remaining > 0) { 13956085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes ssize_t n = TEMP_FAILURE_RETRY(write(fd, p, remaining)); 14056085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes if (n == -1) return false; 14156085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes p += n; 14256085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes remaining -= n; 14356085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes } 14456085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes return true; 14556085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes} 14656085edbf8c74a3a123f08e44be6e8f294deb465Elliott Hughes 147c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert} // namespace base 148c007bc3856a4cf86b8f610eb045f26a9dedc2894Dan Albert} // namespace android 149