* limitations under the License.
*/
-#include <vector>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <vconf.h>
+
#include <iterator>
#include <sstream>
-#include <vconf.h>
#include <fstream>
#include "utils.h"
+#include "path_manager.h"
#include "plugin_manager.h"
#include "log.h"
static const char* __TIZEN_API_PATH_KEY = "db/dotnet/tizen_api_path";
-static const char* PLATFORM_TPA_CACHE = "/usr/share/dotnet.tizen/lib/platform_tpa_cache";
#define __XSTR(x) #x
#define __STR(x) __XSTR(x)
static const char* __DEVICE_API_DIR = __STR(DEVICE_API_DIR);
static const char* __RUNTIME_DIR = __STR(RUNTIME_DIR);
+static const char* __NATIVE_LIB_DIR = __STR(NATIVE_LIB_DIR);
+static const char* __READ_ONLY_APP_UPDATE_DIR = __STR(READ_ONLY_APP_UPDATE_DIR);
+
#undef __STR
#undef __XSTR
-typedef struct DllPath {
- std::string runtime_dir;
- std::string tizenfx_dir;
- std::string tizenfx_ref_dir;
- std::vector <std::string>extra_dirs;
-} DllPath;
+// /appRoot/lib/{Architecture}/xxxxx.so
+static std::string getExtraNativeLibDirs(const std::string& appRoot)
+{
+ std::string candidate = concatPath(appRoot, "lib/" ARCHITECTURE_IDENTIFIER);
+ if (!strncmp(ARCHITECTURE_IDENTIFIER, "arm64", 5)) {
+ candidate = candidate + ":" + concatPath(appRoot, "lib/aarch64");
+ } else if (!strncmp(ARCHITECTURE_IDENTIFIER, "armel", 5)) {
+ candidate = candidate + ":" + concatPath(appRoot, "lib/arm");
+ }
-static DllPath* __dllPath = nullptr;
-static std::string __tpa;
+ return candidate;
+}
-// on success, return 0. otherwise return -1.
-int initializePathManager(const std::string& runtimeDir, const std::string& tizenFXDir, const std::string& extraDir)
+void PathManager::updateAppRelatedPath(const std::string& appRootPath, const std::string& appNIRootPath)
{
- __dllPath = new DllPath();
- if (!__dllPath) {
- _ERR("fail to allocate memory for dll path structure\n");
- return -1;
+ std::string appBinPath = concatPath(appRootPath, "bin");
+ std::string appLibPath = concatPath(appRootPath, "lib");
+
+ std::string appNIBinPath = concatPath(concatPath(appNIRootPath, "bin"), APP_NI_SUB_DIR);
+ std::string appNILibPath = concatPath(concatPath(appNIRootPath, "lib"), APP_NI_SUB_DIR);
+
+ appTacPath = concatPath(appBinPath, TAC_SYMLINK_SUB_DIR);
+ appPaths = appRootPath + ":" + appBinPath + ":" + appLibPath + ":" + appTacPath;
+ appNIPaths = appNIBinPath + ":" + appNILibPath + ":" + appTacPath;
+
+ if (!extraDllPaths.empty()) {
+ appPaths = appPaths + ":" + extraDllPaths;
+ appNIPaths = appNIPaths + ":" + extraDllPaths;
}
+}
- if (!runtimeDir.empty()) {
- __dllPath->runtime_dir = absolutePath(runtimeDir);
+PathManager::PathManager() :
+ rootFD(-1),
+ niRootFD(-1)
+{
+ // set runtime path
+ runtimePath = getAbsolutePath(__RUNTIME_DIR);
+ platformAssembliesPaths.push_back(runtimePath);
+
+ // set tizenfx path
+ char* tizenfx_path = vconf_get_str(__TIZEN_API_PATH_KEY);
+ if (tizenfx_path) {
+ tizenfxPath = std::string(tizenfx_path);
+ _DBG("Device API Directory is set by vconf : %s", tizenfx_path);
+ free(tizenfx_path);
} else {
- __dllPath->runtime_dir = absolutePath(__RUNTIME_DIR);
+ tizenfxPath = getAbsolutePath(__DEVICE_API_DIR);
+ }
+ platformAssembliesPaths.push_back(tizenfxPath);
+ platformAssembliesPaths.push_back(tizenfxPath + "/ref");
+
+ // set temporal application root path for candidate process
+ rootFD = open("/proc/self", O_DIRECTORY);
+ if (rootFD < 0) {
+ _ERR("Failed to open /proc/self");
+ throw std::ios_base::failure("Fail to open /proc/self");
}
- if (!tizenFXDir.empty()) {
- __dllPath->tizenfx_dir = absolutePath(tizenFXDir);
- } else {
- char* tmp = vconf_get_str(__TIZEN_API_PATH_KEY);
- if (tmp) {
- __dllPath->tizenfx_dir = std::string(tmp);
- _DBG("Device API Directory is set by vconf : %s", tmp);
- } else {
- __dllPath->tizenfx_dir = absolutePath(__DEVICE_API_DIR);
- }
+ // set temporal application root path for native image
+ niRootFD = open("/proc/self", O_DIRECTORY);
+ if (niRootFD < 0) {
+ _ERR("Failed to open /proc/self");
+ throw std::ios_base::failure("Fail to open /proc/self");
}
- __dllPath->tizenfx_ref_dir = __dllPath->tizenfx_dir + "/ref";
+ std::string fdPath = "/proc/" + std::to_string(getpid()) + "/fd/";
+ appRootPath = fdPath + std::to_string(rootFD);
+ appNIRootPath = fdPath + std::to_string(niRootFD);
- // ":" seperated extra directories
- if (!extraDir.empty()) {
- splitPath(extraDir, __dllPath->extra_dirs);
- } else {
- char* extraPath = pluginGetDllPath();
- if (extraPath) {
- splitPath(extraPath, __dllPath->extra_dirs);
- }
- }
+ updateAppRelatedPath(appRootPath, appNIRootPath);
- _INFO("Path manager initialize success");
+ // Set native library searching path
+ nativeDllSearchingPaths = runtimePath + ":" + __NATIVE_LIB_DIR + ":" +
+ concatPath(appRootPath, "bin") + ":" + concatPath(appRootPath, "lib") + ":" +
+ getExtraNativeLibDirs(appRootPath);
- return 0;
+ _INFO("Path manager created successfully");
}
-void finalizePathManager()
+PathManager::~PathManager()
{
- if (__dllPath) {
- delete __dllPath;
- __dllPath = NULL;
- }
+ _INFO("Path manager destroyed");
}
-std::string getRuntimeDir()
+// paths: ":" separated muliple path.
+void PathManager::addPlatformAssembliesPaths(const std::string& paths, bool isHighPriority)
{
- return __dllPath->runtime_dir;
-}
+ std::vector<std::string>::iterator it;
+ std::vector<std::string> pathVec;
+ splitPath(paths, pathVec);
-std::string getTizenFXDir()
-{
- return __dllPath->tizenfx_dir;
-}
+ for (unsigned int i = 0; i < pathVec.size(); i++) {
+ pathVec[i] = getAbsolutePath(pathVec[i]);
+ }
-std::string getTizenFXRefDir()
-{
- return __dllPath->tizenfx_ref_dir;
+ if (isHighPriority) {
+ it = platformAssembliesPaths.begin();
+ } else {
+ it = platformAssembliesPaths.end();
+ }
+
+ platformAssembliesPaths.insert(it, pathVec.begin(), pathVec.end());
}
-std::vector <std::string> getExtraDirs()
+void PathManager::addNativeDllSearchingPaths(const std::string& paths, bool isHighPriority)
{
- return __dllPath->extra_dirs;
+ if (isHighPriority) {
+ nativeDllSearchingPaths = paths + ":" + nativeDllSearchingPaths;
+ } else {
+ nativeDllSearchingPaths = nativeDllSearchingPaths + ":" + paths;
+ }
}
-static std::string getPlatformTPA()
+void PathManager::setAppRootPath(const std::string& rootPath)
{
- std::string platform_tpa;
+ appRootPath = getAbsolutePath(rootPath);
- if (isFileExist(PLATFORM_TPA_CACHE)) {
- _INFO("platform tpa cache found.\n");
- std::ifstream cacheFile;
- cacheFile.open(PLATFORM_TPA_CACHE);
- std::getline(cacheFile, platform_tpa);
- cacheFile.close();
+ // check readonly update directory eixst or not
+ std::string niRootPath = replaceAll(appRootPath, getBaseName(appRootPath), __READ_ONLY_APP_UPDATE_DIR);
+ if (isReadOnlyArea(appRootPath) && isDirectory(niRootPath)) {
+ appNIRootPath = getAbsolutePath(niRootPath);
} else {
- std::vector<std::string> tpaDir;
- tpaDir.push_back(getRuntimeDir());
- tpaDir.push_back(getTizenFXDir());
- tpaDir.push_back(getTizenFXRefDir());
- assembliesInDirectory(tpaDir, platform_tpa);
+ appNIRootPath = appRootPath;
+ }
+
+ // override root path for application launch mode (candidate / standalone mode)
+ if (rootFD >= 0) {
+ int tmpFD = open(appRootPath.c_str(), O_DIRECTORY);
+ dup3(tmpFD, rootFD, O_CLOEXEC);
+ if (tmpFD >= 0)
+ close(tmpFD);
}
- return platform_tpa;
+ // override ni root path
+ if (niRootFD >= 0) {
+ int tmpFD = open(appNIRootPath.c_str(), O_DIRECTORY);
+ dup3(tmpFD, niRootFD, O_CLOEXEC);
+ if (tmpFD >= 0)
+ close(tmpFD);
+ }
+
+ updateAppRelatedPath(appRootPath, appNIRootPath);
}
-static std::string getPluginTPA()
+// paths: ":" separated muliple path.
+void PathManager::setExtraDllPaths(const char* paths)
{
- std::string plugin_tpa;
-
- char* plugin_tpa_list = pluginGetTPA();
- if (plugin_tpa_list) {
- _INFO("plugin TPA list found. use TPA list for plugin");
- plugin_tpa = plugin_tpa_list;
- } else if (!__dllPath->extra_dirs.empty()){
- _INFO("plugin extra directory found. use plugin extra directroy for TPA");
- assembliesInDirectory(__dllPath->extra_dirs, plugin_tpa);
+ extraDllPaths = std::string(paths);
+ if (!extraDllPaths.empty()) {
+ appPaths = appPaths + ":" + extraDllPaths;
+ appNIPaths = appNIPaths + ":" + extraDllPaths;
}
+}
- return plugin_tpa;
+const std::string& PathManager::getRuntimePath()
+{
+ return runtimePath;
}
-std::string getTPA()
+const std::string& PathManager::getTizenFXPath()
{
- if (!__tpa.empty()) {
- return __tpa;
- }
+ return tizenfxPath;
+}
- if (__dllPath == NULL) {
- return std::string("");
- }
+// return platform assembly paths
+const std::vector<std::string>& PathManager::getPlatformAssembliesPaths()
+{
+ return platformAssembliesPaths;
+}
- return getPlatformTPA() + ":" + getPluginTPA();
+// return app root path
+const std::string& PathManager::getAppRootPath()
+{
+ return appRootPath;
+}
+
+// return .tac_symlink path
+const std::string& PathManager::getAppTacPath()
+{
+ return appTacPath;
+}
+
+// return dll searching paths for app
+const std::string& PathManager::getAppPaths()
+{
+ return appPaths;
+}
+
+// return ni dll searching paths for app
+const std::string& PathManager::getAppNIPaths()
+{
+ return appNIPaths;
}
+// return native dll searching paths for app
+const std::string& PathManager::getNativeDllSearchingPaths()
+{
+ return nativeDllSearchingPaths;
+}