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 APPDIR1 "/opt/apps/"
57 #define APPDIR2 "/opt/usr/apps/"
59 uint64_t str_to_uint64(char* str)
65 while(*str >= '0' && *str <= '9')
67 res = res * 10 + (*str - '0');
75 int64_t str_to_int64(char* str)
93 while(*str >= '0' && *str <= '9')
95 res = res * 10 + (*str - '0');
100 return (res * factor);
103 // return 0 if succeed
104 // return -1 if error occured
105 int remove_indir(const char *dirname)
108 struct dirent *entry;
111 dir = opendir(dirname);
117 while((entry = readdir(dir)) != NULL)
119 if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
121 snprintf(path, (size_t) PATH_MAX, "%s/%s", dirname, entry->d_name);
122 if (entry->d_type != DT_DIR) // file
126 else { } // directory
134 /* execute applcation with executable binary path */
135 int exec_app_tizen(const char *app_id, const char *exec_path)
139 LOGI("exec %s\n", exec_path);
141 if (exec_path == NULL || !strlen(exec_path)) {
142 LOGE("Executable path is not correct\n");
145 LOGI("launch app path is %s, executable path is %s\n"
146 "launch app name (%s), app_id (%s)\n",
147 LAUNCH_APP_PATH, exec_path, LAUNCH_APP_NAME, app_id);
152 if (pid > 0) { /* parent */
155 ret = waitpid(pid, &status, 0);
156 while (ret == -1 && errno == EINTR);
159 execl(LAUNCH_APP_PATH, LAUNCH_APP_NAME, app_id, LAUNCH_APP_SDK,
160 DA_PRELOAD_EXEC, NULL);
161 /* FIXME: If code flows here, it deserves greater attention */
166 int exec_app_common(const char* exec_path)
169 char command[PATH_MAX];
171 LOGI("exec %s\n", exec_path);
172 if (exec_path == NULL || !strlen(exec_path)) {
173 LOGE("Executable path is not correct\n");
177 sprintf(command, "%s %s", DA_PRELOAD_OSP, exec_path);
178 LOGI("cmd: %s\n", command);
184 if (pid > 0) { /* parent */
187 execl(SHELL_CMD, SHELL_CMD, "-c", command, NULL);
188 /* FIXME: Again, such case deserve much more attention */
193 // find process id from executable binary path
194 pid_t find_pid_from_path(const char* path)
198 char buffer[BUFFER_MAX] = {0};
199 char command[BUFFER_MAX] = {0};
201 sprintf(command, "/bin/pidof %s", path);
202 LOGI("look for <%s>\n", path);
204 FILE *fp = popen(command, "r");
208 while (fgets(buffer, BUFFER_MAX, fp) != NULL)
209 LOGI("result of 'pidof' is %s\n", buffer);
213 if (strlen(buffer) > 0) {
214 if (sscanf(buffer, "%d\n", &status) != 1) {
215 LOGW("Failed to read result buffer of 'pidof',"
216 " status(%d) with cmd '%s'\n", status, command);
224 static pid_t get_pid_by_path(const char *binary_path)
229 static const char exe_line[] = ".exe";
232 pkg_pid = find_pid_from_path(binary_path);
234 len = strlen(binary_path);
235 real_path = malloc(len + sizeof(exe_line));
236 if (real_path == NULL) {
237 LOGE("cannot alloc memory\n");
240 memcpy(real_path, binary_path, len + 1);
242 // try remove or add ".exe" and get pid
243 if (strcmp(real_path + len - (sizeof(exe_line) - 1), exe_line) == 0)
244 // remove .exe from tPath
245 real_path[len - (sizeof(exe_line) - 1)] = '\0';
248 memcpy(&real_path[len], exe_line, sizeof(exe_line));
250 pkg_pid = find_pid_from_path(real_path);
257 static int find_alternative_bin_path(const char *binary_path, char *alter_bin_path) {
258 // alternative path may be /opt/apps/... or /opt/usr/apps/...)
259 if (strncmp(binary_path, APPDIR1, strlen(APPDIR1)) == 0) {
260 strcpy(alter_bin_path, APPDIR2);
261 strcat(alter_bin_path, binary_path + strlen(APPDIR1));
262 } else if (strncmp(binary_path, APPDIR2, strlen(APPDIR2)) == 0) {
263 strcpy(alter_bin_path, APPDIR1);
264 strcat(alter_bin_path, binary_path + strlen(APPDIR2));
271 int kill_app(const char *binary_path)
274 char alter_bin_path[PATH_MAX];
276 LOGI("kill %s (%d)\n", binary_path, SIGKILL);
278 pkg_pid = get_pid_by_path(binary_path);
281 if (find_alternative_bin_path(binary_path, alter_bin_path) == 0)
282 pkg_pid = get_pid_by_path(alter_bin_path);
286 if (kill(pkg_pid, SIGTERM) == -1) {
287 LOGE("cannot kill %d -%d err<%s>\n", pkg_pid, SIGKILL,
291 // we need sleep up there because kill() function
292 // returns control immediately after send signal
293 // without it app_launch returns err on start app
295 LOGI("killed %d -%d\n", pkg_pid, SIGKILL);
298 LOGI("cannot kill <%s>; process not found\n", binary_path);
303 int get_executable(char* appPath, char* buf, int buflen)
307 sprintf(buf, "%s.exe", appPath);
308 fd = open(buf, O_RDONLY);
315 strcpy(buf, appPath);
320 int get_app_install_path(char *strAppInstall, int length)
323 char buf[BUFFER_MAX];
327 if ((fp = fopen(DA_INSTALL_PATH, "r")) == NULL)
329 LOGE("Failed to open %s\n", DA_INSTALL_PATH);
333 /*ex : <15> DW_AT_comp_dir : (indirect string, offset: 0x25f): /home/yt/workspace/templatetest/Debug-Tizen-Emulator */
334 while (fgets(buf, BUFFER_MAX, fp) != NULL)
338 for (i = 0; i < BUFFER_MAX; i++)
351 for (; i < BUFFER_MAX; i++)
368 for (; i < BUFFER_MAX - 1; i++)
370 if (*p == ':' || *p == ' ' || *p == '\t')
377 if (strlen(p) <= length)
379 sprintf(strAppInstall, "%s", p);
380 for (i = 0; i < strlen(p); i++)
382 if (strAppInstall[i] == '\n' || strAppInstall[i] == '\t')
384 strAppInstall[i] = '\0';
396 int is_app_built_pie(void)
400 char buf[BUFFER_MAX];
402 if((fp = fopen(DA_BUILD_OPTION, "r")) == NULL)
404 LOGE("Failed to open %s\n", DA_BUILD_OPTION);
408 if(fgets(buf, BUFFER_MAX, fp) != NULL)
410 if(strcmp(buf, "DYN\n") == 0)
412 else if(strcmp(buf, "EXEC\n") == 0)
426 int get_app_base_address(int *baseAddress)
430 char buf[BUFFER_MAX];
432 if((fp = fopen(DA_BASE_ADDRESS, "r")) == NULL)
434 LOGE("Failed to open %s\n", DA_BASE_ADDRESS);
438 if(fgets(buf, BUFFER_MAX, fp) != NULL)
440 res = sscanf(buf, "%x", baseAddress);
451 int is_same_app_process(char* appPath, int pid)
456 char buf[BUFFER_MAX];
457 char cmdPath[PATH_MAX];
458 char tPath[PATH_MAX];
459 char buf_res[PATH_MAX];
460 char tPath_res[PATH_MAX];
462 strcpy(tPath, appPath);
463 tlen = strlen(tPath);
464 if(strcmp(tPath + tlen - 4, ".exe") == 0)
466 // remove .exe from tPath
467 tPath[tlen - 4] = '\0';
470 sprintf(cmdPath, "/proc/%d/cmdline", pid);
472 if((fp = fopen(cmdPath, "r")) == NULL)
477 if(fgets(buf, BUFFER_MAX, fp) != NULL)
480 if(strcmp(buf + tlen - 4, ".exe") == 0)
482 // remove .exe from tPath
483 buf[tlen - 4] = '\0';
486 dereference_tizen_exe_path(buf, buf_res);
487 dereference_tizen_exe_path(tPath, tPath_res);
489 if(strcmp(buf_res, tPath_res) == 0)
499 char *dereference_tizen_exe_path(const char *path, char *resolved)
502 char tmp_path[PATH_MAX];
505 //try resolve <path>.exe
506 sprintf(tmp_path, "%s.exe", path);
507 if ((res = realpath(tmp_path, resolved)) == NULL) {
508 //try to resolve path <path>
509 res = realpath(path, resolved);
515 float get_uptime(void)
517 const char *LINUX_UPTIME_FILE = "/proc/uptime";
518 FILE *fp = fopen(LINUX_UPTIME_FILE, "r");
523 if (fscanf(fp, "%f", &uptime) != 1)