2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FApp_AppEntry.cpp
19 * @brief This is the entry point for the application.
27 #include <sys/types.h>
29 #include <sys/types.h>
34 #include <sys/prctl.h>
35 #include <linux/capability.h>
37 #include <unique_ptr.h>
40 #include <privilege-control.h>
41 #include <pkgmgr-info.h>
44 #include <FOspConfig.h>
47 #define LOG_IO_TAG "LOADER"
48 #define MAX_PACKAGE_ID 10
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 AppInfo_Update(void);
65 AdjustPrivilege(const char* pkgname)
67 set_privilege(pkgname);
70 extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
73 AdjustCapability(void)
75 cap_user_header_t head = 0;
76 cap_user_data_t data = 0;
78 head = static_cast<cap_user_header_t>(malloc(sizeof(*head)));
81 fprintf(stderr, "Memory allocation failure.\n");
85 head->version = _LINUX_CAPABILITY_VERSION;
88 data = static_cast<cap_user_data_t>(calloc(sizeof(*data), _LINUX_CAPABILITY_U32S));
91 fprintf(stderr, "Memory allocation failure.\n");
97 data[CAP_TO_INDEX(CAP_NET_RAW)].effective |= CAP_TO_MASK(CAP_NET_RAW);
98 data[CAP_TO_INDEX(CAP_NET_RAW)].permitted |= CAP_TO_MASK(CAP_NET_RAW);
100 if (capset(head, data) < 0)
102 fprintf(stderr, "Capability setting error\n");
117 GetPackageIdAppExecutableNameFromPath(const char appName[], char* appId, char* exeName)
119 char buffer[PATH_MAX];
121 // path is ".../[appid]/bin/[executable_name]"
123 memset(buffer, 0, PATH_MAX);
124 const char* pRet = realpath(appName, buffer);
127 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, Improper appname %s", appName);
131 const char* p = strrchr(buffer, '/');
134 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, Improper appname %s", appName);
138 const size_t pathLen = strlen(buffer);
139 const int execLen = strlen(p);
140 if (execLen <= 0 || execLen > PATH_MAX || pathLen > PATH_MAX)
142 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, Improper appname %s", appName);
146 strncpy(exeName, p + 1, execLen);
147 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, exeName is %s", exeName);
149 if (pathLen < 1 + 10 + strlen("/bin/") + execLen)
151 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, Improper appname %s", appName);
155 strncpy(appId, p - strlen("bin/") - 10, 10);
156 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, package is %s", appId);
163 PrintArgs(int argc, char* argv[])
165 const char* p = NULL;
170 LOG(LOG_DEBUG, LOG_IO_TAG, "%dth arg : [%s]", i, p);
177 DoPreExec(const char* packageName, const char* bin_path)
181 int (* DoPreExecFunc)(const char*, const char*) = NULL;
184 handle = dlopen("libosp-env-config.so", RTLD_LAZY | RTLD_GLOBAL);
187 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > Failed to dlopen libosp-env-config.so (%s)", dlerror());
190 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > dlopen() ok");
193 DoPreExecFunc = reinterpret_cast <int (*)(const char*, const char*)>(dlsym(handle, "do_pre_exec"));
194 errormsg = dlerror();
195 if (errormsg != NULL)
197 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > Failed to dlsym() (%s)", errormsg);
201 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > dlsym() ok");
203 ret = DoPreExecFunc(packageName, bin_path);
206 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > Failed to do_pre_exe() (%d)", ret);
208 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io > do_pre_exe() ok");
216 ChangeProcessName(const char* fullPath, int argc, char** const argv)
218 // http://stupefydeveloper.blogspot.com/2008/10/linux-change-process-name.html
219 // [INFO] While this implementation may not be portable, most program loader does similar work.
221 // fullPath should be less than original size
222 const int size = strlen(argv[0]);
223 char* args = argv[0];
224 memset(args, '\0', size);
225 strncpy(args, fullPath, size - 1);
227 const char* fileName = NULL;
228 fileName = strrchr(fullPath, '/') + 1;
231 char procName[MAX_PR_NAME];
232 memset(procName, '\0', MAX_PR_NAME);
234 snprintf(procName, MAX_PR_NAME - 1, "%s", fileName);
235 prctl(PR_SET_NAME, procName);
236 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > Process name %s.", __func__, __LINE__, procName);
242 AdjustHwAccInfo(const char* appId)
244 pkgmgrinfo_appinfo_h appHandle = NULL;
245 int ret = pkgmgrinfo_appinfo_get_appinfo(appId, &appHandle);
246 if (ret != PMINFO_R_OK)
248 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::App, %s, %d > Getting package info failed for %s.", __func__, __LINE__, appId);
252 pkgmgrinfo_app_hwacceleration hwAcceleration;
254 ret = pkgmgrinfo_appinfo_get_hwacceleration(appHandle, &hwAcceleration);
255 if (ret != PMINFO_R_OK)
257 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::App, %s, %d > Getting hwaccel info failed for %s.", __func__, __LINE__, appId);
258 pkgmgrinfo_appinfo_destroy_appinfo(appHandle);
261 switch(hwAcceleration)
263 case PMINFO_HWACCELERATION_NOT_USE_GL:
264 setenv("HWACC", "NOT_USE", 1);
266 case PMINFO_HWACCELERATION_USE_GL:
267 setenv("HWACC", "USE", 1);
269 case PMINFO_HWACCELERATION_USE_SYSTEM_SETTING:
272 // no need to handle default
276 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::App, %s, %d > HWACC sets for %s with %d.", __func__, __LINE__, appId, hwAcceleration);
277 pkgmgrinfo_appinfo_destroy_appinfo(appHandle);
282 * The entry function of SLP application called by the operating system.
285 main(int argc, char* pArgv[])
287 bool bCommand = false;
289 char packageId[MAX_PACKAGE_ID + 1];
290 char exeName[MAX_APP_EXECUTABLE_NAME];
291 char fullPath[PATH_MAX];
293 memset(packageId, 0, sizeof(packageId));
294 memset(exeName, 0, sizeof(exeName));
295 memset(fullPath, 0, PATH_MAX);
297 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > executable binary path: %s", __func__, __LINE__, pArgv[0]);
298 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > uid: %d, euid: %d", __func__, __LINE__, getuid(), geteuid());
300 const int len = strlen(pArgv[0]);
301 bCommand = (len > 4 && (strncmp(pArgv[0] + len - 4, ".exe", 4) == 0));
304 const int path_size = std::min(PATH_MAX - 1, len - 4);
305 strncpy(fullPath, pArgv[0], path_size);
309 strncpy(fullPath, pArgv[0], PATH_MAX - 1);
311 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > processed binary path: %s", __func__, __LINE__, fullPath);
313 // convert package path to packageId
314 GetPackageIdAppExecutableNameFromPath(fullPath, packageId, exeName);
316 // acquire appId from packageId and exec
317 char appId[MAX_PACKAGE_ID + MAX_APP_EXECUTABLE_NAME + 2] = {0, };
318 strncpy(appId, packageId, 10);
320 strncpy(appId + 11, exeName, MAX_APP_EXECUTABLE_NAME);
326 DoPreExec(packageId, fullPath);
329 AdjustPrivilege(appId);
334 PrintArgs(argc, pArgv);
338 ChangeProcessName(fullPath, argc, pArgv);
339 pArgv[0] = strdup(fullPath);
343 appinfo_init(appId, 0);
344 appinfo_set_argv(argc, pArgv);
348 AdjustHwAccInfo(appId);
350 int r = OspMain(argc, pArgv);
352 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > OSP application is terminated.", __func__, __LINE__);
353 LOG(LOG_DEBUG, LOG_IO_TAG, "Tizen::Io, %s, %d > uid: %d, euid: %d", __func__, __LINE__, getuid(), geteuid());
360 #endif // __cplusplus