• 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.cpp: Implementation of common functions
8 
9 #include "common/system_utils.h"
10 
11 #include <stdlib.h>
12 
13 #if defined(ANGLE_PLATFORM_ANDROID)
14 #    include <sys/system_properties.h>
15 #endif
16 
17 namespace angle
18 {
GetExecutableName()19 std::string GetExecutableName()
20 {
21 #if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 21
22     // Support for "getprogname" function in bionic was introduced in L (API level 21)
23     const char *executableName = getprogname();
24     return (executableName) ? std::string(executableName) : "ANGLE";
25 #else
26     std::string executableName = GetExecutablePath();
27     size_t lastPathSepLoc      = executableName.find_last_of(GetPathSeparator());
28     return (lastPathSepLoc > 0 ? executableName.substr(lastPathSepLoc + 1, executableName.length())
29                                : "ANGLE");
30 #endif  // ANGLE_PLATFORM_ANDROID
31 }
32 
33 // On Android return value cached in the process environment, if none, call
34 // GetEnvironmentVarOrUnCachedAndroidProperty if not in environment.
GetEnvironmentVarOrAndroidProperty(const char * variableName,const char * propertyName)35 std::string GetEnvironmentVarOrAndroidProperty(const char *variableName, const char *propertyName)
36 {
37 #if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 21
38     // Can't use GetEnvironmentVar here because that won't allow us to distinguish between the
39     // environment being set to an empty string vs. not set at all.
40     const char *variableValue = getenv(variableName);
41     if (variableValue != nullptr)
42     {
43         std::string value(variableValue);
44         return value;
45     }
46 #endif
47     return GetEnvironmentVarOrUnCachedAndroidProperty(variableName, propertyName);
48 }
49 
50 // Call out to 'getprop' on a shell to get an Android property.  If the value was set, set an
51 // environment variable with that value.  Return the value of the environment variable.
GetEnvironmentVarOrUnCachedAndroidProperty(const char * variableName,const char * propertyName)52 std::string GetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName,
53                                                        const char *propertyName)
54 {
55 #if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26
56     std::string propertyValue;
57 
58     const prop_info *propertyInfo = __system_property_find(propertyName);
59     if (propertyInfo != nullptr)
60     {
61         __system_property_read_callback(
62             propertyInfo,
63             [](void *cookie, const char *, const char *value, unsigned) {
64                 auto propertyValue = reinterpret_cast<std::string *>(cookie);
65                 *propertyValue     = value;
66             },
67             &propertyValue);
68     }
69 
70     // Set the environment variable with the value.
71     SetEnvironmentVar(variableName, propertyValue.c_str());
72     return propertyValue;
73 #else
74     // Return the environment variable's value.
75     return GetEnvironmentVar(variableName);
76 #endif  // ANGLE_PLATFORM_ANDROID
77 }
78 
GetBoolEnvironmentVar(const char * variableName)79 bool GetBoolEnvironmentVar(const char *variableName)
80 {
81     std::string envVarString = GetEnvironmentVar(variableName);
82     return (!envVarString.empty() && envVarString == "1");
83 }
84 
PrependPathToEnvironmentVar(const char * variableName,const char * path)85 bool PrependPathToEnvironmentVar(const char *variableName, const char *path)
86 {
87     std::string oldValue = GetEnvironmentVar(variableName);
88     const char *newValue = nullptr;
89     std::string buf;
90     if (oldValue.empty())
91     {
92         newValue = path;
93     }
94     else
95     {
96         buf = path;
97         buf += GetPathSeparatorForEnvironmentVar();
98         buf += oldValue;
99         newValue = buf.c_str();
100     }
101     return SetEnvironmentVar(variableName, newValue);
102 }
103 
IsFullPath(std::string dirName)104 bool IsFullPath(std::string dirName)
105 {
106     if (dirName.find(GetRootDirectory()) == 0)
107     {
108         return true;
109     }
110     return false;
111 }
112 
ConcatenatePath(std::string first,std::string second)113 std::string ConcatenatePath(std::string first, std::string second)
114 {
115     if (first.empty())
116     {
117         return second;
118     }
119     if (second.empty())
120     {
121         return first;
122     }
123     if (IsFullPath(second))
124     {
125         return second;
126     }
127     bool firstRedundantPathSeparator = first.find_last_of(GetPathSeparator()) == first.length() - 1;
128     bool secondRedundantPathSeparator = second.find(GetPathSeparator()) == 0;
129     if (firstRedundantPathSeparator && secondRedundantPathSeparator)
130     {
131         return first + second.substr(1);
132     }
133     else if (firstRedundantPathSeparator || secondRedundantPathSeparator)
134     {
135         return first + second;
136     }
137     return first + GetPathSeparator() + second;
138 }
139 }  // namespace angle
140