14a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley/* 24a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * Copyright (C) 2015, The Android Open Source Project 34a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * 44a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * Licensed under the Apache License, Version 2.0 (the "License"); 54a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * you may not use this file except in compliance with the License. 64a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * You may obtain a copy of the License at 74a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * 84a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * http://www.apache.org/licenses/LICENSE-2.0 94a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * 104a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * Unless required by applicable law or agreed to in writing, software 114a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * distributed under the License is distributed on an "AS IS" BASIS, 124a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * See the License for the specific language governing permissions and 144a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley * limitations under the License. 154a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley */ 164a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley 174a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley#include "io_delegate.h" 184a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley 19054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#include <cstring> 204a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley#include <fstream> 21054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#include <vector> 22054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 23054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#ifdef _WIN32 24054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#include <direct.h> 25054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#else 26054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#include <sys/stat.h> 279d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley#include <unistd.h> 28054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#endif 29054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 300a62067f35e957493bc37c4b42dfdcfc16353831Elliott Hughes#include <android-base/strings.h> 316453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin 32054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#include "logging.h" 33054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#include "os.h" 344a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley 354a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wileyusing std::string; 364a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wileyusing std::unique_ptr; 37054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wileyusing std::vector; 384a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley 396453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlinusing android::base::Split; 406453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin 414a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wileynamespace android { 424a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wileynamespace aidl { 434a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley 443f3924909f21c64ff397511b57169dcebeec7686Christopher Wileybool IoDelegate::GetAbsolutePath(const string& path, string* absolute_path) { 453f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley#ifdef _WIN32 463f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley 473f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley char buf[4096]; 483f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley DWORD path_len = GetFullPathName(path.c_str(), sizeof(buf), buf, nullptr); 493f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley if (path_len <= 0 || path_len >= sizeof(buf)) { 503f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley LOG(ERROR) << "Failed to GetFullPathName(" << path << ")"; 513f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley return false; 523f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley } 533f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley *absolute_path = buf; 543f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley 553f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley return true; 563f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley 573f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley#else 583f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley 593f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley if (path.empty()) { 603f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley LOG(ERROR) << "Giving up on finding an absolute path to represent the " 613f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley "empty string."; 623f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley return false; 633f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley } 643f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley if (path[0] == OS_PATH_SEPARATOR) { 653f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley *absolute_path = path; 663f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley return true; 673f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley } 683f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley 693f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley char buf[4096]; 703f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley if (getcwd(buf, sizeof(buf)) == nullptr) { 713f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley LOG(ERROR) << "Path of current working directory does not fit in " 723f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley << sizeof(buf) << " bytes"; 733f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley return false; 743f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley } 753f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley 763f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley *absolute_path = buf; 773f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley *absolute_path += OS_PATH_SEPARATOR; 783f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley *absolute_path += path; 793f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley return true; 803f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley#endif 813f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley} 823f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley 834a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wileyunique_ptr<string> IoDelegate::GetFileContents( 844a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley const string& filename, 854a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley const string& content_suffix) const { 864a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley unique_ptr<string> contents; 874a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley std::ifstream in(filename, std::ios::in | std::ios::binary); 884a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley if (!in) { 894a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley return contents; 904a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley } 914a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley contents.reset(new string); 924a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley in.seekg(0, std::ios::end); 934a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley ssize_t file_size = in.tellg(); 944a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley contents->resize(file_size + content_suffix.length()); 954a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley in.seekg(0, std::ios::beg); 964a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley // Read the file contents into the beginning of the string 974a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley in.read(&(*contents)[0], file_size); 984a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley // Drop the suffix in at the end. 994a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley contents->replace(file_size, content_suffix.length(), content_suffix); 1004a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley in.close(); 1014a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley 1024a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley return contents; 1034a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley} 1044a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley 105ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wileyunique_ptr<LineReader> IoDelegate::GetLineReader( 106ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley const string& file_path) const { 107ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley return LineReader::ReadFromFile(file_path); 108ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley} 109ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley 11072877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wileybool IoDelegate::FileIsReadable(const string& path) const { 11172877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley#ifdef _WIN32 11272877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley // check that the file exists and is not write-only 11372877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley return (0 == _access(path.c_str(), 0)) && // mode 0=exist 11472877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley (0 == _access(path.c_str(), 4)); // mode 4=readable 11572877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley#else 11672877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley return (0 == access(path.c_str(), R_OK)); 11772877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley#endif 11872877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley} 119054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 120054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wileybool IoDelegate::CreatedNestedDirs( 121054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const string& caller_base_dir, 122054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const vector<string>& nested_subdirs) const { 123054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley string base_dir = caller_base_dir; 124054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley if (base_dir.empty()) { 125054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley base_dir = "."; 126054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley } 127054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley for (const string& subdir : nested_subdirs) { 128054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley if (base_dir[base_dir.size() - 1] != OS_PATH_SEPARATOR) { 129054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley base_dir += OS_PATH_SEPARATOR; 130054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley } 131054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley base_dir += subdir; 132054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley bool success; 133054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#ifdef _WIN32 134054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley success = _mkdir(base_dir.c_str()) == 0; 135054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#else 136054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley success = mkdir(base_dir.c_str(), 137054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0; 138054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#endif 1393badcdead366eb89cadd28e84f06e37067e62c99Christopher Wiley // On darwin when you try to mkdir("/", ...) we get EISDIR. 1403badcdead366eb89cadd28e84f06e37067e62c99Christopher Wiley if (!success && (errno != EEXIST && errno != EISDIR)) { 141f65179befe46a0234459f3ae0e209107f7a9ecc3Dan Albert LOG(ERROR) << "Error while creating " << base_dir << ": " 142f65179befe46a0234459f3ae0e209107f7a9ecc3Dan Albert << strerror(errno); 143f65179befe46a0234459f3ae0e209107f7a9ecc3Dan Albert return false; 144054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley } 145054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley } 146054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley return true; 147054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley} 148054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 1496453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlinbool IoDelegate::CreatePathForFile(const string& path) const { 1506453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin if (path.empty()) { 1516453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin return true; 1526453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin } 1536453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin 1543f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley string absolute_path; 1553f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley if (!GetAbsolutePath(path, &absolute_path)) { 1563f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley return false; 1573f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley } 1583f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley 1593f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley auto directories = Split(absolute_path, string{1u, OS_PATH_SEPARATOR}); 1603f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley 1613f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley // The "base" directory is just the root of the file system. On Windows, 1623f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley // this will look like "C:\" but on Unix style file systems we get an empty 1633f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley // string after splitting "/foo" with "/" 1643f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley string base = directories[0]; 1653f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley if (base.empty()) { 1666453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin base = "/"; 1676453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin } 1683f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley directories.erase(directories.begin()); 1696453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin 1703f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley // Remove the actual file in question, we're just creating the directory path. 1713f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley directories.pop_back(); 1726453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin 1733f3924909f21c64ff397511b57169dcebeec7686Christopher Wiley return CreatedNestedDirs(base, directories); 1746453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin} 1756453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin 176054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wileyunique_ptr<CodeWriter> IoDelegate::GetCodeWriter( 177054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const string& file_path) const { 178054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley return GetFileWriter(file_path); 179054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley} 180054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 1819d6e0b29add607669e440085f1fc60cd434dc987Christopher Wileyvoid IoDelegate::RemovePath(const std::string& file_path) const { 1829d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley#ifdef _WIN32 1839d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley _unlink(file_path.c_str()); 1849d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley#else 1859d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley unlink(file_path.c_str()); 1869d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley#endif 1879d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley} 1889d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley 1894a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley} // namespace android 1904a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley} // namespace aidl 191