From 9604424274a177bdcd46345f3c989d8bea6ea34f Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=B5=9C=EC=A2=85=ED=97=8C/Common=20Platform=20Lab=28SR=29?= =?utf8?q?/Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Tue, 18 Aug 2020 16:46:43 +0900 Subject: [PATCH 01/16] Delete unused libraries when installing the application (#269) Change-Id: I984b1ba19f2190504b912ee9a70a501e978c0d71 --- NativeLauncher/CMakeLists.txt | 9 ++ NativeLauncher/dotnet-launcher.info | 4 + .../delete_unused_library_plugin.cc | 134 +++++++++++++++++++++ NativeLauncher/tool/tac_common.cc | 37 +----- packaging/dotnet-launcher.spec | 3 + 5 files changed, 155 insertions(+), 32 deletions(-) create mode 100644 NativeLauncher/installer-plugin/delete_unused_library_plugin.cc diff --git a/NativeLauncher/CMakeLists.txt b/NativeLauncher/CMakeLists.txt index 11945bf..e3254ee 100644 --- a/NativeLauncher/CMakeLists.txt +++ b/NativeLauncher/CMakeLists.txt @@ -223,6 +223,14 @@ ADD_LIBRARY(${PREFER_NUGET_CACHE_PLUGIN} SHARED ${${PREFER_NUGET_CACHE_PLUGIN}_S SET_TARGET_PROPERTIES(${PREFER_NUGET_CACHE_PLUGIN} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_LIB}) TARGET_LINK_LIBRARIES(${PREFER_NUGET_CACHE_PLUGIN} ${${PROJECT_NAME}_LDFLAGS} ${DOTNET_LAUNCHER_UTIL} ${TAC_COMMON}) +SET(DELETE_UNUSED_LIBRARY_PLUGIN "delete_unused_library_plugin") +SET(${DELETE_UNUSED_LIBRARY_PLUGIN}_SOURCE_FILES + installer-plugin/delete_unused_library_plugin.cc +) +ADD_LIBRARY(${DELETE_UNUSED_LIBRARY_PLUGIN} SHARED ${${DELETE_UNUSED_LIBRARY_PLUGIN}_SOURCE_FILES}) +SET_TARGET_PROPERTIES(${DELETE_UNUSED_LIBRARY_PLUGIN} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_LIB}) +TARGET_LINK_LIBRARIES(${DELETE_UNUSED_LIBRARY_PLUGIN} ${${PROJECT_NAME}_LDFLAGS} ${DOTNET_LAUNCHER_UTIL}) + CONFIGURE_FILE(dotnet-launcher.pc.in dotnet-launcher.pc @ONLY) INSTALL(TARGETS ${DOTNET_LAUNCHER_UTIL} DESTINATION ${LIBDIR}) @@ -237,6 +245,7 @@ INSTALL(TARGETS ${TPATOOL} DESTINATION ${BINDIR}) INSTALL(TARGETS ${DOTNETTOOL} DESTINATION ${BINDIR}) INSTALL(TARGETS ${PREFER_DOTNET_AOT_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR}) INSTALL(TARGETS ${PREFER_NUGET_CACHE_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR}) +INSTALL(TARGETS ${DELETE_UNUSED_LIBRARY_PLUGIN} DESTINATION ${INSTALL_PLUGIN_DIR}) INSTALL(FILES dotnet.loader DESTINATION ${LOADERDIR}) INSTALL(FILES dotnet.launcher DESTINATION ${LOADERDIR}) INSTALL(FILES dotnet.debugger DESTINATION ${LOADERDIR}) diff --git a/NativeLauncher/dotnet-launcher.info b/NativeLauncher/dotnet-launcher.info index d7aa1cc..067a4b6 100644 --- a/NativeLauncher/dotnet-launcher.info +++ b/NativeLauncher/dotnet-launcher.info @@ -1,2 +1,6 @@ +type="tag";name="ui-application";path="/etc/package-manager/parserlib/libdelete_unused_library_plugin.so" +type="tag";name="service-application";path="/etc/package-manager/parserlib/libdelete_unused_library_plugin.so" +type="tag";name="widget-application";path="/etc/package-manager/parserlib/libdelete_unused_library_plugin.so" +type="tag";name="watch-application";path="/etc/package-manager/parserlib/libdelete_unused_library_plugin.so" type="metadata";name="http://tizen.org/metadata/prefer_nuget_cache";path="/etc/package-manager/parserlib/metadata/libprefer_nuget_cache_plugin.so" type="metadata";name="http://tizen.org/metadata/prefer_dotnet_aot";path="/etc/package-manager/parserlib/metadata/libprefer_dotnet_aot_plugin.so" diff --git a/NativeLauncher/installer-plugin/delete_unused_library_plugin.cc b/NativeLauncher/installer-plugin/delete_unused_library_plugin.cc new file mode 100644 index 0000000..d016f89 --- /dev/null +++ b/NativeLauncher/installer-plugin/delete_unused_library_plugin.cc @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "log.h" +#include "utils.h" + +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "DOTNET_INSTALLER_PLUGIN" + +typedef struct _xmlDoc xmlDoc; +typedef xmlDoc* xmlDocPtr; + +bool pluginInstalled = false; + +extern "C" int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc, const char* pkgId) +{ + // Can be multiple apps in one package + if (pluginInstalled) { + _INFO("Plugin already installed"); + return 0; + } + pluginInstalled = true; + + std::string appType = getAppType(pkgId); + if (appType.empty()) { + _ERR("Failed to get app type from [%s]", pkgId); + return 0; + } + + if (appType.find("dotnet") == std::string::npos) { + return 0; + } + + std::string rootPath = getRootPath(pkgId); + if (rootPath.empty()) { + _ERR("Failed to get root path from [%s]", pkgId); + return 0; + } + + std::string runtimesDir = concatPath(rootPath, "bin/runtimes"); + if (!bf::exists(runtimesDir)) { + return 0; + } + + char buffer[128]; + sprintf(buffer, "(tizen|linux|unix|base|any)(.\\d.\\d.\\d)?(-%s)?", ARCHITECTURE_IDENTIFIER); + std::regex pattern(buffer); + + std::vector unusedDir; + try { + for (auto& path : bf::recursive_directory_iterator(runtimesDir)) { + std::string filepath = path.path().string(); + std::string targetDir = filepath.substr(filepath.rfind("/runtimes/") + 10); + if (!std::regex_match(targetDir.substr(0, targetDir.find('/')), pattern)) { + if (isDirectory(filepath)) { + unusedDir.push_back(filepath); + } + } + } + } catch (const bf::filesystem_error& error) { + _ERR("Failed to recursive directory: %s", error.what()); + } + + for (auto& path : unusedDir) { + if (!removeAll(path)) { + _ERR("Failed to remove of %s", path.c_str()); + } + } + unusedDir.clear(); + + return 0; +} +extern "C" int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr doc, const char* pkgId) +{ + return PKGMGR_PARSER_PLUGIN_INSTALL(doc, pkgId); +} +extern "C" int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr doc, const char* pkgId) +{ + return 0; +} +extern "C" int PKGMGR_PARSER_PLUGIN_REMOVED(xmlDocPtr doc, const char* pkgId) +{ + return 0; +} +extern "C" int PKGMGR_PARSER_PLUGIN_CLEAN(xmlDocPtr doc, const char* pkgId) +{ + return 0; +} +extern "C" int PKGMGR_PARSER_PLUGIN_UNDO(xmlDocPtr doc, const char* pkgId) +{ + return 0; +} +extern "C" int PKGMGR_PARSER_PLUGIN_PRE_INSTALL(const char *pkgId) +{ + return 0; +} +extern "C" int PKGMGR_PARSER_PLUGIN_PRE_UPGRADE(const char *pkgId) +{ + return 0; +} +extern "C" int PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL(const char *pkgId) +{ + return 0; +} +extern "C" int PKGMGR_PARSER_PLUGIN_POST_INSTALL(const char *pkgId) +{ + return 0; +} +extern "C" int PKGMGR_PARSER_PLUGIN_POST_UPGRADE(const char *pkgId) +{ + return 0; +} +extern "C" int PKGMGR_PARSER_PLUGIN_POST_UNINSTALL(const char *pkgId) +{ + return 0; +} diff --git a/NativeLauncher/tool/tac_common.cc b/NativeLauncher/tool/tac_common.cc index 72c6c71..4cc26fd 100644 --- a/NativeLauncher/tool/tac_common.cc +++ b/NativeLauncher/tool/tac_common.cc @@ -15,7 +15,6 @@ */ #include -#include #include #include #include @@ -430,44 +429,18 @@ std::vector depsJsonParser(const std::string& rootPath, const std:: std::vector getLibrariesInfo(const std::string& rootPath) { std::vector LibrariesInfo; - std::vector unusedDir; std::string runtimesDir = concatPath(rootPath, "bin/runtimes"); if (!bf::exists(runtimesDir)) return LibrariesInfo; - char buffer[128]; - sprintf(buffer, "(tizen|linux|unix|base|any)(.\\d.\\d.\\d)?(-%s)?", ARCHITECTURE_IDENTIFIER); - std::regex pattern(buffer); - - try { - for (auto& path : bf::recursive_directory_iterator(runtimesDir)) { - std::string filepath = path.path().string(); - std::size_t pos = filepath.rfind("/runtimes/"); - if (pos != std::string::npos) { - std::string targetDir = filepath.substr(pos + 10); - if (!std::regex_match(targetDir.substr(0, targetDir.find('/')), pattern)) { - if (isDirectory(filepath)) - unusedDir.push_back(filepath); - continue; - } - } - if (filepath.rfind(".so") == std::string::npos) - continue; - + auto convert = [&LibrariesInfo](const std::string& filepath, const std::string& filename) { + if (filepath.rfind(".so") != std::string::npos) { std::string buffer = SHA256(filepath); LibrariesInfo.push_back(filepath + ":" + buffer); - _INFO("Library : [%s] / SHA256 : [%s]", filepath.substr(filepath.rfind('/') + 1).c_str(), buffer.c_str()); + _INFO("Library : [%s] / SHA256 : [%s]", filename.c_str(), buffer.c_str()); } - } catch (const bf::filesystem_error& error) { - _ERR("Failed to recursive directory: %s", error.what()); - } - - for (auto& path : unusedDir) { - if (!removeAll(path)) { - _ERR("Failed to remove of %s", path.c_str()); - } - } - unusedDir.clear(); + }; + scanFilesInDirectory(runtimesDir, convert, -1); return LibrariesInfo; } diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec index 8670b5e..54cda09 100644 --- a/packaging/dotnet-launcher.spec +++ b/packaging/dotnet-launcher.spec @@ -54,6 +54,7 @@ Requires(preun): /usr/bin/systemctl %define _runtime_dir /usr/share/dotnet.tizen/netcoreapp %define _framework_dir /usr/share/dotnet.tizen/framework %define _install_mdplugin_dir /etc/package-manager/parserlib/metadata +%define _install_plugin_dir /etc/package-manager/parserlib %define _native_lib_dir /usr/share/dotnet.tizen/lib %define _dotnet_dir /opt/usr/dotnet %define _system_base_addr_file /opt/usr/dotnet.system.base.addr @@ -120,6 +121,7 @@ cmake \ -DFRAMEWORK_DIR=%{_framework_dir} \ -DCROSSGEN_PATH=%{_runtime_dir}/crossgen \ -DINSTALL_MDPLUGIN_DIR=%{_install_mdplugin_dir} \ + -DINSTALL_PLUGIN_DIR=%{_install_plugin_dir} \ -DDOTNET_DIR=%{_dotnet_dir} \ -DVERSION=%{version} \ -DNATIVE_LIB_DIR=%{_native_lib_dir} \ @@ -173,6 +175,7 @@ chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet %{_bindir}/dotnettool %{_install_mdplugin_dir}/libprefer_nuget_cache_plugin.so %{_install_mdplugin_dir}/libprefer_dotnet_aot_plugin.so +%{_install_plugin_dir}/libdelete_unused_library_plugin.so %{_bindir}/dotnet-launcher %{_bindir}/dotnet-loader %{_bindir}/dotnet -- 2.7.4 From 3a4e40c00bc02085db54fd718d0b8e6de60a57e0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=B5=9C=EC=A2=85=ED=97=8C/Common=20Platform=20Lab=28SR=29?= =?utf8?q?/Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Tue, 18 Aug 2020 16:53:27 +0900 Subject: [PATCH 02/16] Added error handling for failures during the TAC (#262) Change-Id: I723505929933af4132666f42db27d4dac16b6d9a --- NativeLauncher/inc/ni_common.h | 4 +- .../installer-plugin/prefer_nuget_cache_plugin.cc | 378 ++++++++++++++------- NativeLauncher/tool/ni_common.cc | 4 +- 3 files changed, 255 insertions(+), 131 deletions(-) diff --git a/NativeLauncher/inc/ni_common.h b/NativeLauncher/inc/ni_common.h index 2b00a6f..bdaba44 100644 --- a/NativeLauncher/inc/ni_common.h +++ b/NativeLauncher/inc/ni_common.h @@ -79,7 +79,7 @@ ni_error_e createNIDll(const std::string& dllPath, DWORD flags); * @param[i] flags additional flags for the image generator * @return ni_error_e */ -ni_error_e createNIUnderDirs(const std::string rootPaths, DWORD flags); +ni_error_e createNIUnderDirs(const std::string& rootPaths, DWORD flags); /** * @brief create native images for all DLLs in a package @@ -98,7 +98,7 @@ void removeNIPlatform(); * @brief remove native images under directories * @param[i] rootPaths paths to directories */ -void removeNIUnderDirs(const std::string rootPaths); +void removeNIUnderDirs(const std::string& rootPaths); /** * @brief remove native images of a package diff --git a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc index 0a20793..b1f18f3 100644 --- a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc +++ b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -101,14 +102,10 @@ static bool compareSHA256Info(std::string sha256Info, std::string nugetPackage) return false; } -static int copyAssemblyCreateSymlink(std::string binPath, std::string tacVersionDir, std::string nugetPackage, bool isCreateTacDir) +static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, std::string nugetPackage, bool isCreateTacDir) { - std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR); - if (!createDir(tac_dir)) { - _ERR("Cannot create directory: %s", tac_dir.c_str()); - return -1; - } - + std::string tac_version_dir = concatPath(__DOTNET_DIR, nugetPackage); + bool nuget_restoration = false; for (auto& npAssemblySha : nugetPackagesAssembliesSha) { std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':')); std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':')); @@ -116,20 +113,36 @@ static int copyAssemblyCreateSymlink(std::string binPath, std::string tacVersion if (!strcmp(nuget_package.c_str(), nugetPackage.c_str())) { if (bf::exists(concatPath(binPath, assembly))) { if (isCreateTacDir) { - if (!copyFile(concatPath(binPath, assembly), concatPath(tacVersionDir, assembly))) { + if (!copyFile(concatPath(binPath, assembly), concatPath(tac_version_dir, assembly))) { _ERR("Failed to copy of %s", assembly.c_str()); - return -1; + nuget_restoration = true; + break; } } - bf::create_symlink(concatPath(tacVersionDir, assembly), concatPath(tac_dir, assembly)); + bf::create_symlink(concatPath(tac_version_dir, assembly), concatPath(tacDir, assembly)); + if (!removeFile(concatPath(binPath, assembly))) { _ERR("Failed to remove of %s", assembly.c_str()); - return -1; + nuget_restoration = true; + break; } } } } - return 0; + + if (nuget_restoration) { + for (auto& npAssemblySha : nugetPackagesAssembliesSha) { + std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':')); + std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':')); + std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1); + if (!strcmp(nuget_package.c_str(), nugetPackage.c_str())) { + copyFile(concatPath(tac_version_dir, assembly), concatPath(binPath, assembly)); + removeFile(concatPath(tacDir, assembly)); + } + } + } + + return nuget_restoration; } static void copyLibraryCreateSymlink(const char* pkgId, std::vector LibrariesInfo, std::string tlcDir) @@ -221,23 +234,29 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app } status = "install"; + if (tacDB.empty()) { + _INFO("Not exist data for TAC in %s", pkgId); + return 0; + } + tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE); if (!tac_db) { _ERR("Sqlite create error. So restore the database."); if (tac_restoreDB() != TAC_ERROR_NONE) { _ERR("Sqlite create error"); - return 0; + return -1; } tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE); if (!tac_db) { _ERR("Sqlite create error"); - return 0; + return -1; } } sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL); - if (tacDB.empty()) { - _INFO("Not exist data for TAC in %s", pkgId); + std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR); + if (!createDir(tac_dir)) { + _ERR("Cannot create directory: %s", tac_dir.c_str()); return 0; } @@ -253,53 +272,69 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str()); if (!createDir(tac_version_dir)) { _ERR("Cannot create directory: %s", tac_version_dir.c_str()); - return 0; + status = "restore"; + return -1; } createDirectories.push_back(tac_version_dir); if (!bf::is_symlink(sha256_info)) { createSHA256Info(sha256_info, np); } else { _ERR("Failed to create sha256_info. Symbolic link is detected"); + status = "restore"; + return -1; + } + + if (!bf::exists(sha256_info)) { + status = "restore"; return -1; } - if (copyAssemblyCreateSymlink(binPath, tac_version_dir, np, true) < 0) { + if (copyAssemblyCreateSymlink(binPath, tac_dir, np, true)) { _ERR("Failed to create symlink"); + status = "restore"; return -1; } char *sql = sqlite3_mprintf( "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \ "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str()); - insertDB(tac_db, sql); + if (!insertDB(tac_db, sql)) { + _ERR("Sqlite insert error"); + sqlite3_free(sql); + status = "restore"; + return -1; + } sqlite3_free(sql); } else { _INFO("Exists tac_version_dir [%s]", tac_version_dir.c_str()); if (!bf::is_symlink(sha256_info)) { if (compareSHA256Info(sha256_info, np)) { - if (copyAssemblyCreateSymlink(binPath, tac_version_dir, np, false) < 0) { + if (copyAssemblyCreateSymlink(binPath, tac_dir, np, false)) { _ERR("Failed to create symlink"); + status = "restore"; return -1; } char *sql = sqlite3_mprintf( "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \ "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str()); - insertDB(tac_db, sql); + if (!insertDB(tac_db, sql)) { + _ERR("Sqlite insert error"); + sqlite3_free(sql); + status = "restore"; + return -1; + } sqlite3_free(sql); } else { _INFO("Different nuget : %s", np.c_str()); + continue; } } else { _ERR("Failed to create sha256_info. Symbolic link is detected"); + status = "restore"; return -1; } } - if (!bf::exists(sha256_info)) { - if (!removeAll(tac_version_dir)) { - _ERR("Failed to remove of %s", tac_version_dir.c_str()); - } - } } ///// TLC ///// @@ -336,7 +371,7 @@ static int sqliteCb(void *count, int argc, char **argv, char **colName) return 0; } -static int tac_updateDB(sqlite3 *sqlite) +static void tac_updateDB(sqlite3 *sqlite) { for (auto& unp : updateTac) { int count = -1; @@ -345,7 +380,7 @@ static int tac_updateDB(sqlite3 *sqlite) if (ret != SQLITE_OK) { _ERR("Sqlite select error"); sqlite3_free(sql); - return -1; + continue; } if (count == 0) { std::string tac_version_dir_prev = concatPath(__DOTNET_DIR, unp); @@ -353,17 +388,16 @@ static int tac_updateDB(sqlite3 *sqlite) if (!copyDir(tac_version_dir_prev, tac_version_dir_backup)) { _ERR("Failed to copy of %s to %s", tac_version_dir_prev.c_str(), tac_version_dir_backup.c_str()); sqlite3_free(sql); - return -1; + continue; } if (!removeAll(tac_version_dir_prev)) { _ERR("Failed to remove of %s", tac_version_dir_prev.c_str()); sqlite3_free(sql); - return -1; + continue; } } sqlite3_free(sql); } - return 0; } static void tlc_updateDB(sqlite3 *sqlite, std::vector updateTlc, std::string tlcDir) @@ -437,12 +471,12 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app _ERR("Sqlite create error. So restore the database."); if (tac_restoreDB() != TAC_ERROR_NONE) { _ERR("Sqlite create error"); - return 0; + return -1; } tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE); if (!tac_db) { _ERR("Sqlite create error"); - return 0; + return -1; } } sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL); @@ -454,14 +488,24 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app bool skipTLC = false; if (tacDB.empty()) { sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q;", pkgId); - deleteDB(tac_db, sql); - sqlite3_free(sql); - if (tac_updateDB(tac_db) < 0) { + if (!deleteDB(tac_db, sql)) { + _ERR("Sqlite delete error"); + sqlite3_free(sql); return -1; } + sqlite3_free(sql); + + tac_updateDB(tac_db); + skipTLC = true; _INFO("Not exist data for TAC in %s", pkgId); } else { + std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR); + if (!createDir(tac_dir)) { + _ERR("Cannot create directory: %s", tac_dir.c_str()); + return 0; + } + for (auto& np : tacDB) { std::string tac_name = np.substr(0, np.find('/')); std::string tac_version = np.substr(np.rfind('/') + 1); @@ -474,18 +518,26 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str()); if (!createDir(tac_version_dir)) { _ERR("Cannot create directory: %s", tac_version_dir.c_str()); - return 0; + status = "restore"; + return -1; } createDirectories.push_back(tac_version_dir); if (!bf::is_symlink(sha256_info)) { createSHA256Info(sha256_info, np); } else { _ERR("Failed to create sha256_info. Symbolic link is detected"); + status = "restore"; + return -1; + } + + if (!bf::exists(sha256_info)) { + status = "restore"; return -1; } - if (copyAssemblyCreateSymlink(binPath, tac_version_dir, np, true) < 0) { + if (copyAssemblyCreateSymlink(binPath, tac_dir, np, true)) { _ERR("Failed to create symlink"); + status = "restore"; return -1; } @@ -496,6 +548,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app if (ret != SQLITE_OK) { _ERR("Sqlite select error"); sqlite3_free(sql); + status = "restore"; return -1; } sqlite3_free(sql); @@ -503,21 +556,32 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app sql = sqlite3_mprintf( "UPDATE TAC SET NAME = %Q, VERSION = %Q, NUGET = %Q WHERE PKGID = %Q AND NAME = %Q;", tac_name.c_str(), tac_version.c_str(), np.c_str(), pkgId, tac_name.c_str()); - updateDB(tac_db, sql); + if (!updateDB(tac_db, sql)) { + _ERR("Sqlite update error"); + sqlite3_free(sql); + status = "restore"; + return -1; + } sqlite3_free(sql); } else if (count == 0) { sql = sqlite3_mprintf( "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \ "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str()); - insertDB(tac_db, sql); + if (!insertDB(tac_db, sql)) { + _ERR("Sqlite insert error"); + sqlite3_free(sql); + status = "restore"; + return -1; + } sqlite3_free(sql); } } else { _INFO("Exists tac_version_dir [%s]", tac_version_dir.c_str()); if (!bf::is_symlink(sha256_info)) { if (compareSHA256Info(sha256_info, np)) { - if (copyAssemblyCreateSymlink(binPath, tac_version_dir, np, false) < 0) { + if (copyAssemblyCreateSymlink(binPath, tac_dir, np, false)) { _ERR("Failed to create symlink"); + status = "restore"; return -1; } @@ -528,6 +592,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app if (ret != SQLITE_OK) { _ERR("Sqlite select error"); sqlite3_free(sql); + status = "restore"; return -1; } sqlite3_free(sql); @@ -535,28 +600,35 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app sql = sqlite3_mprintf( "UPDATE TAC SET NAME = %Q, VERSION = %Q, NUGET = %Q WHERE PKGID = %Q AND NAME = %Q;", tac_name.c_str(), tac_version.c_str(), np.c_str(), pkgId, tac_name.c_str()); - updateDB(tac_db, sql); + if (!updateDB(tac_db, sql)) { + _ERR("Sqlite update error"); + sqlite3_free(sql); + status = "restore"; + return -1; + } sqlite3_free(sql); } else if (count == 0) { sql = sqlite3_mprintf( "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \ "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str()); - insertDB(tac_db, sql); + if (!insertDB(tac_db, sql)) { + _ERR("Sqlite insert error"); + sqlite3_free(sql); + status = "restore"; + return -1; + } sqlite3_free(sql); } } else { _INFO("Different nuget : %s", np.c_str()); + continue; } } else { _ERR("Failed to create sha256_info. Symbolic link is detected"); + status = "restore"; return -1; } } - if (!bf::exists(sha256_info)) { - if (!removeAll(tac_version_dir)) { - _ERR("Failed to remove of %s", tac_version_dir.c_str()); - } - } } for (auto& unp : updateTac) { bool isExits = false; @@ -568,13 +640,16 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app } if (!isExits) { char *sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q AND NUGET = %Q;", pkgId, unp.c_str()); - deleteDB(tac_db, sql); + if (!deleteDB(tac_db, sql)) { + _ERR("Sqlite delete error"); + sqlite3_free(sql); + status = "restore"; + return -1; + } sqlite3_free(sql); } } - if (tac_updateDB(tac_db) < 0) { - return -1; - } + tac_updateDB(tac_db); } ///// TLC ///// @@ -604,12 +679,16 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app sqlite3_free(sql); sql = sqlite3_mprintf("DELETE FROM TLC WHERE PKGID = %Q;", pkgId); - deleteDB(tlc_db, sql); + if (!deleteDB(tlc_db, sql)) { + _ERR("Sqlite delete error"); + sqlite3_free(sql); + return 0; + } sqlite3_free(sql); - std::vector librariesInfo = getLibrariesInfo(rootPath); - if (skipTLC) { - librariesInfo.clear(); + std::vector librariesInfo; + if (!skipTLC) { + librariesInfo = getLibrariesInfo(rootPath); } copyLibraryCreateSymlink(pkgId, librariesInfo, tlcDir); @@ -637,12 +716,12 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgId, const char *a _ERR("Sqlite open error. So restore the database."); if (tac_restoreDB() != TAC_ERROR_NONE) { _ERR("Sqlite open error"); - return 0; + return -1; } tac_db = openDB(TAC_APP_LIST_DB); if (!tac_db) { _ERR("Sqlite open error"); - return 0; + return -1; } } sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL); @@ -652,12 +731,16 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgId, const char *a sqlite3_free(sql); sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q;", pkgId); - deleteDB(tac_db, sql); - sqlite3_free(sql); - if (tac_updateDB(tac_db) < 0) { + if (!deleteDB(tac_db, sql)) { + _ERR("Sqlite delete error"); + sqlite3_free(sql); + status = "restore"; return -1; } + sqlite3_free(sql); + + tac_updateDB(tac_db); ///// TLC ///// tlc_db = openDB(TLC_APP_LIST_DB); @@ -680,7 +763,11 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgId, const char *a sqlite3_free(sql); sql = sqlite3_mprintf("DELETE FROM TLC WHERE PKGID = %Q;", pkgId); - deleteDB(tlc_db, sql); + if (!deleteDB(tlc_db, sql)) { + _ERR("Sqlite delete error"); + sqlite3_free(sql); + return 0; + } sqlite3_free(sql); tlc_updateDB(tlc_db, updateTlc, concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR)); @@ -698,33 +785,19 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_REMOVED(const char *pkgId, const char *app return PKGMGR_MDPARSER_PLUGIN_UPGRADE(pkgId, appId, list); } -void cleanStep(std::string tac) +void undoStep(std::string tac) { std::string current_tac = concatPath(__DOTNET_DIR, tac.substr(0, tac.find('/'))); try { for (auto& bck : bf::recursive_directory_iterator(current_tac)) { std::string bck_path = bck.path().string(); if (bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") != NULL) { - if (!removeAll(bck_path)) { - _ERR("Failed to remove of %s", bck_path.c_str()); + if (!moveFile(bck_path, bck_path.substr(0, bck_path.rfind(".bck")))) { + _ERR("Failed to move %s", bck_path.c_str()); } break; } } - - bool isExist = false; - for (auto& bck : bf::recursive_directory_iterator(current_tac)) { - std::string bck_path = bck.path().string(); - if (bf::exists(bck_path) && bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") == NULL) { - isExist = true; - break; - } - } - if (!isExist) { - if (!removeAll(current_tac)) { - _ERR("Failed to remove of %s", current_tac.c_str()); - } - } } catch (const bf::filesystem_error& error) { _ERR("Failed to recursive directory: %s", error.what()); return; @@ -733,8 +806,8 @@ void cleanStep(std::string tac) ///// TLC ///// auto convert = [](const std::string& path, const std::string& filename) { if (filename.rfind(".bck") != std::string::npos) { - if (!removeFile(path)) { - _ERR("Failed to remove of %s", path.c_str()); + if (!moveFile(path, replaceAll(path, ".bck", ""))) { + _ERR("Failed to move %s", path.c_str()); } } }; @@ -742,74 +815,101 @@ void cleanStep(std::string tac) scanFilesInDirectory(concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR), convert, 0); } -void install_Clean() +void install_Undo() { - return; + for (auto& cd : createDirectories) { + if (!removeAll(cd)) { + _ERR("Failed to remove of %s", cd.c_str()); + } + } + + for (auto& cl : createLibraries) { + if (!removeFile(cl)) { + _ERR("Failed to remove of %s", cl.c_str()); + } + } } -void unInstall_Clean() +void unInstall_Undo() { for (auto& unp : updateTac) { - cleanStep(unp); + undoStep(unp); } } -void update_Clean() +void update_Undo() { + install_Undo(); if (!tacDB.empty()) { for (auto& np : tacDB) { - cleanStep(np); + undoStep(np); } } - unInstall_Clean(); + unInstall_Undo(); } -extern "C" int PKGMGR_MDPARSER_PLUGIN_CLEAN(const char *pkgId, const char *appId, GList *list) +extern "C" int PKGMGR_MDPARSER_PLUGIN_UNDO(const char *pkgId, const char *appId, GList *list) { - _DBG("[===== PKGMGR_MDPARSER_PLUGIN_CLEAN =====]"); + _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNDO =====]"); _INFO("PackageID : %s", pkgId); // Can be multiple apps in one package if (tacPluginFinished) { - _INFO("TAC plugin already finished(CLEAN)"); + _INFO("TAC plugin already finished(UNDO)"); return 0; } tacPluginFinished = true; if (!strcmp("install", status.c_str())) { - install_Clean(); + install_Undo(); } else if (!strcmp("update", status.c_str())) { - update_Clean(); + update_Undo(); } else if (!strcmp("uninstall", status.c_str())) { - unInstall_Clean(); + unInstall_Undo(); + } else if (!strcmp("restore", status.c_str())) { + update_Undo(); } if (tac_db) { - closeDB(tac_db); + rollbackDB(tac_db); tac_db = NULL; } if (tlc_db) { - closeDB(tlc_db); + rollbackDB(tlc_db); tlc_db = NULL; } return 0; } -void undoStep(std::string tac) +void cleanStep(std::string tac) { std::string current_tac = concatPath(__DOTNET_DIR, tac.substr(0, tac.find('/'))); try { for (auto& bck : bf::recursive_directory_iterator(current_tac)) { std::string bck_path = bck.path().string(); if (bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") != NULL) { - if (!moveFile(bck_path, bck_path.substr(0, bck_path.rfind(".bck")))) { - _ERR("Failed to move %s", bck_path.c_str()); + if (!removeAll(bck_path)) { + _ERR("Failed to remove of %s", bck_path.c_str()); } break; } } + + bool isExist = false; + for (auto& bck : bf::recursive_directory_iterator(current_tac)) { + std::string bck_path = bck.path().string(); + if (bf::exists(bck_path) && bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") == NULL) { + isExist = true; + break; + } + } + if (!isExist) { + if (!removeAll(current_tac)) { + _ERR("Failed to remove of %s", current_tac.c_str()); + } + } } catch (const bf::filesystem_error& error) { _ERR("Failed to recursive directory: %s", error.what()); return; @@ -818,8 +918,8 @@ void undoStep(std::string tac) ///// TLC ///// auto convert = [](const std::string& path, const std::string& filename) { if (filename.rfind(".bck") != std::string::npos) { - if (!moveFile(path, replaceAll(path, ".bck", ""))) { - _ERR("Failed to move %s", path.c_str()); + if (!removeFile(path)) { + _ERR("Failed to remove of %s", path.c_str()); } } }; @@ -827,66 +927,90 @@ void undoStep(std::string tac) scanFilesInDirectory(concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR), convert, 0); } -void install_Undo() +void install_Clean() { - for (auto& cd : createDirectories) { - if (!removeAll(cd)) { - _ERR("Failed to remove of %s", cd.c_str()); - } - } - - for (auto& cl : createLibraries) { - if (!removeFile(cl)) { - _ERR("Failed to remove of %s", cl.c_str()); - } - } + return; } -void unInstall_Undo() +void unInstall_Clean() { for (auto& unp : updateTac) { - undoStep(unp); + cleanStep(unp); } } -void update_Undo() +void update_Clean() { - install_Undo(); if (!tacDB.empty()) { for (auto& np : tacDB) { - undoStep(np); + cleanStep(np); } } - unInstall_Undo(); + unInstall_Clean(); } -extern "C" int PKGMGR_MDPARSER_PLUGIN_UNDO(const char *pkgId, const char *appId, GList *list) +extern "C" int PKGMGR_MDPARSER_PLUGIN_CLEAN(const char *pkgId, const char *appId, GList *list) { - _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNDO =====]"); + if (!strcmp("restore", status.c_str())) { + disableTACPackage(pkgId); + + std::string rootPath = getRootPath(std::string(pkgId)); + if (!rootPath.empty()) { + std::string binPath = concatPath(rootPath, "bin"); + removeAll(concatPath(binPath, TAC_SYMLINK_SUB_DIR)); + } + + std::string runtimesDir = concatPath(rootPath, "bin/runtimes"); + if (bf::exists(runtimesDir)) { + char buffer[128]; + sprintf(buffer, "(tizen|linux|unix|base|any)(.\\d.\\d.\\d)?(-%s)?", ARCHITECTURE_IDENTIFIER); + std::regex pattern(buffer); + + try { + for (auto& path : bf::recursive_directory_iterator(runtimesDir)) { + std::string symPath = path.path().string(); + if (isDirectory(symPath) || !bf::is_symlink(symPath)) + continue; + std::string targetDir = symPath.substr(symPath.rfind("/runtimes/") + 10); + if (!std::regex_match(targetDir.substr(0, targetDir.find('/')), pattern)) + continue; + if (symPath.rfind(".so") == std::string::npos) + continue; + copyFile(bf::read_symlink(symPath).string(), symPath); + } + } catch (const bf::filesystem_error& error) { + _ERR("Failed to recursive directory: %s", error.what()); + } + } + + return PKGMGR_MDPARSER_PLUGIN_UNDO(pkgId, appId, list); + } + + _DBG("[===== PKGMGR_MDPARSER_PLUGIN_CLEAN =====]"); _INFO("PackageID : %s", pkgId); // Can be multiple apps in one package if (tacPluginFinished) { - _INFO("TAC plugin already finished(UNDO)"); + _INFO("TAC plugin already finished(CLEAN)"); return 0; } tacPluginFinished = true; if (!strcmp("install", status.c_str())) { - install_Undo(); + install_Clean(); } else if (!strcmp("update", status.c_str())) { - update_Undo(); + update_Clean(); } else if (!strcmp("uninstall", status.c_str())) { - unInstall_Undo(); + unInstall_Clean(); } if (tac_db) { - rollbackDB(tac_db); + closeDB(tac_db); tac_db = NULL; } if (tlc_db) { - rollbackDB(tlc_db); + closeDB(tlc_db); tlc_db = NULL; } diff --git a/NativeLauncher/tool/ni_common.cc b/NativeLauncher/tool/ni_common.cc index cabb813..59a32d6 100644 --- a/NativeLauncher/tool/ni_common.cc +++ b/NativeLauncher/tool/ni_common.cc @@ -529,7 +529,7 @@ ni_error_e createNIDll(const std::string& dllPath, DWORD flags) return crossgen(dllPath, std::string(), flags); } -ni_error_e createNIUnderDirs(const std::string rootPaths, DWORD flags) +ni_error_e createNIUnderDirs(const std::string& rootPaths, DWORD flags) { if (!isCoreLibPrepared(flags)) { return NI_ERROR_CORE_NI_FILE; @@ -639,7 +639,7 @@ void removeNIPlatform() removeNIUnderDirs(__pm->getRuntimePath() + ":" + __pm->getTizenFXPath()); } -void removeNIUnderDirs(const std::string rootPaths) +void removeNIUnderDirs(const std::string& rootPaths) { auto convert = [](const std::string& path, const std::string& filename) { if (isNativeImage(path)) { -- 2.7.4 From 972daf129ad11deaa791e41d13faea4908eae18c Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=A1=B0=EC=9B=85=EC=84=9D/Common=20Platform=20Lab=28SR=29?= =?utf8?q?/Principal=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Tue, 18 Aug 2020 17:02:14 +0900 Subject: [PATCH 03/16] Wrap bf::exists() to check for exception. (#270) bf::exists() can throw exception. To avoid crash by exception, exist() which wrap bf::exists() is added. --- NativeLauncher/inc/utils.h | 7 +++++ .../installer-plugin/prefer_nuget_cache_plugin.cc | 8 +++--- NativeLauncher/tool/tac_common.cc | 22 +++++++-------- NativeLauncher/util/utils.cc | 31 +++++++++++++++------- 4 files changed, 43 insertions(+), 25 deletions(-) diff --git a/NativeLauncher/inc/utils.h b/NativeLauncher/inc/utils.h index 2633024..77daa24 100644 --- a/NativeLauncher/inc/utils.h +++ b/NativeLauncher/inc/utils.h @@ -169,6 +169,13 @@ void scanFilesInDirectory(const std::string& directory, FileReader reader, unsig void copySmackAndOwnership(const std::string& fromPath, const std::string& toPath, bool isSymlink = false); /** + * @brief check whether the path exists or not. + * @param[in] source path + * @return return true when the path exist. + */ +bool exist(const bf::path& path); + +/** * @brief create the new directory. * @param[in] source path * @return return true when the directory was created. diff --git a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc index b1f18f3..dbdae36 100644 --- a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc +++ b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc @@ -111,7 +111,7 @@ static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, s std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':')); std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1); if (!strcmp(nuget_package.c_str(), nugetPackage.c_str())) { - if (bf::exists(concatPath(binPath, assembly))) { + if (exist(concatPath(binPath, assembly))) { if (isCreateTacDir) { if (!copyFile(concatPath(binPath, assembly), concatPath(tac_version_dir, assembly))) { _ERR("Failed to copy of %s", assembly.c_str()); @@ -157,7 +157,7 @@ static void copyLibraryCreateSymlink(const char* pkgId, std::vector std::string filename = library.substr(library.rfind('/') + 1); std::string fileSha = filename + ".." + librarySha.substr(librarySha.find(':') + 1); bool fileCopied = false; - if (!bf::exists(concatPath(tlcDir, fileSha))) { + if (!exist(concatPath(tlcDir, fileSha))) { if (!copyFile(library, concatPath(tlcDir, fileSha))) { _ERR("Failed to copy of %s", filename.c_str()); continue; @@ -268,7 +268,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app std::string tac_version_dir = concatPath(__DOTNET_DIR, np); std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO); - if (!bf::exists(tac_version_dir)) { + if (!exist(tac_version_dir)) { _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str()); if (!createDir(tac_version_dir)) { _ERR("Cannot create directory: %s", tac_version_dir.c_str()); @@ -514,7 +514,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app std::string tac_version_dir = concatPath(__DOTNET_DIR, np); std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO); - if (!bf::exists(tac_version_dir)) { + if (!exist(tac_version_dir)) { _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str()); if (!createDir(tac_version_dir)) { _ERR("Cannot create directory: %s", tac_version_dir.c_str()); diff --git a/NativeLauncher/tool/tac_common.cc b/NativeLauncher/tool/tac_common.cc index 4cc26fd..d56e519 100644 --- a/NativeLauncher/tool/tac_common.cc +++ b/NativeLauncher/tool/tac_common.cc @@ -112,7 +112,7 @@ static int tac_restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData) for (auto& npAssembly : depsJsonParser(rootPath, execName)) { std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':')); std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1); - if (bf::exists(tacDir) && bf::exists(concatPath(tacDir, assemblyName))) { + if (exist(tacDir) && exist(concatPath(tacDir, assemblyName))) { parserData.push_back(nugetPackage); } } @@ -226,7 +226,7 @@ tac_error_e disableTACPackage(const std::string& pkgId) std::string binDir = concatPath(rootPath, "bin"); std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR); std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR); - if (bf::exists(tacDir)) { + if (exist(tacDir)) { try { for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) { std::string symPath = symlinkAssembly.path().string(); @@ -286,7 +286,7 @@ tac_error_e enableTACPackage(const std::string& pkgId) std::string binDir = concatPath(rootPath, "bin"); std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR); std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR); - if (!bf::exists(tacDir)) { + if (!exist(tacDir)) { if (!createDir(tacDir)) { fprintf(stderr, "Cannot create directory: %s\n", tacDir.c_str()); return TAC_ERROR_UNKNOWN; @@ -298,21 +298,21 @@ tac_error_e enableTACPackage(const std::string& pkgId) std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':')); std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1); std::string nugetPath = concatPath(__DOTNET_DIR, nugetPackage); - if (bf::exists(nugetPath)) { + if (exist(nugetPath)) { std::string originPath = concatPath(nugetPath, assemblyName); - if (bf::exists(originPath)) { + if (exist(originPath)) { enableNuget.push_back(originPath); } } } for (auto& originPath : enableNuget) { - if (bf::exists(originPath)) { + if (exist(originPath)) { std::string fileName = originPath.substr(originPath.rfind('/') + 1); std::string NIFileName = fileName.substr(0, fileName.rfind(".dll")) + ".ni.dll"; - if (bf::exists(binNIDir)) { + if (exist(binNIDir)) { std::string originNIPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll"; - if (bf::exists(originNIPath)) { + if (exist(originNIPath)) { bf::create_symlink(originNIPath, concatPath(tacDir, NIFileName)); fprintf(stdout, "%s symbolic link file generated successfully.\n", concatPath(tacDir, NIFileName).c_str()); copySmackAndOwnership(tacDir.c_str(), concatPath(tacDir, NIFileName).c_str(), true); @@ -353,7 +353,7 @@ std::vector depsJsonParser(const std::string& rootPath, const std:: std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + ".deps.json"; std::string depsJsonPath = concatPath(rootPath, depsJsonName); try { - if (bf::exists(depsJsonPath)) { + if (exist(depsJsonPath)) { std::ifstream ifs(depsJsonPath); Json::CharReaderBuilder reader; Json::Value root; @@ -430,7 +430,7 @@ std::vector getLibrariesInfo(const std::string& rootPath) { std::vector LibrariesInfo; std::string runtimesDir = concatPath(rootPath, "bin/runtimes"); - if (!bf::exists(runtimesDir)) + if (!exist(runtimesDir)) return LibrariesInfo; auto convert = [&LibrariesInfo](const std::string& filepath, const std::string& filename) { @@ -467,7 +467,7 @@ static int tlc_restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData) for (auto& librarySha : getLibrariesInfo(rootPath)) { std::string library = librarySha.substr(0, librarySha.find(':')); - if (bf::exists(library)) { + if (exist(library)) { std::string fileSha = library.substr(library.rfind('/') + 1) + ".." + librarySha.substr(librarySha.find(':') + 1); char *sql = sqlite3_mprintf("INSERT INTO TLC (PKGID, LIBRARY) VALUES (%Q, %Q);", pkgId, fileSha.c_str()); insertDB(tlc_db, sql); diff --git a/NativeLauncher/util/utils.cc b/NativeLauncher/util/utils.cc index 2864a6f..d6ba2de 100644 --- a/NativeLauncher/util/utils.cc +++ b/NativeLauncher/util/utils.cc @@ -456,7 +456,7 @@ static bool setDirOwnershipAndPermissions(const bf::path& path, bf::perms permis static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& path2) { - if (!bf::exists(path)) { + if (!exist(path)) { _ERR("Failed to copy ownership and permissions from %s to %s", path.c_str(), path2.c_str()); return false; } @@ -472,9 +472,20 @@ static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& pa return true; } +bool exist(const bf::path& path) +{ + bs::error_code error; + bf::exists(path, error); + if (error) { + _ERR("Failed to check %s exists : %s", path.c_str(), error.message().c_str()); + return false; + } + return true; +} + bool createDir(const bf::path& path) { - if (bf::exists(path)) { + if (exist(path)) { return true; } bs::error_code error; @@ -490,11 +501,11 @@ bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) { try { // Check whether the function call is valid - if (!bf::exists(path1) || !bf::is_directory(path1)) { + if (!exist(path1) || !bf::is_directory(path1)) { _ERR("Source directory %s does not exist or is not a directory", path1.c_str()); return false; } - if (!bf::exists(path2)) { + if (!exist(path2)) { // Create the destination directory if (!createDir(path2)) { _ERR("Unable to create destination directory %s", path2.c_str()); @@ -523,7 +534,7 @@ bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) bf::path current(file->path()); bf::path target = path2 / current.filename(); if (bf::is_symlink(symlink_status(current))) { - if ((flags & (FS_MERGE_SKIP | FS_MERGE_OVERWRITE)) && bf::exists(target)) { + if ((flags & (FS_MERGE_SKIP | FS_MERGE_OVERWRITE)) && exist(target)) { continue; } bs::error_code error; @@ -538,7 +549,7 @@ bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) return false; } } else { - if ((flags & FS_MERGE_SKIP) && bf::exists(target)) { + if ((flags & FS_MERGE_SKIP) && exist(target)) { continue; } bf::path destination = target; @@ -571,7 +582,7 @@ bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) bool copyFile(const bf::path& path1, const bf::path& path2) { bs::error_code error; - if (!bf::exists(path1)) { + if (!exist(path1)) { return false; } bf::copy_file(path1, path2, bf::copy_option::overwrite_if_exists, error); @@ -584,7 +595,7 @@ bool copyFile(const bf::path& path1, const bf::path& path2) bool moveFile(const bf::path& path1, const bf::path& path2) { - if (!bf::exists(path1) || bf::exists(path2)) { + if (!exist(path1) || exist(path2)) { return false; } bs::error_code error; @@ -607,7 +618,7 @@ bool moveFile(const bf::path& path1, const bf::path& path2) bool removeFile(const bf::path& path) { - if (!bf::exists(path)) { + if (!exist(path)) { return true; } bs::error_code error; @@ -621,7 +632,7 @@ bool removeFile(const bf::path& path) bool removeAll(const bf::path& path) { - if (!exists(path)) { + if (!exist(path)) { return true; } bs::error_code error; -- 2.7.4 From 8cfcddaa9435665085f2fc9ed075bae0640c2cc1 Mon Sep 17 00:00:00 2001 From: "j-h.choi" Date: Fri, 21 Aug 2020 10:54:41 +0900 Subject: [PATCH 04/16] Wrap bf::exists() to check for exception Change-Id: I0facee498025112514ea16416052d148eaccb04c --- NativeLauncher/installer-plugin/delete_unused_library_plugin.cc | 2 +- NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/NativeLauncher/installer-plugin/delete_unused_library_plugin.cc b/NativeLauncher/installer-plugin/delete_unused_library_plugin.cc index d016f89..1e2fdbd 100644 --- a/NativeLauncher/installer-plugin/delete_unused_library_plugin.cc +++ b/NativeLauncher/installer-plugin/delete_unused_library_plugin.cc @@ -56,7 +56,7 @@ extern "C" int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc, const char* pkgId) } std::string runtimesDir = concatPath(rootPath, "bin/runtimes"); - if (!bf::exists(runtimesDir)) { + if (!exist(runtimesDir)) { return 0; } diff --git a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc index dbdae36..30c16a8 100644 --- a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc +++ b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc @@ -284,7 +284,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app return -1; } - if (!bf::exists(sha256_info)) { + if (!exist(sha256_info)) { status = "restore"; return -1; } @@ -530,7 +530,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app return -1; } - if (!bf::exists(sha256_info)) { + if (!exist(sha256_info)) { status = "restore"; return -1; } @@ -900,7 +900,7 @@ void cleanStep(std::string tac) bool isExist = false; for (auto& bck : bf::recursive_directory_iterator(current_tac)) { std::string bck_path = bck.path().string(); - if (bf::exists(bck_path) && bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") == NULL) { + if (exist(bck_path) && bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") == NULL) { isExist = true; break; } @@ -961,7 +961,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_CLEAN(const char *pkgId, const char *appId } std::string runtimesDir = concatPath(rootPath, "bin/runtimes"); - if (bf::exists(runtimesDir)) { + if (exist(runtimesDir)) { char buffer[128]; sprintf(buffer, "(tizen|linux|unix|base|any)(.\\d.\\d.\\d)?(-%s)?", ARCHITECTURE_IDENTIFIER); std::regex pattern(buffer); -- 2.7.4 From 061b0befc34a164e16af031f38de79c2aa2fd137 Mon Sep 17 00:00:00 2001 From: "j-h.choi" Date: Tue, 1 Sep 2020 12:36:56 +0900 Subject: [PATCH 05/16] Add missing header Change-Id: I827bf7d54b3d415b365968961bdde9a28ba4891e --- NativeLauncher/tool/dotnettool.cc | 2 ++ NativeLauncher/util/path_manager.cc | 1 + 2 files changed, 3 insertions(+) diff --git a/NativeLauncher/tool/dotnettool.cc b/NativeLauncher/tool/dotnettool.cc index bb8ba55..4b9e579 100644 --- a/NativeLauncher/tool/dotnettool.cc +++ b/NativeLauncher/tool/dotnettool.cc @@ -19,6 +19,8 @@ #include "tac_common.h" #include +#include +#include #include #include diff --git a/NativeLauncher/util/path_manager.cc b/NativeLauncher/util/path_manager.cc index 04efda1..6094915 100644 --- a/NativeLauncher/util/path_manager.cc +++ b/NativeLauncher/util/path_manager.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include -- 2.7.4 From b165638d7bf1c350b2f2141c54189c0ad1ec0ea3 Mon Sep 17 00:00:00 2001 From: Woongsuk Cho Date: Fri, 28 Aug 2020 14:12:57 +0900 Subject: [PATCH 06/16] Support PBA on aarch64 Enable PBA on aarch64 architecture, and change formmater to support both 32bit and 64bit. --- NativeLauncher/tool/ni_common.cc | 14 +++++++++----- packaging/dotnet-launcher.spec | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/NativeLauncher/tool/ni_common.cc b/NativeLauncher/tool/ni_common.cc index 59a32d6..eb8f825 100644 --- a/NativeLauncher/tool/ni_common.cc +++ b/NativeLauncher/tool/ni_common.cc @@ -29,12 +29,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include "ni_common.h" #include "db_manager.h" @@ -169,7 +171,7 @@ static uintptr_t getNextBaseAddrFromFile() uintptr_t addr = 0; uintptr_t size = 0; - while (fscanf(pFile, "%u %u", &addr, &size) != EOF) { + while (fscanf(pFile, "%" SCNxPTR " %" SCNuPTR "", &addr, &size) != EOF) { } fclose(pFile); @@ -212,7 +214,7 @@ static void updateBaseAddrFile(const std::string& absNIPath, uintptr_t baseAddr) return; } - fprintf(pFile, "%u %u\n", baseAddr, niSize); + fprintf(pFile, "%" PRIxPTR " %" PRIuPTR "\n", baseAddr, niSize); fclose(pFile); } @@ -337,11 +339,13 @@ static ni_error_e crossgen(const std::string& dllPath, const std::string& appPat } #ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT - char baseAddrString[11] = {0}; + std::string baseAddrString; if (baseAddr != 0) { argv.push_back("/BaseAddress"); - snprintf(baseAddrString, 11, "0x%08x", baseAddr); - argv.push_back(baseAddrString); + std::stringstream ss; + ss << "0x" << std::hex << baseAddr; + baseAddrString = ss.str(); + argv.push_back(baseAddrString.c_str()); } #endif diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec index 54cda09..712b4de 100644 --- a/packaging/dotnet-launcher.spec +++ b/packaging/dotnet-launcher.spec @@ -125,7 +125,7 @@ cmake \ -DDOTNET_DIR=%{_dotnet_dir} \ -DVERSION=%{version} \ -DNATIVE_LIB_DIR=%{_native_lib_dir} \ -%ifarch %{arm} +%ifarch %{arm} aarch64 %if 0%{?use_default_base_addr} -DUSE_DEFAULT_BASE_ADDR="" \ %endif -- 2.7.4 From d0e47a5dd913225b5ccd5af1fed87371d8e35588 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=B5=9C=EC=A2=85=ED=97=8C/Common=20Platform=20Lab=28SR=29?= =?utf8?q?/Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Fri, 4 Sep 2020 07:30:31 +0900 Subject: [PATCH 07/16] Modify the bf::exists function to check error.value (#275) Change-Id: I2dc642bfd18c8d3ddb476fcb086f6e6519d8bc7c --- NativeLauncher/util/utils.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/NativeLauncher/util/utils.cc b/NativeLauncher/util/utils.cc index d6ba2de..bb1ea62 100644 --- a/NativeLauncher/util/utils.cc +++ b/NativeLauncher/util/utils.cc @@ -475,12 +475,13 @@ static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& pa bool exist(const bf::path& path) { bs::error_code error; - bf::exists(path, error); + int ret = bf::exists(path, error); if (error) { - _ERR("Failed to check %s exists : %s", path.c_str(), error.message().c_str()); - return false; + if ((error.value() != bs::errc::success) && (error.value() != bs::errc::no_such_file_or_directory)) { + _ERR("Failed to check %s exists : %s", path.c_str(), error.message().c_str()); + } } - return true; + return ret; } bool createDir(const bf::path& path) -- 2.7.4 From 0da4d3033fb9b7ee1a7c092202ab2b10f62887d4 Mon Sep 17 00:00:00 2001 From: "j-h.choi" Date: Wed, 9 Sep 2020 17:15:11 +0900 Subject: [PATCH 08/16] Modified to check the exists of the preload directory Change-Id: I76bf379c055b807642d6ec824dec502830a0ab73 --- Managed/Tizen.Runtime/Preloader.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Managed/Tizen.Runtime/Preloader.cs b/Managed/Tizen.Runtime/Preloader.cs index 63a4a76..814d15c 100644 --- a/Managed/Tizen.Runtime/Preloader.cs +++ b/Managed/Tizen.Runtime/Preloader.cs @@ -39,6 +39,9 @@ namespace Tizen.Runtime { CheckAsciiCasing(); + if (!Directory.Exists(preloadPath)) + return; + string[] paths = Directory.GetFiles(preloadPath, "*.preload"); Array.Sort(paths); foreach (string path in paths) -- 2.7.4 From a78640db5e609dc7981ed66fc66852e74f7af203 Mon Sep 17 00:00:00 2001 From: "j-h.choi" Date: Fri, 11 Sep 2020 15:09:50 +0900 Subject: [PATCH 09/16] Added smack permissions for the .tac_symlink folder in preload install Change-Id: Idb91cea264c7b6802b6723eca2d686c12efc865d --- NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc index 30c16a8..2e80c2c 100644 --- a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc +++ b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc @@ -259,6 +259,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app _ERR("Cannot create directory: %s", tac_dir.c_str()); return 0; } + copySmackAndOwnership(binPath.c_str(), tac_dir.c_str()); for (auto& np : tacDB) { std::string tac_name = np.substr(0, np.find('/')); @@ -505,6 +506,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app _ERR("Cannot create directory: %s", tac_dir.c_str()); return 0; } + copySmackAndOwnership(binPath.c_str(), tac_dir.c_str()); for (auto& np : tacDB) { std::string tac_name = np.substr(0, np.find('/')); -- 2.7.4 From 994379dce69e5300e90fedea7f69ead400aeb07c Mon Sep 17 00:00:00 2001 From: Hyungju Lee Date: Wed, 16 Sep 2020 13:19:44 +0900 Subject: [PATCH 10/16] Add symlink to distinguish candidate process Change-Id: I1e8071313b5576904d7a5c569102288f166fb819 --- NativeLauncher/dotnet-nui.loader | 2 +- packaging/dotnet-launcher.spec | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NativeLauncher/dotnet-nui.loader b/NativeLauncher/dotnet-nui.loader index ac9f465..4dd4d9a 100644 --- a/NativeLauncher/dotnet-nui.loader +++ b/NativeLauncher/dotnet-nui.loader @@ -1,6 +1,6 @@ [LOADER] NAME dotnet-nui-loader -EXE /usr/bin/dotnet-loader +EXE /usr/bin/dotnet-nui-loader APP_TYPE dotnet-nui DETECTION_METHOD TIMEOUT|DEMAND TIMEOUT 5000 diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec index 712b4de..3b9a99f 100644 --- a/packaging/dotnet-launcher.spec +++ b/packaging/dotnet-launcher.spec @@ -161,6 +161,8 @@ cp -a %{buildroot}%{_bindir}/dotnet %{buildroot}%{_bindir}/dotnet-corerun %post mkdir -p /opt/etc/skel/.dotnet chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet +ln -s /usr/bin/dotnet-loader /usr/bin/dotnet-nui-loader +chsmack -a User /usr/bin/dotnet-nui-loader %files %manifest dotnet-launcher.manifest -- 2.7.4 From 27f4966472e821f80b355674c4ad3e6cfa190cec Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=B5=9C=EC=A2=85=ED=97=8C/Common=20Platform=20Lab=28SR=29?= =?utf8?q?/Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Thu, 24 Sep 2020 16:51:49 +0900 Subject: [PATCH 11/16] Add ibcdata for aarch64 (#282) Change-Id: Ie631305a700966591cdc4593b4b79800ca9228eb --- packaging/dotnet-launcher.spec | 3 +- packaging/ibcdata.info | 51 +++++++++++++++++++++++++++++ packaging/ibcdata_aarch64.zip | Bin 0 -> 126367 bytes packaging/{ibcdata.zip => ibcdata_arm.zip} | Bin packaging/ibcdata_i386.zip | 1 + packaging/ibcdata_x86_64.zip | 1 + 6 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 packaging/ibcdata_aarch64.zip rename packaging/{ibcdata.zip => ibcdata_arm.zip} (100%) create mode 120000 packaging/ibcdata_i386.zip create mode 120000 packaging/ibcdata_x86_64.zip diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec index 3b9a99f..90d62b3 100644 --- a/packaging/dotnet-launcher.spec +++ b/packaging/dotnet-launcher.spec @@ -151,7 +151,8 @@ mkdir -p %{buildroot}/etc/tmpfiles.d install -m 0644 %{name}.conf %{buildroot}/etc/tmpfiles.d/%{name}.conf mkdir -p %{buildroot}%{_ibc_data_dir} -unzip packaging/ibcdata.zip -d %{buildroot}%{_ibc_data_dir} +unzip packaging/ibcdata_%{_arch}.zip -d %{buildroot}%{_ibc_data_dir} + mkdir -p %{buildroot}%{_tizen_preload_dir} mv packaging/10.Dotnet.Launcher.preload %{buildroot}%{_tizen_preload_dir} diff --git a/packaging/ibcdata.info b/packaging/ibcdata.info index 2d0abf8..1577a00 100644 --- a/packaging/ibcdata.info +++ b/packaging/ibcdata.info @@ -1,3 +1,8 @@ +##### Architecture ##### +arm +i386 +x86_64 + ##### Target Binary ##### Model=SM-R800; Build=DayR800XX_20200528.001; @@ -129,3 +134,49 @@ org.tizenschool.SmartLevel org.tizenschool.SquatCounter panther.radiantrfid.com ru.MaxKuzmin.VkMessenger + +================================================== +##### Architecture ##### +aarch64 + +##### Target Binary ##### +Model=Tizen6/Unified; +Build=tizen-unified_20200906.2; + +##### CoreCLR ##### +dc5ea62a519533d193194025ad31135262acf0e9 + +##### CoreFX ##### +a6f9553b8408d5b5afdeb45877610a10fecb6f38 + +##### IBC Data : 23 ##### +ElmSharp.ibc +System.Collections.Concurrent.ibc +System.Collections.ibc +System.Drawing.Primitives.ibc +System.IO.FileSystem.ibc +System.Linq.Expressions.ibc +System.Linq.ibc +System.ObjectModel.ibc +System.Private.CoreLib.ibc +System.Private.Uri.ibc +System.Reflection.Emit.ILGeneration.ibc +System.Reflection.Primitives.ibc +System.Runtime.InteropServices.ibc +System.Runtime.ibc +System.Security.Cryptography.Algorithms.ibc +System.Security.Cryptography.Primitives.ibc +Tizen.Applications.Common.ibc +Tizen.Applications.UI.ibc +Tizen.Log.ibc +Tizen.Runtime.ibc +Tizen.System.Information.ibc +Tizen.ibc +netstandard.ibc + +##### Store App : 5 ##### +org.tizen.example.ApplicationControl.Tizen.Mobile +org.tizen.example.Puzzle.Tizen.Mobile +org.tizen.example.Settings.Tizen.Mobile +org.tizen.example.System_info.Tizen.Mobile +org.tizen.example.Xamarin.Hello.F_HUB.Tizen diff --git a/packaging/ibcdata_aarch64.zip b/packaging/ibcdata_aarch64.zip new file mode 100644 index 0000000000000000000000000000000000000000..965d1742c4c7e4dbf3dc3cac42f4e8c7326caf71 GIT binary patch literal 126367 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 Jpop`fFiHYAP^0s|+YrtS(ZJ9eD2K zdAAtZZYh2M;VQeL74n)8#HZwYTd$0Oc7-e4d2#+uF?Vr#{IcoLPPp8cHE@Hhw>dM4 zl$L^#HRJJIf^6-R0zT#0EBb76^kGT|Ca_$;U=(0@0 zF#Ei^^z+XP2kB?sdFP80-QBg<>>URfiqF2#TP0njy|pF&Tt6~$jM6qjE&L^ZUSxD{ zzaf_|0(^XI#l?Z`${N;dC*9iIUBh^mF~;6J>(*Vrn;^{?9g&kMBM=KNcWe=6-~UMgg;l#W6`C5;b)2I$a6GKryRNlg@E-Oz3?Cb348j%~; z6FAq`Zr6E&Q4oGTie;c5zIgbFq*%m&SlYl6z_@?2XZ@4Q>ARt#7L`$-G(%)YRCPt~ z?L??=VeZc7b3qeG+uVTLMDgIaXIpM3DpoJO>B)iX99#i*))3_iR4*`Ad7|D&&g*f` zav?;$*&QqVsUiRN46AZ)ZJ6=9pN_9{5@q!wsx3_P!m8Ep{aj)~CVBg2#=`$8Y5o0J zZHzgF)lQ6gmb-!!Cj>;$X^esP)c79B??ID%^#4%yl|gNNd%HEDE!IM@V#TdUaieekGBKiK3 z9bhSBELljVPf}jLFm`8x5$R~6RG|60x{J$FkcGWpM)tOnsW5R(^L0YUnY7FMq4AEf z2fq;jEIn6$akv*Lxc#l+vD4{8c~nyC6KrSW+WeCaC!OObXx#1&Jci}+$^=(ouiEQ_ zV>?}e)#p*h9DQ#5J+~sCp4&Bdsf(l|!?k^+c3jSR<~IZVpvmnW0A%Xiu8e#JS;O@? zD7tXJg z+;I!nv`3PnL5CgyjAku?0;Bt{p9q~$ma$(yN_THHKIp3)2XK-q(a8Gbk!5*XmmJ2s zV{oOzv&K94uM#&PI(OIcx9TdXTy((T&2MvdHoG%dSH*DyH%@TDK3T%~VhhJvcqQ zB=l@6@=L0>L>>$tI3E1RPc|+iYa?$W10$iNNH(A6i08AU7O&csv*mATj?Fi`Hf&#v z4=2;hwnqEW9@}mBY*h42_EeErFa@W94c~z?hss&a--5qg5td3Qqj*W_zw?W*%Y^zp zug+?WnUe!2I1_0HQyd3u5OH>7pR5*v3uW_WUjjS+D1WeaB@K*9$)$!_S{05nYTOV< zId#6V%OKfM-Qe87>#^*k_B!Q=xoUkkz7p8=!V;0quXM;XqmEV(aMz#(n4~2U*p?QuV`pOkVQ*x@hLZ*_j?l? z4CzU6>Rfs=Zpa~nge7@MgkSv|fRXk1D)XIOU2h1BG^yS3<6~ft1qrX&2M^X5=^wH@X&@(kK-Mb65}$&1nQtc5Nt4RytFzG`FTqbqPK>m8Aq-E zr@MD9@W=a4kMG_4An{+I@BdF5Rn{O#PXVh_KZ$-|T=crkRFz>+onPRI3T60y#xs&v zZ$I8sQSNygY0Mdo6ZyS{>V9I-n}o2}ps#XNF zRJK#*EL!n859~OcMK8A8WEt?fKF`1)d?AG(3_8C|f*5@Vf~A4*_=C}`=&F_-wfr%% zJ>Sr4t&(XGLsov>@_>ie+K072E#v~5#(&)5wncXGY~yjt^EV=NmM2`6D753>TEN@W zGqpK%y3KZK?qAbo6_*Agj64OL&0e7S>Z|vjN!D)ul;lNiBx=t0w&`#-Uc<>2aB9Bz z+&_3A>yK*4zxf1_rdEw^xOioCsPP$wufx1(Tha*s6*B^k1M=jS8via=|H%~dRJD5l zgWmfGBLl@i3a_Tuo5n2C#%VT8`DM&XC(K!svZEe3<#6Nsv|pyad73rEd5SXB8>i81 zA!(*jR;pm1&cWf^E&{QKPsZFG0G#G+2yHG4G&p`pkzxtR)W1NylV}{}q ze|UKeJ3Tk%vC({UX?p!x^4tpY=cFbMP-<+xR(bnAW?w=1wVW&Y0bxUGSh68^G~An! zBpKvar(j$dHS;W0==%-dHOjhtU{?4A(F)B4B8Uj_LwG|P#u-xISYuCDxB0&VErmK7WA|o5C^A-Mq(;OWY!dCl#xTKB8NJj?x z>C>vk_-BsK+E1IP%6w~@9Cl2eLP**I^&GgzYY(k}5%nVsYOWomrr~=W3y#Exj7sJ# zKz{$1P8gDl`ut5B57UFE_P~t}u+`zL(@#Aol%UwR>tOHHdT$a)4tChx&dkE2BbOiM zT-%%@G{oF^c;-I~k&^2$#uth?tCpzS_IYS5*vTF5AH9xDt@-x@Le$hSqaQx=o_^O}!X^lC>Wcq#rpY(HEUDzV z;z@FXZCXE}=X1a5TJ#aUd;6AH5hsi0SM6e1wVVydpFsWcRjxC!XNqd~O%}PIXnn4> z^%i*}8O37|SxP@YyQ43mSReGDr`E{UW~GI3l#q+3QvzT6SCoPMGR=aZ|@_7=9N3F-(Z;cmipi4(Xk-&*R_H2QfX zztD1FDci8pFJe7KI~m2a`UGPhIfRTFN{>S$9= zd>Bvb25cX~b9MDpAjofng&mK6RdqP3uRmwgaDzsfmfp?I<*aWYod#?gx;*XYDg*m^ zAOv5tz{7}NiI^sJb`XCG0nQ!A zYoZWS67I_nMCtW)R~UN8Rz`(JxD~>CVCzd?j8~{6m#W&Rj9BrBJ3iSJUuD&3syWJc zShng#e8C08|G9c(ZWyjlk+`F|X$ZBHcZ%eHNZY%Gr^X203dufFCq0*ge#JR0`FSz~kzl^~|e2 z`6g~$a;OFE9-`owridIn29}SHh{v_owIR8yDuP3a6a~2=3GRrWxoxoAmgUY- z4u=dH*Gi=bfGS&Yen48eyVqkEiGj*zT6;xOt``~`EpUxwdm~u?sH+`3F*G<}XsvYY zBt`Nx|5GUgz*35Y*j^s~*(C7qe8@q_>8QeEnV%iI&ApwY&_A9V9-y%=9oDYZ{tBss zoul>JKWFB|E2GbSRU8ip9peRezcnP)qgc(Qxq0&|@QCT6t}0bf{U}_fnFn|xWgBaD zH`F#aQm0^ieoWoR;Rm6BRiI>70+n+@DVkD{SSZI%W4f+uA&9YdsseRVE!*KXF-vgm z658%MA%}~OlkKpbKvH=Pd=DhJHVeJ$$?MQQ`#!nqGy!>OjZ1LNWUbyIyUMpsOnCh; zwB2E%8#l*pTD{tK$+q5%>A)*A*K$IDFd$WSTzI>Mz!)7;>`N5o3=Q$)Q^)vQq?==u z)1|YY7rDJe<8MXmXweZ(-74Bw2mn-_y2F6@kKZ26&b<3do+so?$Kg-Mm>iBTUQ=gcXww8>wl$|Ks<78E-u(S z(|@J0n>Z)`qp`bKXU+Zi^8PXBllJm9bBj08oqguk&Y=&(6CP2MT2;D`&}4sPV0GB2 z^Ldrb-1Al$YcV{1R^q6u|6}&-BpVbUEY2>__ zbqrx--g)snDg-z-k`1!k8i7o+%36;EVeYndUY_sXgm~W3hXj_ND}ew-=iq?NDQBDe zLuP$9H^lH09jyz8iZ_@-UEC|=d0(rFR4o6*2X(xsMr-kTeS+Fr#UsvwMPz7+PTI%u z@5jG`3Cz{eVv|OeBha7NGXu_e0Z-BGOVf8|48o%RWGwmf>8QW>9R8!ZLDB5BCNZc4 z@pq_)SG11D$R>dM?^@lV6`Jw1j4_$cQ}#VP2yg{_n&&^1oRKhZ>7zTFWeWym@t&H0 z8pYalwI4^Kjt)iaLOgfgy?XN*ugIUyVlVRM$gRc5_45`E>~cxLgrP!*b2|m^YVCa)mpApF~KA{}^g+=!ce$sm67!4!%-IEi2GNGfXlh27V z?VQw}qaif){(h>keY*mZ>q|z9@T&S5Ou%j2FURMA$ubrqmhG7DivuRKHIJDL_*JE= zOZe2-&+FpSXOH=LcR0LQ;;)3V^i?VV2=Z#V>BCW36t1~^D|x>8UtS6 zp)1bvWv?8Fs#)yAH_BfZYY}?CsbQ~Rxncv*LCb{nxh#rPMgQ_$zOyU0T>-DqdjS9^ z%qB+G=5`8sTSANr4$ULDD?DpP5)BqT?YqppL*>LmBLG4k7P@MC5x!HuV96L-gHsrL z0D~guhl^KQcyuo^l|~%P!C^t3spe%#8;Sh`{1^VzCgbK&j%3;tywq>c*Nh7oPpv~{ zBol1DHHh_OvR%KZHM)@N=?#uHayVoQ#uvj`2Gd!tOzkVQ;b!@fAUIja7B%p-c%`n7 z&VtJ;m>V8u-|{&@w3br&5yF7)gLNKxbPomtpJ@BXqW!-HQ;UVPDHH#xrQn^l(iI8d zvZrPK8n6VaI}`$r*fF*z)reZgvRsq3MjZH;zT2ug=5vD~r=!Y`aRAJb^f|&2gHcJ1 z6#yqwdoA#WWc;7}7(beR#8o}r@ZnyE$hU*s{gtzQvmsG6=L`E^06O>*%VnIAQ4dd3 z0ITTO&j|lC8p#1V6lWl7{EQ8T;@hmbjn+(zgBcFezo#ljsHy>IUs8Xfwx3agC^HZ< ziHMxn-tzCwuA7mMbSaeL%DFPm7F4=F??9YdXKg{9??u|i7=6$Ay&_! zciVK%*35)$9l=;{U70;^Cd)j4oV_8sw<5hE*5fu;NU5V$FIW&zTIf#VHjCajzBgoc ziRAY3fyc8TqglSwR?+)J;NY$x9Z5e&fMy(?lBIsq<&9w(QThJo&}=wJN{gaQCn)Q5 zZK}M_PuRkO?)IM6hUx5BD7>B5l7gpp)kXiu)WF=greQZ*>7_7=sw}AbS7M97A?opn z=>GbX>!bBr;mqUl(T#44?wan~teW1jI=UMkl0tGjd&F5}FJ4sF)7F=EV}6vC{OTIBf|n3()ET$BHBi7h8YU;;$dkKs;zZIPJA$ zz#}JUb&I0COVfcr=!!KMdW&5IcGI&$&p2&~0Zb*fdQHOylYm$p9YxVFmytO)Dt(50 zZ?+}08yaf{#LDsm9lM&DFWlObQbck^D3*_q=@QF^*sHKUIy%P=bf$$w?<12o_j91n zjojQ80>-wepfS(AkiC^eEzLvI_-3?T)?X-3Pj>^|GTg$;5E4c> z;`e(`i#cvOG#1-F`Q0dJ?>ZY`=e@=sE`4b#%JR!mBb`7IiThf}0;|6Tg^x*--sB8_ zJiZHjU&2&b>06Hky8gDoO@Tb0ZU}9lDs{?2}5BAP}fFOU2 zHoeG8#4hqrgGf7YgH1r0gRiyhoxB^v8hm!u;ZwAgJnr6!Wy7XshmJC-6)}lbRvdv2 zab<|6fKO#XS%67kYK_W*XDk}k7AbAChLZR?MK<uycc8oqO0Bh z_}OjAbsqzX{f0ky#HEba`HA_luMHZoqggvcj@?s|fE+YuzhbpNb)lX{kePo!aupgQ zr3=PB_l2ha1t&mHiyBhR0Tu+!)_YFiF!YyDcC%5H0Uaj1Qz66WiK7M%LF1%7ZgU{`(3 z=-X&;Bt@5cx`&KK*1*9z#eYS$xX@Cn?FNH4$zVtl(%=M`+-fmM%#Ol$n4zfRZLk$< z+BE)ku6=SLSgiZw=tdQh)RiPqYYJwzxUw$dYT6VH;Z_DR_4`>TR3fz~(7W_LsII#VHFWetnLe0rHP zeecu@?8Pu!7Yuv&6u}8D?$W1gXb?9~DDF$Sd?)1d!;wqxbRe+g52;ZT5|kO?l6CY$ zW;Dg+unogQ(oLV%b7WorW}g2~zMQwY*q?a|3WKz9 zg+s~vkEFF+PtQ#(BG;j0scx=FZs^X^MHKr|-VxK&5dC%Qrxx$8lDazduBx6Q^m^R& z*851JD}uTL;ou=NHdO8UN=x|Ih|jyGi2`yev0igW&+5mhT%qJdvA;4-cQkBiYOGV= zvVH_xTo>@twmOIVjCt#*6dC0TTH6EjWxT3n&eq@~KXPif#zCGRSb(SIT;(gKKK$3vgy_;Ej`sVu8KNIEa#C8|tHzb**VLhwNMv2eY7nHfe!-jkh=p-6LfT6_V^H*PL%jilSk{^DzBT=3Pm<&phzGSi4_8h=TG zj$MRMfA>|{Bf=qvz)dpL`@TGyqC&MjoxW?NymxydDP(qi6Nsj|HmR;RT3iiZX2>IF z{0gYJT?1-#rb+8Xe&NfzGS2C1f!g#`TYg`~rVTN1OVbs=%9g_QQFQ(_ze~|7ci4w@qwQyq(@t5d zarA6T%E5b=iP5vtcH33n0eltl4Dp*t|2&O1Ir`FHoLA#j;%R<|c<+DKUNJ}r%))Z2 z?lDR1Wi&F7WY-}ofV$Pr{kn=yD8(G=zLmx2)yxDj%}3&eX|&#tRO``x@RumD@#g&f z4uLbx+7kl6MgA1~=>@-d7==c=FO?LR@1`gna=k<=vic-g=-}guR{a@w{}pbq= zcOB5#ynJ*y_`0E_S$)N3*<{HWRxb9uADVV^AyiIj1*faYCn=*KZC!j!?A>D8;}eu)A;>WE&6Y|H%3`8Q%fAk@M- z;!3A%yws)xx*PZ^JoQ~eL;uvuqYT?~nm4UqcxvT^BKL`R^w|_6f*uysU@294W1=pm zV`eO+I@8!GKC61hy#=G4QO*`*xK4s-3Sq0gslGV5`-BbXD{{u*Jw@ZEfoW2Ct+Nu8)>YU zxQsc??E@C=nIVr~%}BJ3W!ar;S*jTA(byJ`#kil}Bd*F}yp6T>2#2O?zedT5)Ob8% zUVFE`wEC`YWZt~3w62en%EN8wm$c@@iT*?Fms+r}Hbd`+8Nqe5Z->^C&Ar^KL!&D; z)~xU;W+{x*=W+yif{!A`i*(jEtoI&K&@*NQl^^dd_A1f7wPW4(v*n_V$<9ihx7u`) zSGC+!wQ7sMv3%CTX((nF0^DDnphOV~7oMVFy#t}i@<#I?Hd{V~)%L(2ora4pYC4rm zzO$oS{b1<-#Jugo1@Qs?*SJy`5UilYHG8_FZHU5U(e5+0gb!bpKbK+mT2e@^`Ydg7 z27QER9H$xC|6qqF(4Xea2Lk;#r?xW~OGj1JLNNSfcGB%Ue5aCZ8e}YA9?`?nj_u!8 zL0-M&9>6~xp;Y!`EJYlURY~ovZDnJ3TjVmY`?2k3Y%J&>M)i?P|6t|g{AFw`2yf=7 z1)jzpRRf62YAY{&g%^4z*sZ?|zoEj<`xL;q-(}96I~6(f5IXs#1rv(NS~ZnF3cc17 zVIy)4PERe1&l(1xCAKWH48TUzOG{yKj`6fxZ6+8Vm4h~ggT(tmQw`N3A#rI{1H=Dn~nM3~jkj!IS2u|cYFxvd$tk>!;8tM8naa{A$?t#DtsxrW>4+zUfN4-YOA z2y{k%=K!~D^gHyW*C$z~se>8^>A^-{mzr%7HS=}}VO~`Pb=~lHe1hhQ@5{Jt)89`C zuARQFkW4czVCp6@$&(f~XEN3k<1fz)Vo|-g2SVH8p%>I%DYCQFbwjAndG-V^DsJ@e z+Du-=%6g4yT95IB26v@n3MMgx+wZdOnq^zc@dP$M<=~ed7`e6(ijRL6p%V1?_K>HI z)+@05l_G{!Mlqy8Owm_0hCCE-ca`S;Yw;lDWgQwb>^*#-R!J%4a5hef#t3bn9#W#+ zLfbPb@~1KEA%hT|-7#vy4)lNIr<|jFamKKMw!P%NdxZanUFvSY{|ahlny8!hQ}xUI z?xPS+Q%%`dOsxHd--5qYW6t~Qw-teK4{jFoM+Txf)}hhr{B-8AX-(yQ(RPc^)}f>D zLVuN$B+jod&RK}H_3L>n7mB3|_31dzORDszFGN5@!~65+FMS9ZxA`&!R!1^WhXSVv zdo#p^Kn4n*KSH%AG z)krlhMBc0GPc7T6W>kYlxCD`*xg0OITaI{Bzny&5Q+^u`f9#SkctkKPamF>-lnBHj zduZ!2J;xhz8^AfflPF?fGV?ka=A^?NVUu+Qm&!0hks!gX`t?cr=08bCzN+aF32?== zEvADWuXsca+U07H9u&XYi|1eYSaH5^r??;Ytp2ffoiRM(7051qQJuHX@X?sQJ4c^LijJDg=0S{U zm#UlU@%(f&#<)-len2Gl3JAv~QA-e&bM4&}45D8`&&{#~8ImTLZ+Q<(+oco?yl=jO zcQbQ~)Uv9Y^ciMDW%qTB&8H`a^oP~zhKRLoW?xm)HT9lBe$|)f6*y9*#78Nc@~llt zW2>wJbPZ>s4yU#$G^_L8Ek08)rfjAO8S!sPcoHOAkXrt zogfTIKp*K0n)(AJlCHl#v;SjkZnIignLAaJ{JQB<#ht7YxLqdTmrR5Dn02}_)e^P4 zcFs66z49#ZOmUCRWkAJn4KMt?Y*&^;iNWXfO5*D$1P6~3=R30ifVvv#0efnXMa`S% zP1<1{<{wNC!pQByMQN|SI!L(#)&OJ8+(*O%Le9D_C9Px4B8~M#HCt~KwTE5>5=o@e~?$wR;#9TM#Fgbu=N1-2X)lN$JQz>W}!+= zHaL3EUaAG=Q?y>}{By(TbL>v}`(kH;T!x&{87Yf$E%SPW4{&7b9?N;f)aS+PM=J`C za@S&L|M(xj0nWYh7k-7cJ`g$XCzzI=8>Q@C;sz0q{3wj9IJk=u>AbB8h@s3?OmmVK zirF`bDJ9LHZ@>R%zPzS_lsj;3T{22PwMWSH*I2z(P&AHTpHLFJ%7@6fn1!_G9Vk0B zt|fF7i06BvCNUt#3c&F{$ct?8vV}u)klX(BdF{B<7@inM*;)F)+V*4eJ7v-LW2=Bg=s zc|}d;vp0jJ=zZhJ&d#QM1M=YZPVPFdtET9UYtew=OYqX?B^KY_AomB(~Q|o~5oqaPEA*0*KiV=(Q=bxte6|B#L25MAb`?7uTK|TB(e%M;*)PoJ z;`GxJspJ=33-(p^6euWKuv#|HKU($-BR(kt5fe@CjG3|*H0ovwyX|{sqgAwq7JeXMz6kODrvYB0?uyx+ z8?A3s)k!J)j2<<(^uo3#NP)L?E{_|+jFM0<$CAS5)p4Vu zo^&Ij_~G4nuy99HdMEL2NAnvGkJIHkQ}B{$^Y&``jkEcnt%Ey=OT1L7Ap$}EkLB}{ zwO*4CN8r7Q)Q|PV5l`w8>IXopCyuOFuLZY}1)^8V10uhLtB! z4N^GN75?#WDO~DSDxfPRTY-VDpLzJU^>N!4zT^J`VrE~SiHDlIP0%^zItIJ#?Z3GS zAn>P?BaZ(8>7Q7%-d=xW6G$-sqQjtU3?^9yJ4S<2#%hFDun%JwgPAnEsgn(HoS-JS7QvNrJ<{&9Cne%+S^Y4v3Ll>w z#g(#|;H5lEmJP9;&xA*P2zEW>fyhLkrME62J%-+nfH13sVw!V zEYJ8jn*u$;zB_zQdjE%9`S++*4X?MbNcE^(;xm%Zs>*tj`c}_Lh>zHk*_fHX_t0LM{V#`zMP14c@bf%S#UjGM&4mRTi!IIKa=p5drVm zO0pzq#owaup9!??mC(PtJXv{%W;-MQ;u=QeD*@756+L4$sGK34j&mJvyyiqx?XLY5 zSvO(=ZkGLFXUIs-Z*3{~2GnbpZBc2Mbj@34J}B+1atqpp5pNCENS)Y)S$FD)1#1{@ z{*q*qMWsp_qh4CySF9JV9>VsB8a;7HVH#0Yjv6{Df00>3AxZ>ENcLnJGG(8>`7YB_dG*p%rlH0 zvaU=p$%A`Kp>t3J#b2z<-6Pb==#kRV#2?L%;5h_XfK-&?D;4xav3suActvoMQ-9d0 zb(*+hVC8do7h$P|9AM*!D4#t&@;CGgg@5m1Ekw4muuA%1UO=PPrUr2!w%Veiq%E3&OEY2PA z%?-F(el&lFojI;Dt&R`ji;2&RM@0HJXgK5u(OXp_i3c?O=`b#q6zWH3-8Dx+(t}-`B z$~J_dKLOWe-qfSh1_3NJ<8>$qG^2W~_;PA|)U+*nR6}Xi=c+DaDu2=5 zKP4!wMZCh6*63vO+ZwBBvBMsfq(U4xBKue%(+MLyRxhw=<79r2X@7HU!Sp6RQ|hm4 z-7Sfj?zO*nMw>Ss#7tp~CF9LP&yh>*JQvfPF@z~Ub!ta6li<6Bj4A8U3Ofja1xV4E z*_tGmIh&D(iT4{@yKb1V07*HCOl2lw=YYv|(I3Jhl6gFvwlmu{F+B3PxI5B;_%m*Ja{A;dtOVtH^nd|B9U8@1p%R>T@$ zoW3WLQDxqqh-e*?%xK{48WtF!&esYGeBbV($$T(7rP3BcT|s})nB#v{LO3evRQ(1* z7BJ-VTfnMjz6s$pGFTSqs?~`#V0$Xna{GPITw9i3Qy80j$jZy(9!` z8|InUDwIpuxt2m(Sm9col36>e>lqrSzKSh4dNh@JDYOK{W0NrU43J|Dpyl$4-(3cG zpQGti8#c}B#D@2W!%rDBhwP^C@*v_-IQ3gJ#K)2kR$W_>_X2y@+mnucjzBUoi0(zH zvIlPCwNruui|TuWjRBV0r&8G3&(z*^1UqoDwR4rK+}%yY%JN>7eB;gRQ|b2Jp~ty?_(R?O@l&2n$H&ZK08u>E z{{EYJ>Pt_XasuhY-a|UcOWafAWhwZ&1u-T7Tl@L7vjc*QsRVU=N(&Exfn*>9*t(kX zr?(Oj^j__KLZ7n*qJRG;rfBQy?ksdLq9M}!SbDZ3qf#C|>G^_ye;Aa&ud0{lM1!}= z^fJsVxLNcH2m2@$!alSiyKO9sQ4P~w*>rvsptLGGNy)Edvzu{#epepGJTi2Zyg%Vn zo!zy4SsAv4M@PPs&Y2w?H!%gWXIcGfLCTaLE`RnRj=Frxo8w0K7Kj*aEzEfX8t1xu zHIM({r=a>0>5Z*6rnlFZ!6GTd6!8@#rmYdqMAfX$u4&JZkNGLEeKie#x(BeUey!O4 zuHXfe2+1Dp60zLe^zWgEha#|}%)Wuk>XHN`gh!Ds&t{ktmr3RxSN1C&ybO_%d7qvS zaBY4NIMx#G?|0q;&51}kb!u8NMCp@O=!_R*8rw1&9R#)91TKG72e2XsUdIyG;T7b{B2u5tpZyTgUpJGOz`$&P6>5&#b^N;}u7) zRq`f3wLUs84g12T8?a(>vd~TE%A+#8;SQ1!kI`XmqCGdM+1SRx_SN`s^DRKPJU})$ z9o!x2gQ@jiOEfn655*`8*@z6KjH%f`?gM z@Lp%!S4(@*wvxy7+8EPto&QUA=>jraxMPu0yaO=;CCy}an4qmDfiuNB4rQ3Q`U@>v zhvvm3@0rZn?#$CnAw=UehN4X7!(>POmTBEK(!?u8C}d<8QtL$r-TH}vkP#_CD?Xuk zF@LXa`b|Qv{{su9TWlucVM}%d-eUcL|HeZ9JE%*=)y~b+<-ad7&oaT*?NIf1oL`5x z2^MIWkSKTsEt^qWkgxJO#Sn^q`2Ep^pwE=7{zoIBV3;6Bfoo&($Ljl}F%Rd0e&%t) z84@{#i1owrr1eVm3U}cgI$SU7v4+3{5LbOi2FPc8f4+Cl{MXNVy3sKVmNlvbp=yo4 zD%ebSNZ-8*y;zQ)X@k_Gh^a%ah8Jd$gwPbkAH)wHiajLaFGkQX=<=mP>HUng5aFoo zywN-&k?6W9p8ORYi(iP@21D!IymsPtO%r*uRnD5v4ap05M1KIfTAwhgE#cQzJxRK9 zXo)M`GtNL6b1u){Gg#^fJlsIm(DqbD?SRUk7KP(!+|CLoNsz-fq$y;g2!@>`4V1aZ z$*`}XCsv*t88X4{{jj)!!PmoCDAn6=y+K(cuHF-us4;MquL71k`fLU7;! z^*Ph2sf=ke<7CLFhX}L_J7P?ZTEfex6BNqyJs$Jhg;%>s3QZb>ZmJf%c$W3Fq`2Y8 zN0A3sDD&gR{Iu4sxQ%t!;&~0^+~Z+vn0>aTi_oA^ZghfqOo&MVz1xF7{f%_hE0jDjW4C&W6D#59P+`g8(+8XgeYw-KA#Ls8iXU0s;Y;Xm0z*`jnoF7ZNh^ zhxm~u55bY+1Y&F~OunZXI15xrqKTJJ?%^drDVbAn*JHAL? zN|t48|75&3RQ)v=XPlu8Qo0?z4gXXr4 zu(Qz_9EnNK4(DM9!HfJcv= zHYLibWZX#6Rd7>@(adr+M>Cx9;0*)KvF-q3A$zR*XtW^M+|0%;hs7>`+h2{fPDrSy zK?j)<4CdCD&>q-1<4^UnwxG}nk6gKDT?}V#2s_U_e1)Vo#42}QOt!oS9{jbrBD5ph zAA%EBG*24hE;MEoS&pyy(T==z0{lHY6IGCw>O2Yu+Yyt{+mEKbBGah@Tq8HE(3$&N z`|;lvdxLJsTDPsYi~&kw=BqvmP&%qzu*(Ec7e`7z=6o-uDo-+Z^B?JMW|U!wbbC<) z^7SCtU+#aTJI?FbYVl^6Fmqxt_~&NrGx~4-Sm}<{Cj88?;Slv8=%iE%>OV70^PRcf zJJ4MX@;htbx6jyIP=HxBjDXrI=OC5zVwcGA@R>#FnNbSmrCkuQsB=kQgOB@6)(6+J zfX_6!y{Tn3LNSNF+gR-`E9fEfsZm9PYx%xH_zg3lj5*Ig)Vq>w+vN3cpu9j-7iGkD z=Jd7BiOB5qpHF8Sb7B+|>ctdQV|=Aws2t-pgWJ)@C-*gnRF~QK z1wCnqpPq}+t(`vhG>MW9L6H-WYhZhJTJG}uY``rCQEQ7+`-1iSd*@T#{^ujveZ?q{ zBY-DHCPFN_NGOEI8hUwb8tTiyD2iiZ|L$|35-;~1IMl@c`0AAWtH~@F1(Jvf`HUSs zMI0Te8rc$3as(?IA$T5TAnOo(`-+QRL`J&jWmXVj!C1U+wFoPz*J~mf*M6ih z?!HvYR)@n~)>en6(PNC+6U_P7b6P*g+e>=546SNkh=|Pd+e;#k_b`2Pxot5iJR)%5 z80e3rs1O%LUntWrPVYl{HiIBTv3qzKSnDGHTR@juHl9{e?7VYuounUiZ-vvHq~Y?V zEWolBE8u;7<1%1AV0OoRx_-a4@wJ;;Cb7)GQ2%&@8nFIk@@SodcJ!*o5PTJA=#v|w z>*J^)H7BBxEIv6gdZe+9yp#~_7yHgEsV;)}Q=-@4oz z2{we(<%dj>VjFmuABaMj;60ItL@6?fEIzk$;bD0t)rt>~{|b$94>HvkyX>v;tmq8= zzLx}3Q;~Y!X>OZll=%Oml71Y2vC~sfruJM$yZuw{XB95`Gh|vrIaB0cS0GD`?#6cn z-B5m2Bih>Zkb0VKaR~A9UtE&wUgX(!Rzp~ue=NI2f}5qw$H%!}Z_K`Z)w&j;jG`;> zujO=DaX#Ln*>#K%07mp)YlP3;`iCuF9|()5zL^g+wKiBhAZiI(2~HcHo0TLIF_3JV z%Se;52hT2Z&tQV~g}tQu(>>BE;XW<>u1*KO+aq_i$5|xjmD8?x`xm;i+4>{%dzq)n z%c)Ign?@HL2JH~bdD?FChd?UP#ouDMV?w|BfBWN(#iy0n*!m%(F={h3(-m);1te?U zSws35pN5S6M)|DdffS`YnVDt-ianES|8zOh`WYBo^9b}gUCKC}J4q^r=p8nGGN7_< z2t9RKa$1vAgE%VgQ}+Fu{hfh3#_!(n2}H2}=7|3xf@%)fraOuwfhR4OIzF*3;B`Zg z1rD!xlWqAS{?jQzw%Z4bTR(lY;N`w)DI#wh6#l6VmlaBKVEt zZMe~Y7_!_Iu%skLRLOTl{_v98@9%FU)fF2qkFfj1keavNWeT>XX61LGIbJ;Fl>zSE zyP{Cymse&FYmclN$A8Zf+?qVRsil>)U%Mo@6?hn8wKhT{7x!t8uyyoz1R;3xw=d!C zk53_%Yd5%eS)U-nR*Md6`MB-t9!J!;W2a)GHA|fmv3K|LF}%Yx;Nk5M#c~iJCw5o* zs$8oT0=@ZblwNql-_|raR&5XT-U3yRc@&?bOzX!n!;qov(X_qb+y4NVLCKT}8CbII z3>&L`@^66oUy*E!ZvP6+;yewjOr*5_OS$X=U0zOgF-kRWIGCy7)-(R4YVx(v^ee6c z-^ZsbZ_7Twb$IF@|9y93m6ylM+DBmlp6F2u62XnZe3Z`G25!;#0C`^@@VGdFeE5OE z0>CX_NQRq;NmZoe-7N3w>%0TMzl+}Pds;4}!!j83%#glPG$q$}^5}C^=Jh|iqe9yN zN%ijRM87?L$z9}tb={@*BIC>z`Y-)=-pPQUQiP0L4#Oq9f`+FCx)I+)^3CLE?O%u~ zl$~9ZF4&$LoWHLw>{d15Rgigi@G^ipm&Mc6JP~X3`o3T6l8l?n;2$0Qe&!GHAL6Is z%Dr;d#4ER30kWlVC46ptyP;$KlGNps0zWuyQ`-s4ioai(V}icxPwSDdsV4CJmr@ z>T7?c>n+7MLI<}+8#XZys;ENcY(@y9XHq-fq51wIbDJUT8{L-oAiyrAXz+cr9~{lh zZBShl-jH3*?uMQ#u5107pHh{Iuuq|POlW%9aC4pO9d zihOB@#V3PE(C-}n@p(BWkblPdyq>s;FotMzM|HzlY0Qycg6R&DqsiC%mq=JM;8gEDZ!HMxy`~X zeM2|0*Y~l2k*b9jc6wHW*!8jk=S2Ed=NmvQ9hEpbTm-H5Cncoy$9w>K8}ZR|*))6V z0joDl>a!BFOLb=zp;{HvQkiwBO#3Zo(@(gE2a;MKk0{o~)h%*5*@3zQd=HV69DhOLIuu3x6j&?)l~UX5<1>j{Cf3VERDaF>Bvf$~|;U0}0f-jy{1} z|H_FMhDD2f0>5`A%5HM(Ckg*gYv&o&RJJzYpo0iVR}pCf(xi73snVo~h!p9?5D*9^ zNa!$tKtfdk8G2KLbVMLX6Aisf6{L4*fk;QVhq)@(e6!Y_@qXb)U@g}BoW0LJXPvY6 zyPvm=tS`^MMn|3tV>` z$wY6pnU=MCPfwFGv@c9W+YgIZUJb5v3g;bNj&WN@J*)4Xe^%*7n&-TNS!dYdWz2Se zYHh>C*Tc)`4^e;=yLQCQMH?=aN9KN9%zRd(U1F(}`j!#(RxGJV=7G6)BZH(uic>TP z0*Zp1~6$#WU9IUCbh=Qkf|11qF_+qcC(%-3hrwO+Cb z8qE9*t+w2)4t#Q{oY+aua)Y7GgPt24%W@n>#ath7%O`TzeHqAt8Y$Zc-IT86ajyJo zw{5r{k3--q-ws7DipR#6ym50gm6gcbru1#sY59b6K^EKHnw%v=cu{>7?jy#HN!zg< z3+Z95D#YQz(Dd^69f>?IU)hGHnkekqd>V>1nycj_THX%|h*G=5@RrV5;qunj4dZr6 zIhKnJuVxkYx7_)>CN&bm%WE4128P3D&27vhs?bb(3x~UBxikc~Hmz_g*1HwUdpIB) zyqdM~p`XkQkm(iqEz>Jf=lF4p#EtVLB(rER^v_ZSv-?)oy@5}CEFZyA%wps+XpP6D zx5&C0U*N0iYIXE(f!ml4{m(jQCFfR3v*Wu@t(Y#aZHI^K7EUC2vs1EEM?Wo&3TY|6 z=i!XQVK!{x@qAbJXc8#!QsA7YJwd+F?k~@fCNHu)UnQ+9q|9mO=#DBiQ~#LM6-FtD zxL>5tWa>CRQBrr7%REL(kcD#pN(?Ezb0Rke6X>{6RA1ms&*}tj?SkZT2y`*qa+-2i#^xZPzR|FVH*sY}Ky~@Wv*u=E4xQi6P}0ODw=Rr3 z4xx+StnnXf-WIN1tQ=e#YOigMFG+IBtyELv8^zBeriEOzgt4B!5=k>H zmezp;L^CHh;}18^E?Uk^Jt4Qv7b*qj(;i9LR+n!^b%p*ksPT~_)J^%5qORxHJW*|d|IJOS( z+_)%E8rlZ9Pb(w0X{qIVnStpgF9_}jfsje0&&T~XasS)={@T>eY@_!inP%DMqF zbm#-gdbK#NxyNTncY;MmoWpC3{s7{?sur!csW*;NJg{pm2X}gfUyciht@{;29tPGg z*VuQiFn+mj6|lhotRF6m&NWbY_M~xB>}UoW_;1HW!6$kHB}VrNs#;v2c%=InkoIBK zKp-mM`34Gp;PSua^NQ;ktUKB`!^T4W>t;ob(nh!ZO6lTOVAx?i`JHAt~m>t$m=5-Uc=k zU$H^ki{*81T%I+N?l4!jj4f)NX)POFkr^$oT=9ZZB}&{mx!Sny5QiR1nMMt)HVKhs z7a04MFBW}RurF#1dkdzm_lvtf+$gqY-a&7jEu618W_UlULEq34r)BC#R1;Xi&>y74 zW;>n|xKQ6fRW`c&Da+7DJr1tKBaEn9S z)Md=)3Jc|3ly#!}t!Lz6MjU;U<`>CU=cyA{li1+6Lq8vp8un8p$EFWr+w@`0Y=;`d zNO(yd4OB>|4nZkDKco8Qd61_?k~;IFhE2J&KEXD%PdJZXL}Ahn*Q;N}CIeBPD8DtfHls zFUulxuekXDDLe6-r#lBlz|$w4UZS@+t_p{# zsYv903iJ37WvoxMs;gTjHbU9V^UkSD$7VSUXDI5bE%-?bQBI|ntzUgU zNVaT0T8i+g$T}THUBjOnAnCoVSi>zs?{Uib(cZ3xN|Iq1*|Qrx11ELpYX`Nk2tI>q z3Y%0UW;(q?9}x77*M=IOc+z2@{G1+-|LrqS;b1`-N_7wMuI0)=PcVGieJFwlUID=& z0;M^PX;w8%FZ~8 zS0J2+g1(Tk;uRy3;@ypoHie1?87T@ceCLh)LD|sQ*xjP#V-5~{dcvB}Dmo^moQhTc z%`s@}V`r=Oi(^h{2bTx>ORa8P2{Z--eZT!F=(`CB`tEE~w8nRC=J*(y$j}sjor4re zXXiGlI*Rog+Xoc9B=Wgv<>q<*Y0o=3Dr5U=UlMc?3RkIynC{)E5Lu4>g99GXlMx$> zamF_CV;QCHVRT1BKaqu-TwazDmJ+2YXm}*luf(7+SSTa@a@N?W>-WA7H=T(F%aHGJ z+9P_{;;c=k8+rO!-Q(T)B(qCW<0>3~D*E0p6#I6ysW8I*+Vs5iPQVv=64Pv}!`Esr z?3SzmioQ@DRuw;i#^|CYYN40R*JoOWud5!M%VjZ!#VQU)A1eAtjaB&xv{U;<@2mxloZ$q$ZR$x0&a5#o^PDx)ZWQ0o(i#6MJ>h^z`y$u7b_r1QUD838E=S-lTwj_z>z#kCq7GTTO7eTpcoEyeQWV0hmFh*A z<}z88?C-H$5ZipuHzoNjO#0h}zLagvtMd?&jSQmasojNxjH^i$D~?D@`5q-AW1K}- zw5ELOTV8S4PB~>$O+nG;Sy7(-OzE=j@pJ~=qVdI4{+%u1dxO*{?X*I<>iAeUW7dLN zCPoj+hxt*4mQG2h=4`CLz!>%f6{k{EE~DMFgVvpm4uaPUZcKL76sP-fRE@fZyzmQ~ z9C0Rp;pebS_SK6L_Go$XM`8%$2_#9^!(f$B2mtIeD*}2_lA9acJ^#%Zjb+r&B^ZSQt&; zd#U2J_J#2tn!HL`PmG01H!zjP;>+-KseUx(Og7qcKwGByj(`Wn$=-Rea(Rp-lzfJ0xk zn-c3JV-yx-=IKXPIVFE+Zu=uXFItO_Dor42^EJ7{^q9ejeO{#jaPQmg&U?K^bn!rr zOM`DkwG~c7@-lMx+_cZlRN~Jj0fI>ot2U;-R;#wf#QMy5ymr0w9~?@3trk8zA>_5< zE(>Pq@j901_^6l&7Jl~{Mw*hBI}XCc}~%&f~?qq+L@253RoL4OEWW|=xZ8!>YQ+HcriEv z9wAUadu+YpV);gUHnJz@PetF!j7qgikb?kn%pi4CqG{`)Umy)|AW|)-``SiEFL)jJ zSUqHmmrsOvuUu{Yw^B_6TZHXKqUjQmlgLRFWNW5{M4Zict_0`^6q;6zMvbn4x`9@Q zBjtu8dn89BcZ&UM&I8`*j!GY_?kMc89@EDwKqNgR2NF%A!!1eEK+{0iaUo@XsJfCi zI7KELBKFami!sFG66`cg9CixEzbZa4kL8+>o^YRFz>1+DG^5wNg;x8KD;(9STSOBi zCj2%W>6fYew9V8t)pybF|N`t0B({*sSUueHrN(Z5l zLDEx0=w_*9P%bDu5|1KBlB2?qVJI^!C-ylOjGe|pC&(s(u(4QuEX#xnwigiem0(@5 zVW>FjemWsebJfZuj6dcv2IWo+6N8bjW@7WOe5fJh5K6|oABo9+@pA6zK`LHf$cD;4 zrJIT20((h)yX89>+p{j>2l>Gh zsy-@?To%jydj)9mgD;A0h|s12UZ@YfL_^XC$D#c41E;n#r_0<%db|^MT+8gBo)-A9 zF!7oqEf>DJ&nqkT`=Jwl!8@Xl+cc>hQdFkpeN^y*ug2A!?W!?JGqlqO@%0NNiQ;jK zJxSu)_{pgjlG~f3Q!6Jzho1L0xf#=wBP)1PbioO%FGM^;`x+Iq`Rsg_G6sClq00-6 z@k$Adqv-OlD$i$H#08yiG1+z{2(0w(O`9b6X*$f-pL(U&nQ{%Ru`5p1*X5m7f>Rr$ zvu@!n#Y-HZ`qtS(X3E4Q{1$um%9Pp;o_V;|DZw1rEwYjYvmM$pMcC!EN(I`w7R4QI zaLUXMNU#>&8_{%XZ~0)#s=XSX?!&K(=Pu?=DR?6Ln)`vCj1NUZjf=j^3lYTUO8>s6 zenJBwBUP&2sI5z@A=rLo&Be&@&Z}|KahOPVfmO+g7OXtiKE$@L_!A}F@CQZ99tsmwala1-ySM;V;E#mt|KRL+_m%hr0U)-Ff4@c^^&ExQ z&!Asu1wMNvOA&ZS#a$yj^`j|2g6mk{1FG0-JKqI6{>t!b1vkxL@_{-2!egNGKlRju z>>mu^lq0MjfPs+=2W#0|{|e_|rFF}T5(E<0CTz>YJ4D~Fn(rKaxc#p%1TB}8WxthC z=KiTIdUih;x4^dFu1rA{pro?kbuBe86b%2{*)oI!ny_~B(Fjlg@%c^&cI`TQT=FAQVq68wmvtN2suue~J2gItM}w;fBQ{%(3F{n7_GwkuWr2%KuSl#>(%Z z|G@?T!tjJybVuR2>%NEowVXOa65(>{5eeDxo%9Qr58*84QCPbHqJKK4c~g@ZxOsv= Q^uW(G!26*(MFjlyFAOxUFaQ7m literal 0 HcmV?d00001 diff --git a/packaging/ibcdata.zip b/packaging/ibcdata_arm.zip similarity index 100% rename from packaging/ibcdata.zip rename to packaging/ibcdata_arm.zip diff --git a/packaging/ibcdata_i386.zip b/packaging/ibcdata_i386.zip new file mode 120000 index 0000000..33d8fbc --- /dev/null +++ b/packaging/ibcdata_i386.zip @@ -0,0 +1 @@ +ibcdata_arm.zip \ No newline at end of file diff --git a/packaging/ibcdata_x86_64.zip b/packaging/ibcdata_x86_64.zip new file mode 120000 index 0000000..33d8fbc --- /dev/null +++ b/packaging/ibcdata_x86_64.zip @@ -0,0 +1 @@ +ibcdata_arm.zip \ No newline at end of file -- 2.7.4 From 951f5dfc6d043d7b90d767193d9f4fcbf5e6d9c4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=A1=B0=EC=9B=85=EC=84=9D/Common=20Platform=20Lab=28SR=29?= =?utf8?q?/Principal=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Thu, 24 Sep 2020 16:51:59 +0900 Subject: [PATCH 12/16] Remove unnecessary command name changing code (#284) Because executable name for nui loader is changed to dotnet-nui-loader, there is no need to change command name for candidate process. Additionally, add apptype to extra for dotnet-nui loader. --- NativeLauncher/dotnet-nui.loader | 1 + NativeLauncher/launcher/exec/loader.cc | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/NativeLauncher/dotnet-nui.loader b/NativeLauncher/dotnet-nui.loader index 4dd4d9a..7e714cd 100644 --- a/NativeLauncher/dotnet-nui.loader +++ b/NativeLauncher/dotnet-nui.loader @@ -6,4 +6,5 @@ DETECTION_METHOD TIMEOUT|DEMAND TIMEOUT 5000 ON_BOOT OFF HYDRA OFF +EXTRA --appType dotnet-nui EXTRA TIZEN_UIFW NUI diff --git a/NativeLauncher/launcher/exec/loader.cc b/NativeLauncher/launcher/exec/loader.cc index 08505ff..e7e1a76 100644 --- a/NativeLauncher/launcher/exec/loader.cc +++ b/NativeLauncher/launcher/exec/loader.cc @@ -123,20 +123,12 @@ static void __loader_create_cb(bundle *extra, int type, void *user_data) } char *uifw = NULL; - char const *cmdName = "dotnet-loader"; - bundle_get_str(extra, KEY_TIZEN_UIFW, &uifw); if (uifw != NULL) { setenv(KEY_TIZEN_UIFW, uifw, 1); _INFO("TIZEN_UIFW is set to %s", uifw); - - if (strcmp(uifw, "NUI") == 0) { - cmdName = "nui-loader"; - } } - setCmdName(cmdName); - // initialize CoreRuntime (launchmode, dlog redirection enable, root path NULL) if (CoreRuntime::initialize(appType ? appType : "dotnet", LaunchMode::loader) != 0) { _ERR("Failed to initialized"); -- 2.7.4 From 5cfd9a874c1300106dc26b0578a8064ce00e7b2c Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=B5=9C=EC=A2=85=ED=97=8C/Common=20Platform=20Lab=28SR=29?= =?utf8?q?/Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Thu, 24 Sep 2020 16:52:07 +0900 Subject: [PATCH 13/16] Fixed build warning in i586, x86_64 (#283) Change-Id: Ib243a6e405fae7bd5b278c286935b05a486c071d --- NativeLauncher/tool/ni_common.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NativeLauncher/tool/ni_common.cc b/NativeLauncher/tool/ni_common.cc index eb8f825..7e0dde0 100644 --- a/NativeLauncher/tool/ni_common.cc +++ b/NativeLauncher/tool/ni_common.cc @@ -55,7 +55,9 @@ #define __XSTR(x) #x #define __STR(x) __XSTR(x) +#if defined(__arm__) || defined(__aarch64__) static const char* __NATIVE_LIB_DIR = __STR(NATIVE_LIB_DIR); +#endif static const char* __CROSSGEN_PATH = __STR(CROSSGEN_PATH); static const char* __DOTNET_DIR = __STR(DOTNET_DIR); -- 2.7.4 From 8863a014d0ede56d090d3c459996e61359f6bc26 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=B5=9C=EC=A2=85=ED=97=8C/Common=20Platform=20Lab=28SR=29?= =?utf8?q?/Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Thu, 24 Sep 2020 16:53:02 +0900 Subject: [PATCH 14/16] Support for architecture-specific assemblies in a folder named runtimes (#276) Change-Id: I55399888f14f37e4c82c9ad2713918b05a0e87fb --- .../installer-plugin/prefer_dotnet_aot_plugin.cc | 2 +- NativeLauncher/util/path_manager.cc | 48 +++++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc b/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc index dd35e47..6f93e44 100644 --- a/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc +++ b/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc @@ -63,7 +63,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app } if (createNIUnderPkgRoot(pkgId, 0) != NI_ERROR_NONE) { - _ERR("Failed to get root path from [%s]", pkgId); + _ERR("Failed to generate application to native image [%s]", pkgId); return -1; } diff --git a/NativeLauncher/util/path_manager.cc b/NativeLauncher/util/path_manager.cc index 6094915..fbd2b3e 100644 --- a/NativeLauncher/util/path_manager.cc +++ b/NativeLauncher/util/path_manager.cc @@ -31,6 +31,7 @@ static const char* __TIZEN_API_PATH_KEY = "db/dotnet/tizen_api_path"; static const char* __TIZEN_RID_VERSION_KEY = "db/dotnet/tizen_rid_version"; +static const char* __TIZEN_TFM_SUPPORT_KEY = "db/dotnet/tizen_tfm_support"; #define __XSTR(x) #x #define __STR(x) __XSTR(x) @@ -46,7 +47,7 @@ static const char* __NATIVE_LIB_DIR = __STR(NATIVE_LIB_DIR); // 3. OS(tizen, linux, unix) + Architecture // 4. OS(tizen, linux, unix) // 5. any, base -static std::string getExtraNativeLibDirs(const std::string& appRoot) +static std::string getRidFallbackGraphDirs(const std::string& appRoot) { std::vector RID_FALLBACK_GRAPH; char* tizen_rid = vconf_get_str(__TIZEN_RID_VERSION_KEY); @@ -77,6 +78,15 @@ static std::string getExtraNativeLibDirs(const std::string& appRoot) candidate += concatPath(appRoot, "bin/runtimes/" + RID_FALLBACK_GRAPH[i] + "/native"); } + return candidate; +} + +// 1. /appRoot/runtimes/{Platform}-{Architecture}/native/xxxxx.so +// 2. /appRoot/lib/{Architecture}/xxxxx.so +static std::string getExtraNativeLibDirs(const std::string& appRoot) +{ + std::string candidate = getRidFallbackGraphDirs(appRoot); + candidate = candidate + ":" + concatPath(appRoot, "lib/" ARCHITECTURE_IDENTIFIER); if (!strncmp(ARCHITECTURE_IDENTIFIER, "arm64", 5)) { candidate = candidate + ":" + concatPath(appRoot, "lib/aarch64"); @@ -87,13 +97,47 @@ static std::string getExtraNativeLibDirs(const std::string& appRoot) return candidate; } +// 1. /appRoot/runtimes/{Platform}-{Architecture}/lib/{TFMs}/xxxxx.dll +static std::string getExtraTfmDirs(const std::string& appRoot) +{ + std::string candidate; + std::vector tfmList; + char* tizen_tfm = vconf_get_str(__TIZEN_TFM_SUPPORT_KEY); + if (tizen_tfm) { + splitPath(tizen_tfm, tfmList); + free(tizen_tfm); + } + + std::vector paths; + splitPath(replaceAll(getRidFallbackGraphDirs(appRoot), "/native", "/lib"), paths); + + if (tfmList.empty() || paths.empty()) + return candidate; + + std::vector tfmDirectoryList; + for (unsigned int i = 0; i < paths.size(); i++) { + for (unsigned int j = 0; j < tfmList.size(); j++) { + tfmDirectoryList.push_back(concatPath(paths[i], tfmList[j])); + } + } + + for (unsigned int i = 0; i < tfmDirectoryList.size(); i++) { + if (!candidate.empty()) { + candidate += ":"; + } + candidate += tfmDirectoryList[i]; + } + + return candidate; +} + void PathManager::updateAppRelatedPath(const std::string& appRootPath) { std::string appBinPath = concatPath(appRootPath, "bin"); std::string appLibPath = concatPath(appRootPath, "lib"); appTacPath = concatPath(appBinPath, TAC_SYMLINK_SUB_DIR); - appPaths = appRootPath + ":" + appBinPath + ":" + appLibPath + ":" + appTacPath; + appPaths = appRootPath + ":" + appBinPath + ":" + appLibPath + ":" + appTacPath + ":" + getExtraTfmDirs(appRootPath); appNIPaths = concatPath(appBinPath, APP_NI_SUB_DIR) + ":" + concatPath(appLibPath, APP_NI_SUB_DIR) + ":"+ appTacPath; nativeDllSearchingPaths = runtimePath + ":" + __NATIVE_LIB_DIR + ":" + getExtraNativeLibDirs(appRootPath) + ":" + appBinPath + ":" + appLibPath; } -- 2.7.4 From b0b4c44d8e0b8f711eb5e9130fba88eaa9a8917e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=B5=9C=EC=A2=85=ED=97=8C/Common=20Platform=20Lab=28SR=29?= =?utf8?q?/Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Fri, 25 Sep 2020 06:16:55 +0900 Subject: [PATCH 15/16] Modify ln option in spec (#285) Change-Id: Idaa6b3c655b579579010f964cd773a2aa2663169 --- packaging/dotnet-launcher.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec index 90d62b3..80988f6 100644 --- a/packaging/dotnet-launcher.spec +++ b/packaging/dotnet-launcher.spec @@ -162,7 +162,7 @@ cp -a %{buildroot}%{_bindir}/dotnet %{buildroot}%{_bindir}/dotnet-corerun %post mkdir -p /opt/etc/skel/.dotnet chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet -ln -s /usr/bin/dotnet-loader /usr/bin/dotnet-nui-loader +ln -sf /usr/bin/dotnet-loader /usr/bin/dotnet-nui-loader chsmack -a User /usr/bin/dotnet-nui-loader %files -- 2.7.4 From 44165da4d21313a1d388c858a008af7055f20adc Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=A1=B0=EC=9B=85=EC=84=9D/Common=20Platform=20Lab=28SR=29?= =?utf8?q?/Principal=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Mon, 28 Sep 2020 09:43:42 +0900 Subject: [PATCH 16/16] Add missing smack label setting for preloaded app (#286) In the case of preload app installation, the smack label may not be changed automatically. This patch add that kind of missing smack label setting --- NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc index 2e80c2c..f241865 100644 --- a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc +++ b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc @@ -120,6 +120,7 @@ static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, s } } bf::create_symlink(concatPath(tac_version_dir, assembly), concatPath(tacDir, assembly)); + copySmackAndOwnership(tacDir, concatPath(tacDir, assembly), true); if (!removeFile(concatPath(binPath, assembly))) { _ERR("Failed to remove of %s", assembly.c_str()); @@ -137,6 +138,7 @@ static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, s std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1); if (!strcmp(nuget_package.c_str(), nugetPackage.c_str())) { copyFile(concatPath(tac_version_dir, assembly), concatPath(binPath, assembly)); + copySmackAndOwnership(binPath, concatPath(binPath, assembly)); removeFile(concatPath(tacDir, assembly)); } } @@ -173,12 +175,14 @@ static void copyLibraryCreateSymlink(const char* pkgId, std::vector continue; } bf::create_symlink(concatPath(tlcDir, fileSha), library); + copySmackAndOwnership(getBaseName(library), library, true); char *sql = sqlite3_mprintf("INSERT INTO TLC (PKGID, LIBRARY) VALUES (%Q, %Q);", pkgId, fileSha.c_str()); if (!insertDB(tlc_db, sql)) { _ERR("Sqlite insert error"); sqlite3_free(sql); copyFile(concatPath(tlcDir, fileSha), library); + copySmackAndOwnership(getBaseName(library), library); if (fileCopied) { removeFile(concatPath(tlcDir, fileSha)); } -- 2.7.4