boost::filesystem::coy_option is deprecated.
[platform/core/dotnet/launcher.git] / NativeLauncher / util / path_manager.cc
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <vconf.h>
22
23 #include <iterator>
24 #include <sstream>
25 #include <fstream>
26
27 #include "utils.h"
28 #include "path_manager.h"
29 #include "plugin_manager.h"
30 #include "log.h"
31
32 static const char* __TIZEN_API_PATH_KEY = "db/dotnet/tizen_api_path";
33
34 #define __XSTR(x) #x
35 #define __STR(x) __XSTR(x)
36 static const char* __DEVICE_API_DIR = __STR(DEVICE_API_DIR);
37 static const char* __RUNTIME_DIR = __STR(RUNTIME_DIR);
38 static const char* __NATIVE_LIB_DIR = __STR(NATIVE_LIB_DIR);
39 static const char* __READ_ONLY_APP_UPDATE_DIR = __STR(READ_ONLY_APP_UPDATE_DIR);
40
41 #undef __STR
42 #undef __XSTR
43
44 // /appRoot/lib/{Architecture}/xxxxx.so
45 static std::string getExtraNativeLibDirs(const std::string& appRoot)
46 {
47         std::string candidate = concatPath(appRoot, "lib/" ARCHITECTURE_IDENTIFIER);
48         if (!strncmp(ARCHITECTURE_IDENTIFIER, "arm64", 5)) {
49                 candidate = candidate + ":" + concatPath(appRoot, "lib/aarch64");
50         } else if (!strncmp(ARCHITECTURE_IDENTIFIER, "armel", 5)) {
51                 candidate = candidate + ":" + concatPath(appRoot, "lib/arm");
52         }
53
54         return candidate;
55 }
56
57 void PathManager::updateAppRelatedPath(const std::string& appRootPath, const std::string& appNIRootPath)
58 {
59         std::string appBinPath = concatPath(appRootPath, "bin");
60         std::string appLibPath = concatPath(appRootPath, "lib");
61
62         std::string appNIBinPath = concatPath(concatPath(appNIRootPath, "bin"), APP_NI_SUB_DIR);
63         std::string appNILibPath = concatPath(concatPath(appNIRootPath, "lib"), APP_NI_SUB_DIR);
64
65         appTacPath = concatPath(appBinPath, TAC_SYMLINK_SUB_DIR);
66         appPaths = appRootPath + ":" + appBinPath + ":" + appLibPath + ":" + appTacPath;
67         appNIPaths = appNIBinPath + ":" + appNILibPath + ":" + appTacPath;
68
69         if (!extraDllPaths.empty()) {
70                 appPaths = appPaths + ":" + extraDllPaths;
71                 appNIPaths = appNIPaths + ":" + extraDllPaths;
72         }
73 }
74
75 PathManager::PathManager() :
76         rootFD(-1),
77         niRootFD(-1)
78 {
79         // set runtime path
80         runtimePath = getAbsolutePath(__RUNTIME_DIR);
81         platformAssembliesPaths.push_back(runtimePath);
82
83         // set tizenfx path
84         char* tizenfx_path = vconf_get_str(__TIZEN_API_PATH_KEY);
85         if (tizenfx_path) {
86                 tizenfxPath = std::string(tizenfx_path);
87                 _DBG("Device API Directory is set by vconf : %s", tizenfx_path);
88                 free(tizenfx_path);
89         } else {
90                 tizenfxPath = getAbsolutePath(__DEVICE_API_DIR);
91         }
92         platformAssembliesPaths.push_back(tizenfxPath);
93         platformAssembliesPaths.push_back(tizenfxPath + "/ref");
94
95         // set temporal application root path for candidate process
96         rootFD = open("/proc/self", O_DIRECTORY);
97         if (rootFD < 0) {
98                 _ERR("Failed to open /proc/self");
99                 throw std::ios_base::failure("Fail to open /proc/self");
100         }
101
102         // set temporal application root path for native image
103         niRootFD = open("/proc/self", O_DIRECTORY);
104         if (niRootFD < 0) {
105                 _ERR("Failed to open /proc/self");
106                 throw std::ios_base::failure("Fail to open /proc/self");
107         }
108
109         std::string fdPath = "/proc/" + std::to_string(getpid()) + "/fd/";
110         appRootPath = fdPath + std::to_string(rootFD);
111         appNIRootPath = fdPath + std::to_string(niRootFD);
112
113         updateAppRelatedPath(appRootPath, appNIRootPath);
114
115         // Set native library searching path
116         nativeDllSearchingPaths = runtimePath + ":" + __NATIVE_LIB_DIR + ":" +
117                                   concatPath(appRootPath, "bin") + ":" + concatPath(appRootPath, "lib") + ":" +
118                                   getExtraNativeLibDirs(appRootPath);
119
120         _INFO("Path manager created successfully");
121 }
122
123 PathManager::~PathManager()
124 {
125         _INFO("Path manager destroyed");
126 }
127
128 // paths: ":" separated muliple path.
129 void PathManager::addPlatformAssembliesPaths(const std::string& paths, bool isHighPriority)
130 {
131         std::vector<std::string>::iterator it;
132         std::vector<std::string> pathVec;
133         splitPath(paths, pathVec);
134
135         for (unsigned int i = 0; i < pathVec.size(); i++) {
136                 pathVec[i] = getAbsolutePath(pathVec[i]);
137         }
138
139         if (isHighPriority) {
140                 it = platformAssembliesPaths.begin();
141         } else {
142                 it = platformAssembliesPaths.end();
143         }
144
145         platformAssembliesPaths.insert(it, pathVec.begin(), pathVec.end());
146 }
147
148 void PathManager::addNativeDllSearchingPaths(const std::string& paths, bool isHighPriority)
149 {
150         if (isHighPriority) {
151                 nativeDllSearchingPaths = paths + ":" + nativeDllSearchingPaths;
152         } else {
153                 nativeDllSearchingPaths = nativeDllSearchingPaths + ":" + paths;
154         }
155 }
156
157 void PathManager::setAppRootPath(const std::string& rootPath)
158 {
159         appRootPath = getAbsolutePath(rootPath);
160
161         // check readonly update directory eixst or not
162         std::string niRootPath = replaceAll(appRootPath, getBaseName(appRootPath), __READ_ONLY_APP_UPDATE_DIR);
163         if (isReadOnlyArea(appRootPath) && isDirectory(niRootPath)) {
164                 appNIRootPath = getAbsolutePath(niRootPath);
165         } else {
166                 appNIRootPath = appRootPath;
167         }
168
169         // override root path for application launch mode (candidate / standalone mode)
170         if (rootFD >= 0) {
171                 int tmpFD = open(appRootPath.c_str(), O_DIRECTORY);
172                 dup3(tmpFD, rootFD, O_CLOEXEC);
173                 if (tmpFD >= 0)
174                         close(tmpFD);
175         }
176
177         // override ni root path
178         if (niRootFD >= 0) {
179                 int tmpFD = open(appNIRootPath.c_str(), O_DIRECTORY);
180                 dup3(tmpFD, niRootFD, O_CLOEXEC);
181                 if (tmpFD >= 0)
182                         close(tmpFD);
183         }
184
185         updateAppRelatedPath(appRootPath, appNIRootPath);
186 }
187
188 // paths: ":" separated muliple path.
189 void PathManager::setExtraDllPaths(const char* paths)
190 {
191         extraDllPaths = std::string(paths);
192         if (!extraDllPaths.empty()) {
193                 appPaths = appPaths + ":" + extraDllPaths;
194                 appNIPaths = appNIPaths + ":" + extraDllPaths;
195         }
196 }
197
198 const std::string& PathManager::getRuntimePath()
199 {
200         return runtimePath;
201 }
202
203 const std::string& PathManager::getTizenFXPath()
204 {
205         return tizenfxPath;
206 }
207
208 // return platform assembly paths
209 const std::vector<std::string>& PathManager::getPlatformAssembliesPaths()
210 {
211         return platformAssembliesPaths;
212 }
213
214 // return app root path
215 const std::string& PathManager::getAppRootPath()
216 {
217         return appRootPath;
218 }
219
220 // return .tac_symlink path
221 const std::string& PathManager::getAppTacPath()
222 {
223         return appTacPath;
224 }
225
226 // return dll searching paths for app
227 const std::string& PathManager::getAppPaths()
228 {
229         return appPaths;
230 }
231
232 // return ni dll searching paths for app
233 const std::string& PathManager::getAppNIPaths()
234 {
235         return appNIPaths;
236 }
237
238 // return native dll searching paths for app
239 const std::string& PathManager::getNativeDllSearchingPaths()
240 {
241         return nativeDllSearchingPaths;
242 }