1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file. 4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_system.h" 6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <errno.h> 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <stdlib.h> 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <string.h> 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <sys/stat.h> 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <unistd.h> 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "crazy_linker_util.h" 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Note: unit-testing support files are in crazy_linker_files_mock.cpp 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace crazy { 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef UNIT_TESTS 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool FileDescriptor::OpenReadOnly(const char* path) { 22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Close(); 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) fd_ = TEMP_FAILURE_RETRY(::open(path, O_RDONLY)); 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return (fd_ != -1); 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool FileDescriptor::OpenReadWrite(const char* path) { 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Close(); 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) fd_ = TEMP_FAILURE_RETRY(::open(path, O_RDWR)); 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return (fd_ != -1); 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int FileDescriptor::Read(void* buffer, size_t buffer_size) { 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return TEMP_FAILURE_RETRY(::read(fd_, buffer, buffer_size)); 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int FileDescriptor::SeekTo(off_t offset) { 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ::lseek(fd_, offset, SEEK_SET); 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void* FileDescriptor::Map(void* address, 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t length, 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int prot, 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int flags, 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) off_t offset) { 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ::mmap(address, length, prot, flags, fd_, offset); 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void FileDescriptor::Close() { 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (fd_ != -1) { 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int old_errno = errno; 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) TEMP_FAILURE_RETRY(close(fd_)); 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) errno = old_errno; 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) fd_ = -1; 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const char* GetEnv(const char* var_name) { return ::getenv(var_name); } 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)String GetCurrentDirectory() { 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) String result; 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t capacity = 128; 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (;;) { 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result.Resize(capacity); 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (getcwd(&result[0], capacity)) 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) capacity *= 2; 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return result; 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool PathExists(const char* path) { 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) struct stat st; 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (TEMP_FAILURE_RETRY(stat(path, &st)) < 0) 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return S_ISREG(st.st_mode) || S_ISDIR(st.st_mode); 78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool PathIsFile(const char* path) { 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) struct stat st; 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (TEMP_FAILURE_RETRY(stat(path, &st)) < 0) 83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return S_ISREG(st.st_mode); 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif // !UNIT_TESTS 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Returns true iff |lib_name| corresponds to one of the NDK-exposed 91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// system libraries. 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool IsSystemLibrary(const char* lib_name) { 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static const char* const kSystemLibs[] = { 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "libandroid.so", "libc.so", "libdl.so", "libjnigraphics.so", 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "liblog.so", "libm.so", "libstdc++.so", "libz.so", 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "libEGL.so", "libGLESv1_CM.so", "libGLESv2.so", "libGLESv3.so", 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "libOpenMAXAL.so", "libOpenSLES.so", }; 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const size_t kSize = sizeof(kSystemLibs) / sizeof(kSystemLibs[0]); 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const char* base_name = ::strrchr(lib_name, '/'); 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!base_name) 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base_name = lib_name; 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base_name += 1; 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) for (size_t n = 0; n < kSize; ++n) { 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!strcmp(kSystemLibs[n], base_name)) 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return true; 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace crazy 113