4 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
8 * Jaewon Lim <jaewon81.lim@samsung.com>
9 * Woojin Jung <woojin2.jung@samsung.com>
10 * Juyoung Kim <j0.kim@samsung.com>
11 * Cherepanov Vitaliy <v.cherepanov@samsung.com>
12 * Nikita Kalyazin <n.kalyazin@samsung.com>
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
18 * http://www.apache.org/licenses/LICENSE-2.0
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
28 * - Samsung RnD Institute Russia
37 #include <signal.h> // for signal
39 #include <unistd.h> // for unlink
40 #include <dirent.h> // for opendir, readdir
41 #include <sys/types.h> // for open
42 #include <sys/stat.h> // for open
43 #include <fcntl.h> // for open
44 #include <grp.h> // for setgroups
45 #include <sys/wait.h> /* waitpid */
52 #define BUFFER_MAX 1024
54 #define MANIFEST_PATH "/info/manifest.xml"
56 #define PROC_FS "/proc"
57 #define PROC_CMDLINE "/proc/%s/cmdline"
59 #define APPDIR1 "/opt/apps/"
60 #define APPDIR2 "/opt/usr/apps/"
62 uint64_t str_to_uint64(char* str)
68 while(*str >= '0' && *str <= '9')
70 res = res * 10 + (*str - '0');
78 int64_t str_to_int64(char* str)
96 while(*str >= '0' && *str <= '9')
98 res = res * 10 + (*str - '0');
103 return (res * factor);
106 // return 0 if succeed
107 // return -1 if error occured
108 int remove_indir(const char *dirname)
111 struct dirent *entry;
114 dir = opendir(dirname);
120 while((entry = readdir(dir)) != NULL)
122 if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
124 snprintf(path, (size_t) PATH_MAX, "%s/%s", dirname, entry->d_name);
125 if (entry->d_type != DT_DIR) // file
129 else { } // directory
137 /* execute applcation with executable binary path */
138 int exec_app_tizen(const char *app_id, const char *exec_path)
142 LOGI("exec %s\n", exec_path);
144 if (exec_path == NULL || !strlen(exec_path)) {
145 LOGE("Executable path is not correct\n");
148 LOGI("launch app path is %s, executable path is %s\n"
149 "launch app name (%s), app_id (%s)\n",
150 LAUNCH_APP_PATH, exec_path, LAUNCH_APP_NAME, app_id);
155 if (pid > 0) { /* parent */
158 ret = waitpid(pid, &status, 0);
159 while (ret == -1 && errno == EINTR);
162 execl(LAUNCH_APP_PATH, LAUNCH_APP_NAME, app_id, LAUNCH_APP_SDK,
163 DA_PRELOAD_EXEC, NULL);
164 /* FIXME: If code flows here, it deserves greater attention */
169 int exec_app_common(const char* exec_path)
172 char command[PATH_MAX];
174 LOGI("exec %s\n", exec_path);
175 if (exec_path == NULL || !strlen(exec_path)) {
176 LOGE("Executable path is not correct\n");
180 sprintf(command, "%s %s", DA_PRELOAD_TIZEN, exec_path);
181 LOGI("cmd: %s\n", command);
187 if (pid > 0) { /* parent */
190 execl(SHELL_CMD, SHELL_CMD, "-c", command, NULL);
191 /* FIXME: Again, such case deserve much more attention */
196 int exec_app_web(const char *app_id)
200 LOGI("wrt-launcher path is %s,\n"
201 "wrt-launcher name (%s), app_id (%s)\n",
202 WRT_LAUNCHER_PATH, WRT_LAUNCHER_NAME, app_id);
208 if (pid > 0) { /* parent */
211 ret = waitpid(pid, &status, 0);
212 while (ret == -1 && errno == EINTR);
215 execl(WRT_LAUNCHER_PATH,
220 /* FIXME: If code flows here, it deserves greater attention */
221 LOGE("Cannot run exec!\n");
226 void kill_app_web(const char *app_id)
230 LOGI("wrt-launcher path is %s,\n"
231 "wrt-launcher name (%s), app_id (%s)\n",
232 WRT_LAUNCHER_PATH, WRT_LAUNCHER_NAME, app_id);
238 if (pid > 0) { /* parent */
241 ret = waitpid(pid, &status, 0);
242 while (ret == -1 && errno == EINTR);
245 execl(WRT_LAUNCHER_PATH,
250 /* FIXME: If code flows here, it deserves greater attention */
251 LOGE("Cannot run exec!\n");
256 // find process id from executable binary path
257 pid_t find_pid_from_path(const char *path)
259 char buf[BUFFER_MAX];
260 char cmdline[PATH_MAX];
263 struct dirent *entry;
264 int found, len = strlen(path);
267 LOGI("look for <%s>\n", path);
269 proc = opendir(PROC_FS);
273 while ((entry = readdir(proc)) != NULL) {
274 pid = (pid_t)atoi(entry->d_name);
278 snprintf(cmdline, sizeof(cmdline), PROC_CMDLINE, entry->d_name);
280 fp = fopen(cmdline, "r");
285 if (fscanf(fp, "%s", buf) != EOF) /* read only argv[0] */
286 found = (strncmp(path, buf, len) == 0);
303 static pid_t get_pid_by_path(const char *binary_path)
308 static const char exe_line[] = ".exe";
311 pkg_pid = find_pid_from_path(binary_path);
313 len = strlen(binary_path);
314 real_path = malloc(len + sizeof(exe_line));
315 if (real_path == NULL) {
316 LOGE("cannot alloc memory\n");
319 memcpy(real_path, binary_path, len + 1);
321 // try remove or add ".exe" and get pid
322 if (strcmp(real_path + len - (sizeof(exe_line) - 1), exe_line) == 0)
323 // remove .exe from tPath
324 real_path[len - (sizeof(exe_line) - 1)] = '\0';
327 memcpy(&real_path[len], exe_line, sizeof(exe_line));
329 pkg_pid = find_pid_from_path(real_path);
336 static int find_alternative_bin_path(const char *binary_path, char *alter_bin_path) {
337 // alternative path may be /opt/apps/... or /opt/usr/apps/...)
338 if (strncmp(binary_path, APPDIR1, strlen(APPDIR1)) == 0) {
339 strcpy(alter_bin_path, APPDIR2);
340 strcat(alter_bin_path, binary_path + strlen(APPDIR1));
341 } else if (strncmp(binary_path, APPDIR2, strlen(APPDIR2)) == 0) {
342 strcpy(alter_bin_path, APPDIR1);
343 strcat(alter_bin_path, binary_path + strlen(APPDIR2));
350 int kill_app(const char *binary_path)
353 char alter_bin_path[PATH_MAX];
355 LOGI("kill %s (%d)\n", binary_path, SIGKILL);
357 pkg_pid = get_pid_by_path(binary_path);
360 if (find_alternative_bin_path(binary_path, alter_bin_path) == 0)
361 pkg_pid = get_pid_by_path(alter_bin_path);
365 if (kill(pkg_pid, SIGTERM) == -1) {
366 LOGE("cannot kill %d -%d err<%s>\n", pkg_pid, SIGKILL,
370 // we need sleep up there because kill() function
371 // returns control immediately after send signal
372 // without it app_launch returns err on start app
374 LOGI("killed %d -%d\n", pkg_pid, SIGKILL);
377 LOGI("cannot kill <%s>; process not found\n", binary_path);
382 int get_executable(char* appPath, char* buf, int buflen)
386 sprintf(buf, "%s.exe", appPath);
387 fd = open(buf, O_RDONLY);
394 strcpy(buf, appPath);
399 int get_app_install_path(char *strAppInstall, int length)
402 char buf[BUFFER_MAX];
406 if ((fp = fopen(DA_INSTALL_PATH, "r")) == NULL)
408 LOGE("Failed to open %s\n", DA_INSTALL_PATH);
412 /*ex : <15> DW_AT_comp_dir : (indirect string, offset: 0x25f): /home/yt/workspace/templatetest/Debug-Tizen-Emulator */
413 while (fgets(buf, BUFFER_MAX, fp) != NULL)
417 for (i = 0; i < BUFFER_MAX; i++)
430 for (; i < BUFFER_MAX; i++)
447 for (; i < BUFFER_MAX - 1; i++)
449 if (*p == ':' || *p == ' ' || *p == '\t')
456 if (strlen(p) <= length)
458 sprintf(strAppInstall, "%s", p);
459 for (i = 0; i < strlen(p); i++)
461 if (strAppInstall[i] == '\n' || strAppInstall[i] == '\t')
463 strAppInstall[i] = '\0';
475 int is_app_built_pie(void)
479 char buf[BUFFER_MAX];
481 if((fp = fopen(DA_BUILD_OPTION, "r")) == NULL)
483 LOGE("Failed to open %s\n", DA_BUILD_OPTION);
487 if(fgets(buf, BUFFER_MAX, fp) != NULL)
489 if(strcmp(buf, "DYN\n") == 0)
491 else if(strcmp(buf, "EXEC\n") == 0)
505 int get_app_base_address(int *baseAddress)
509 char buf[BUFFER_MAX];
511 if((fp = fopen(DA_BASE_ADDRESS, "r")) == NULL)
513 LOGE("Failed to open %s\n", DA_BASE_ADDRESS);
517 if(fgets(buf, BUFFER_MAX, fp) != NULL)
519 res = sscanf(buf, "%x", baseAddress);
530 int is_same_app_process(char* appPath, int pid)
535 char buf[BUFFER_MAX];
536 char cmdPath[PATH_MAX];
537 char tPath[PATH_MAX];
538 char buf_res[PATH_MAX];
539 char tPath_res[PATH_MAX];
541 strcpy(tPath, appPath);
542 tlen = strlen(tPath);
543 if(strcmp(tPath + tlen - 4, ".exe") == 0)
545 // remove .exe from tPath
546 tPath[tlen - 4] = '\0';
549 sprintf(cmdPath, "/proc/%d/cmdline", pid);
551 if((fp = fopen(cmdPath, "r")) == NULL)
556 if(fgets(buf, BUFFER_MAX, fp) != NULL)
559 if(strcmp(buf + tlen - 4, ".exe") == 0)
561 // remove .exe from tPath
562 buf[tlen - 4] = '\0';
565 dereference_tizen_exe_path(buf, buf_res);
566 dereference_tizen_exe_path(tPath, tPath_res);
568 if(strcmp(buf_res, tPath_res) == 0)
578 char *dereference_tizen_exe_path(const char *path, char *resolved)
581 char tmp_path[PATH_MAX];
584 //try resolve <path>.exe
585 sprintf(tmp_path, "%s.exe", path);
586 if ((res = realpath(tmp_path, resolved)) == NULL) {
587 //try to resolve path <path>
588 res = realpath(path, resolved);
594 float get_uptime(void)
596 const char *LINUX_UPTIME_FILE = "/proc/uptime";
597 FILE *fp = fopen(LINUX_UPTIME_FILE, "r");
602 if (fscanf(fp, "%f", &uptime) != 1)