X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=NativeLauncher%2Finstaller-plugin%2Fcommon.cc;h=f84e79cfb7a70417cddb4060d3b515e27ed7cc20;hb=1a2aa15b1a961dcd54c46883356351e8b84bc8fb;hp=377fab9ea3f27f7dec2306e8998b68d31bcffe21;hpb=7831908665a20bc904217edfbdbb7e40343ff2bd;p=platform%2Fcore%2Fdotnet%2Flauncher.git diff --git a/NativeLauncher/installer-plugin/common.cc b/NativeLauncher/installer-plugin/common.cc index 377fab9..f84e79c 100644 --- a/NativeLauncher/installer-plugin/common.cc +++ b/NativeLauncher/installer-plugin/common.cc @@ -29,6 +29,12 @@ #include #include +#include +#include +#include +#include +#include + #include "common.h" #ifdef LOG_TAG @@ -50,253 +56,304 @@ #define __XSTR(x) #x #define __STR(x) __XSTR(x) -static const char* DeviceAPIDir = __STR(DEVICE_API_DIR); -static const char* RuntimeDir = __STR(RUNTIME_DIR); -static const char* CrossgenPath = __STR(CROSSGEN_PATH); -static const char* JITPath = __STR(RUNTIME_DIR)"/libclrjit.so"; +static const char* __DEVICE_API_DIR = __STR(DEVICE_API_DIR); +static const char* __RUNTIME_DIR = __STR(RUNTIME_DIR); +static const char* __CROSSGEN_PATH = __STR(CROSSGEN_PATH); +static const char* __JIT_PATH = __STR(RUNTIME_DIR)"/libclrjit.so"; #undef __STR #undef __XSTR -static void crossgen(const char* dll_path, const char* app_path); -static void smack_(const char* dll_path); -void create_ni_platform() +#if 0 +static std::string replace(std::string &str, const std::string& from, const std::string& to) { - std::string corlib = ConcatPath(RuntimeDir, "System.Private.CoreLib.dll"); - std::string nicorlib = ConcatPath(RuntimeDir, "System.Private.CoreLib.ni.dll"); + size_t startPos = 0; + while ((startPos = str.find(from, startPos)) != std::string::npos) { + str.replace(startPos, from.length(), to); + startPos += to.length(); + } + return str; +} +#endif - if (FileNotExist(nicorlib)) - { - crossgen(corlib.c_str(), nullptr); - smack_(nicorlib.c_str()); - } +static void smack_(const char* dllPath, const char* label) +{ + static const char* chsmack = "/usr/bin/chsmack"; + pid_t pid = fork(); + if (pid == -1) + return; + + if (pid > 0) { + int status; + waitpid(pid, &status, 0); + if (WIFEXITED(status)) + return; + } else { + const char* args[] = { + chsmack, + "-a", label, + dllPath, + nullptr + }; + execv(chsmack, const_cast(args)); + + exit(0); + } +} - const char* platform_dirs[] = {RuntimeDir, DeviceAPIDir, "/usr/bin"}; - const char* ignores[] = {corlib.c_str()}; +static void crossgen(const char* dllPath, const char* appPath) +{ + //pid_t parent = getpid(); + pid_t pid = fork(); + if (pid == -1) + return; + + if (pid > 0) { + int status; + waitpid(pid, &status, 0); + if (WIFEXITED(status)) + return; + } else { + // search dlls in the application directory first, to use application dlls + // instead of system dlls when proceeding NI + std::vector tpaDir; + if (appPath != NULL) { + std::string path(appPath); + std::string::size_type prevPos = 0, pos = 0; + while ((pos = path.find(':', pos)) != std::string::npos) { + std::string substring(path.substr(prevPos, pos - prevPos)); + tpaDir.push_back(substring); + prevPos = ++pos; + } + std::string substring(path.substr(prevPos, pos - prevPos)); + tpaDir.push_back(substring); + } + tpaDir.push_back(__RUNTIME_DIR); + tpaDir.push_back(__DEVICE_API_DIR); + + // get reference API directory ([DEVICE_API_DIR]/ref) + int len = strlen(__DEVICE_API_DIR); + char* refAPIDir = (char*)calloc(len + 5, 1); + if (!refAPIDir) { + printf("fail to allocate memory for reference API directory\n"); + return; + } + snprintf(refAPIDir, len + 5, "%s%s", __DEVICE_API_DIR, "/ref"); + tpaDir.push_back(refAPIDir); + + std::string tpa; + assembliesInDirectory(tpaDir, tpa); + + std::vector argv = { + __CROSSGEN_PATH, + "/Trusted_Platform_Assemblies", tpa.c_str(), + "/JITPath", __JIT_PATH, + "/FragileNonVersionable" + }; + if (appPath != nullptr) { + argv.push_back("/App_Paths"); + argv.push_back(appPath); + } + argv.push_back(dllPath); + argv.push_back(nullptr); + + printf("+ %s\n", dllPath); + + execv(__CROSSGEN_PATH, const_cast(argv.data())); + exit(0); + } +} - create_ni_under_dirs(platform_dirs, 3, ignores, 1, [](const char* ni){ - smack_(ni); - }); +static int getRootPath(const char *pkgId, std::string& rootPath) +{ + int ret = 0; + char *path = 0; + + uid_t uid = 0; + + if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { + _ERR("Failed to get UID"); + return -1; + } + + _INFO("user id is %d", uid); + + pkgmgrinfo_pkginfo_h handle; + if (uid == 0) { + ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId, &handle); + if (ret != PMINFO_R_OK) + return -1; + } else { + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId, uid, &handle); + if (ret != PMINFO_R_OK) + return -1; + } + + ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return -1; + } + rootPath = path; + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + + return 0; } -static void smack_(const char* dll_path) +static bool niExist(const std::string& path, std::string& ni) { - static const char* CHKSMACK = "/usr/bin/chsmack"; - pid_t pid = fork(); - if (pid == -1) - { - return; - } - - if (pid > 0) - { - int status; - waitpid(pid, &status, 0); - if (WIFEXITED(status)) - { - return; - } - } - else - { - const char* args[] = { - CHKSMACK, - "-a", "_", - dll_path, - nullptr - }; - execv(CHKSMACK, const_cast(args)); - - exit(0); - } + // native image of System.Private.CoreLib.dll should have to overwrite + // original file to support new coreclr + if (path.find("System.Private.CoreLib.dll") != std::string::npos) { + std::string coreLibBackup = path + ".Backup"; + if (!fileNotExist(coreLibBackup)) { + ni = path; + return true; + } + return false; + } + + static const char* possibleExts[] = { + ".ni.dll", ".NI.dll", ".NI.DLL", ".ni.DLL", + ".ni.exe", ".NI.exe", ".NI.EXE", ".ni.EXE" + }; + std::string fName = path.substr(0, path.size() - 4); + + struct stat sb; + + for (const char* ext : possibleExts) { + std::string f = fName + ext; + if (stat(f.c_str(), &sb) == 0) { + ni = f; + return true; + } + } + + return false; } -static void crossgen(const char* dll_path, const char* app_path) +static void createCoreLibNI() { - //pid_t parent = getpid(); - pid_t pid = fork(); - if (pid == -1) - { - return; - } - - if (pid > 0) - { - int status; - waitpid(pid, &status, 0); - if (WIFEXITED(status)) - { - return; - } - } - else - { - std::vector tpaDir = { - RuntimeDir, DeviceAPIDir - }; - std::string tpa; - AssembliesInDirectory(tpaDir, tpa); - - std::vector argv = - { - CrossgenPath, - "/Trusted_Platform_Assemblies", tpa.c_str(), - "/JITPath", JITPath, - "/FragileNonVersionable" - }; - if (app_path != nullptr) - { - argv.push_back("/App_Paths"); - argv.push_back(app_path); - } - argv.push_back(dll_path); - argv.push_back(nullptr); - - /* - for (const char* arg : argv) - { - printf("%s ", arg); - } - printf("\n"); - */ - printf("+ %s\n", dll_path); - - execv(CrossgenPath, const_cast(argv.data())); - exit(0); - } + std::string coreLib = concatPath(__RUNTIME_DIR, "System.Private.CoreLib.dll"); + std::string niCoreLib = concatPath(__RUNTIME_DIR, "System.Private.CoreLib.ni.dll"); + std::string coreLibBackup = concatPath(__RUNTIME_DIR, "System.Private.CoreLib.dll.Backup"); + + if (!niExist(coreLib, niCoreLib)) { + crossgen(coreLib.c_str(), nullptr); + if (!fileNotExist(niCoreLib)) { + // change owner and groups for generated ni file. + struct stat info; + if (!stat(coreLib.c_str(), &info)) { + if (chown(niCoreLib.c_str(), info.st_uid, info.st_gid) == -1) + _ERR("Failed to change owner and group name"); + } + smack_(niCoreLib.c_str(), "_"); + rename(coreLib.c_str(), coreLibBackup.c_str()); + rename(niCoreLib.c_str(), coreLib.c_str()); + } + } } -static int get_root_path(const char *pkgid, std::string& root_path) +void createNiPlatform() { - int ret = 0; - char *path = 0; - - uid_t uid = 0; - - if (pkgmgr_installer_info_get_target_uid(&uid) < 0) - { - _ERR("Failed to get UID"); - return -1; - } - - _INFO("user id is %d", uid); - - pkgmgrinfo_pkginfo_h handle; - if (uid == 0) - { - ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle); - if (ret != PMINFO_R_OK) - return -1; - } - else - { - ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle); - if (ret != PMINFO_R_OK) - return -1; - } - - ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path); - if (ret != PMINFO_R_OK) { - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - return -1; - } - root_path = path; - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - - return 0; + createCoreLibNI(); + + const char* platformDirs[] = {__RUNTIME_DIR, __DEVICE_API_DIR, "/usr/bin"}; + + createNiUnderDirs(platformDirs, 3, [](const char* ni) { + smack_(ni, "_"); + }); } -static bool NIExist(const std::string& path, std::string& ni) +void createNiSelect(const char* dllPath) { - static const char* possible_exts[] = { - ".ni.dll", ".NI.dll", ".NI.DLL", ".ni.DLL" - }; - std::string fname = path.substr(0, path.size() - 4); - - struct stat sb; - - for (const char* ext : possible_exts) - { - std::string f = fname + ext; - if (stat(f.c_str(), &sb) == 0) - { - ni = f; - return true; - } - } - - return false; + createCoreLibNI(); + + std::string niPath; + if (!fileNotExist(dllPath)) { + if (!niExist(dllPath, niPath)) { + crossgen(dllPath, nullptr); + if (niExist(dllPath, niPath)) { + // change owner and groups for generated ni file. + struct stat info; + if (!stat(dllPath, &info)) { + if (chown(niPath.c_str(), info.st_uid, info.st_gid) == -1) + _ERR("Failed to change owner and group name"); + } + smack_(niPath.c_str(), "_"); + } + } + else + printf("Already [%s] file is exist\n", niPath.c_str()); + } } -void create_ni_under_dirs(const char* root_paths[], int count, const char* ignores[], int igcount, after_create cb) +void createNiUnderDirs(const char* rootPaths[], int count, const char* ignores[], int igcount, afterCreate cb) { - std::string app_paths; - for (int i=0; i