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