1 //
2 // Copyright (c) 2015 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_linux.cpp: Implementation of OS-specific functions for Linux
8 
9 #include "system_utils.h"
10 
11 #include <sys/stat.h>
12 #include <sys/time.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15 
16 #include <array>
17 
18 namespace angle
19 {
20 
21 namespace
22 {
23 
GetExecutablePathImpl()24 std::string GetExecutablePathImpl()
25 {
26     // We cannot use lstat to get the size of /proc/self/exe as it always returns 0
27     // so we just use a big buffer and hope the path fits in it.
28     char path[4096];
29 
30     ssize_t result = readlink("/proc/self/exe", path, sizeof(path) - 1);
31     if (result < 0 || static_cast<size_t>(result) >= sizeof(path) - 1)
32     {
33         return "";
34     }
35 
36     path[result] = '\0';
37     return path;
38 }
39 
GetExecutableDirectoryImpl()40 std::string GetExecutableDirectoryImpl()
41 {
42     std::string executablePath = GetExecutablePath();
43     size_t lastPathSepLoc      = executablePath.find_last_of("/");
44     return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
45 }
46 
47 }  // anonymous namespace
48 
GetExecutablePath()49 const char *GetExecutablePath()
50 {
51     // TODO(jmadill): Make global static string thread-safe.
52     const static std::string &exePath = GetExecutablePathImpl();
53     return exePath.c_str();
54 }
55 
GetExecutableDirectory()56 const char *GetExecutableDirectory()
57 {
58     // TODO(jmadill): Make global static string thread-safe.
59     const static std::string &exeDir = GetExecutableDirectoryImpl();
60     return exeDir.c_str();
61 }
62 
GetSharedLibraryExtension()63 const char *GetSharedLibraryExtension()
64 {
65     return "so";
66 }
67 
GetCWD()68 Optional<std::string> GetCWD()
69 {
70     std::array<char, 4096> pathBuf;
71     char *result = getcwd(pathBuf.data(), pathBuf.size());
72     if (result == nullptr)
73     {
74         return Optional<std::string>::Invalid();
75     }
76     return std::string(pathBuf.data());
77 }
78 
SetCWD(const char * dirName)79 bool SetCWD(const char *dirName)
80 {
81     return (chdir(dirName) == 0);
82 }
83 
SetEnvironmentVar(const char * variableName,const char * value)84 bool SetEnvironmentVar(const char *variableName, const char *value)
85 {
86     return (setenv(variableName, value, 1) == 0);
87 }
88 
89 }  // namespace angle
90