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