/* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "FileUtils.h" #ifdef BINDER_NO_LIBBASE #include #include #if defined(__APPLE__) #include #endif #if defined(_WIN32) #include #include #endif namespace android::binder { bool ReadFdToString(borrowed_fd fd, std::string* content) { content->clear(); // Although original we had small files in mind, this code gets used for // very large files too, where the std::string growth heuristics might not // be suitable. https://code.google.com/p/android/issues/detail?id=258500. struct stat sb; if (fstat(fd.get(), &sb) != -1 && sb.st_size > 0) { content->reserve(sb.st_size); } char buf[4096] __attribute__((__uninitialized__)); ssize_t n; while ((n = TEMP_FAILURE_RETRY(read(fd.get(), &buf[0], sizeof(buf)))) > 0) { content->append(buf, n); } return (n == 0) ? true : false; } bool WriteStringToFd(std::string_view content, borrowed_fd fd) { const char* p = content.data(); size_t left = content.size(); while (left > 0) { ssize_t n = TEMP_FAILURE_RETRY(write(fd.get(), p, left)); if (n == -1) { return false; } p += n; left -= n; } return true; } static std::filesystem::path GetExecutablePath2() { #if defined(__linux__) return std::filesystem::read_symlink("/proc/self/exe"); #elif defined(__APPLE__) char path[PATH_MAX + 1]; uint32_t path_len = sizeof(path); int rc = _NSGetExecutablePath(path, &path_len); if (rc < 0) { std::unique_ptr path_buf(new char[path_len]); _NSGetExecutablePath(path_buf.get(), &path_len); return path_buf.get(); } return path; #elif defined(_WIN32) char path[PATH_MAX + 1]; DWORD result = GetModuleFileName(NULL, path, sizeof(path) - 1); if (result == 0 || result == sizeof(path) - 1) return ""; path[PATH_MAX - 1] = 0; return path; #elif defined(__EMSCRIPTEN__) abort(); #else #error unknown OS #endif } std::string GetExecutableDirectory() { return GetExecutablePath2().parent_path(); } } // namespace android::binder #endif // BINDER_NO_LIBBASE