1 //
2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // system_utils_posix.cpp: Implementation of POSIX OS-specific functions.
8
9 #include "system_utils.h"
10
11 #include <array>
12 #include <iostream>
13
14 #include <dlfcn.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #include <sys/wait.h>
18 #include <unistd.h>
19
20 namespace angle
21 {
GetCWD()22 Optional<std::string> GetCWD()
23 {
24 std::array<char, 4096> pathBuf;
25 char *result = getcwd(pathBuf.data(), pathBuf.size());
26 if (result == nullptr)
27 {
28 return Optional<std::string>::Invalid();
29 }
30 return std::string(pathBuf.data());
31 }
32
SetCWD(const char * dirName)33 bool SetCWD(const char *dirName)
34 {
35 return (chdir(dirName) == 0);
36 }
37
UnsetEnvironmentVar(const char * variableName)38 bool UnsetEnvironmentVar(const char *variableName)
39 {
40 return (unsetenv(variableName) == 0);
41 }
42
SetEnvironmentVar(const char * variableName,const char * value)43 bool SetEnvironmentVar(const char *variableName, const char *value)
44 {
45 return (setenv(variableName, value, 1) == 0);
46 }
47
GetEnvironmentVar(const char * variableName)48 std::string GetEnvironmentVar(const char *variableName)
49 {
50 const char *value = getenv(variableName);
51 return (value == nullptr ? std::string() : std::string(value));
52 }
53
GetPathSeparatorForEnvironmentVar()54 const char *GetPathSeparatorForEnvironmentVar()
55 {
56 return ":";
57 }
58
GetHelperExecutableDir()59 std::string GetHelperExecutableDir()
60 {
61 std::string directory;
62 static int dummySymbol = 0;
63 Dl_info dlInfo;
64 if (dladdr(&dummySymbol, &dlInfo) != 0)
65 {
66 std::string moduleName = dlInfo.dli_fname;
67 directory = moduleName.substr(0, moduleName.find_last_of('/') + 1);
68 }
69 return directory;
70 }
71
72 class PosixLibrary : public Library
73 {
74 public:
PosixLibrary(const std::string & fullPath)75 PosixLibrary(const std::string &fullPath) : mModule(dlopen(fullPath.c_str(), RTLD_NOW))
76 {
77 if (!mModule)
78 {
79 std::cerr << "Failed to load " << fullPath << ": " << dlerror() << std::endl;
80 }
81 }
82
~PosixLibrary()83 ~PosixLibrary() override
84 {
85 if (mModule)
86 {
87 dlclose(mModule);
88 }
89 }
90
getSymbol(const char * symbolName)91 void *getSymbol(const char *symbolName) override
92 {
93 if (!mModule)
94 {
95 return nullptr;
96 }
97
98 return dlsym(mModule, symbolName);
99 }
100
getNative() const101 void *getNative() const override { return mModule; }
102
103 private:
104 void *mModule = nullptr;
105 };
106
OpenSharedLibrary(const char * libraryName,SearchType searchType)107 Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
108 {
109 std::string directory;
110 if (searchType == SearchType::ApplicationDir)
111 {
112 directory = GetHelperExecutableDir();
113 }
114
115 std::string fullPath = directory + libraryName + "." + GetSharedLibraryExtension();
116 return new PosixLibrary(fullPath);
117 }
118
OpenSharedLibraryWithExtension(const char * libraryName)119 Library *OpenSharedLibraryWithExtension(const char *libraryName)
120 {
121 return new PosixLibrary(libraryName);
122 }
123
IsDirectory(const char * filename)124 bool IsDirectory(const char *filename)
125 {
126 struct stat st;
127 int result = stat(filename, &st);
128 return result == 0 && ((st.st_mode & S_IFDIR) == S_IFDIR);
129 }
130
IsDebuggerAttached()131 bool IsDebuggerAttached()
132 {
133 // This could have a fuller implementation.
134 // See https://cs.chromium.org/chromium/src/base/debug/debugger_posix.cc
135 return false;
136 }
137
BreakDebugger()138 void BreakDebugger()
139 {
140 // This could have a fuller implementation.
141 // See https://cs.chromium.org/chromium/src/base/debug/debugger_posix.cc
142 abort();
143 }
144
GetExecutableExtension()145 const char *GetExecutableExtension()
146 {
147 return "";
148 }
149
GetPathSeparator()150 char GetPathSeparator()
151 {
152 return '/';
153 }
154 } // namespace angle
155