2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FApp_AppEntry.cpp
20 * @brief This is the entry point for the application.
28 #include <sys/types.h>
30 #include <sys/types.h>
35 #include <sys/prctl.h>
36 #include <linux/capability.h>
38 #include <unique_ptr.h>
41 #include <privilege-control.h>
42 #include <pkgmgr-info.h>
44 #include <FOspConfig.h>
47 #define LOG_IO_TAG "LOADER"
49 #define MAX_APP_EXECUTABLE_NAME 230
50 #define MAX_PACKAGE_NAME 100
51 #define MAX_PR_NAME 16
60 extern int OspMain(int argc, char* pArgv[]) __attribute__((weak));
61 //extern void Osp_Initialize();
62 extern void InitAppInfo(const char* appId, const char* exeName, int argc, char* pArgv[], int fd);
65 AdjustPrivilege(const char* pkgname)
67 void* handle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_LOCAL);
70 fprintf(stderr, "Cannot open libprivilege-control.so.0\n");
77 int (* ppriv_func)(const char*) = NULL;
79 ppriv_func = reinterpret_cast <int (*)(const char*)>(dlsym(handle, "set_privilege"));
83 fprintf(stderr, "Dlsym error: %s\n", msg);
89 int ret = (*ppriv_func)(pkgname);
92 fprintf(stderr, "set_privilege() returned %d\n", ret);
98 extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
101 AdjustCapability(void)
103 cap_user_header_t head = 0;
104 cap_user_data_t data = 0;
106 head = static_cast<cap_user_header_t>(malloc(sizeof(*head)));
109 fprintf(stderr, "Memory allocation failure.\n");
113 head->version = _LINUX_CAPABILITY_VERSION;
114 head->pid = getpid();
116 data = static_cast<cap_user_data_t>(calloc(sizeof(*data), _LINUX_CAPABILITY_U32S));
119 fprintf(stderr, "Memory allocation failure.\n");
125 data[CAP_TO_INDEX(CAP_NET_RAW)].effective |= CAP_TO_MASK(CAP_NET_RAW);
126 data[CAP_TO_INDEX(CAP_NET_RAW)].permitted |= CAP_TO_MASK(CAP_NET_RAW);
128 if (capset(head, data) < 0)
130 fprintf(stderr, "Capability setting error\n");
145 GetAppIdAppExecutableNameFromPathNew(const char appName[], char* appId, char* exeName)
147 char buffer[PATH_MAX];
149 // path is ".../[appid]/bin/[executable_name]"
151 memset(buffer, 0, PATH_MAX);
152 const char* pRet = realpath(appName, buffer);
155 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, Improper appname %s", appName);
159 const char* p = strrchr(buffer, '/');
162 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, Improper appname %s", appName);
166 const size_t pathLen = strlen(buffer);
167 const int execLen = strlen(p);
168 if (execLen <= 0 || execLen > PATH_MAX || pathLen > PATH_MAX)
170 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, Improper appname %s", appName);
174 strncpy(exeName, p + 1, execLen);
175 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, exeName is %s", exeName);
177 if (pathLen < 1 + 10 + strlen("/bin/") + execLen)
179 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, Improper appname %s", appName);
183 strncpy(appId, p - strlen("bin/") - 10, 10);
184 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, app is %s", appId);
190 GetAppIdAppExecutableNameFromPath(const char appName[], char* appId, char* exeName)
192 const char* begin = NULL;
193 const char* end = NULL;
194 const int path_len = strlen(appName);
196 // Calculate the header
197 const char* p = strstr(appName, "/apps/org.tizen.");
200 return GetAppIdAppExecutableNameFromPathNew(appName, appId, exeName);
205 end = strchr(begin + 1, '/');
208 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, Improper appname %s", appName);
212 int len = end - begin - 1;
216 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, Improper appname %s with length %d", appName, len);
221 strncpy(appId, begin + 1, len);
222 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, app is %s", appId);
226 if (path_len > len + 21)
228 exe_len = std::min(MAX_APP_EXECUTABLE_NAME - 1, path_len - len - 21);
229 strncpy(exeName, end + 5, exe_len);
232 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, exeName is %s", exeName);
238 GetPackageNameFromAppIdAppExecutableName(const char appId[], const char exeName[], char* pkgName, int maxPkgName)
240 // package name is "org.tizen.[appid]#[executable]"
242 //snprintf(pkgName, maxPkgName, "org.tizen.%s#%s", appId, exeName);
243 snprintf(pkgName, maxPkgName, "%s", appId);
245 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::App, packageName is %s", pkgName);
251 PrintArgs(int argc, char* argv[])
253 const char* p = NULL;
258 LOG(LOG_DEBUG, LOG_IO_TAG, "%dth arg : [%s]", i, p);
265 DoPreExec(const char* packageName, const char* bin_path)
269 int (* DoPreExecFunc)(const char*, const char*) = NULL;
272 handle = dlopen("libosp-env-config.so", RTLD_LAZY | RTLD_GLOBAL);
275 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > Failed to dlopen libosp-env-config.so (%s)", dlerror());
278 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > dlopen() ok");
280 DoPreExecFunc = reinterpret_cast <int (*)(const char*, const char*)>(dlsym(handle, "do_pre_exec"));
281 errormsg = dlerror();
282 if (errormsg != NULL)
284 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > Failed to dlsym() (%s)", errormsg);
288 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > dlsym() ok");
290 ret = DoPreExecFunc(packageName, bin_path);
293 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > Failed to do_pre_exe() (%d)", ret);
295 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > do_pre_exe() ok");
303 ChangeProcessName(const char* fullPath, int argc, char** const argv)
305 // http://stupefydeveloper.blogspot.com/2008/10/linux-change-process-name.html
306 // [INFO] While this implementation may not be portable, most program loader does similar work.
308 // fullPath should be less than original size
309 const int size = strlen(argv[0]);
310 char* args = argv[0];
311 memset(args, '\0', size);
312 strncpy(args, fullPath, size - 1);
314 const char* fileName = NULL;
315 fileName = strrchr(fullPath, '/') + 1;
318 char procName[MAX_PR_NAME];
319 memset(procName, '\0', MAX_PR_NAME);
321 snprintf(procName, MAX_PR_NAME - 1, "%s", fileName);
322 prctl(PR_SET_NAME, procName);
323 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > Process name %s.", __func__, __LINE__, procName);
328 GetDirFdFromPath(const char* pPath)
331 const int len = strlen(pPath);
332 char dname[PATH_MAX];
333 memset(dname, 0, PATH_MAX);
335 const char* p = pPath + len;
336 for (int i = 0; i < len; i++, p--)
349 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > Wrong path format : %s.", __func__, __LINE__, pPath);
354 strncpy(dname, pPath, p - pPath);
356 const int fd = open(dname, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
358 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::App, %s, %d > Directory path : %s, fd : %d.", __func__, __LINE__, dname, fd);
365 AdjustHwAccInfo(const char* packageId, const char* execName)
367 char appId[MAX_APPID + MAX_APP_EXECUTABLE_NAME + 2] = {0, };
368 strncpy(appId, packageId, 10);
370 strncpy(appId + 11, execName, MAX_APP_EXECUTABLE_NAME);
372 pkgmgrinfo_appinfo_h appHandle = NULL;
373 int ret = pkgmgrinfo_appinfo_get_appinfo(appId, &appHandle);
374 if (ret != PMINFO_R_OK)
376 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::App, %s, %d > Getting package info failed for %s.", __func__, __LINE__, appId);
380 pkgmgrinfo_app_hwacceleration hwAcceleration;
382 ret = pkgmgrinfo_appinfo_get_hwacceleration(appHandle, &hwAcceleration);
383 if (ret != PMINFO_R_OK)
385 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::App, %s, %d > Getting hwaccel info failed for %s.", __func__, __LINE__, appId);
386 pkgmgrinfo_appinfo_destroy_appinfo(appHandle);
389 switch(hwAcceleration)
391 case PMINFO_HWACCELERATION_NOT_USE_GL:
392 setenv("HWACC", "NOT_USE", 1);
394 case PMINFO_HWACCELERATION_USE_GL:
395 setenv("HWACC", "USE", 1);
397 case PMINFO_HWACCELERATION_USE_SYSTEM_SETTING:
400 // no need to handle default
404 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::App, %s, %d > HWACC sets for %s with %d.", __func__, __LINE__, appId, hwAcceleration);
405 pkgmgrinfo_appinfo_destroy_appinfo(appHandle);
410 * The entry function of SLP application called by the operating system.
413 main(int argc, char* pArgv[])
415 bool bCommand = false;
417 char appId[MAX_APPID];
418 char exeName[MAX_APP_EXECUTABLE_NAME];
419 char packageName[MAX_PACKAGE_NAME];
420 char fullPath[PATH_MAX];
422 memset(appId, 0, MAX_APPID);
423 memset(exeName, 0, MAX_APP_EXECUTABLE_NAME);
424 memset(packageName, 0, MAX_PACKAGE_NAME);
425 memset(fullPath, 0, PATH_MAX);
427 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > executable binary path: %s", __func__, __LINE__, pArgv[0]);
428 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > uid: %d, euid: %d", __func__, __LINE__, getuid(), geteuid());
430 const int len = strlen(pArgv[0]);
431 bCommand = (len > 4 && (strncmp(pArgv[0] + len - 4, ".exe", 4) == 0));
434 const int path_size = std::min(PATH_MAX - 1, len - 4);
435 strncpy(fullPath, pArgv[0], path_size);
439 strncpy(fullPath, pArgv[0], PATH_MAX - 1);
441 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > processed binary path: %s", __func__, __LINE__, fullPath);
443 // convert package path to appId
444 GetAppIdAppExecutableNameFromPath(fullPath, appId, exeName);
445 GetPackageNameFromAppIdAppExecutableName(appId, exeName, packageName, MAX_PACKAGE_NAME);
450 DoPreExec(packageName, fullPath);
453 AdjustPrivilege(packageName);
458 PrintArgs(argc, pArgv);
462 ChangeProcessName(fullPath, argc, pArgv);
463 pArgv[0] = strdup(fullPath);
466 int fd = GetDirFdFromPath(pArgv[0]);
469 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > Failed to open path [%d][%s].", __func__, __LINE__, getpid(), strerror(errno));
473 // dlopen will load Osp_Initialize() internally as __attribute__((constructor))
475 InitAppInfo(appId, exeName, argc, pArgv, fd);
477 AdjustHwAccInfo(appId, exeName);
479 int r = OspMain(argc, pArgv);
481 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > OSP application is terminated.", __func__, __LINE__);
482 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > uid: %d, euid: %d", __func__, __LINE__, getuid(), geteuid());
489 #endif // __cplusplus