2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
28 #include <unordered_map>
36 static pthread_t loggingThread;
38 bool iCompare(const std::string& a, const std::string& b)
40 return a.length() == b.length() &&
41 std::equal(b.begin(), b.end(), a.begin(),
42 [](unsigned char a, unsigned char b)
43 { return std::tolower(a) == std::tolower(b); });
46 bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffset, int length)
48 return static_cast<int>(a.length()) - length >= aOffset &&
49 static_cast<int>(b.length()) - length >= bOffset &&
50 std::equal(b.begin() + bOffset, b.begin() + bOffset + length, a.begin() + aOffset,
51 [](unsigned char a, unsigned char b)
52 { return std::tolower(a) == std::tolower(b); });
55 bool isManagedAssembly(const std::string& fileName)
57 return iCompare(fileName, fileName.size()-4, ".dll", 0, 4) ||
58 iCompare(fileName, fileName.size()-4, ".exe", 0, 4);
61 bool isNativeImage(const std::string& fileName)
63 return iCompare(fileName, fileName.size()-7, ".ni", 0, 3);
66 std::string readSelfPath()
69 ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1);
72 return std::string(buff);
78 std::string concatPath(const std::string& path1, const std::string& path2)
80 std::string path(path1);
81 if (path.back() == PATH_SEPARATOR) {
84 path += PATH_SEPARATOR;
91 void splitPath(const std::string& path, std::vector<std::string>& out)
93 std::istringstream ss(path);
96 while (std::getline(ss, token, ':')) {
101 void appendPath(std::string& path1, const std::string& path2)
103 if (path1.back() == PATH_SEPARATOR) {
106 path1 += PATH_SEPARATOR;
111 std::string absolutePath(const std::string& path)
114 char realPath[PATH_MAX];
115 if (realpath(path.c_str(), realPath) != nullptr && realPath[0] != '\0')
116 absPath.assign(realPath);
121 std::string baseName(const std::string& path)
123 auto pos = path.find_last_of(PATH_SEPARATOR);
124 if (pos != std::string::npos)
125 return path.substr(0, pos);
127 return std::string(".");
131 bool endWithIgnoreCase(const std::string& str1, const std::string& str2, std::string& fileName)
133 std::string::size_type len1 = str1.length();
134 std::string::size_type len2 = str2.length();
139 bool result = std::all_of(str1.cend() - len2, str1.end(),
140 [&i, &str2] (char x) {
141 return std::tolower(x) == std::tolower(str2[i++]);
144 fileName = str1.substr(0, len1 - len2);
149 bool fileNotExist(const std::string& path)
152 return stat(path.c_str(), &sb) != 0;
155 #ifdef NOT_USE_FUNCTION
156 static bool extCheckAndGetFileNameIfExist(const std::string& dir, const std::string& ext, struct dirent* entry, std::string& fileName)
158 std::string fName(entry->d_name);
159 if (fName.length() < ext.length() ||
160 fHame.compare(fName.length() - ext.length(), ext.length(), ext) != 0) {
164 std::string fullName = concatPath(dir, entry->d_name);
165 switch (entry->d_type) {
169 if (fileNotExist(fullName))
181 std::string stripNiDLL(const std::string& path)
183 std::string niPath(path);
184 if (path.size() < 5) return niPath;
185 if (!strncasecmp(path.c_str() + path.size() - 4, ".dll", 4))
186 niPath = path.substr(0, path.size()-4);
187 else if (!strncasecmp(path.c_str() + path.size() - 4, ".exe", 4))
188 niPath = path.substr(0, path.size()-4);
190 if (!strncasecmp(niPath.c_str() + niPath.size() - 3, ".ni", 3))
191 return niPath.substr(0, niPath.size()-3);
196 std::string joinStrings(const std::vector<std::string>& strings, const char* const delimeter)
198 switch (strings.size()) {
204 std::ostringstream os;
205 std::copy(strings.begin(), strings.end()-1, std::ostream_iterator<std::string>(os, delimeter));
206 os << *strings.rbegin();
211 struct AssemblyFile {
216 bool operator == (const AssemblyFile& lhs, const AssemblyFile& rhs)
218 return lhs.noExt == rhs.noExt && lhs.ext == rhs.ext;
223 struct hash<AssemblyFile> {
224 std::size_t operator () (const AssemblyFile& f) const {
225 const std::size_t h1 = std::hash<std::string>{}(f.noExt);
226 const std::size_t h2 = std::hash<std::string>{}(f.ext);
228 return h1 ^ (h2 << 1);
233 void assembliesInDirectory(const std::vector<std::string>& directories, std::string& tpaList)
235 std::map<std::string, std::string> assemblyList;
236 std::map<std::string, std::string> tmpList;
238 auto reader = [&assemblyList, &tmpList] (const char* path, const char* name) {
239 std::string pathStr(path);
240 if (isManagedAssembly(pathStr)) {
241 std::string dllName = stripNiDLL(name);
242 std::pair<std::map<std::string, std::string>::iterator, bool> ret;
243 ret = tmpList.insert(std::pair<std::string, std::string>(dllName, pathStr));
244 if (ret.second == false) {
245 if (isNativeImage(pathStr))
246 tmpList[dllName] = pathStr;
251 for (auto directory : directories) {
252 scanFilesInDir(directory.c_str(), reader, 1);
253 // merge scaned dll list to tpa list.
254 // if the dll is already exist in the list, that is skipped.
255 assemblyList.insert(tmpList.begin(), tmpList.end());
258 std::map<std::string, std::string>::iterator it;
259 for (it = assemblyList.begin(); it != assemblyList.end(); it++)
260 tpaList += it->second + ':';
262 if (tpaList.back() == ':')
266 void scanFilesInDir(const char* directory, FileReader reader, unsigned int depth)
269 struct dirent* entry;
272 dir = opendir(directory);
277 std::vector<std::string> innerDirectories;
279 while ((entry = readdir(dir)) != nullptr) {
281 std::string path = concatPath(directory, entry->d_name);
282 switch (entry->d_type) {
290 if (stat(path.c_str(), &sb) == -1)
293 if (S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode))
299 reader(path.c_str(), entry->d_name);
300 else if (depth > 1 && strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
301 innerDirectories.push_back(path);
305 for (auto& d : innerDirectories)
306 scanFilesInDir(d.c_str(), reader, depth-1);
311 static void *stdlog(void*)
317 if (setvbuf(stdout, NULL, _IOLBF, 0) < 0) {
318 _DBG("fail to make stdout line-buffered");
322 if (setvbuf(stderr, NULL, _IONBF, 0) < 0) {
323 _DBG("make stderr unbuffered");
327 /* create the pipe and redirect stdout and stderr */
329 _DBG("fail to create pipe for logging");
333 if (dup2(pfd[1], fileno(stdout)) == -1) {
334 _DBG("fail to duplicate fd to stdout");
338 if (dup2(pfd[1], fileno(stderr)) == -1) {
339 _DBG("fail to duplicate fd to stderr");
345 while ((readSize = read(pfd[0], buf, sizeof buf - 1)) > 0) {
346 if (buf[readSize - 1] == '\n') {
360 int runLoggingThread() {
361 /* spawn the logging thread */
362 if (pthread_create(&loggingThread, 0, stdlog, 0) != 0) {
363 _DBG("fail to create pthread");
367 if (pthread_detach(loggingThread) != 0) {
368 _DBG("fail to detach pthread");