Add RTLD_NODELETE option to open plugin library.
[platform/core/dotnet/launcher.git] / NativeLauncher / util / utils.cc
index f5b9406..fff4cfb 100644 (file)
  * limitations under the License.
  */
 
-#include <stdio.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <limits.h>
 #include <strings.h>
-#include <pthread.h>
 
 #include <cstdlib>
 #include <cstring>
 #include <vector>
 #include <iterator>
 #include <sstream>
+#include <map>
 
 #include "utils.h"
-#include "log.h"
+#include "path_manager.h"
 
-static int pfd[2];
-static pthread_t loggingThread;
-
-bool iCompare(const std::string& a, const std::string& b)
-{
-       return a.length() == b.length() &&
-               std::equal(b.begin(), b.end(), a.begin(),
-                       [](unsigned char a, unsigned char b)
-                       { return std::tolower(a) == std::tolower(b); });
-}
-
-bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffset, int length)
+static bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffset, int length)
 {
        return static_cast<int>(a.length()) - length >= aOffset &&
                static_cast<int>(b.length()) - length >= bOffset &&
@@ -55,8 +43,9 @@ bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffs
 
 bool isManagedAssembly(const std::string& fileName)
 {
-       return iCompare(fileName, fileName.size()-4, ".dll", 0, 4) ||
-               iCompare(fileName, fileName.size()-4, ".exe", 0, 4);
+       return (iCompare(fileName, fileName.size()-4, ".dll", 0, 4) ||
+                       iCompare(fileName, fileName.size()-4, ".exe", 0, 4)) &&
+                       !isNativeImage(fileName);
 }
 
 bool isNativeImage(const std::string& fileName)
@@ -89,13 +78,13 @@ std::string concatPath(const std::string& path1, const std::string& path2)
        return path;
 }
 
-void appendPath(std::string& path1, const std::string& path2)
+void splitPath(const std::string& path, std::vector<std::string>& out)
 {
-       if (path1.back() == PATH_SEPARATOR) {
-               path1.append(path2);
-       } else {
-               path1 += PATH_SEPARATOR;
-               path1.append(path2);
+       std::istringstream ss(path);
+       std::string token;
+
+       while (std::getline(ss, token, ':')) {
+               out.push_back(token);
        }
 }
 
@@ -119,55 +108,11 @@ std::string baseName(const std::string& path)
        return path;
 }
 
-bool endWithIgnoreCase(const std::string& str1, const std::string& str2, std::string& fileName)
-{
-       std::string::size_type len1 = str1.length();
-       std::string::size_type len2 = str2.length();
-       if (len2 > len1)
-               return false;
-
-       int i = 0;
-       bool result = std::all_of(str1.cend() - len2, str1.end(),
-                               [&i, &str2] (char x) {
-                                       return std::tolower(x) == std::tolower(str2[i++]);
-                               });
-       if (result)
-               fileName = str1.substr(0, len1 - len2);
-
-       return result;
-}
-
-bool fileNotExist(const std::string& path)
+bool isFileExist(const std::string& path)
 {
        struct stat sb;
-       return stat(path.c_str(), &sb) != 0;
-}
-
-#ifdef NOT_USE_FUNCTION
-static bool extCheckAndGetFileNameIfExist(const std::string& dir, const std::string& ext, struct dirent* entry, std::string& fileName)
-{
-       std::string fName(entry->d_name);
-       if (fName.length() < ext.length() ||
-                       fHame.compare(fName.length() - ext.length(), ext.length(), ext) != 0) {
-               return false;
-       }
-
-       std::string fullName = concatPath(dir, entry->d_name);
-       switch (entry->d_type) {
-               case DT_REG: break;
-               case DT_LNK:
-               case DT_UNKNOWN:
-                       if (fileNotExist(fullName))
-                               return false;
-               default:
-                       return false;
-       }
-
-       fileName = fullName;
-
-       return true;
+       return stat(path.c_str(), &sb) == 0;
 }
-#endif
 
 std::string stripNiDLL(const std::string& path)
 {
@@ -184,57 +129,19 @@ std::string stripNiDLL(const std::string& path)
        return niPath;
 }
 
-std::string joinStrings(const std::vector<std::string>& strings, const char* const delimeter)
-{
-       switch (strings.size()) {
-               case 0:
-                       return "";
-               case 1:
-                       return strings[0];
-               default:
-                       std::ostringstream os;
-                       std::copy(strings.begin(), strings.end()-1, std::ostream_iterator<std::string>(os, delimeter));
-                       os << *strings.rbegin();
-                       return os.str();
-       }
-}
-
-struct AssemblyFile {
-       std::string noExt;
-       std::string ext;
-};
-
-bool operator == (const AssemblyFile& lhs, const AssemblyFile& rhs)
-{
-       return lhs.noExt == rhs.noExt && lhs.ext == rhs.ext;
-}
-
-namespace std {
-       template<>
-       struct hash<AssemblyFile> {
-               std::size_t operator () (const AssemblyFile& f) const {
-                       const std::size_t h1 = std::hash<std::string>{}(f.noExt);
-                       const std::size_t h2 = std::hash<std::string>{}(f.ext);
-
-                       return h1 ^ (h2 << 1);
-               }
-       };
-}
-
 void assembliesInDirectory(const std::vector<std::string>& directories, std::string& tpaList)
 {
        std::map<std::string, std::string> assemblyList;
        std::map<std::string, std::string> tmpList;
 
-       auto reader = [&assemblyList, &tmpList] (const char* path, const char* name) {
-               std::string pathStr(path);
-               if (isManagedAssembly(pathStr)) {
+       auto reader = [&assemblyList, &tmpList] (const std::string& path, const char* name) {
+               if (isManagedAssembly(path) || isNativeImage(path)) {
                        std::string dllName = stripNiDLL(name);
                        std::pair<std::map<std::string, std::string>::iterator, bool> ret;
-                       ret = tmpList.insert(std::pair<std::string, std::string>(dllName, pathStr));
+                       ret = tmpList.insert(std::pair<std::string, std::string>(dllName, path));
                        if (ret.second == false) {
-                               if (isNativeImage(pathStr))
-                                       tmpList[dllName] = pathStr;
+                               if (isNativeImage(path))
+                                       tmpList[dllName] = path;
                        }
                }
        };
@@ -254,13 +161,13 @@ void assembliesInDirectory(const std::vector<std::string>& directories, std::str
                tpaList.pop_back();
 }
 
-void scanFilesInDir(const char* directory, FileReader reader, unsigned int depth)
+void scanFilesInDir(const std::string& directory, FileReader reader, unsigned int depth)
 {
        DIR *dir;
        struct dirent* entry;
        bool isDir;
 
-       dir = opendir(directory);
+       dir = opendir(directory.c_str());
 
        if (dir == nullptr)
                return;
@@ -287,7 +194,7 @@ void scanFilesInDir(const char* directory, FileReader reader, unsigned int depth
                                continue;
                }
                if (!isDir)
-                       reader(path.c_str(), entry->d_name);
+                       reader(path, entry->d_name);
                else if (depth > 1 && strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
                        innerDirectories.push_back(path);
        }
@@ -299,62 +206,3 @@ void scanFilesInDir(const char* directory, FileReader reader, unsigned int depth
        closedir(dir);
 }
 
-static void *stdlog(void*)
-{
-    ssize_t readSize;
-    char buf[1024];
-
-    while ((readSize = read(pfd[0], buf, sizeof buf - 1)) > 0) {
-        if (buf[readSize - 1] == '\n') {
-            --readSize;
-        }
-
-        buf[readSize] = 0;
-
-        _ERRX("%s", buf);
-    }
-
-    return 0;
-}
-
-int runLoggingThread() { // run this function to redirect your output to android log
-    if (setvbuf(stdout, NULL, _IOLBF, 0) < 0) {
-               _DBG("fail to make stdout line-buffered");
-               return -1;
-    }
-
-    if (setvbuf(stderr, NULL, _IONBF, 0) < 0) {
-               _DBG("make stderr unbuffered");
-               return -1;
-       }
-
-    /* create the pipe and redirect stdout and stderr */
-    if (pipe(pfd) < 0) {
-               _DBG("fail to create pipe for logging");
-               return -1;
-    }
-
-    if (dup2(pfd[1], fileno(stdout)) == -1) {
-               _DBG("fail to duplicate fd to stdout");
-               return -1;
-    }
-
-    if (dup2(pfd[1], fileno(stderr)) == -1) {
-               _DBG("fail to duplicate fd to stderr");
-               return -1;
-       }
-
-    /* spawn the logging thread */
-    if (pthread_create(&loggingThread, 0, stdlog, 0) != 0) {
-               _DBG("fail to create pthread");
-        return -1;
-    }
-
-    if (pthread_detach(loggingThread) != 0) {
-               _DBG("fail to detach pthread");
-               return -1;
-       }
-
-    return 0;
-}
-