• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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