Refactoring debug-launchpad 09/53609/12 accepted/tizen/mobile/20151212.070856 accepted/tizen/tv/20151212.072422 accepted/tizen/wearable/20151212.072917 submit/tizen/20151211.044548 submit/tizen_common/20151229.142028 submit/tizen_common/20151229.144031 submit/tizen_common/20151229.154718
authorHwankyu Jhun <h.jhun@samsung.com>
Fri, 4 Dec 2015 11:57:26 +0000 (20:57 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Fri, 11 Dec 2015 02:41:48 +0000 (11:41 +0900)
- sync with tizen_2.4
- use glib main loop
- remove unnecessary dependencies (x11, aul, ail)

Change-Id: I79652c1a5415f4f5a9bf0cbb68d4c13e8e8a7c8e
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
33 files changed:
CMakeLists.txt
LICENSE [moved from LICENSE.APLv2 with 100% similarity]
debug-launchpad.manifest [new file with mode: 0644]
feature/preexec.h [deleted file]
include/access_control.h [deleted file]
include/app_signal.h [deleted file]
include/app_sock.h [deleted file]
include/aul_util.h [deleted file]
include/common.h [new file with mode: 0644]
include/debug_util.h [new file with mode: 0644]
include/defs.h [new file with mode: 0644]
include/file_util.h [moved from src/fileutils.h with 71% similarity]
include/menu_db_util.h [deleted file]
include/perf.h
include/preload.h [deleted file]
include/security_util.h [moved from src/gl.h with 61% similarity, mode: 0644]
include/signal_util.h [moved from src/config.h with 55% similarity, mode: 0644]
include/simple_util.h [deleted file]
packaging/debug-launchpad.service [new file with mode: 0644]
packaging/debug-launchpad.socket [new file with mode: 0644]
packaging/debug-launchpad.spec [changed mode: 0644->0755]
src/app_sock.c [deleted file]
src/common.c [new file with mode: 0644]
src/debug-launchpad.c [new file with mode: 0644]
src/debug_util.c [new file with mode: 0644]
src/file_util.c [new file with mode: 0644]
src/fileutils.c [deleted file]
src/heap_dbg.h [deleted file]
src/launchpad.c [deleted file]
src/security_util.c [new file with mode: 0644]
src/sigchild.h [deleted file]
src/signal_util.c [new file with mode: 0644]
src/simple_util.c [deleted file]

index 9a65cf3..bc44053 100755 (executable)
@@ -16,11 +16,16 @@ IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
 ENDIF()
 MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
 
-
 # Set required packages
 INCLUDE(FindPkgConfig)
 
-pkg_check_modules(pkgs REQUIRED dlog x11 libprivilege-control dbus-glib-1 sqlite3 bundle vconf libsmack aul)
+SET(pkgs_requires "dlog glib-2.0 libprivilege-control dbus-glib-1 bundle vconf libsmack security-manager pkgmgr-info")
+IF(_APPFW_FEATURE_SOCKET_ACTIVATION)
+       SET(pkgs_requires "${pkgs_requires} libsystemd-daemon")
+       ADD_DEFINITIONS("-D_APPFW_FEATURE_SOCKET_ACTIVATION")
+ENDIF(_APPFW_FEATURE_SOCKET_ACTIVATION)
+
+pkg_check_modules(pkgs REQUIRED ${pkgs_requires})
 
 FIND_LIBRARY(LIB_DL dl)
 
@@ -38,51 +43,28 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_CFLAGS}")
 SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
 SET(CMAKE_C_FLAGS_RELEASE "-O2")
-
 SET(CMAKE_SKIP_BUILD_RPATH true)
 
-# Get uname value to set 'TARGET' definition 
-# TODO: Is this needed?
-FIND_PROGRAM(UNAME NAMES uname)
-EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
-IF("${ARCH}" STREQUAL "arm")
-       ADD_DEFINITIONS("-DTARGET")
-       MESSAGE("add -DTARGET")
-ENDIF("${ARCH}" STREQUAL "arm")
-
 ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
 ADD_DEFINITIONS("-DSHARE_PREFIX=\"/usr/share/aul\"")
 
 # Linker flags
 SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
 
-
 ### Build ###
-
-# launchpad(old avatar) daemon
-SET(AVATAR_NAME "debug_launchpad_preloading_preinitializing_daemon")
-add_executable(${AVATAR_NAME}
-       src/fileutils.c
-       src/app_sock.c
-       src/simple_util.c
-       src/launchpad.c
+# debug_launchpad_preloading_preinitializing_daemon
+SET(DEBUG_LAUNCHPAD "debug_launchpad_preloading_preinitializing_daemon")
+add_executable(${DEBUG_LAUNCHPAD}
+       src/file_util.c
+       src/debug_util.c
+       src/security_util.c
+       src/signal_util.c
+       src/common.c
+       src/debug-launchpad.c
        )
 
-MESSAGE("       "${pkgs_LDFLAGS})
-target_link_libraries(${AVATAR_NAME} aul cap ${pkgs_LDFLAGS} ${LIB_DL})
-set_target_properties(${AVATAR_NAME}
-               PROPERTIES SKIP_BUILD_RPATH true
-               ) # remove rpath option that is automatically generated by cmake.
-
-
-INSTALL(TARGETS ${LAUNCH_AGENT} DESTINATION bin)
-
-
-
-# pkgconfig file
-
-
-### Install ###
-INSTALL(TARGETS ${AVATAR_NAME} DESTINATION bin)
-
+target_link_libraries(${DEBUG_LAUNCHPAD} ${pkgs_LDFLAGS} ${LIB_DL} "-pie")
+set_target_properties(${DEBUG_LAUNCHPAD} PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE")
+set_target_properties(${DEBUG_LAUNCHPAD} PROPERTIES SKIP_BUILD_RPATH true)
 
+INSTALL(TARGETS ${DEBUG_LAUNCHPAD} DESTINATION bin)
similarity index 100%
rename from LICENSE.APLv2
rename to LICENSE
diff --git a/debug-launchpad.manifest b/debug-launchpad.manifest
new file mode 100644 (file)
index 0000000..5874aa8
--- /dev/null
@@ -0,0 +1,8 @@
+<manifest>
+       <request>
+               <domain name="_"/>
+       </request>
+       <assign>
+               <filesystem path="/usr/bin/debug_launchpad_preloading_preinitializing_daemon" label="_" exec_label="none" />
+       </assign>
+</manifest>
diff --git a/feature/preexec.h b/feature/preexec.h
deleted file mode 100755 (executable)
index 644c416..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifdef PREEXEC_ACTIVATE
-
-#include <dlfcn.h>
-#include <glib.h>
-#define PREEXEC_FILE SHARE_PREFIX"/preexec_list.txt"
-
-static int preexec_initialized = 0;
-
-GSList *preexec_list = NULL;
-
-typedef struct _preexec_list_t {
-       char *pkg_type;
-       char *so_path;
-       int (*dl_do_pre_exe) (char *, char *);
-} preexec_list_t;
-
-static void __preexec_list_free()
-{
-       GSList *iter = NULL;
-       preexec_list_t *type_t;
-
-       for (iter = preexec_list; iter != NULL; iter = g_slist_next(iter)) {
-               type_t = iter->data;
-               if (type_t) {
-                       if (type_t->pkg_type)
-                               free(type_t->pkg_type);
-                       if (type_t->so_path)
-                               free(type_t->so_path);
-                       free(type_t);
-               }
-       }
-       g_slist_free(preexec_list);
-       preexec_initialized = 0;
-       return;
-}
-
-static inline void __preexec_init(int argc, char **argv)
-{
-       void *handle = NULL;
-       FILE *preexec_file;
-       char *saveptr = NULL;
-       char line[MAX_LOCAL_BUFSZ];
-       char *type = NULL;
-       char *sopath = NULL;
-       char *symbol = NULL;
-       int (*func) (char *, char *) = NULL;
-       preexec_list_t *type_t = NULL;
-
-       preexec_file = fopen(PREEXEC_FILE, "rt");
-       if (preexec_file == NULL) {
-               _E("no preexec\n");
-               return;
-       }
-
-       _D("preexec start\n");
-
-       while (fgets(line, MAX_LOCAL_BUFSZ, preexec_file) > 0) {
-               /* Parse each line */
-               if (line[0] == '#' || line[0] == '\0')
-                       continue;
-
-               type = strtok_r(line, ":\f\n\r\t\v ", &saveptr);
-               if (type == NULL)
-                       continue;
-               sopath = strtok_r(NULL, ",\f\n\r\t\v ", &saveptr);
-               if (sopath == NULL)
-                       continue;
-               symbol = strtok_r(NULL, ",\f\n\r\t\v ", &saveptr);
-               if (symbol == NULL)
-                       continue;
-
-               type_t = (preexec_list_t *) calloc(1, sizeof(preexec_list_t));
-               if (type_t == NULL) {
-                       _E("no available memory\n");
-                       __preexec_list_free();
-                       fclose(preexec_file);
-                       return;
-               }
-
-               handle = dlopen(sopath, RTLD_NOW);
-               if (handle == NULL) {
-                       free(type_t);
-                       continue;
-               }
-               _D("preexec %s %s# - handle : %x\n", type, sopath, handle);
-
-               func = dlsym(handle, symbol);
-               if (func == NULL) {
-                       _E("failed to get symbol type:%s path:%s\n",
-                          type, sopath);
-                       free(type_t);
-                       dlclose(handle);
-                       handle = NULL;
-                       continue;
-               }
-
-               type_t->pkg_type = strdup(type);
-               if (type_t->pkg_type == NULL) {
-                       _E("no available memory\n");
-                       free(type_t);
-                       __preexec_list_free();
-                       fclose(preexec_file);
-                       return;
-               }
-               type_t->so_path = strdup(sopath);
-               if (type_t->so_path == NULL) {
-                       _E("no available memory\n");
-                       free(type_t->pkg_type);
-                       free(type_t);
-                       __preexec_list_free();
-                       fclose(preexec_file);
-                       return;
-               }
-               type_t->dl_do_pre_exe = func;
-
-               preexec_list = g_slist_append(preexec_list, (void *)type_t);
-       }
-
-       fclose(preexec_file);
-       preexec_initialized = 1;
-}
-
-static inline void __preexec_run(const char *pkg_type, const char *pkg_name,
-                                const char *app_path)
-{
-       GSList *iter = NULL;
-       preexec_list_t *type_t;
-
-       if (!preexec_initialized)
-               return;
-
-       for (iter = preexec_list; iter != NULL; iter = g_slist_next(iter)) {
-               type_t = iter->data;
-               if (type_t) {
-                       if (!strcmp(pkg_type, type_t->pkg_type)) {
-                               if (type_t->dl_do_pre_exe != NULL) {
-                                       type_t->dl_do_pre_exe((char *)pkg_name,
-                                                             (char *)app_path);
-                                       _D("called dl_do_pre_exe() type: %s",
-                                          pkg_type);
-                               } else {
-                                       _E("no symbol for this type: %s",
-                                          pkg_type);
-                               }
-                       }
-               }
-       }
-
-}
-
-#else
-
-static void __preexec_list_free()
-{
-}
-
-static inline void __preexec_init(int argc, char **argv)
-{
-}
-
-static inline void __preexec_run(const char *pkg_type, const char *pkg_name,
-                                const char *app_path)
-{
-}
-
-#endif
diff --git a/include/access_control.h b/include/access_control.h
deleted file mode 100755 (executable)
index 604b095..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifdef DAC_ACTIVATE
-
-#include <privilege-control.h>
-
-#define INHOUSE_UID     5000
-static inline int __set_access(const char* pkg_name, const char* pkg_type, const char* app_path)
-{
-       return set_app_privilege(pkg_name, pkg_type, app_path);
-}
-
-#else
-
-static inline int __set_access(const char* pkg_name, const char* pkg_type, const char* app_path)
-{
-       return 0;
-}
-
-#endif
-
-
diff --git a/include/app_signal.h b/include/app_signal.h
deleted file mode 100755 (executable)
index 474def5..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __APP_DBUS_H__
-#define __APP_DBUS_H__
-
-#include <glib.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
-#define AUL_DBUS_PATH "/aul/dbus_handler"
-#define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal"
-#define AUL_DBUS_APPDEAD_SIGNAL        "app_dead"
-#define AUL_DBUS_APPLAUNCH_SIGNAL      "app_launch"
-
-#define OPT_VALGRIND_LOGFILE           "--log-file="
-#define OPT_VALGRIND_LOGFILE_FIXED     "--log-file=/tmp/valgrind_result.txt"
-#define PATH_VALGRIND_LOGFILE          "/tmp/valgrind_result.txt"
-#define OPT_VALGRIND_XMLFILE           "--xml-file="
-#define OPT_VALGRIND_XMLFILE_FIXED     "--xml-file=/tmp/valgrind_result.xml"
-#define PATH_VALGRIND_XMLFILE          "/tmp/valgrind_result.xml"
-#define OPT_VALGRIND_MASSIFFILE                "--massif-out-file="
-#define OPT_VALGRIND_MASSIFFILE_FIXED  "--massif-out-file=/tmp/valgrind_result.xml"
-
-#endif
diff --git a/include/app_sock.h b/include/app_sock.h
deleted file mode 100755 (executable)
index 35d400c..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __APP_PKT_H_
-#define __APP_PKT_H_
-
-#include <unistd.h>
-#define __USE_GNU
-#include <sys/socket.h>
-#include <linux/un.h>
-
-enum app_cmd {
-       APP_START,
-       APP_OPEN,
-       APP_RESUME,
-       APP_RESUME_BY_PID,
-       APP_TERM_BY_PID,
-       APP_RESULT,
-       APP_START_RES,
-       APP_CANCEL,
-       APP_KILL_BY_PID,
-       APP_ADD_HISTORY,
-       APP_RUNNING_INFO,
-       APP_RUNNING_INFO_RESULT,
-       APP_IS_RUNNING,
-       APP_GET_APPID_BYPID,
-       APP_GET_APPID_BYPID_OK,
-       APP_GET_APPID_BYPID_ERROR,
-       APP_KEY_EVENT,
-       APP_KEY_RESERVE,
-       APP_KEY_RELEASE,
-       APP_STATUS_UPDATE,
-       APP_RELEASED,
-       APP_RUNNING_LIST_UPDATE
-};
-
-#define AUL_SOCK_PREFIX "/tmp/alaunch"
-#define AUL_SOCK_MAXBUFF 65535
-#define DEBUG_LAUNCHPAD_PID -4
-#define ELOCALLAUNCH_ID 128
-#define EILLEGALACCESS 127
-#define ETERMINATING 126
-
-typedef struct _app_pkt_t {
-       int cmd;
-       int len;
-       unsigned char data[1];
-} app_pkt_t;
-
-int __create_server_sock(int pid);
-int __create_client_sock(int pid);
-int __app_send_raw(int pid, int cmd, unsigned char *kb_data, int datalen);
-int __app_send_raw_with_noreply(int pid, int cmd, unsigned char *kb_data, int datalen);
-app_pkt_t *__app_recv_raw(int fd, int *clifd, struct ucred *cr);
-app_pkt_t *__app_send_cmd_with_result(int pid, int cmd, unsigned char *kb_data, int datalen);
-
-
-#endif
-
diff --git a/include/aul_util.h b/include/aul_util.h
deleted file mode 100755 (executable)
index c6ebb8f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __AUL_UTIL_H_
-#define __AUL_UTIL_H_
-
-#define AUL_UTIL_PID -2
-
-#define MAX_PACKAGE_STR_SIZE 512
-#define MAX_PACKAGE_APP_PATH_SIZE 512
-#define MAX_RUNNING_APP_INFO 512
-
-typedef struct _app_status_info_t{
-       char appid[MAX_PACKAGE_STR_SIZE];
-       char app_path[MAX_PACKAGE_APP_PATH_SIZE];
-       int status;
-       int pid;
-} app_status_info_t;
-
-struct amdmgr {
-       struct appinfomgr *af;  /* appinfo manager */
-       struct cginfo *cg;  /* cgroup infomation */
-};
-
-int _add_app_status_info_list(char *appid, int pid);
-int _update_app_status_info_list(int pid, int status);
-int _remove_app_status_info_list(int pid);
-
-#endif
-
-
-
diff --git a/include/common.h b/include/common.h
new file mode 100644 (file)
index 0000000..487c120
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <ctype.h>
+#include <dlog.h>
+#include <bundle.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#define LOG_TAG "DEBUG_LAUNCHPAD"
+#endif
+
+#define _E(fmt, arg...) LOGE(fmt, ##arg)
+#define _D(fmt, arg...) LOGD(fmt, ##arg)
+#define _W(fmt, arg...) LOGW(fmt, ##arg)
+
+#define SOCKET_PATH "/run/user"
+#define MAX_LOCAL_BUFSZ 128
+#define AUL_SOCK_MAXBUFF 65535
+
+#define PAD_CMD_LAUNCH 0
+
+typedef struct _app_pkt_t {
+       int cmd;
+       int len;
+       unsigned char data[1];
+} app_pkt_t;
+
+typedef struct {
+       char *appid;
+       char *app_path;
+       char *original_app_path;
+       char *debug_appid;
+       char *pkg_type;
+       char *hwacc;
+       char *taskmanage;
+       char *comp_type;
+} appinfo_t;
+
+struct ucred;
+
+int _create_server_sock(void);
+app_pkt_t *_recv_pkt_raw(int fd, int *clifd, struct ucred *cr);
+int _send_pkt_raw(int client_fd, app_pkt_t *pkt);
+
+appinfo_t *_appinfo_create(bundle *kb);
+void _appinfo_free(appinfo_t *appinfo);
+void _modify_bundle(bundle *kb, int caller_pid, appinfo_t *appinfo, int cmd);
+
+void _set_env(appinfo_t *app_info, bundle *kb);
+char **_create_argc_argv(bundle *kb, int *margc, const char *app_path);
+
+char *_proc_get_cmdline_bypid(int pid);
+
+#endif /* __COMMON_H__ */
diff --git a/include/debug_util.h b/include/debug_util.h
new file mode 100644 (file)
index 0000000..4168c95
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DEBUG_UTIL_H__
+#define __DEBUG_UTIL_H__
+
+#include <stdbool.h>
+#include <bundle.h>
+
+bool _gdbserver_is_running(void);
+int _get_gdbserver_pid(void);
+int _get_gdbserver_app_pid(void);
+int _get_valgrind_option(void);
+int _prepare_debug_tool(bundle *kb, const char *appid,
+               const char **str_arr, int len);
+void _change_file(const char *path);
+void _wait_for_valgrind_output(void);
+void _set_env(appinfo_t *app_info, bundle *kb);
+char **_create_argc_argv(bundle *kb, int *margc, const char *app_path);
+
+#endif /* __DEBUG_UTIL_H__ */
diff --git a/include/defs.h b/include/defs.h
new file mode 100644 (file)
index 0000000..8e48b21
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DEFS_H__
+#define __DEFS_H__
+
+#define AUL_K_STARTTIME "__AUL_STARTTIME__"
+#define AUL_K_EXEC "__AUL_EXEC__"
+#define AUL_K_PACKAGETYPE "__AUL_PACKAGETYPE__"
+#define AUL_K_HWACC "__AUL_HWACC__"
+#define AUL_K_APPID "__AUL_APPID__"
+#define AUL_K_PID "__AUL_PID__"
+#define AUL_K_TASKMANAGE "__AUL_TASKMANAGE__"
+#define AUL_K_INTERNAL_POOL "__AUL_INTERNAL_POOL__"
+#define AUL_K_PKGID "__AUL_PKGID_"
+#define AUL_K_DEBUG "__AUL_DEBUG__"
+#define AUL_K_SDK "__AUL_SDK__"
+#define AUL_K_ORG_CALLER_PID "__AUL_ORG_CALLER_PID__"
+#define AUL_K_CALLER_PID "__AUL_CALLER_PID__"
+#define AUL_K_COMP_TYPE "__AUL_COMP_TYPE__"
+#define AUL_K_PRIVACY_APPID "__AUL_PRIVACY_APPID__"
+
+#define SDK_CODE_COVERAGE "CODE_COVERAGE"
+#define SDK_DEBUG "DEBUG"
+#define SDK_DYNAMIC_ANALYSIS "DYNAMIC_ANALYSIS"
+#define SDK_UNIT_TEST "UNIT_TEST"
+#define SDK_VALGRIND "VALGRIND"
+#define SDK_ATTACH "ATTACH"
+
+/* DLP is short for debug-launchpad */
+#define DLP_K_DEBUG_ARG "__DLP_DEBUG_ARG__"
+#define DLP_K_UNIT_TEST_ARG "__DLP_UNIT_TEST_ARG__"
+#define DLP_K_VALGRIND_ARG "__DLP_VALGRIND_ARG__"
+#define DLP_K_ATTACH_ARG "__DLP_ATTACH_ARG__"
+
+#define PATH_GDBSERVER "/home/developer/sdk_tools/gdbserver/gdbserver"
+#define PATH_VALGRIND "/home/developer/sdk_tools/valgrind/usr/bin/valgrind"
+#define PATH_DA_SO "/home/developer/sdk_tools/da/da_probe.so"
+
+#define OPT_VALGRIND_LOGFILE_FIXED "--log-file=/tmp/valgrind_result.txt"
+#define OPT_VALGRIND_XMLFILE_FIXED "--xml-file=/tmp/valgrind_result.xml"
+#define OPT_VALGRIND_MASSIFFILE_FIXED "--massif-out-file=/tmp/valgrind_result.xml"
+#define PATH_VALGRIND_LOGFILE "/tmp/valgrind_result.txt"
+#define PATH_VALGRIND_XMLFILE "/tmp/valgrind_result.xml"
+#define PATH_VALGRIND_MASSIFFILE PATH_VALGRIND_XMLFILE
+
+#endif /* __DEFS_H__ */
+
similarity index 71%
rename from src/fileutils.h
rename to include/file_util.h
index 948c261..dbc158e 100644 (file)
@@ -1,9 +1,5 @@
 /*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- *
  */
 
-#ifndef _FILEUTILS_H_
-#define _FILEUTILS_H_
+#ifndef __FILE_UTIL_H__
+#define __FILE_UTIL_H__
+
+#include <sys/stat.h>
 
 int dlp_chmod(const char *path, mode_t mode, int recursive);
-#endif
 
+#endif /* __FILE_UTIL_H__ */
diff --git a/include/menu_db_util.h b/include/menu_db_util.h
deleted file mode 100755 (executable)
index 2179d85..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include <ail.h>
-#include <string.h>
-#include <stdio.h>
-#include "simple_util.h"
-
-#define MAX_PATH_LEN   1024
-
-#define AUL_APP_INFO_FLD_PKG_NAME              "package"
-#define AUL_APP_INFO_FLD_APP_PATH              "exec"
-#define AUL_APP_INFO_FLD_APP_TYPE              "x_slp_packagetype"
-#define AUL_APP_INFO_FLD_WIDTH                 "x_slp_baselayoutwidth"
-#define AUL_APP_INFO_FLD_HEIGHT                        "x_slp_baselayoutheight"
-#define AUL_APP_INFO_FLD_VERTICAL              "x_slp_ishorizontalscale"
-#define AUL_APP_INFO_FLD_MULTIPLE              "x_slp_multiple"
-#define AUL_APP_INFO_FLD_TASK_MANAGE   "x_slp_taskmanage"
-#define AUL_APP_INFO_FLD_MIMETYPE              "mimetype"
-#define AUL_APP_INFO_FLD_SERVICE               "x_slp_service"
-
-#define AUL_RETRIEVE_PKG_NAME                  "package = '?'"
-#define AUL_RETRIEVE_APP_PATH                  "exec = '?'"
-#define AUL_RETRIEVE_MIMETYPE                  "mimetype like '?'"
-#define AUL_RETRIEVE_SERVICE                   "x_slp_service like '?'"
-
-typedef struct {
-       char *pkg_name;         /* package */
-       char *app_path;         /* exec */
-       char *original_app_path;        /* exec */
-       char *pkg_type;         /* x_slp_packagetype */
-       char *hwacc;            /* hwacceleration */
-} app_info_from_db;
-
-static inline char *_get_pkgname(app_info_from_db *menu_info)
-{
-       return menu_info ? menu_info->pkg_name : NULL;
-}
-
-static inline char *_get_app_path(app_info_from_db *menu_info)
-{
-       int i = 0;
-       int path_len = -1;
-
-       if (!menu_info || menu_info->app_path == NULL)
-               return NULL;
-
-       while (menu_info->app_path[i] != 0) {
-               if (menu_info->app_path[i] == ' '
-                   || menu_info->app_path[i] == '\t') {
-                       path_len = i;
-                       break;
-               }
-               i++;
-       }
-
-       if (path_len == 0) {
-               free(menu_info->app_path);
-               menu_info->app_path = NULL;
-       } else if (path_len > 0) {
-               char *tmp_app_path = malloc(sizeof(char) * (path_len + 1));
-               if(tmp_app_path == NULL)
-                       return NULL;
-               snprintf(tmp_app_path, path_len + 1, "%s", menu_info->app_path);
-               free(menu_info->app_path);
-               menu_info->app_path = tmp_app_path;
-       }
-
-       return menu_info->app_path;
-}
-
-static inline char *_get_original_app_path(app_info_from_db *menu_info)
-{
-       return menu_info ? menu_info->original_app_path : NULL;
-}
-
-static inline void _free_app_info_from_db(app_info_from_db *menu_info)
-{
-       if (menu_info != NULL) {
-               if (menu_info->pkg_name != NULL)
-                       free(menu_info->pkg_name);
-               if (menu_info->app_path != NULL)
-                       free(menu_info->app_path);
-               if (menu_info->original_app_path != NULL)
-                       free(menu_info->original_app_path);
-               if (menu_info->hwacc != NULL)
-                       free(menu_info->hwacc);
-               free(menu_info);
-       }
-}
-
-static inline app_info_from_db *_get_app_info_from_db_by_pkgname(
-                                                       const char *pkgname)
-{
-       app_info_from_db *menu_info;
-       ail_appinfo_h handle;
-       ail_error_e ret;
-       char *str = NULL;
-
-       menu_info = calloc(1, sizeof(app_info_from_db));
-       if (menu_info == NULL) {
-               return NULL;
-       }
-
-       ret = ail_get_appinfo(pkgname, &handle);
-       if (ret != AIL_ERROR_OK) {
-               _free_app_info_from_db(menu_info);
-               return NULL;
-       }
-
-       ret = ail_appinfo_get_str(handle, AIL_PROP_PACKAGE_STR, &str);
-       if (str) {
-               menu_info->pkg_name = strdup(str);      
-               str = NULL;
-       }
-
-       ret = ail_appinfo_get_str(handle, AIL_PROP_EXEC_STR, &str);
-       if (str) {
-               menu_info->app_path = strdup(str);
-               str = NULL;
-       }
-
-       if (menu_info->app_path != NULL)
-               menu_info->original_app_path = strdup(menu_info->app_path);
-
-       ret = ail_appinfo_get_str(handle, AIL_PROP_X_SLP_PACKAGETYPE_STR, &str);
-       if (str) {
-               menu_info->pkg_type = strdup(str);
-               str = NULL;
-       }
-       
-       ret = ail_destroy_appinfo(handle);
-       if (ret != AIL_ERROR_OK) {
-               _E("ail_destroy_appinfo failed");
-       }
-
-       if (!_get_app_path(menu_info)) {
-               _free_app_info_from_db(menu_info);
-               return NULL;
-       }
-
-       return menu_info;
-}
-
-static inline ail_cb_ret_e __appinfo_func(const ail_appinfo_h appinfo, void *user_data)
-{
-       app_info_from_db *menu_info = (app_info_from_db *)user_data;
-       char *package;
-       ail_cb_ret_e ret = AIL_CB_RET_CONTINUE;
-
-       if (!menu_info)
-               return ret;
-
-       ail_appinfo_get_str(appinfo, AIL_PROP_PACKAGE_STR, &package);
-       if (package) {
-               menu_info->pkg_name = strdup(package);
-               ret = AIL_CB_RET_CANCEL;
-       }
-
-       return ret;
-}
-
-static inline app_info_from_db *_get_app_info_from_db_by_apppath(
-                                                       const char *apppath)
-{
-       app_info_from_db *menu_info = NULL;
-       ail_filter_h filter;
-       ail_error_e ret;
-       int count;
-       
-       if (apppath == NULL)
-               return NULL;
-
-       menu_info = calloc(1, sizeof(app_info_from_db));
-       if (menu_info == NULL)
-               return NULL;
-
-       ret = ail_filter_new(&filter);
-       if (ret != AIL_ERROR_OK) {
-               _free_app_info_from_db(menu_info);
-               return NULL;
-       }
-
-       ret = ail_filter_add_str(filter, AIL_PROP_X_SLP_EXE_PATH, apppath);
-       if (ret != AIL_ERROR_OK) {
-               ail_filter_destroy(filter);
-               _free_app_info_from_db(menu_info);
-               return NULL;
-       }
-
-       ret = ail_filter_count_appinfo(filter, &count);
-       if (ret != AIL_ERROR_OK) {
-               ail_filter_destroy(filter);
-               _free_app_info_from_db(menu_info);
-               return NULL;
-       }
-       if (count < 1) {
-               ail_filter_destroy(filter);
-               _free_app_info_from_db(menu_info);
-               return NULL;
-       }
-
-       ail_filter_list_appinfo_foreach(filter, __appinfo_func, (void *)menu_info);
-
-       ail_filter_destroy(filter);
-
-       menu_info->app_path = strdup(apppath);
-       menu_info->original_app_path = strdup(apppath);
-
-       return menu_info;
-       
-}
-
index bec46e8..cfa9f59 100755 (executable)
@@ -1,9 +1,5 @@
 /*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- *
  */
 
-
 #ifndef __PERF_H__
 #define __PERF_H__
 
 #ifdef PERF_ACTIVATE
-
 #include <sys/time.h>
+#include <bundle_internal.h>
+
 static struct timeval __g_base_time = {
        .tv_sec = 0,
        .tv_usec = 0
 };
 
-#define INIT_PERF(kb)\
-do {\
-       const char *tmp;\
-       struct timeval tv;\
-       tmp = bundle_get_val(kb, AUL_K_STARTTIME);\
-       if (tmp != NULL)\
-               sscanf(tmp, "%ld/%ld", &tv.tv_sec, &tv.tv_usec);\
-       else\
-               gettimeofday(&tv, NULL);\
-       __g_base_time.tv_sec = tv.tv_sec;\
-       __g_base_time.tv_usec = tv.tv_usec;\
-} while (0);
-
-#define PERF(fmt, arg...)\
-do {\
-       struct timeval cur;\
-       struct timeval res;\
-       gettimeofday(&cur, NULL);\
-       if (__g_base_time.tv_sec != 0) {\
-               timersub(&cur, &__g_base_time, &res);\
-               printf("%c[1;31m[%s,%d] %ld sec %ld msec "fmt" %c[0m\n",\
-                       27, __FUNCTION__, __LINE__, \
-                               res.tv_sec, res.tv_usec/1000, ##arg, 27);\
-       } \
-} while (0);
-
+#define INIT_PERF(kb) \
+       do { \
+               const char *tmp; \
+               struct timeval tv; \
+               tmp = bundle_get_val(kb, AUL_K_STARTTIME); \
+               if (tmp != NULL) \
+                       sscanf(tmp, "%ld/%ld", &tv.tv_sec, &tv.tv_usec); \
+               else \
+                       gettimeofday(&tv, NULL); \
+               __g_base_time.tv_sec = tv.tv_sec; \
+               __g_base_time.tv_usec = tv.tv_usec; \
+       } while (0)
+
+#define PERF(fmt, arg...) \
+       do { \
+               struct timeval cur; \
+               struct timeval res; \
+               gettimeofday(&cur, NULL); \
+               if (__g_base_time.tv_sec != 0) { \
+                       timersub(&cur, &__g_base_time, &res); \
+                       printf("%c[1;31m[%s,%d] %ld sec %ld msec "fmt" %c[0m\n", \
+                                       27, __FUNCTION__, __LINE__, \
+                                       res.tv_sec, res.tv_usec/1000, ##arg, 27); \
+               } \
+       } while (0)
 #else
-
 #define INIT_PERF(kb)
 #define PERF(fmt, arg...)
-
-#endif
-
 #endif
 
+#endif /* __PERF_H__ */
diff --git a/include/preload.h b/include/preload.h
deleted file mode 100755 (executable)
index b817375..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifdef PRELOAD_ACTIVATE 
-
-#include <dlfcn.h>
-#define PRELOAD_FILE SHARE_PREFIX"/preload_list.txt"
-
-#define EFL_PREINIT_FUNC       "elm_quicklaunch_init"
-#define EFL_SHUTDOWN_FUNC      "elm_quicklaunch_shutdown"
-
-static int preload_initialized = 0;
-static int g_argc;
-static char **g_argv;
-static int max_cmdline_size = 0;
-
-static int (*dl_einit) () = NULL;
-static int (*dl_efini) () = NULL;
-
-static inline void __preload_init(int argc, char **argv)
-{
-       void *handle = NULL;
-       char soname[MAX_LOCAL_BUFSZ];
-       FILE *preload_list;
-       int (*func)() = NULL;
-       int i;
-
-       g_argc = argc;
-       g_argv = argv;
-       for (i = 0; i < argc; i++) {
-               max_cmdline_size += (strlen(argv[i]) + 1);
-       }
-       _D("max_cmdline_size = %d", max_cmdline_size);
-
-       preload_list = fopen(PRELOAD_FILE, "rt");
-       if (preload_list == NULL) {
-               _E("no preload\n");
-               return;
-       }
-
-       while (fgets(soname, MAX_LOCAL_BUFSZ, preload_list) > 0) {
-               soname[strlen(soname) - 1] = 0;
-               handle = dlopen((const char *) soname, RTLD_NOW);
-               if (handle == NULL)
-                       continue;
-               _D("preload %s# - handle : %x\n", soname, handle);
-
-               func = dlsym(handle, EFL_PREINIT_FUNC);
-               if (func != NULL) {
-                       _D("get pre-initialization function\n");
-                       dl_einit = func;
-                       func = dlsym(handle, EFL_SHUTDOWN_FUNC);
-                       if (func != NULL) {
-                               _D("get shutdown function\n");
-                               dl_efini = func;
-                       }
-               }
-       }
-
-       fclose(preload_list);
-       preload_initialized = 1;
-}
-
-static inline int preinit_init()
-{
-       if (dl_einit != NULL)
-               dl_einit(0, NULL);
-       _D("pre-initialzation on");
-       return 0;
-}
-
-static inline int preinit_fini()
-{
-       if (dl_efini != NULL)
-               dl_efini();
-       _D("pre-initialization off");
-       return 0;
-}
-
-/* TODO : how to set cmdline gracefully ?? */
-static inline int __change_cmdline(char *cmdline)
-{
-       if (strlen(cmdline) > max_cmdline_size + 1) {
-               _E("cmdline exceed max size : %d", max_cmdline_size);
-               return -1;
-       }
-
-       memset(g_argv[0], '\0', max_cmdline_size);
-       snprintf(g_argv[0], max_cmdline_size, "%s", cmdline);
-
-       return 0;
-}
-
-static inline void __preload_exec(int argc, char **argv)
-{
-       void *handle = NULL;
-       int (*dl_main) (int, char **);
-
-       if (!preload_initialized)
-               return;
-
-       handle = dlopen(argv[0], RTLD_LAZY | RTLD_GLOBAL);
-       if (handle == NULL) {
-               return;
-       }
-
-       dl_main = dlsym(handle, "main");
-       if (dl_main != NULL) {
-               if (__change_cmdline(argv[0]) < 0) {
-                       _E("change cmdline fail");
-                       return;
-               }
-               dl_main(argc, argv);
-       } else {
-               _E("dlsym not founded. bad preloaded app - check fpie pie");
-       }
-
-       exit(0);
-}
-
-#else
-
-static inline void __preload_init();
-static inline void __preload_exec(int argc, char **argv);
-
-#endif
-
old mode 100755 (executable)
new mode 100644 (file)
similarity index 61%
rename from src/gl.h
rename to include/security_util.h
index dd59c97..61c2a56
--- a/src/gl.h
@@ -1,9 +1,5 @@
 /*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- *
  */
 
+#ifndef __SECURITY_UTIL_H__
+#define __SECURITY_UTIL_H__
 
-#ifdef GL_ACTIVATE
-
-#define USE_ENGINE(engine) setenv("ELM_ENGINE", engine, 1);
-
-#else
-
-#define USE_ENGINE(engine)
-
-#endif
+int _set_smack_access_label(const char *path, const char *label);
+int _apply_smack_rules(const char *subject, const char *object,
+               const char *access_type);
+int _set_access(const char *appid);
 
+#endif /* __SECURITY_UTIL_H__ */
old mode 100755 (executable)
new mode 100644 (file)
similarity index 55%
rename from src/config.h
rename to include/signal_util.h
index 894d6b6..8466ade
@@ -1,9 +1,5 @@
 /*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- *
  */
 
+#ifndef __SIGNAL_UTIL_H__
+#define __SIGNAL_UTIL_H__
+
+#include <sys/signalfd.h>
 
-#define LAUNCHPAD_LOG
-#define DAC_ACTIVATE
-#define PRELOAD_ACTIVATE
-#define PREEXEC_ACTIVATE
-/*#define GL_ACTIVATE*/
-/*#define HEAPDGB_ACTIVATE*/
-/*#define PERF_ACTIVATE*/
+int _send_app_dead_signal(int dead_pid);
+int _send_app_launch_signal(int launch_pid);
+void _debug_launchpad_sigchld(struct signalfd_siginfo *info);
+int _signal_init(void);
+int _signal_get_sigchld_fd(void);
+int _signal_unblock_sigchld(void);
+int _signal_fini(void);
 
+#endif /* __SIGNAL_UTIL_H__ */
diff --git a/include/simple_util.h b/include/simple_util.h
deleted file mode 100755 (executable)
index 83f554d..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#ifndef __SIMPLE_UTIL__
-#define __SIMPLE_UTIL__
-
-#include <unistd.h>
-#include <ctype.h>
-#include <dlog.h>
-
-#ifdef LAUNCHPAD_LOG
-#undef LOG_TAG
-#define LOG_TAG "AUL_PAD"
-#else
-#undef LOG_TAG
-#define LOG_TAG "AUL"
-#endif
-#ifdef AMD_LOG
-#undef LOG_TAG
-#define LOG_TAG "AUL_AMD"
-#endif
-
-
-#define MAX_LOCAL_BUFSZ 128
-#define MAX_PID_STR_BUFSZ 20
-
-#define _E(fmt, arg...) LOGE(fmt, ##arg)
-#define _D(fmt, arg...) LOGD(fmt, ##arg)
-#define _W(fmt, arg...) LOGW(fmt, ##arg)
-
-#define retvm_if(expr, val, fmt, arg...) do { \
-       if (expr) { \
-               _E(fmt, ##arg); \
-               _E("(%s) -> %s() return", #expr, __FUNCTION__); \
-               return (val); \
-       } \
-} while (0)
-
-#define retv_if(expr, val) do { \
-       if (expr) { \
-               _E("(%s) -> %s() return", #expr, __FUNCTION__); \
-               return (val); \
-       } \
-} while (0)
-
-int __proc_iter_cmdline(int (*iterfunc)
-                        (const char *dname, const char *cmdline, void *priv),
-                       void *priv);
-int __proc_iter_pgid(int pgid, int (*iterfunc) (int pid, void *priv),
-                    void *priv);
-char *__proc_get_cmdline_bypid(int pid);
-
-static inline const char *FILENAME(const char *filename)
-{
-       const char *p;
-       const char *r;
-
-       if (!filename)
-               return NULL;
-
-       r = p = filename;
-       while (*p) {
-               if (*p == '/')
-                       r = p + 1;
-               p++;
-       }
-
-       return r;
-}
-
-#endif
diff --git a/packaging/debug-launchpad.service b/packaging/debug-launchpad.service
new file mode 100644 (file)
index 0000000..0b7d052
--- /dev/null
@@ -0,0 +1,6 @@
+[Unit]
+Description=Start the debug preload/preinit daemon
+After=dbus.service ac.service
+
+[Service]
+ExecStart=/usr/bin/debug_launchpad_preloading_preinitializing_daemon
diff --git a/packaging/debug-launchpad.socket b/packaging/debug-launchpad.socket
new file mode 100644 (file)
index 0000000..4c5d81f
--- /dev/null
@@ -0,0 +1,9 @@
+[Unit]
+Description=The debug preload/preinit daemon Socket
+
+[Socket]
+ListenStream=/run/user/%U/.debug-launchpad-sock
+DirectoryMode=0777
+
+[Install]
+WantedBy=sockets.target
old mode 100644 (file)
new mode 100755 (executable)
index 7ccda1f..85494a2
@@ -3,8 +3,10 @@ Summary:    Debug Launchpad
 Version:    0.0.12
 Release:    1
 Group:      System Environment/Daemons
-License:    Apache License, Version 2.0
+License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
+Source1:    debug-launchpad.service
+Source2:    debug-launchpad.socket
 BuildRoot:  %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 Requires(post): /sbin/ldconfig
@@ -14,17 +16,29 @@ Requires(postun): /usr/bin/systemctl
 Requires(preun): /usr/bin/systemctl
 
 BuildRequires:  cmake
+BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(dbus-glib-1)
-BuildRequires:  pkgconfig(sqlite3)
-BuildRequires:  pkgconfig(x11)
 BuildRequires:  pkgconfig(bundle)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(libprivilege-control)
 BuildRequires:  pkgconfig(vconf)
 BuildRequires:  pkgconfig(libsmack)
-BuildRequires:  pkgconfig(aul)
-BuildRequires:  libcap-devel
+BuildRequires:  pkgconfig(pkgmgr-info)
+BuildRequires:  pkgconfig(security-manager)
 
+%if "%{?profile}" == "wearable"
+BuildRequires:  pkgconfig(libsystemd-daemon)
+%define appfw_feature_socket_activation 1
+%else
+%if "%{?profile}" == "mobile"
+BuildRequires:  pkgconfig(libsystemd-daemon)
+%define appfw_feature_socket_activation 1
+%else
+%if "%{?profile}" == "tv"
+%define appfw_feature_socket_activation 0
+%endif
+%endif
+%endif
 
 %description
 Debug launchpad
@@ -33,19 +47,26 @@ Debug launchpad
 %setup -q
 
 %build
-%ifarch %{ix86}
-cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DARCH=x86
-%else
-cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DARCH=arm
+%if 0%{?appfw_feature_socket_activation}
+_APPFW_FEATURE_SOCKET_ACTIVATION=ON
 %endif
+
+cmake  -DCMAKE_INSTALL_PREFIX=%{_prefix} \
+       -D_APPFW_FEATURE_SOCKET_ACTIVATION:BOOL=${_APPFW_FEATURE_SOCKET_ACTIVATION} \
+       .
+
 make %{?jobs:-j%jobs}
 
 %install
 rm -rf %{buildroot}
 %make_install
 
-mkdir -p %{buildroot}/usr/share/license
-cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
+%if 0%{?appfw_feature_socket_activation}
+mkdir -p %{buildroot}%{_unitdir_user}/sockets.target.wants
+install -m 0644 %{SOURCE1} %{buildroot}%{_unitdir_user}/debug-launchpad.service
+install -m 0644 %{SOURCE2} %{buildroot}%{_unitdir_user}/debug-launchpad.socket
+ln -s ../debug-launchpad.socket %{buildroot}%{_unitdir_user}/sockets.target.wants/debug-launchpad.socket
+%endif
 
 %clean
 rm -rf %{buildroot}
@@ -53,5 +74,11 @@ rm -rf %{buildroot}
 %post
 
 %files
-%attr(0755, root, root) %{_bindir}/debug_launchpad_preloading_preinitializing_daemon
-/usr/share/license/%{name}
+%license LICENSE
+%manifest debug-launchpad.manifest
+%caps(cap_mac_admin,cap_mac_override,cap_setgid=ei) %{_bindir}/debug_launchpad_preloading_preinitializing_daemon
+%if 0%{?appfw_feature_socket_activation}
+%{_unitdir_user}/debug-launchpad.service
+%{_unitdir_user}/debug-launchpad.socket
+%{_unitdir_user}/sockets.target.wants/debug-launchpad.socket
+%endif
diff --git a/src/app_sock.c b/src/app_sock.c
deleted file mode 100755 (executable)
index 1029ab4..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/smack.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include "app_sock.h"
-#include "simple_util.h"
-
-static int __connect_client_sock(int sockfd, const struct sockaddr *saptr, socklen_t salen,
-                  int nsec);
-
-
-static inline void __set_sock_option(int fd, int cli)
-{
-       int size;
-       struct timeval tv = { 3, 200 * 1000 };  /*  3.2 sec */
-
-       size = AUL_SOCK_MAXBUFF;
-       setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
-       setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
-       if (cli)
-               setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
-}
-
-int __create_server_sock(int pid)
-{
-       struct sockaddr_un saddr;
-       struct sockaddr_un p_saddr;
-       int fd;
-       mode_t orig_mask;
-
-       /* Create basedir for our sockets */
-       orig_mask = umask(0);
-       (void) mkdir(AUL_SOCK_PREFIX, S_IRWXU | S_IRWXG | S_IRWXO | S_ISVTX);
-       umask(orig_mask);
-
-       fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
-       /*  support above version 2.6.27*/
-       if (fd < 0) {
-               if (errno == EINVAL) {
-                       fd = socket(AF_UNIX, SOCK_STREAM, 0);
-                       if (fd < 0) {
-                               _E("second chance - socket create error");
-                               return -1;
-                       }
-               } else {
-                       _E("socket error");
-                       return -1;
-               }
-       }
-
-       memset(&saddr, 0, sizeof(saddr));
-       saddr.sun_family = AF_UNIX;
-       snprintf(saddr.sun_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, pid);
-       unlink(saddr.sun_path);
-
-       /* labeling to socket for SMACK */
-       if(getuid() == 0) {     // this is meaningful iff current user is ROOT
-               if(smack_fsetlabel(fd, "@", SMACK_LABEL_IPOUT) != 0) {
-                       /* in case of unsupported filesystem on 'socket' */
-                       /* or permission error by using 'emulator', bypass*/
-                       if((errno != EOPNOTSUPP) && (errno != EPERM)) {
-                               _E("labeling to socket(IPOUT) error");
-                               close(fd);
-                               return -1;
-                       }
-               }
-               if(smack_fsetlabel(fd, "*", SMACK_LABEL_IPIN) != 0) {
-                       /* in case of unsupported filesystem on 'socket' */
-                       /* or permission error by using 'emulator', bypass*/
-                       if((errno != EOPNOTSUPP) && (errno != EPERM)) {
-                               _E("labeling to socket(IPIN) error");
-                               close(fd);
-                               return -1;
-                       }
-               }
-       }
-
-       if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
-               _E("bind error");
-               close(fd);
-               return -1;
-       }
-
-       if (chmod(saddr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
-               /* Flawfinder: ignore*/
-               _E("failed to change the socket permission");
-               close(fd);
-               return -1;
-       }
-
-       __set_sock_option(fd, 0);
-
-       if (listen(fd, 128) == -1) {
-               _E("listen error");
-               close(fd);
-               return -1;
-       }
-
-       /* support app launched by shell script */
-       /*if (pid != LAUNCHPAD_PID) {
-               int pgid;
-               pgid = getpgid(pid);
-               if (pgid > 1) {
-                       snprintf(p_saddr.sun_path, UNIX_PATH_MAX, "%s/%d",
-                                AUL_SOCK_PREFIX, pgid);
-                       if (link(saddr.sun_path, p_saddr.sun_path) < 0) {
-                               if (errno == EEXIST)
-                                       _D("pg path - already exists");
-                               else
-                                       _E("pg path - unknown create error");
-                       }
-               }
-       }*/
-
-       return fd;
-}
-
-int __create_client_sock(int pid)
-{
-       int fd = -1;
-       struct sockaddr_un saddr = { 0, };
-       int retry = 1;
-       int ret = -1;
-
-       fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);    
-       /*  support above version 2.6.27*/
-       if (fd < 0) {
-               if (errno == EINVAL) {
-                       fd = socket(AF_UNIX, SOCK_STREAM, 0);
-                       if (fd < 0) {
-                               _E("second chance - socket create error");
-                               return -1;
-                       }
-               } else {
-                       _E("socket error");
-                       return -1;
-               }
-       }
-
-       saddr.sun_family = AF_UNIX;
-       snprintf(saddr.sun_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX, pid);
- retry_con:
-       ret = __connect_client_sock(fd, (struct sockaddr *)&saddr, sizeof(saddr),
-                       100 * 1000);
-       if (ret < -1) {
-               _E("maybe peer not launched or peer daed\n");
-               if (retry > 0) {
-                       usleep(100 * 1000);
-                       retry--;
-                       goto retry_con;
-               }
-       }
-       if (ret < 0) {
-               close(fd);
-               return -1;
-       }
-
-       __set_sock_option(fd, 1);
-
-       return fd;
-}
-
-static int __connect_client_sock(int fd, const struct sockaddr *saptr, socklen_t salen,
-                  int nsec)
-{
-       int flags;
-       int ret;
-       int error;
-       socklen_t len;
-       fd_set readfds;
-       fd_set writefds;
-       struct timeval timeout;
-
-       flags = fcntl(fd, F_GETFL, 0);
-       fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-
-       error = 0;
-       if ((ret = connect(fd, (struct sockaddr *)saptr, salen)) < 0) {
-               if (errno != EAGAIN && errno != EINPROGRESS) {
-                       fcntl(fd, F_SETFL, flags);      
-                       return (-2);
-               }
-       }
-
-       /* Do whatever we want while the connect is taking place. */
-       if (ret == 0)
-               goto done;      /* connect completed immediately */
-
-       FD_ZERO(&readfds);
-       FD_SET(fd, &readfds);
-       writefds = readfds;
-       timeout.tv_sec = 0;
-       timeout.tv_usec = nsec;
-
-       if ((ret = select(fd + 1, &readfds, &writefds, NULL, 
-                       nsec ? &timeout : NULL)) == 0) {
-               close(fd);      /* timeout */
-               errno = ETIMEDOUT;
-               return (-1);
-       }
-
-       if (FD_ISSET(fd, &readfds) || FD_ISSET(fd, &writefds)) {
-               len = sizeof(error);
-               if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
-                       return (-1);    /* Solaris pending error */
-       } else
-               return (-1);    /* select error: sockfd not set*/
-
- done:
-       (void) fcntl(fd, F_SETFL, flags);
-       if (error) {
-               close(fd);
-               errno = error;
-               return (-1);
-       }
-       return (0);
-}
-
-/**
- * @brief      Send data (in raw) to the process with 'pid' via socket
- */
-int __app_send_raw(int pid, int cmd, unsigned char *kb_data, int datalen)
-{
-       int fd;
-       int len;
-       int ret;
-       int res = 0;
-       app_pkt_t *pkt = NULL;
-
-       if (kb_data == NULL || datalen > AUL_SOCK_MAXBUFF - 8) {
-               _E("keybundle error\n");
-               return -EINVAL;
-       }
-
-       _D("pid(%d) : cmd(%d)", pid, cmd);
-
-       fd = __create_client_sock(pid);
-       if (fd < 0)
-               return -ECOMM;
-
-       pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
-       if (NULL == pkt) {
-               _E("Malloc Failed!");
-               return -ENOMEM;
-       }
-       memset(pkt, 0, AUL_SOCK_MAXBUFF);
-
-       pkt->cmd = cmd;
-       pkt->len = datalen;
-       memcpy(pkt->data, kb_data, datalen);
-
-       if ((len = send(fd, pkt, datalen + 8, 0)) != datalen + 8) {
-               _E("sendto() failed - %d %d (errno %d)", len, datalen + 8, errno);
-               if(len > 0) {
-                       while (len != datalen + 8) {
-                               ret = send(fd, &pkt->data[len-8], datalen + 8 - len, 0);
-                               if (ret < 0) {
-                                       _E("second sendto() failed - %d %d (errno %d)", ret, datalen + 8, errno);
-                                       if (errno == EPIPE) {
-                                               _E("pid:%d, fd:%d\n", pid, fd);
-                                       }
-                                       close(fd);
-                                       if (pkt) {
-                                               free(pkt);
-                                               pkt = NULL;
-                                       }
-                                       return -ECOMM;
-                               }
-                               len += ret;
-                               _D("sendto() len - %d %d", len, datalen + 8);
-                       }
-               } else {
-                       if (errno == EPIPE) {
-                               _E("pid:%d, fd:%d\n", pid, fd);
-                       }
-                       close(fd);
-                       if (pkt) {
-                               free(pkt);
-                               pkt = NULL;
-                       }
-                       return -ECOMM;
-               }
-       }
-       if (pkt) {
-               free(pkt);
-               pkt = NULL;
-       }
-
-       len = recv(fd, &res, sizeof(int), 0);
-       if (len == -1) {
-               if (errno == EAGAIN) {
-                       _E("recv timeout \n");
-                       res = -EAGAIN;
-               } else {
-                       _E("recv error\n");
-                       res = -ECOMM;
-               }
-       }
-       close(fd);
-
-       return res;
-}
-
-int __app_send_raw_with_noreply(int pid, int cmd, unsigned char *kb_data, int datalen)
-{
-       int fd;
-       int len;
-       int ret;
-       int res = 0;
-       app_pkt_t *pkt = NULL;
-
-       if (kb_data == NULL || datalen > AUL_SOCK_MAXBUFF - 8) {
-               _E("keybundle error\n");
-               return -EINVAL;
-       }
-
-       _D("pid(%d) : cmd(%d)", pid, cmd);
-
-       fd = __create_client_sock(pid);
-       if (fd < 0)
-               return -ECOMM;
-
-       pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
-       if (NULL == pkt) {
-               _E("Malloc Failed!");
-               return -ENOMEM;
-       }
-       memset(pkt, 0, AUL_SOCK_MAXBUFF);
-
-       pkt->cmd = cmd;
-       pkt->len = datalen;
-       memcpy(pkt->data, kb_data, datalen);
-
-       if ((len = send(fd, pkt, datalen + 8, 0)) != datalen + 8) {
-               _E("sendto() failed - %d %d (errno %d)", len, datalen + 8, errno);
-               if(len > 0) {
-                       while (len != datalen + 8) {
-                               ret = send(fd, &pkt->data[len-8], datalen + 8 - len, 0);
-                               if (ret < 0) {
-                                       _E("second sendto() failed - %d %d (errno %d)", ret, datalen + 8, errno);
-                                       if (errno == EPIPE) {
-                                               _E("pid:%d, fd:%d\n", pid, fd);
-                                       }
-                                       close(fd);
-                                       if (pkt) {
-                                               free(pkt);
-                                               pkt = NULL;
-                                       }
-                                       return -ECOMM;
-                               }
-                               len += ret;
-                               _D("sendto() len - %d %d", len, datalen + 8);
-                       }
-               } else {
-                       if (errno == EPIPE) {
-                               _E("pid:%d, fd:%d\n", pid, fd);
-                       }
-                       close(fd);
-                       if (pkt) {
-                               free(pkt);
-                               pkt = NULL;
-                       }
-                       return -ECOMM;
-               }
-       }
-       if (pkt) {
-               free(pkt);
-               pkt = NULL;
-       }
-
-       close(fd);
-
-       return res;
-}
-
-app_pkt_t *__app_recv_raw(int fd, int *clifd, struct ucred *cr)
-{
-       int len;
-       int ret;
-       struct sockaddr_un aul_addr = { 0, };
-       int sun_size;
-       app_pkt_t *pkt = NULL;
-       int cl = sizeof(struct ucred);
-
-       sun_size = sizeof(struct sockaddr_un);
-
-       if ((*clifd = accept(fd, (struct sockaddr *)&aul_addr,
-                            (socklen_t *) &sun_size)) == -1) {
-               if (errno != EINTR)
-                       _E("accept error");
-               return NULL;
-       }
-
-       if (getsockopt(*clifd, SOL_SOCKET, SO_PEERCRED, cr,
-                      (socklen_t *) &cl) < 0) {
-               _E("peer information error");
-               close(*clifd);
-               return NULL;
-       }
-
-       pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
-       if(pkt == NULL) {
-               close(*clifd);
-               return NULL;
-       }
-       memset(pkt, 0, AUL_SOCK_MAXBUFF);
-
-       __set_sock_option(*clifd, 1);
-
- retry_recv:
-       /* receive single packet from socket */
-       len = recv(*clifd, pkt, AUL_SOCK_MAXBUFF, 0);
-       if (len < 0)
-               if (errno == EINTR)
-                       goto retry_recv;
-
-       if (len < 8) {
-               _E("recv error %d %d", len, pkt->len);
-               free(pkt);
-               close(*clifd);
-               return NULL;
-       }
-
-       while( len != (pkt->len + 8) ) {
-               ret = recv(*clifd, &pkt->data[len-8], AUL_SOCK_MAXBUFF, 0);
-               if (ret < 0) {
-                       _E("recv error %d %d", len, pkt->len);
-                       free(pkt);
-                       close(*clifd);
-                       return NULL;
-               }
-               len += ret;
-               _D("recv len %d %d", len, pkt->len);
-       }
-
-       return pkt;
-}
-
-app_pkt_t *__app_send_cmd_with_result(int pid, int cmd, unsigned char *kb_data, int datalen)
-{
-       int fd;
-       int len;
-       app_pkt_t *pkt = NULL;
-
-       fd = __create_client_sock(pid);
-       if (fd < 0)
-               return NULL;
-
-       pkt = (app_pkt_t *) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
-       if (NULL == pkt) {
-               _E("Malloc Failed!");
-               return NULL;
-       }
-       memset(pkt, 0, AUL_SOCK_MAXBUFF);
-
-       pkt->cmd = cmd;
-       pkt->len = datalen;
-       if(kb_data) {
-               memcpy(pkt->data, kb_data, datalen);
-       }
-
-       if ((len = send(fd, pkt, datalen + 8, 0)) != datalen + 8) {
-               _E("sendto() failed - %d", len);
-               if (errno == EPIPE) {
-                       _E("pid:%d, fd:%d\n", pid, fd);
-               }
-               close(fd);
-
-               free(pkt);
-               return NULL;
-       }
-
-retry_recv:
-       /* receive single packet from socket */
-       len = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0);
-       if (len == -1) {
-               if (errno == EAGAIN) {
-                       _E("recv timeout \n");
-                       free(pkt);
-                       close(fd);
-                       return NULL;
-               } else if (errno == EINTR) {
-                       goto retry_recv;
-               } else {
-                       _E("recv error %s\n", strerror(errno));
-                       free(pkt);
-                       close(fd);
-                       return NULL;
-               }
-       } else
-               _D("recv result  = %d", len);
-       close(fd);
-
-       return pkt;
-}
-
-
diff --git a/src/common.c b/src/common.c
new file mode 100644 (file)
index 0000000..a84ac6a
--- /dev/null
@@ -0,0 +1,759 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/xattr.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <dirent.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#ifdef _APPFW_FEATURE_SOCKET_ACTIVATION
+#include <systemd/sd-daemon.h>
+#endif /* _APPFW_FEATURE_SOCKET_ACTIVATION */
+
+#include "common.h"
+#include "debug_util.h"
+#include "defs.h"
+
+#define MAX_PATH_LEN 1024
+#define BINSH_NAME "/bin/sh"
+#define BINSH_SIZE 7
+#define VALGRIND_NAME "/home/developer/sdk_tools/valgrind/usr/bin/valgrind"
+#define VALGRIND_SIZE 51
+#define BASH_NAME "/bin/bash"
+#define BASH_SIZE 9
+#define OPROFILE_NAME "/usr/bin/oprofile_command"
+#define OPROFILE_SIZE 25
+#define OPTION_VALGRIND_NAME "valgrind"
+#define OPTION_VALGRIND_SIZE 8
+#define MAX_CMD_BUFSZ 1024
+#define PATH_TMP "/tmp"
+#define PATH_DATA "/data"
+#define AUL_PKT_HEADER_SIZE (sizeof(int) + sizeof(int))
+
+static void __set_sock_option(int fd, int cli)
+{
+       int size;
+       struct timeval tv = { 5, 200 * 1000 };  /* 5.2 sec */
+
+       size = AUL_SOCK_MAXBUFF;
+       setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
+       setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+       if (cli)
+               setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+}
+
+#ifdef _APPFW_FEATURE_SOCKET_ACTIVATION
+static int __create_sock_activation(void)
+{
+       int listen_fds;
+
+       listen_fds = sd_listen_fds(0);
+       if (listen_fds == 1)
+               return SD_LISTEN_FDS_START;
+       else if (listen_fds > 1)
+               _E("Too many file descriptors received.");
+       else
+               _E("There is no socket stream");
+
+       return -1;
+}
+#endif /* _APPFW_FEATURE_SOCKET_ACTIVATION */
+
+static int __create_server_socket(void)
+{
+       struct sockaddr_un saddr;
+       int fd;
+
+       fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+       /* support above version 2.6.27 */
+       if (fd < 0) {
+               if (errno == EINVAL) {
+                       fd = socket(AF_UNIX, SOCK_STREAM, 0);
+                       if (fd < 0) {
+                               _E("second chance - socket create error");
+                               return -1;
+                       }
+               } else {
+                       _E("socket error");
+                       return -1;
+               }
+       }
+
+       memset(&saddr, 0, sizeof(saddr));
+       saddr.sun_family = AF_UNIX;
+       snprintf(saddr.sun_path, sizeof(saddr.sun_path),
+                       "%s/%d/.debug-launchpad-sock",
+                       SOCKET_PATH, getuid());
+       unlink(saddr.sun_path);
+
+       if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
+               _E("bind error");
+               close(fd);
+               return -1;
+       }
+
+       if (chmod(saddr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
+               /* Flawfinder: ignore */
+               _E("Failed to change the socket permission");
+               close(fd);
+               return -1;
+       }
+
+       __set_sock_option(fd, 0);
+
+       if (listen(fd, 128) == -1) {
+               _E("listen error");
+               close(fd);
+               return -1;
+       }
+
+       return fd;
+}
+
+int _create_server_sock(void)
+{
+       int fd = -1;
+
+#ifdef _APPFW_FEATURE_SOCKET_ACTIVATION
+       fd = __create_sock_activation();
+#endif /* _APPFW_FEATURE_SOCKET_ACTIAVTION */
+       if (fd < 0) {
+               fd = __create_server_socket();
+               if (fd < 0) {
+                       _E("server sock error %d", fd);
+                       return -1;
+               }
+       }
+
+       return fd;
+}
+
+app_pkt_t *_recv_pkt_raw(int fd, int *clifd, struct ucred *cr)
+{
+       int len;
+       int ret;
+       struct sockaddr_un aul_addr = {0, };
+       int sun_size;
+       app_pkt_t *pkt = NULL;
+       int cl = sizeof(struct ucred);
+       unsigned char buf[AUL_SOCK_MAXBUFF];
+       int cmd;
+       int datalen;
+
+       sun_size = sizeof(struct sockaddr_un);
+
+       if ((*clifd = accept(fd, (struct sockaddr *)&aul_addr,
+                                       (socklen_t *)&sun_size)) == -1) {
+               if (errno != EINTR)
+                       _E("accept error");
+               return NULL;
+       }
+
+       if (getsockopt(*clifd, SOL_SOCKET, SO_PEERCRED, cr,
+                               (socklen_t *)&cl) < 0) {
+               _E("peer information error");
+               close(*clifd);
+               return NULL;
+       }
+
+       __set_sock_option(*clifd, 1);
+
+retry_recv:
+       /* receive header(cmd, datalen) */
+       len = recv(*clifd, buf, AUL_PKT_HEADER_SIZE, 0);
+       if (len < 0)
+               if (errno == EINTR)
+                       goto retry_recv;
+
+       if (len < AUL_PKT_HEADER_SIZE) {
+               _E("recv error");
+               close(*clifd);
+               return NULL;
+       }
+       memcpy(&cmd, buf, sizeof(int));
+       memcpy(&datalen, buf + sizeof(int), sizeof(int));
+
+       /* allocate for a null byte */
+       pkt = (app_pkt_t *)calloc(1, AUL_PKT_HEADER_SIZE + datalen + 1);
+       if (pkt == NULL) {
+               close(*clifd);
+               return NULL;
+       }
+       pkt->cmd = cmd;
+       pkt->len = datalen;
+
+       len = 0;
+       while (len != pkt->len) {
+               ret = recv(*clifd, pkt->data + len, pkt->len - len, 0);
+               if (ret < 0) {
+                       _E("recv error %d %d", len, pkt->len);
+                       free(pkt);
+                       close(*clifd);
+                       return NULL;
+               }
+               len += ret;
+               _D("recv len %d %d", len, pkt->len);
+       }
+
+       return pkt;
+}
+
+int _send_pkt_raw(int client_fd, app_pkt_t *pkt)
+{
+       int send_ret = 0;
+       int pkt_size = 0;
+
+       if (client_fd == -1 || pkt == NULL) {
+               _E("arguments error!");
+               return -1;
+       }
+
+       pkt_size = sizeof(pkt->cmd) + sizeof(pkt->len) + pkt->len;
+
+       send_ret = send(client_fd, pkt, pkt_size, 0);
+       _D("send(%d) : %d / %d", client_fd, send_ret, pkt_size);
+
+       if (send_ret == -1) {
+               _E("send error!");
+               return -1;
+       } else if (send_ret != pkt_size) {
+               _E("send byte fail!");
+               return -1;
+       }
+
+       return 0;
+}
+
+static char *__appinfo_get_app_path(appinfo_t *appinfo)
+{
+       int i = 0;
+       int path_len = -1;
+       char *tmp_app_path;
+
+       if (appinfo == NULL || appinfo->app_path == NULL)
+               return NULL;
+
+       while (appinfo->app_path[i] != 0) {
+               if (appinfo->app_path[i] == ' '
+                               || appinfo->app_path[i] == '\t') {
+                       path_len = i;
+                       break;
+               }
+
+               i++;
+       }
+
+       if (path_len == 0) {
+               free(appinfo->app_path);
+               appinfo->app_path = NULL;
+       } else if (path_len > 0) {
+               tmp_app_path = (char *)malloc(sizeof(char) * (path_len + 1));
+               if (tmp_app_path == NULL)
+                       return NULL;
+
+               snprintf(tmp_app_path, path_len + 1, "%s", appinfo->app_path);
+               free(appinfo->app_path);
+               appinfo->app_path = tmp_app_path;
+       }
+
+       return appinfo->app_path;
+}
+
+appinfo_t *_appinfo_create(bundle *kb)
+{
+       appinfo_t *appinfo;
+       const char *ptr;
+
+       appinfo = (appinfo_t *)calloc(1, sizeof(appinfo_t));
+       if (appinfo == NULL)
+               return NULL;
+
+       ptr = bundle_get_val(kb, AUL_K_APPID);
+       if (ptr)
+               appinfo->appid = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_PACKAGETYPE);
+       if (ptr)
+               appinfo->pkg_type = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_HWACC);
+       if (ptr)
+               appinfo->hwacc = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_PKGID);
+       if (ptr)
+               appinfo->debug_appid = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_TASKMANAGE);
+       if (ptr)
+               appinfo->taskmanage = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_COMP_TYPE);
+       if (ptr)
+               appinfo->comp_type = strdup(ptr);
+       ptr = bundle_get_val(kb, AUL_K_EXEC);
+       if (ptr)
+               appinfo->app_path = strdup(ptr);
+       if (appinfo->app_path)
+               appinfo->original_app_path = strdup(appinfo->app_path);
+
+       if (__appinfo_get_app_path(appinfo) == NULL) {
+               _appinfo_free(appinfo);
+               return NULL;
+       }
+
+       return appinfo;
+}
+
+void _appinfo_free(appinfo_t *appinfo)
+{
+       if (appinfo == NULL)
+               return;
+
+       if (appinfo->appid)
+               free(appinfo->appid);
+       if (appinfo->app_path)
+               free(appinfo->app_path);
+       if (appinfo->original_app_path)
+               free(appinfo->original_app_path);
+       if (appinfo->pkg_type)
+               free(appinfo->pkg_type);
+       if (appinfo->hwacc)
+               free(appinfo->hwacc);
+       if (appinfo->taskmanage)
+               free(appinfo->taskmanage);
+       if (appinfo->debug_appid)
+               free(appinfo->debug_appid);
+       if (appinfo->comp_type)
+               free(appinfo->comp_type);
+
+       free(appinfo);
+}
+
+static int __parse_app_path(const char *arg, char *out, int out_size)
+{
+       register int i;
+       int state = 1;
+       char *start_out = out;
+
+       if (arg == NULL || out == NULL)
+               return 0;
+
+       for (i = 0; out_size > 1; i++) {
+               switch (state) {
+               case 1:
+                       switch (arg[i]) {
+                       case ' ':
+                       case '\t':
+                               state = 5;
+                               break;
+                       case '\0':
+                               state = 7;
+                               break;
+                       case '\"':
+                               state = 2;
+                               break;
+                       case '\\':
+                               state = 4;
+                               break;
+                       default:
+                               *out = arg[i];
+                               out++;
+                               out_size--;
+                               break;
+                       }
+                       break;
+               case 2: /* escape start */
+                       switch (arg[i]) {
+                       case '\0':
+                               state = 6;
+                               break;
+                       case '\"':
+                               state = 1;
+                               break;
+                       default:
+                               *out = arg[i];
+                               out++;
+                               out_size--;
+                               break;
+                       }
+                       break;
+               case 4: /* character escape */
+                       if (arg[i] == '\0')
+                               state = 6;
+                       else {
+                               *out = arg[i];
+                               out++;
+                               out_size--;
+                               state = 1;
+                       }
+                       break;
+               case 5: /* token */
+                       if (out != start_out) {
+                               *out = '\0';
+                               out_size--;
+                               return i;
+                       }
+                       i--;
+                       state = 1;
+                       break;
+               case 6:
+                       return -1;  /* error */
+               case 7: /* terminate */
+                       *out = '\0';
+                       out_size--;
+                       return 0;
+               default:
+                       state = 6;
+                       break;  /* error */
+               }
+       }
+
+       if (out_size == 1)
+               *out = '\0';
+
+       /* Buffer overflow*/
+       return -2;
+}
+
+void _modify_bundle(bundle *kb, int caller_pid, appinfo_t *appinfo, int cmd)
+{
+       char *ptr;
+       char exe[MAX_PATH_LEN];
+       int flag;
+       char key[256];
+       char value[256];
+
+       bundle_del(kb, AUL_K_APPID);
+       bundle_del(kb, AUL_K_EXEC);
+       bundle_del(kb, AUL_K_PACKAGETYPE);
+       bundle_del(kb, AUL_K_HWACC);
+       bundle_del(kb, AUL_K_PKGID);
+       bundle_del(kb, AUL_K_TASKMANAGE);
+       bundle_del(kb, AUL_K_COMP_TYPE);
+
+       /* Parse app_path to retrieve default bundle */
+       if (cmd == PAD_CMD_LAUNCH) {
+               ptr = appinfo->original_app_path;
+               flag = __parse_app_path(ptr, exe, sizeof(exe));
+               if (flag > 0) {
+                       ptr += flag;
+                       SECURE_LOGD("parsing app_path: EXEC - %s", exe);
+
+                       do {
+                               flag = __parse_app_path(ptr, key, sizeof(key));
+                               if (flag <= 0)
+                                       break;
+                               ptr += flag;
+
+                               flag = __parse_app_path(ptr, value, sizeof(value));
+                               if (flag < 0)
+                                       break;
+                               ptr += flag;
+
+                               /* bundle_del(kb, key); */
+                               bundle_add(kb, key, value);
+                       } while (flag > 0);
+               } else if (flag == 0) {
+                       _D("parsing app_path: No arguments");
+               } else {
+                       _D("parsing app_path: Invalid argument");
+               }
+
+       }
+}
+
+static void __set_sdk_env(const char *appid, const char *value)
+{
+       char buf[MAX_LOCAL_BUFSZ];
+       char *token = NULL;
+
+       _D("key: %s / value: %s", AUL_K_SDK, value);
+       /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/
+       /* GCOV_PREFIX contains the prefix to add to the absolute paths */
+       /*      in the object file. Prefix can be absolute, or relative.*/
+       /*      The default is no prefix.  */
+       /* GCOV_PREFIX_STRIP indicates the how many initial directory names */
+       /*      to stripoff the hardwired absolute paths. Default value is 0. */
+       if (strncmp(value, SDK_CODE_COVERAGE, strlen(value)) == 0) {
+               token = strrchr(appid, '.');
+               if (token == NULL)
+                       return;
+               token++;
+
+               snprintf(buf, sizeof(buf), PATH_TMP"/%s"PATH_DATA, token);
+               setenv("GCOV_PREFIX", buf, 1);
+               setenv("GCOV_PREFIX_STRIP", "0", 1);
+       } else if (strncmp(value, SDK_DYNAMIC_ANALYSIS, strlen(value)) == 0) {
+               setenv("LD_PRELOAD", PATH_DA_SO, 1);
+       }
+}
+
+void _set_env(appinfo_t *appinfo, bundle *kb)
+{
+       const char *str;
+       const char **str_array = NULL;
+       int len = 0;
+       int i;
+
+       setenv("PKG_NAME", appinfo->appid, 1);
+
+       str = bundle_get_val(kb, AUL_K_STARTTIME);
+       if (str)
+               setenv("APP_START_TIME", str, 1);
+       if (appinfo->hwacc)
+               setenv("HWACC", appinfo->hwacc, 1);
+       if (appinfo->taskmanage)
+               setenv("TASKMANAGE", appinfo->taskmanage, 1);
+
+       if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY)
+               str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
+       else {
+               str = bundle_get_val(kb, AUL_K_SDK);
+               if (str) {
+                       str_array = &str;
+                       len = 1;
+               }
+       }
+
+       for (i = 0; i < len; i++)
+               __set_sdk_env(appinfo->appid, str_array[i]);
+}
+
+static char **__add_arg(bundle * kb, char **argv, int *margc, const char *key)
+{
+       const char *str = NULL;
+       const char **str_array = NULL;
+       int len = 0;
+       int i;
+       char **new_argv = NULL;
+
+       if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY)
+               str_array = bundle_get_str_array(kb, key, &len);
+       else {
+               str = bundle_get_val(kb, key);
+               if (str) {
+                       str_array = &str;
+                       len = 1;
+               }
+       }
+
+       if (str_array) {
+               if (strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
+                               || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0) {
+                       new_argv = (char **)realloc(argv,
+                                       sizeof(char *) * (*margc + len + 2));
+                       if (new_argv == NULL) {
+                               _E("Failed to realloc (key: %s)", key);
+                               exit(-1);
+                       }
+
+                       for (i = *margc + len + 1; i - (len + 1) >= 0; i--)
+                               new_argv[i] = new_argv[i - (len + 1)];
+
+                       /* need to add new_argv[0] */
+                       for (i = 0; i < len; i++)
+                               new_argv[1 + i] = strdup(str_array[i]);
+
+                       len++; /* gdbserver or valgrind */
+               } else if (strncmp(key, DLP_K_ATTACH_ARG, strlen(key)) == 0) {
+                       new_argv = (char **)malloc((len + 2) * sizeof(char *));
+                       if (new_argv == NULL) {
+                               _E("Failed to malloc (key: %s)", key);
+                               exit(-1);
+                       }
+
+                       for (i = 0; i < len; i++)
+                               new_argv[1 + i] = strdup(str_array[i]);
+
+                       *margc = 0;
+                       len = len + 1;
+               } else {
+                       new_argv = (char **)realloc(argv,
+                                       sizeof(char *) * (*margc + len + 1));
+                       if (new_argv == NULL) {
+                               _E("Failed to realloc (key: %s)", key);
+                               exit(-1);
+                       }
+
+                       for (i = 0; i < len; i++)
+                               new_argv[*margc + i] = strdup(str_array[i]);
+               }
+
+               new_argv[*margc + len] = NULL;
+               *margc += len;
+       } else {
+               if (strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
+                               || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0) {
+                       new_argv = (char **)realloc(argv,
+                                       sizeof(char *) * (*margc + 2));
+                       if (new_argv == NULL) {
+                               _E("Failed to realloc (key: %s)", key);
+                               exit(-1);
+                       }
+
+                       for (i = *margc + 1; i - 1 >= 0; i--)
+                               new_argv[i] = new_argv[i - 1];
+
+                       /* need to add new_argv[0] */
+                       (*margc)++;
+               }
+       }
+
+       if (new_argv == NULL)
+               return argv;
+
+       return new_argv;
+}
+
+char **_create_argc_argv(bundle *kb, int *margc, const char *app_path)
+{
+       char **argv = NULL;
+       char **new_argv = NULL;
+       int argc;
+       int i;
+       char buf[MAX_LOCAL_BUFSZ];
+       const char *str;
+       const char **str_array = NULL;
+       int len = 0;
+
+       argc = bundle_export_to_argv(kb, &argv);
+       if (argv)
+               argv[0] = strdup(app_path);
+       else {
+               _E("bundle_export_to_argv() is failed.");
+               return NULL;
+       }
+
+       if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY)
+               str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
+       else {
+               str = bundle_get_val(kb, AUL_K_SDK);
+               if (str) {
+                       str_array = &str;
+                       len = 1;
+               }
+       }
+
+       for (i = 0; i < len; i++) {
+               if (str_array[i] == NULL)
+                       break;
+
+               if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0) {
+                       if (argv[0])
+                               free(argv[0]);
+                       snprintf(buf, sizeof(buf), "%s.exe", app_path);
+                       /* this code is added because core app don't have '.exe' excutable */
+                       /* if '.exe' not exist then use app_path */
+                       if (access(buf, F_OK) != 0)
+                               argv[0] = strdup(app_path);
+                       else
+                               argv[0] = strdup(buf);
+
+                       new_argv = __add_arg(kb, argv, &argc, DLP_K_DEBUG_ARG);
+                       new_argv[0] = strdup(PATH_GDBSERVER);
+                       argv = new_argv;
+               } else if (strncmp(str_array[i], SDK_VALGRIND, strlen(str_array[i])) == 0) {
+                       new_argv = __add_arg(kb, argv, &argc, DLP_K_VALGRIND_ARG);
+                       new_argv[0] = strdup(PATH_VALGRIND);
+                       argv = new_argv;
+               } else if (strncmp(str_array[i], SDK_UNIT_TEST, strlen(str_array[i])) == 0) {
+                       new_argv = __add_arg(kb, argv, &argc, DLP_K_UNIT_TEST_ARG);
+                       argv = new_argv;
+               } else if (strncmp(str_array[i], SDK_ATTACH, strlen(str_array[i])) == 0) {
+                       new_argv = __add_arg(kb, argv, &argc, DLP_K_ATTACH_ARG);
+                       new_argv[0] = strdup(PATH_GDBSERVER);
+                       argv = new_argv;
+               }
+
+       }
+
+       *margc = argc;
+
+       return argv;
+}
+
+static int __read_proc(const char *path, char *buf, int size)
+{
+       int fd;
+       int ret;
+
+       if (buf == NULL || path == NULL)
+               return -1;
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0)
+               return -1;
+
+       ret = read(fd, buf, size - 1);
+       if (ret <= 0) {
+               close(fd);
+               return -1;
+       } else
+               buf[ret] = 0;
+
+       close(fd);
+
+       return ret;
+}
+
+char *_proc_get_cmdline_bypid(int pid)
+{
+       char buf[MAX_CMD_BUFSZ];
+       int ret;
+       char* ptr = NULL;
+
+       snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
+       ret = __read_proc(buf, buf, sizeof(buf));
+       if (ret <= 0)
+               return NULL;
+
+       /* support app launched by shell script*/
+       if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0)
+               return strdup(&buf[BINSH_SIZE + 1]);
+       else if (strncmp(buf, VALGRIND_NAME, VALGRIND_SIZE) == 0) {
+               /* buf comes with double null-terminated string */
+               while (1) {
+                       while (*ptr)
+                               ptr++;
+                       ptr++;
+
+                       if (!(*ptr))
+                               break;
+
+                       /* ignore trailing "--" */
+                       if (strncmp(ptr, "-", 1) != 0)
+                               break;
+               }
+
+               return strdup(ptr);
+       } else if (strncmp(buf, BASH_NAME, BASH_SIZE) == 0) {
+               if (strncmp(&buf[BASH_SIZE + 1], OPROFILE_NAME, OPROFILE_SIZE) == 0) {
+                       if (strncmp(&buf[BASH_SIZE + OPROFILE_SIZE + 2],
+                                               OPTION_VALGRIND_NAME, OPTION_VALGRIND_SIZE) == 0) {
+                               return strdup(&buf[BASH_SIZE + OPROFILE_SIZE +
+                                               OPTION_VALGRIND_SIZE + 3]);
+                       }
+               }
+       }
+
+       return strdup(buf);
+}
diff --git a/src/debug-launchpad.c b/src/debug-launchpad.c
new file mode 100644 (file)
index 0000000..e951d4d
--- /dev/null
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/signalfd.h>
+#include <linux/limits.h>
+#include <glib.h>
+#include <dlog.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+
+#include "common.h"
+#include "signal_util.h"
+#include "security_util.h"
+#include "file_util.h"
+#include "debug_util.h"
+#include "perf.h"
+#include "defs.h"
+
+#define AUL_PR_NAME 16
+
+static int __real_send(int clifd, int ret)
+{
+       if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
+               if (errno == EPIPE) {
+                       _E("send failed due to EPIPE.\n");
+                       close(clifd);
+                       return -1;
+               }
+
+               _E("send fail to client");
+       }
+
+       close(clifd);
+
+       return 0;
+}
+
+static void __send_result_to_caller(int clifd, int ret, const char* app_path)
+{
+       char *cmdline;
+       int wait_count;
+       int cmdline_changed = 0;
+       int cmdline_exist = 0;
+       char sock_path[PATH_MAX];
+
+       _W("Check app launching");
+
+       if (clifd == -1)
+               return;
+
+       if (ret <= 1) {
+               _E("launching failed");
+               __real_send(clifd, ret);
+               return;
+       }
+
+       /* check normally was launched? */
+       wait_count = 1;
+       do {
+               cmdline = _proc_get_cmdline_bypid(ret);
+               if (cmdline == NULL) {
+                       _E("error founded when being launched with %d", ret);
+                       if (cmdline_exist || cmdline_changed) {
+                               _E("The app process might be terminated while we are wating %d", ret);
+                               break;
+                       }
+               } else if (strcmp(cmdline, app_path) == 0) {
+                       /* Check app main loop is prepared or not */
+                       _D("-- now wait app mainloop creation --");
+                       free(cmdline);
+                       cmdline_changed = 1;
+
+                       snprintf(sock_path, sizeof(sock_path), "%s/%d/%d",
+                                       SOCKET_PATH, getuid(), ret);
+                       if (access(sock_path, F_OK) == 0)
+                               break;
+
+               } else {
+                       _D("-- now wait cmdline changing --");
+                       cmdline_exist = 1;
+                       free(cmdline);
+               }
+
+               usleep(50 * 1000); /* 50ms sleep */
+               wait_count++;
+       } while (wait_count <= 20); /* max 50*20ms will be sleep */
+
+       if ((!cmdline_exist) && (!cmdline_changed)) {
+               _E("abnormally launched");
+               __real_send(clifd, -1); /* abnormally launched*/
+               return;
+       }
+
+       if (!cmdline_changed)
+               _E("process launched, but cmdline not changed");
+
+       if (__real_send(clifd, ret) < 0) {
+               if (kill(ret, SIGKILL) == -1)
+                       _E("Failed to send SIGKILL: %d", errno);
+       }
+
+       return;
+}
+
+static int __prepare_exec(const char *appid, const char *app_path,
+               appinfo_t *appinfo, bundle *kb)
+{
+       char *file_name;
+       char process_name[AUL_PR_NAME];
+       int ret;
+       const char *value;
+
+       /* Set new session ID & new process group ID */
+       /* In linux, child can set new session ID without check permission */
+       setsid();
+
+       /* SET PRIVILEGES */
+       value = bundle_get_val(kb, AUL_K_SDK);
+       if (value && strncmp(value, SDK_ATTACH, strlen(SDK_ATTACH) != 0)) {
+               _D("appid: %s / pkg_type: %s / app_path: %s",
+                               appid, appinfo->pkg_type, app_path);
+               if ((ret = _set_access(appid)) != 0) {
+                       _E("Failed to set privileges - check your package's credential: %d", ret);
+                       return -1;
+               }
+       }
+
+       /* SET DUMPABLE - for coredump */
+       prctl(PR_SET_DUMPABLE, 1);
+
+       /* SET PROCESS NAME */
+       if (app_path == NULL) {
+               _D("app_path should not be NULL - check menu db");
+               return -1;
+       }
+
+       file_name = strrchr(app_path, '/') + 1;
+       if (file_name == NULL) {
+               _D("can't locate file name to execute");
+               return -1;
+       }
+
+       memset(process_name, '\0', AUL_PR_NAME);
+       snprintf(process_name, AUL_PR_NAME, "%s", file_name);
+       prctl(PR_SET_NAME, process_name);
+
+       /* SET ENVIROMENT */
+       _set_env(appinfo, kb);
+
+       return 0;
+}
+
+static int __prepare_fork(bundle *kb, const char *appid)
+{
+       const char *str = NULL;
+       const char **str_array = NULL;
+       int len = 0;
+
+       if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY)
+               str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
+       else {
+               str = bundle_get_val(kb, AUL_K_SDK);
+               if (str) {
+                       str_array = &str;
+                       len = 1;
+               }
+       }
+
+       _prepare_debug_tool(kb, appid, str_array, len);
+
+       return 0;
+}
+
+static int __get_caller_pid(bundle *kb)
+{
+       const char *str;
+       int pid;
+
+       str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
+       if (str)
+               goto end;
+
+       str = bundle_get_val(kb, AUL_K_CALLER_PID);
+       if (str == NULL)
+               return -1;
+
+end:
+       pid = atoi(str);
+       if (pid <= 1)
+               return -1;
+
+       return pid;
+}
+
+static int __redirect_stdfds(int caller_pid)
+{
+       char buf[PATH_MAX];
+       int fd;
+       int ret = 0;
+
+       /* stdout */
+       snprintf(buf, sizeof(buf), "/proc/%d/fd/1", caller_pid);
+       fd = open(buf, O_WRONLY);
+       if (fd < 0) {
+               _E("Failed to open caller(%d) stdout", caller_pid);
+               ret = 1;
+       } else {
+               dup2(fd, 1);
+               close(fd);
+       }
+
+       /* stderr */
+       snprintf(buf, sizeof(buf), "/proc/%d/fd/2", caller_pid);
+       fd = open(buf, O_WRONLY);
+       if (fd < 0) {
+               _E("Failed to open caller(%d) stderr", caller_pid);
+               ret += 2;
+       } else {
+               dup2(fd, 2);
+               close(fd);
+       }
+
+       return ret;
+}
+
+static int __normal_fork_exec(int argc, char **argv)
+{
+       _D("start real fork and exec\n");
+
+       if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
+               if (errno == EACCES)
+                       _E("such a file is no executable - %s", argv[0]);
+               else
+                       _E("unknown executable error - %s", argv[0]);
+
+               return -1;
+       }
+
+       /* never reach */
+       return 0;
+}
+
+static void __real_launch(const char *app_path, bundle *kb)
+{
+       int app_argc;
+       char **app_argv;
+       int i;
+
+       app_argv = _create_argc_argv(kb, &app_argc, app_path);
+       for (i = 0; i < app_argc; i++)
+               _D("input argument %d : %s##", i, app_argv[i]);
+
+       PERF("setup argument done");
+
+       /* Temporary log: launch time checking */
+       LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path);
+
+       __normal_fork_exec(app_argc, app_argv);
+}
+
+static int __start_process(const char *appid, const char *app_path,
+               bundle *kb, appinfo_t *appinfo)
+{
+       char sock_path[PATH_MAX];
+       int pid;
+       int max_fd;
+       int iter_fd;
+
+       if (__prepare_fork(kb, appinfo->debug_appid) < 0)
+               return -1;
+
+       pid = fork();
+       if (pid == 0) {
+               PERF("fork done");
+               _D("lock up test log(no error): fork done");
+
+               _signal_unblock_sigchld();
+               _signal_fini();
+
+               max_fd = sysconf(_SC_OPEN_MAX);
+               for (iter_fd = 3; iter_fd <= max_fd; iter_fd++)
+                       close(iter_fd);
+
+               snprintf(sock_path, sizeof(sock_path), "%s/%d/%d",
+                               SOCKET_PATH, getuid(), getpid());
+               unlink(sock_path);
+
+               if (__redirect_stdfds(__get_caller_pid(kb)))
+                       _E("Failed to redirect caller fds");
+
+               PERF("prepare exec - fisrt done");
+               _D("lock up test log(no error): prepare exec - first done");
+
+               if (__prepare_exec(appid, app_path, appinfo, kb) < 0) {
+                       _E("preparing work fail to launch - can not launch %s", appid);
+                       exit(-1);
+               }
+
+               PERF("prepare exec - second done");
+               _D("lock up test log(no error): prepare exec - second done");
+               __real_launch(app_path, kb);
+
+               exit(-1);
+       }
+
+       _D("==> real launch pid: %d %s", pid, app_path);
+
+       return pid;
+}
+
+static gboolean __handle_sigchld(gpointer data)
+{
+       GPollFD *gpollfd = (GPollFD *)data;
+       int fd = gpollfd->fd;
+       struct signalfd_siginfo siginfo;
+       ssize_t s;
+
+       do {
+               s = read(fd, &siginfo, sizeof(struct signalfd_siginfo));
+               if (s == 0)
+                       break;
+
+               if (s != sizeof(struct signalfd_siginfo)) {
+                       _E("error reading sigchld info");
+                       break;
+               }
+
+               _debug_launchpad_sigchld(&siginfo);
+       } while (s > 0);
+
+       return TRUE;
+}
+
+static gboolean __handle_launch_event(gpointer data)
+{
+       GPollFD *gpollfd = (GPollFD *)data;
+       int fd = gpollfd->fd;
+       bundle *kb = NULL;
+       app_pkt_t *pkt = NULL;
+       appinfo_t *appinfo = NULL;
+       const char *app_path = NULL;
+       int pid = -1;
+       int clifd = -1;
+       struct ucred cr;
+
+       pkt = _recv_pkt_raw(fd, &clifd, &cr);
+       if (pkt == NULL) {
+               _E("packet is NULL");
+               return TRUE;
+       }
+
+       kb = bundle_decode(pkt->data, pkt->len);
+       if (kb == NULL) {
+               _E("bundle decode error");
+               goto end;
+       }
+
+       INIT_PERF(kb);
+       PERF("packet processing start");
+
+       appinfo = _appinfo_create(kb);
+       if (appinfo == NULL) {
+               _E("_appinfo_create() is failed.");
+               goto end;
+       }
+
+       app_path = appinfo->app_path;
+       if (app_path == NULL) {
+               _E("app_path is NULL");
+               goto end;
+       }
+
+       if (app_path[0] != '/') {
+               _E("app_path is not absolute path: %s", app_path);
+               goto end;
+       }
+
+       _D("appid: %s", appinfo->appid);
+       _D("exec: %s", appinfo->app_path);
+       _D("debug appid: %s", appinfo->debug_appid);
+       _D("hwacc: %s", appinfo->hwacc);
+
+       _modify_bundle(kb, cr.pid, appinfo, pkt->cmd);
+       if (appinfo->appid == NULL) {
+               _E("unable to get appid from appinfo");
+               goto end;
+       }
+
+       PERF("get package infomation & modify bundle done");
+
+       pid = __start_process(appinfo->appid, app_path, kb, appinfo);
+
+end:
+       __send_result_to_caller(clifd, pid, app_path);
+
+       if (pid > 0)
+               _send_app_launch_signal(pid);
+       if (appinfo)
+               _appinfo_free(appinfo);
+       if (kb)
+               bundle_free(kb);
+       if (pkt)
+               free(pkt);
+       if (_get_valgrind_option())
+               _wait_for_valgrind_output();
+
+       return TRUE;
+}
+
+static gboolean __glib_check(GSource *src)
+{
+       GSList *fd_list;
+       GPollFD *tmp;
+
+       fd_list = src->poll_fds;
+       do {
+               tmp = (GPollFD *)fd_list->data;
+               if ((tmp->revents & (G_IO_IN | G_IO_PRI | G_IO_HUP | G_IO_NVAL)))
+                       return TRUE;
+               fd_list = fd_list->next;
+       } while (fd_list);
+
+       return FALSE;
+}
+
+static gboolean __glib_dispatch(GSource *src, GSourceFunc callback, gpointer data)
+{
+       return callback(data);
+}
+
+static gboolean __glib_prepare(GSource *src, gint *timeout)
+{
+       return FALSE;
+}
+
+static GSourceFuncs funcs = {
+       .prepare = __glib_prepare,
+       .check = __glib_check,
+       .dispatch = __glib_dispatch,
+       .finalize = NULL
+};
+
+static int __poll_fd(int fd, GSourceFunc callback)
+{
+       int r;
+       GPollFD *gpollfd;
+       GSource *src;
+
+       src = g_source_new(&funcs, sizeof(GSource));
+       if (src == NULL) {
+               _E("out of memory");
+               return -1;
+       }
+
+       gpollfd = (GPollFD *)g_malloc(sizeof(GPollFD));
+       if (gpollfd == NULL) {
+               _E("out of memory");
+               g_source_destroy(src);
+               return -1;
+       }
+
+       gpollfd->fd = fd;
+       gpollfd->events = G_IO_IN;
+
+       g_source_add_poll(src, gpollfd);
+       g_source_set_callback(src, callback, (gpointer)gpollfd, NULL);
+       g_source_set_priority(src, G_PRIORITY_DEFAULT);
+
+       r = g_source_attach(src, NULL);
+       if (r == 0) {
+               g_free(gpollfd);
+               g_source_destroy(src);
+               return -1;
+       }
+
+       return r;
+}
+
+static int __init_sigchld_fd(void)
+{
+       int fd;
+
+       fd = _signal_get_sigchld_fd();
+       if (fd < 0) {
+               _E("Failed to get sigchld fd");
+               return -1;
+       }
+
+       if (__poll_fd(fd, (GSourceFunc)__handle_sigchld) < 0) {
+               close(fd);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int __init_debug_launchpad_fd(int argc, char **argv)
+{
+       int fd;
+
+       /* signal init */
+       _signal_init();
+
+       /* create debug-launchpad socket */
+       fd = _create_server_sock();
+       if (fd < 0) {
+               _E("Failed to create server socket");
+               return -1;
+       }
+
+       if (__poll_fd(fd, (GSourceFunc)__handle_launch_event) < 0) {
+               close(fd);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int __before_loop(int argc, char **argv)
+{
+       if (__init_sigchld_fd() < 0) {
+               _E("Failed to initialize sigchld fd.");
+               return -1;
+       }
+
+       if (__init_debug_launchpad_fd(argc, argv) < 0) {
+               _E("Failed to initialize launchpad fd.");
+               return -1;
+       }
+
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       GMainLoop *loop;
+
+       loop = g_main_loop_new(NULL, FALSE);
+       if (loop == NULL) {
+               _E("Failed to create glib main loop.");
+               return -1;
+       }
+
+       if (__before_loop(argc, argv) < 0) {
+               _E("Failed to initiailze debug-launchapd.");
+               return -1;
+       }
+
+       g_main_loop_run(loop);
+
+       return 0;
+}
diff --git a/src/debug_util.c b/src/debug_util.c
new file mode 100644 (file)
index 0000000..5e9074e
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <pkgmgr-info.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+
+#include "defs.h"
+#include "common.h"
+#include "file_util.h"
+#include "security_util.h"
+#include "debug_util.h"
+
+#define LABEL_SDBD "sdbd"
+#define LABEL_NETWORK "system::debugging_network"
+
+#define POLL_VALGRIND_LOGFILE 0x00000001
+#define POLL_VALGRIND_XMLFILE 0x00000002
+#define POLL_VALGRIND_MASSIFFILE 0x00000004
+
+static int gdbserver_pid = -1;
+static int gdbserver_app_pid = -1;
+static bool gdbserver = false;
+static int valgrind_option = 0;
+
+bool _gdbserver_is_running(void)
+{
+       return gdbserver;
+}
+
+int _get_gdbserver_pid(void)
+{
+       return gdbserver_pid;
+}
+
+int _get_gdbserver_app_pid(void)
+{
+       return gdbserver_app_pid;
+}
+
+int _get_valgrind_option(void)
+{
+       return valgrind_option;
+}
+
+static int __check_pkginfo(const char *appid)
+{
+       int r;
+       bool preload = false;
+       char *storeclientid = NULL;
+       pkgmgrinfo_pkginfo_h handle;
+
+       r = pkgmgrinfo_pkginfo_get_pkginfo(appid, &handle);
+       if (r != PMINFO_R_OK) {
+               _E("Failed to get pkginfo: %s", appid);
+               return -1;
+       }
+
+       r = pkgmgrinfo_pkginfo_is_preload(handle, &preload);
+       if (r != PMINFO_R_OK) {
+               _E("Faield to check preload: %s", appid);
+               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+               return -1;
+       }
+
+       r = pkgmgrinfo_pkginfo_get_storeclientid(handle, &storeclientid);
+       if (r != PMINFO_R_OK) {
+               _E("Failed to get store client id: %s", appid);
+               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+               return -1;
+       }
+
+       if (preload == true || (storeclientid && storeclientid[0] != '\0')) {
+               _E("Debugging is not allowed");
+               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+               return -1;
+       }
+
+       r = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+       if (r != PMINFO_R_OK) {
+               _E("Failed to destroy pkginfo: %s", appid);
+               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+       }
+
+       return 0;
+}
+
+static int __prepare_gdbserver(const char *appid)
+{
+       int r;
+
+       r = __check_pkginfo(appid);
+       if (r < 0)
+               return -1;
+
+       if (_apply_smack_rules(LABEL_SDBD, appid, "w"))
+               _E("Failed to apply smack rule %s %s w", LABEL_SDBD, appid);
+
+       /* fixed debug-as fail issue (grant permission to use 10.0.2.2, 10.0.2.16) */
+       if (_apply_smack_rules(appid, LABEL_NETWORK, "rw"))
+               _E("Failed to apply smack rule %s %s rw", appid, LABEL_NETWORK);
+
+       if (_apply_smack_rules(LABEL_NETWORK, appid, "w"))
+               _E("Failed to apply smack rule %s %s w", LABEL_NETWORK, appid);
+
+       r = dlp_chmod(PATH_GDBSERVER, S_IRUSR | S_IWUSR
+                       | S_IXUSR | S_IRGRP | S_IXGRP
+                       | S_IROTH | S_IXOTH, 1);
+       if (r != 0)
+               _W("Failed to set 755: %s", PATH_GDBSERVER);
+
+       gdbserver = true;
+
+       return 0;
+}
+
+static int __prepare_valgrind(bundle *kb)
+{
+       const char *str;
+       const char **str_arr = NULL;
+       int len = 0;
+       int i;
+
+       if (bundle_get_type(kb, DLP_K_VALGRIND_ARG) & BUNDLE_TYPE_ARRAY)
+               str_arr = bundle_get_str_array(kb, DLP_K_VALGRIND_ARG, &len);
+       else {
+               str = bundle_get_val(kb, DLP_K_VALGRIND_ARG);
+               if (str) {
+                       str_arr = &str;
+                       len = 1;
+               }
+       }
+
+       for (i = 0; i < len; i++) {
+               if (str_arr[i] == NULL)
+                       break;
+
+               if (strncmp(str_arr[i], OPT_VALGRIND_LOGFILE_FIXED,
+                               strlen(OPT_VALGRIND_LOGFILE_FIXED)) == 0) {
+                       valgrind_option |= POLL_VALGRIND_LOGFILE;
+                       if (access(PATH_VALGRIND_LOGFILE, F_OK) == 0) {
+                               if (remove(PATH_VALGRIND_LOGFILE) != 0)
+                                       _W("Failed to remove %s",
+                                               PATH_VALGRIND_LOGFILE);
+                       }
+               } else if (strncmp(str_arr[i], OPT_VALGRIND_XMLFILE_FIXED,
+                               strlen(OPT_VALGRIND_XMLFILE_FIXED)) == 0) {
+                       valgrind_option |= POLL_VALGRIND_XMLFILE;
+                       if (access(PATH_VALGRIND_XMLFILE, F_OK) == 0) {
+                               if (remove(PATH_VALGRIND_XMLFILE) != 0)
+                                       _W("Failed to remove %s",
+                                               PATH_VALGRIND_XMLFILE);
+                       }
+               } else if (strncmp(str_arr[i], OPT_VALGRIND_MASSIFFILE_FIXED,
+                               strlen(OPT_VALGRIND_MASSIFFILE_FIXED)) == 0) {
+                       valgrind_option |= POLL_VALGRIND_MASSIFFILE;
+                       if (access(PATH_VALGRIND_MASSIFFILE, F_OK) == 0) {
+                               if (remove(PATH_VALGRIND_MASSIFFILE) != 0)
+                                       _W("Failed to remove %s",
+                                               PATH_VALGRIND_MASSIFFILE);
+                       }
+               }
+       }
+
+       return 0;
+}
+
+int _prepare_debug_tool(bundle *kb, const char *appid,
+               const char **str_arr, int len)
+{
+       int i;
+
+       if (appid == NULL || str_arr == NULL)
+               return -1;
+
+       gdbserver = false;
+       gdbserver_pid = -1;
+       gdbserver_app_pid = -1;
+       valgrind_option = 0;
+
+       for (i = 0; i < len; i++) {
+               if (str_arr[i] == NULL)
+                       break;
+
+               if (strncmp(str_arr[i], SDK_DEBUG, strlen(SDK_DEBUG)) == 0
+                       || strncmp(str_arr[i], SDK_ATTACH, strlen(SDK_ATTACH)) == 0) {
+                       if (__prepare_gdbserver(appid) < 0)
+                               return -1;
+               } else if (strncmp(str_arr[i], SDK_VALGRIND, strlen(SDK_VALGRIND)) == 0) {
+                       __prepare_valgrind(kb);
+               }
+       }
+
+       return 0;
+}
+
+/* chmod and chsmack to read file without root privilege */
+void _change_file(const char *path)
+{
+       int r;
+
+       r = dlp_chmod(path, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, 0);
+       if (r)
+               _E("Failed to set 644: %s", path);
+
+       r = _set_smack_access_label(path, "*");
+       if (r)
+               _E("Failed to set smack label %s *", path);
+}
+
+void _wait_for_valgrind_output(void)
+{
+       int wait_count = 1;
+
+       do {
+               if (valgrind_option & POLL_VALGRIND_LOGFILE) {
+                       if (access(PATH_VALGRIND_LOGFILE, F_OK) == 0) {
+                               _change_file(PATH_VALGRIND_LOGFILE);
+                               valgrind_option &= ~POLL_VALGRIND_LOGFILE;
+                       }
+               }
+
+               if (valgrind_option & POLL_VALGRIND_XMLFILE) {
+                       if (access(PATH_VALGRIND_XMLFILE, F_OK) == 0) {
+                               _change_file(PATH_VALGRIND_XMLFILE);
+                               valgrind_option &= ~POLL_VALGRIND_XMLFILE;
+                       }
+               }
+
+               if (valgrind_option & POLL_VALGRIND_MASSIFFILE) {
+                       if (access(PATH_VALGRIND_MASSIFFILE, F_OK) == 0) {
+                               _change_file(PATH_VALGRIND_MASSIFFILE);
+                               valgrind_option &= ~POLL_VALGRIND_MASSIFFILE;
+                       }
+               }
+
+               usleep(50 * 1000); /* 50ms */
+               wait_count++;
+       } while (valgrind_option && wait_count <= 10);
+
+       if (valgrind_option)
+               _E("Failed to wait for valgrind output file");
+}
diff --git a/src/file_util.c b/src/file_util.c
new file mode 100644 (file)
index 0000000..eb4cce9
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <fcntl.h>
+
+#include "file_util.h"
+
+static int recurse(const char *path, mode_t mode,
+               int (*fn)(const char *, mode_t, int))
+{
+       struct stat st;
+       char dir[PATH_MAX];
+
+       if (path == NULL)
+               return -1;
+
+       if (lstat(path, &st) == -1)
+               return -1;
+
+       if (strrchr(path, '/') != NULL) {
+               int n = strlen(path)-strlen(strrchr(path, '/'));
+               if (n >= PATH_MAX)
+                       return -1;
+
+               strncpy(dir, path, n);
+               dir[n] = '\0';
+               fn(dir, mode, 1);
+               return 0;
+       }
+
+       return -1;
+}
+
+int dlp_chmod(const char *path, mode_t mode, int recursive)
+{
+       int fd;
+       struct stat lstat_info;
+       struct stat fstat_info;
+#ifdef HAVE_WIN32_PROC
+       fprintf(stderr, "error: dlp_chmod not implemented on Win32 (%s)\n", path);
+       return -1;
+#else
+
+       if (lstat(path, &lstat_info) == -1)
+               return -1;
+
+       fd = open(path, O_WRONLY, S_IRWXU);
+       if (fd == -1)
+               return -1;
+
+       if (fstat(fd, &fstat_info) == -1) {
+               close(fd);
+               return -1;
+       }
+
+       /* this complex check is required because of 'chmod' security issue. */
+       /* otherwise hacker can change other file's permission by using race condition and symbolic link. */
+       if (lstat_info.st_mode == fstat_info.st_mode
+                       && lstat_info.st_ino == fstat_info.st_ino
+                       && lstat_info.st_dev == fstat_info.st_dev) {
+               if (fchmod(fd, mode) == -1) {
+                       close(fd);
+                       return -1;
+               }
+       }
+
+       close(fd);
+
+       if (recursive)
+               return recurse(path, mode, dlp_chmod);
+
+       return 0;
+#endif
+}
diff --git a/src/fileutils.c b/src/fileutils.c
deleted file mode 100644 (file)
index 061d437..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <limits.h>
-
-static int recurse(const char *path, mode_t mode, int (*fn)(const char *,mode_t, int)) {
-    struct stat st;
-    char dir[PATH_MAX];
-
-    if (path == NULL) {
-        return -1;
-    }
-    if (lstat (path, &st) == -1) {
-        return -1;
-    }
-    if (strrchr(path, '/') != NULL) {
-        int n = strlen(path)-strlen(strrchr(path, '/'));
-        if (n >= PATH_MAX) {
-            return -1;
-        }
-        strncpy(dir, path, n);
-        dir[n] = '\0';
-        fn(dir, mode,1);
-        return 0;
-    }
-    return -1;
-}
-
-int dlp_chmod(const char *path, mode_t mode, int recursive) {
-#ifdef HAVE_WIN32_PROC
-    fprintf(stderr, "error: dlp_chmod not implemented on Win32 (%s)\n", path);
-    return -1;
-#else
-    struct stat st;
-
-    if (stat (path, &st) == -1)
-        return -1;
-
-    if (chmod (path, mode) == -1) {
-        return -1;
-    }
-    if (recursive) {
-        return recurse(path, mode, dlp_chmod);
-    }
-    return 0;
-#endif
-}
diff --git a/src/heap_dbg.h b/src/heap_dbg.h
deleted file mode 100755 (executable)
index cc51fd8..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include <malloc.h>
-#include <stdio.h>
-#include <signal.h>
-
-#ifdef HEAPDGB_ACTIVATE
-
-#define HOOK_RESET()   \
-do {\
-       __malloc_hook = old_malloc_hook; \
-       __free_hook = old_free_hook;    \
-} while (0);
-
-#define HOOK_SET()     \
-do {\
-       __malloc_hook = my_malloc;      \
-       __free_hook = my_free;          \
-} while (0);
-
-static void *(*old_malloc_hook) (size_t size, const void *caller);
-static void *(*old_realloc_hook) (void *ptr, size_t size, const void *caller);
-static void (*old_free_hook) (void *ptr, const void *caller);
-
-static void *my_malloc(size_t size, const void *caller);
-static void *my_realloc(void *ptr, size_t size, const void *caller);
-static void my_free(void *ptr, const void *caller);
-
-static void my_free(void *ptr, const void *caller)
-{
-       void *callstack_addrs[20];
-       char **callstack_strings;
-       int i;
-
-       HOOK_RESET();
-
-       printf("%c[1;31m[FREE] %x %x", 27, ptr, caller);
-       printf("%c[0m\n", 27);
-       free(ptr);
-
-       HOOK_SET();
-
-}
-
-static void *my_malloc(size_t size, const void *caller)
-{
-       void *ptr;
-
-       HOOK_RESET();
-
-       ptr = malloc(size);
-       printf("%c[1;31m[MALLOC] %x %x", 27, ptr, caller);
-       printf("%c[0m\n", 27);
-
-       HOOK_SET();
-
-       return ptr;
-}
-
-static void malloc_init(void)
-{
-       old_malloc_hook = __malloc_hook;
-       old_free_hook = __free_hook;
-
-       HOOK_SET();
-}
-
-__attribute__ ((visibility("default")))
-void (*__malloc_initialize_hook) (void) = malloc_init;
-
-#else
-
-#endif
diff --git a/src/launchpad.c b/src/launchpad.c
deleted file mode 100755 (executable)
index feb124f..0000000
+++ /dev/null
@@ -1,1363 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-/*
- * simple AUL daemon - launchpad 
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <dlfcn.h>
-#include <X11/Xlib.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-#include <poll.h>
-#include <sys/prctl.h>
-#include <malloc.h>
-
-#include "app_sock.h"
-#include "aul.h"
-
-#include "config.h"
-
-#include "menu_db_util.h"
-#include "simple_util.h"
-#include "access_control.h"
-#include "preload.h"
-#include "preexec.h"
-#include "perf.h"
-#include "sigchild.h"
-#include "aul_util.h"
-
-#include "heap_dbg.h"
-
-#include "gl.h"
-
-#include <sqlite3.h>
-#include <sys/smack.h>
-#include "fileutils.h"
-#include <sys/capability.h>
-
-#define _static_ static inline
-#define POLLFD_MAX 1
-#define SQLITE_FLUSH_MAX       (1048576)       /* (1024*1024) */
-#define AUL_POLL_CNT           15
-#define AUL_PR_NAME                    16
-#define APPID_LEN      10
-#define PATH_TMP "/tmp"
-#define PATH_DATA "/data"
-
-#define SDK_CODE_COVERAGE "CODE_COVERAGE"
-#define SDK_DEBUG "DEBUG"
-#define SDK_DYNAMIC_ANALYSIS "DYNAMIC_ANALYSIS"
-#define SDK_UNIT_TEST "UNIT_TEST"
-#define SDK_VALGRIND "VALGRIND"
-#define SDK_LD_FLAG "LD_FLAG"
-
-/* DLP is short for debug-launchpad */
-#define DLP_K_DEBUG_ARG "__DLP_DEBUG_ARG__"
-#define DLP_K_UNIT_TEST_ARG "__DLP_UNIT_TEST_ARG__"
-#define DLP_K_VALGRIND_ARG "__DLP_VALGRIND_ARG__"
-#define DLP_K_LD_FLAG "__DLP_LD_FLAG__"
-
-#define PATH_GDBSERVER "/home/developer/sdk_tools/gdbserver/gdbserver"
-#define PATH_VALGRIND  "/home/developer/sdk_tools/valgrind/usr/bin/valgrind"
-#define PATH_DA_SO     "/usr/lib/da_probe_tizen.so"
-#define PATH_NATIVE_APP        "/opt/apps/"
-
-#if (ARCH==arm)
-#define PATH_MEMCHECK  "/opt/home/developer/sdk_tools/valgrind/usr/lib/valgrind/memcheck-arm-linux"
-#elif (ARCH==x86)
-#define PATH_MEMCHECK  "/opt/home/developer/sdk_tools/valgrind/usr/lib/valgrind/memcheck-x86-linux"
-#endif
-
-#define POLL_VALGRIND_LOGFILE          0x00000001
-#define POLL_VALGRIND_XMLFILE          0x00000002
-
-#define CAPABILITY_SET_ORIGINAL                0
-#define CAPABILITY_SET_INHERITABLE     1
-
-static int need_to_set_inh_cap_after_fork = 0;
-static char *launchpad_cmdline;
-static int initialized = 0;
-
-static int poll_outputfile = 0;
-static int is_gdbserver_launched;
-
-void __set_oom();
-void __set_env(app_info_from_db * menu_info, bundle * kb);
-int __prepare_exec(const char *pkg_name,
-                           const char *app_path, app_info_from_db * menu_info,
-                           bundle * kb);
-int __fake_launch_app(int cmd, int pid, bundle * kb);
-char **__create_argc_argv(bundle * kb, int *margc, const char *app_path);
-int __normal_fork_exec(int argc, char **argv);
-void __real_launch(const char *app_path, bundle * kb);
-static inline int __parser(const char *arg, char *out, int out_size);
-void __modify_bundle(bundle * kb, int caller_pid,
-                           app_info_from_db * menu_info, int cmd);
-int __send_to_sigkill(int pid);
-int __term_app(int pid);
-void __real_send(int clifd, int ret);
-void __send_result_to_caller(int clifd, int ret);
-void __launchpad_main_loop(int main_fd);
-int __launchpad_pre_init(int argc, char **argv);
-int __launchpad_post_init();
-
-extern ail_error_e ail_db_close(void);
-
-
-
-void __set_oom()
-{
-       char buf[MAX_LOCAL_BUFSZ];
-       FILE *fp;
-
-       /* we should reset oomadj value as default because child 
-       inherits from parent oom_adj*/
-       snprintf(buf, MAX_LOCAL_BUFSZ, "/proc/%d/oom_adj", getpid());
-       fp = fopen(buf, "w");
-       if (fp == NULL)
-               return;
-       fprintf(fp, "%d", -16);
-       fclose(fp);
-}
-
-void __set_sdk_env(app_info_from_db* menu_info, char* str, bundle * kb) {
-       char buf_pkgname[MAX_LOCAL_BUFSZ];
-       char buf[MAX_LOCAL_BUFSZ];
-       int ret;
-
-       _D("key : %s / value : %s", AUL_K_SDK, str);
-       /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/
-       /* GCOV_PREFIX contains the prefix to add to the absolute paths */
-       /*      in the object file. Prefix can be absolute, or relative.*/
-       /*      The default is no prefix.  */
-       /* GCOV_PREFIX_STRIP indicates the how many initial directory names */
-       /*      to stripoff the hardwired absolute paths. Default value is 0. */
-       if (strncmp(str, SDK_CODE_COVERAGE, strlen(str)) == 0) {
-               strncpy(buf_pkgname,_get_pkgname(menu_info),MAX_LOCAL_BUFSZ-1);
-               buf_pkgname[MAX_LOCAL_BUFSZ-1]='\0';
-               snprintf(buf, MAX_LOCAL_BUFSZ, PATH_TMP"/%s"PATH_DATA
-                       , strtok(buf_pkgname,"."));
-               ret = setenv("GCOV_PREFIX", buf, 1);
-               _D("GCOV_PREFIX : %d", ret);
-               ret = setenv("GCOV_PREFIX_STRIP", "0", 1);
-               _D("GCOV_PREFIX_STRIP : %d", ret);
-       }
-       else if (strncmp(str, SDK_DYNAMIC_ANALYSIS, strlen(str)) == 0)
-       {
-               ret = setenv("LD_PRELOAD", PATH_DA_SO, 1);
-               _D("LD_PRELOAD : %d", ret);
-       }
-       else if (strncmp(str, SDK_LD_FLAG, strlen(str)) == 0)
-       {
-               const char *flag_str = NULL;
-               const char **flag_str_array = NULL;
-               int flag_len;
-               if(bundle_get_type(kb, DLP_K_LD_FLAG) & BUNDLE_TYPE_ARRAY) {
-                       flag_str_array = bundle_get_str_array(kb, DLP_K_LD_FLAG, &flag_len);
-               } else {
-                       flag_str = bundle_get_val(kb, DLP_K_LD_FLAG);
-                       if(flag_str) {
-                               flag_str_array = &flag_str;
-                               flag_len = 1;
-                       }
-               }
-               if(flag_str_array != NULL) {
-                       int i;
-                       char * f_name;
-                       char * f_value;
-                       for (i = 0; i < flag_len; i++) {
-                               strncpy(buf,flag_str_array[i],MAX_LOCAL_BUFSZ);
-                               f_name = strtok(buf,"=");
-                               f_value = strtok(NULL,"=");
-                               if(f_value) {
-                                       ret = setenv(f_name,f_value,1);
-                                       _D("LD_FLAG : %s %s %d",f_name,f_value,ret);
-                               } else {
-                                       _E("LD_FLAG : Wrong option! %s", flag_str_array[i]);
-                               }
-                       }
-               }
-
-       }
-}
-
-
-void __set_env(app_info_from_db * menu_info, bundle * kb)
-{
-       const char *str;
-       const char **str_array;
-       int len;
-       int i;
-
-       setenv("PKG_NAME", _get_pkgname(menu_info), 1);
-
-       USE_ENGINE("gl")
-
-       str = bundle_get_val(kb, AUL_K_STARTTIME);
-       if (str != NULL)
-               setenv("APP_START_TIME", str, 1);
-
-       if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
-               str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
-               if(str_array != NULL) {
-                       for (i = 0; i < len; i++) {
-                               _D("index : [%d]", i);
-                               __set_sdk_env(menu_info, (char *)str_array[i], kb);
-                       }
-               }
-       } else {
-               str = bundle_get_val(kb, AUL_K_SDK);
-               if(str != NULL) {
-                       __set_sdk_env(menu_info, (char *)str, kb);
-               }
-       }
-       if (menu_info->hwacc != NULL)
-               setenv("HWACC", menu_info->hwacc, 1);
-}
-
-int __prepare_exec(const char *pkg_name,
-                           const char *app_path, app_info_from_db * menu_info,
-                           bundle * kb)
-{
-       char *file_name;
-       char process_name[AUL_PR_NAME];
-       int ret;
-
-       /* Set new session ID & new process group ID*/
-       /* In linux, child can set new session ID without check permission */
-       /* TODO : should be add to check permission in the kernel*/
-       setsid();
-
-       __preexec_run(menu_info->pkg_type, pkg_name, app_path);
-
-       /* SET OOM*/
-       __set_oom();
-
-       /* SET PRIVILEGES*/
-       if(bundle_get_val(kb, AUL_K_PRIVACY_APPID) == NULL) {
-               _D("pkg_name : %s / pkg_type : %s / app_path : %s ", pkg_name
-                       , menu_info->pkg_type, app_path);
-               if ((ret = __set_access(pkg_name, menu_info->pkg_type
-                       , app_path)) < 0) 
-               {
-                        _D("fail to set privileges - check your package's credential : %d\n"
-                               , ret);
-                       return -1;
-               }
-       }
-       /* SET DUMPABLE - for coredump*/
-       prctl(PR_SET_DUMPABLE, 1);
-
-       /* SET PROCESS NAME*/
-       if (app_path == NULL) {
-               _D("app_path should not be NULL - check menu db");
-               return -1;
-       }
-       file_name = strrchr(app_path, '/') + 1;
-       if (file_name == NULL) {
-               _D("can't locate file name to execute");
-               return -1;
-       }
-       memset(process_name, '\0', AUL_PR_NAME);
-       snprintf(process_name, AUL_PR_NAME, "%s", file_name);
-       prctl(PR_SET_NAME, process_name);
-
-       /* SET ENVIROMENT*/
-       __set_env(menu_info, kb);
-
-       return 0;
-}
-
-int __fake_launch_app(int cmd, int pid, bundle * kb)
-{
-       int datalen;
-       int ret;
-       bundle_raw *kb_data;
-
-       bundle_encode(kb, &kb_data, &datalen);
-       if ((ret = __app_send_raw(pid, cmd, kb_data, datalen)) < 0)
-               _E("error request fake launch - error code = %d", ret);
-       free(kb_data);
-       return ret;
-}
-
-char** __add_arg(bundle * kb, char **argv, int *margc, const char *key)
-{
-       const char *str = NULL;
-       const char **str_array = NULL;
-       int len = 0;
-       int i;
-       char ** new_argv = NULL;
-
-       if(bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
-               str_array = bundle_get_str_array(kb, key, &len);
-       } else {
-               str = bundle_get_val(kb, key);
-               if(str) {
-                       str_array = &str;
-                       len = 1;
-               }
-       }
-       if(str_array != NULL) {
-               if(strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
-                       || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0)
-               {
-                       new_argv = (char **) realloc(argv
-                               , sizeof(char *) * (*margc+len+2));
-                       if(!new_argv) {
-                               _E("realloc fail (key = %s)", key);
-                               exit(-1);
-                       }
-                       for(i=*margc+len+1; i-(len+1)>=0; i--) {
-                               new_argv[i] = new_argv[i-(len+1)];
-                       }
-                       // need to add new_argv[0]
-                       for(i=0; i<len; i++) {
-                               new_argv[1+i] = strdup(str_array[i]);
-                       }
-                       len++;  /* gdbserver or valgrind */
-                       _D("uid : %d", getuid());
-                       _D("euid : %d", geteuid());
-                       _D("gid : %d", getgid());
-                       _D("egid : %d", getegid());
-               } else {
-                       new_argv = (char **) realloc(argv
-                               , sizeof(char *) * (*margc+len+1));
-                       if(!new_argv) {
-                               _E("realloc fail (key = %s)", key);
-                               exit(-1);
-                       }
-                       for(i=0; i<len; i++) {
-                               new_argv[*margc+i] = strdup(str_array[i]);
-                       }
-               }
-               new_argv[*margc+len] = NULL;
-               *margc += len;
-       } else {
-               if(strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
-                       || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0)
-               {
-                       new_argv = (char **) realloc(argv
-                               , sizeof(char *) * (*margc+2));
-                       if(!new_argv) {
-                               _E("realloc fail (key = %s)", key);
-                               exit(-1);
-                       }
-                       for(i=*margc+1; i-1>=0; i--) {
-                               new_argv[i] = new_argv[i-1];
-                       }
-                       // need to add new_argv[0]
-                       (*margc)++;
-               }
-       }
-
-       if(new_argv==NULL) return argv;
-       return new_argv;
-}
-
-char **__create_argc_argv(bundle * kb, int *margc, const char *app_path)
-{
-       char **argv = NULL;
-       char **new_argv = NULL;
-       int argc;
-
-       const char *str = NULL;
-       const char **str_array = NULL;
-       int len = 0;
-       int i;
-
-       argc = bundle_export_to_argv(kb, &argv);
-       if (argv) {
-               for(i=1; i<argc; i++) {
-                       argv[i] = strdup(argv[i]);
-               }
-               argv[0] = strdup(app_path);
-       } else {
-               _E("bundle_export_to_argv error");
-               exit(-1);
-       }
-
-       if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
-               str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
-       } else {
-               str = bundle_get_val(kb, AUL_K_SDK);
-               if(str) {
-                       str_array = &str;
-                       len = 1;
-               }
-       }
-       if(str_array == NULL) {
-               *margc = argc;
-               return argv;
-       }
-
-       for (i = 0; i < len; i++) {
-               if(str_array[i] == NULL) break;
-               _D("index : [%d]", i);
-               /* gdbserver */
-               if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0)
-               {
-                       char buf[MAX_LOCAL_BUFSZ];
-                       if (argv[0]) free(argv[0]);
-                       snprintf(buf,MAX_LOCAL_BUFSZ,"%s.exe",app_path);
-                       argv[0] = strdup(buf);
-                       new_argv = __add_arg(kb, argv, &argc, DLP_K_DEBUG_ARG);
-                       new_argv[0] = strdup(PATH_GDBSERVER);
-                       argv = new_argv;
-               }
-               /* valgrind */
-               else if (strncmp(str_array[i], SDK_VALGRIND
-                       , strlen(str_array[i])) == 0)
-               {
-                       new_argv = __add_arg(kb, argv, &argc
-                               , DLP_K_VALGRIND_ARG);
-                       new_argv[0] = strdup(PATH_VALGRIND);
-                       argv = new_argv;
-               }
-               /* unit test */
-               else if (strncmp(str_array[i], SDK_UNIT_TEST
-                       , strlen(str_array[i])) == 0)
-               {
-                       new_argv = __add_arg(kb, argv, &argc
-                               , DLP_K_UNIT_TEST_ARG);
-                       argv = new_argv;
-               }
-       }
-
-       *margc = argc;
-       if(new_argv==NULL) return argv;
-       return new_argv;
-}
-
-int __normal_fork_exec(int argc, char **argv)
-{
-       _D("start real fork and exec\n");
-
-       if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
-               if (errno == EACCES) {
-                       _E("such a file is no executable - %s", argv[0]);
-               } else {
-                       _E("unknown executable error - %s", argv[0]);
-               }
-               return -1;
-       }
-       /* never reach */
-       return 0;
-}
-
-void __real_launch(const char *app_path, bundle * kb)
-{
-       int app_argc;
-       char **app_argv;
-       int i;
-
-       app_argv = __create_argc_argv(kb, &app_argc, app_path);
-
-       for (i = 0; i < app_argc; i++)
-               _D("input argument %d : %s##", i, app_argv[i]);
-
-       PERF("setup argument done");
-       _D("lock up test log(no error) : setup argument done");
-
-       /* Temporary log: launch time checking */
-       LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path);
-
-       __normal_fork_exec(app_argc, app_argv);
-
-       for(i=0; i<app_argc; i++) {
-               if(app_argv[i]) free(app_argv[i]);
-       }
-       free(app_argv);
-}
-
-
-/*
- * Parsing original app path to retrieve default bundle
- *
- * -1 : Invalid sequence
- * -2 : Buffer overflow
- *
- */
-static inline int __parser(const char *arg, char *out, int out_size)
-{
-       register int i;
-       int state = 1;
-       char *start_out = out;
-
-       if (arg == NULL || out == NULL) {
-               /* Handles null buffer*/
-               return 0;
-       }
-
-       for (i = 0; out_size > 1; i++) {
-               switch (state) {
-               case 1:
-                       switch (arg[i]) {
-                       case ' ':
-                       case '\t':
-                               state = 5;
-                               break;
-                       case '\0':
-                               state = 7;
-                               break;
-                       case '\"':
-                               state = 2;
-                               break;
-                       case '\\':
-                               state = 4;
-                               break;
-                       default:
-                               *out = arg[i];
-                               out++;
-                               out_size--;
-                               break;
-                       }
-                       break;
-               case 2: /* escape start*/
-                       switch (arg[i]) {
-                       case '\0':
-                               state = 6;
-                               break;
-                       case '\"':
-                               state = 1;
-                               break;
-                       default:
-                               *out = arg[i];
-                               out++;
-                               out_size--;
-                               break;
-                       }
-                       break;
-               case 4: /* character escape*/
-                       if (arg[i] == '\0') {
-                               state = 6;
-                       } else {
-                               *out = arg[i];
-                               out++;
-                               out_size--;
-                               state = 1;
-                       }
-                       break;
-               case 5: /* token*/
-                       if (out != start_out) {
-                               *out = '\0';
-                               out_size--;
-                               return i;
-                       }
-                       i--;
-                       state = 1;
-                       break;
-               case 6:
-                       return -1;      /* error*/
-               case 7: /* terminate*/
-                       *out = '\0';
-                       out_size--;
-                       return 0;
-               default:
-                       state = 6;
-                       break;  /* error*/
-               }
-       }
-
-       if (out_size == 1) {
-               *out = '\0';
-       }
-       /* Buffer overflow*/
-       return -2;
-}
-
-void __modify_bundle(bundle * kb, int caller_pid,
-                           app_info_from_db * menu_info, int cmd)
-{
-       bundle_del(kb, AUL_K_PKG_NAME);
-       bundle_del(kb, AUL_K_EXEC);
-       bundle_del(kb, AUL_K_PACKAGETYPE);
-       bundle_del(kb, AUL_K_HWACC);
-
-       /* Parse app_path to retrieve default bundle*/
-       if (cmd == APP_START || cmd == APP_START_RES || cmd == APP_OPEN
-               || cmd == APP_RESUME)
-       {
-               char *ptr;
-               char exe[MAX_PATH_LEN];
-               int flag;
-
-               ptr = _get_original_app_path(menu_info);
-
-               flag = __parser(ptr, exe, sizeof(exe));
-               if (flag > 0) {
-                       char key[256];
-                       char value[256];
-
-                       ptr += flag;
-                       _D("parsing app_path: EXEC - %s\n", exe);
-
-                       do {
-                               flag = __parser(ptr, key, sizeof(key));
-                               if (flag <= 0)
-                                       break;
-                               ptr += flag;
-
-                               flag = __parser(ptr, value, sizeof(value));
-                               if (flag < 0)
-                                       break;
-                               ptr += flag;
-
-                               /*bundle_del(kb, key);*/
-                               bundle_add(kb, key, value);
-                       } while (flag > 0);
-               } else if (flag == 0) {
-                       _D("parsing app_path: No arguments\n");
-               } else {
-                       _D("parsing app_path: Invalid argument\n");
-               }
-       }
-}
-
-int __send_to_sigkill(int pid)
-{
-       int pgid;
-
-       pgid = getpgid(pid);
-       if (pgid <= 1)
-               return -1;
-
-       if (killpg(pgid, SIGKILL) < 0)
-               return -1;
-
-       return 0;
-}
-
-int __term_app(int pid)
-{
-       int dummy;
-       if (__app_send_raw
-           (pid, APP_TERM_BY_PID, (unsigned char *)&dummy, sizeof(int)) < 0) {
-               _D("terminate packet send error - use SIGKILL");
-               if (__send_to_sigkill(pid) < 0) {
-                       _E("fail to killing - %d\n", pid);
-                       return -1;
-               }
-       }
-       _D("term done\n");
-       return 0;
-}
-
-static int __get_caller_pid(bundle *kb)
-{
-       const char *pid_str;
-       int pid;
-
-       pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
-       if(pid_str)
-               goto end;
-
-       pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
-       if (pid_str == NULL)
-               return -1;
-
-end:
-       pid = atoi(pid_str);
-       if (pid <= 1)
-               return -1;
-
-       return pid;
-}
-
-int __foward_cmd(int cmd, bundle *kb, int cr_pid)
-{
-       int pid;
-       char tmp_pid[MAX_PID_STR_BUFSZ];
-       int datalen;
-       bundle_raw *kb_data;
-       int res;
-
-       if ((pid = __get_caller_pid(kb)) < 0)
-                       return AUL_R_ERROR;
-
-       snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", cr_pid);
-
-       bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
-
-       bundle_encode(kb, &kb_data, &datalen);
-       if ((res = __app_send_raw_with_noreply(pid, cmd, kb_data, datalen)) < 0)
-               res = AUL_R_ERROR;
-
-       free(kb_data);
-
-       return res;
-}
-
-void __real_send(int clifd, int ret)
-{
-       if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
-               if (errno == EPIPE) {
-                       _E("send failed due to EPIPE.\n");
-               }
-               _E("send fail to client");
-       }
-
-       close(clifd);
-}
-
-void __send_result_to_caller(int clifd, int ret)
-{
-       char *cmdline;
-       int wait_count;
-       int cmdline_changed = 0;
-       int cmdline_exist = 0;
-
-       if (clifd == -1)
-               return;
-
-       if (ret <= 1) {
-               __real_send(clifd, ret);
-               return;
-       }
-       /* check normally was launched?*/
-       wait_count = 1;
-       do {
-               cmdline = __proc_get_cmdline_bypid(ret);
-               if (cmdline == NULL) {
-                       _E("error founded when being launched with %d", ret);
-
-               } else if (strcmp(cmdline, launchpad_cmdline)) {
-                       free(cmdline);
-                       cmdline_changed = 1;
-                       break;
-               } else {
-                       cmdline_exist = 1;
-                       free(cmdline);
-               }
-
-               _D("-- now wait to change cmdline --");
-               usleep(50 * 1000);      /* 50ms sleep*/
-               wait_count++;
-       } while (wait_count <= 20);     /* max 50*20ms will be sleep*/
-
-       if ((!cmdline_exist) && (!cmdline_changed)) {
-               _E("abnormally launched");
-               __real_send(clifd, -1); /* abnormally launched*/
-               return;
-       }
-
-       if (!cmdline_changed)
-               _E("process launched, but cmdline not changed");
-
-       __real_send(clifd, ret);
-       return;
-}
-
-static app_info_from_db *_get_app_info_from_bundle_by_pkgname(
-       const char *pkgname, bundle *kb)
-{
-       app_info_from_db *menu_info;
-
-       menu_info = calloc(1, sizeof(app_info_from_db));
-       if (menu_info == NULL) {
-               return NULL;
-       }
-
-       menu_info->pkg_name = strdup(pkgname);
-       menu_info->app_path = strdup(bundle_get_val(kb, AUL_K_EXEC));
-       if (menu_info->app_path != NULL)
-               menu_info->original_app_path = strdup(menu_info->app_path);
-       menu_info->pkg_type = strdup(bundle_get_val(kb, AUL_K_PACKAGETYPE));
-       menu_info->hwacc = strdup(bundle_get_val(kb, AUL_K_HWACC));
-
-       if (!_get_app_path(menu_info)) {
-               _free_app_info_from_db(menu_info);
-               return NULL;
-       }
-
-       return menu_info;
-}
-
-/**
- * free after use it
- */
-int get_native_appid(const char* app_path, char** appid) {
-       int rc = smack_lgetlabel(app_path, appid, SMACK_LABEL_ACCESS);
-
-       if (rc != 0 || *appid == NULL) {
-               _E("smack_lgetlabel fail");
-               return -1;
-       }
-
-       if (strlen(*appid) != APPID_LEN) {
-               _E("wrong native appid : %s", *appid);
-               return -1;
-       }
-
-       if (strlen(app_path) < sizeof(PATH_NATIVE_APP)+APPID_LEN-1) {
-               _E("wrong native app_path : %s", app_path);
-               return -1;
-       }
-       else if ( strncmp(app_path, PATH_NATIVE_APP, sizeof(PATH_NATIVE_APP)-1)
-               || strncmp(&app_path[sizeof(PATH_NATIVE_APP)-1]
-               , *appid,APPID_LEN) )
-       {
-               _E("wrong native app_path : %s", app_path);
-               return -1;
-       }
-       
-       _D("get_appid return : %s", *appid);
-       return 0;
-}
-
-int apply_smack_rules(const char* subject, const char* object
-       , const char* access_type)
-{
-       struct smack_accesses *rules = NULL;
-
-       _D("apply_smack_rules : %s %s %s", subject, object, access_type);
-
-       if (smack_accesses_new(&rules)) {
-               _E("smack_accesses_new fail");
-               return -1;
-       }
-
-       if (smack_accesses_add(rules, subject, object, access_type)) {
-               smack_accesses_free(rules);
-               _E("smack_accesses_add fail");
-               return -1;
-       }
-
-       if (smack_accesses_apply(rules)) {
-               smack_accesses_free(rules);
-               _E("smack_accesses_apply fail");
-               return -1;
-       }
-
-       smack_accesses_free(rules);
-
-       return 0;
-}
-
-int __prepare_valgrind_outputfile(bundle *kb)
-{
-       const char *str = NULL;
-       const char **str_array = NULL;
-       int len = 0;
-       int i;
-
-       if(bundle_get_type(kb, DLP_K_VALGRIND_ARG) & BUNDLE_TYPE_ARRAY) {
-               str_array = bundle_get_str_array(kb, DLP_K_VALGRIND_ARG, &len);
-       } else {
-               str = bundle_get_val(kb, DLP_K_VALGRIND_ARG);
-               if(str) {
-                       str_array = &str;
-                       len = 1;
-               }
-       }
-       if(str_array == NULL) return 0;
-
-       for (i = 0; i < len; i++) {
-               if(str_array[i] == NULL) break;
-               /* valgrind log file option */
-               if (strncmp(str_array[i], OPT_VALGRIND_LOGFILE
-                       , sizeof(OPT_VALGRIND_LOGFILE)-1) == 0)
-               {
-                       if(strcmp(str_array[i], OPT_VALGRIND_LOGFILE_FIXED))
-                       {
-                               _E("wrong valgrind option(%s). It should be %s"
-                                       , str_array[i]
-                                       , OPT_VALGRIND_LOGFILE_FIXED);
-                               return -1;
-                       }else{
-                               poll_outputfile |= POLL_VALGRIND_LOGFILE;
-                               if(remove(PATH_VALGRIND_LOGFILE)){
-                                       _D("cannot remove %s"
-                                               , PATH_VALGRIND_LOGFILE);
-                               }
-                       }
-               }
-               /* valgrind xml file option */
-               else if (strncmp(str_array[i], OPT_VALGRIND_XMLFILE
-                       , sizeof(OPT_VALGRIND_XMLFILE)-1) == 0)
-               {
-                       if(strcmp(str_array[i], OPT_VALGRIND_XMLFILE_FIXED))
-                       {
-                               _E("wrong valgrind option(%s). It should be %s"
-                                       , str_array[i]
-                                       , OPT_VALGRIND_XMLFILE_FIXED);
-                               return -1;
-                       }else{
-                               poll_outputfile |= POLL_VALGRIND_XMLFILE;
-                               if(remove(PATH_VALGRIND_XMLFILE)){
-                                       _D("cannot remove %s"
-                                               , PATH_VALGRIND_XMLFILE);
-                               }
-                       }
-               }
-               /* valgrind massif file option */
-               else if (strncmp(str_array[i], OPT_VALGRIND_MASSIFFILE
-                       , sizeof(OPT_VALGRIND_MASSIFFILE)-1) == 0)
-               {
-                       if(strcmp(str_array[i], OPT_VALGRIND_MASSIFFILE_FIXED))
-                       {
-                               _E("wrong valgrind option(%s). It should be %s"
-                                       , str_array[i]
-                                       , OPT_VALGRIND_MASSIFFILE_FIXED);
-                               return -1;
-                       }else{
-                               if(remove(PATH_VALGRIND_XMLFILE)){
-                                       _D("cannot remove %s"
-                                               , PATH_VALGRIND_XMLFILE);
-                               }
-                       }
-               }
-       }
-       return 0;
-}
-
-extern int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
-
-int __adjust_process_capability(int sv)
-{
-       static struct __user_cap_header_struct h;
-       static struct __user_cap_data_struct ori_d[_LINUX_CAPABILITY_U32S_2];
-       static struct __user_cap_data_struct inh_d[_LINUX_CAPABILITY_U32S_2];
-       static int isinit = 0;
-
-       if(isinit==0) {
-               h.version = _LINUX_CAPABILITY_VERSION_2;
-               h.pid = getpid();
-
-               capget(&h, ori_d);
-               capget(&h, inh_d);
-
-               inh_d[CAP_TO_INDEX(CAP_NET_RAW)].inheritable |=
-                       CAP_TO_MASK(CAP_NET_RAW);
-               inh_d[CAP_TO_INDEX(CAP_SYS_CHROOT)].inheritable |=
-                       CAP_TO_MASK(CAP_SYS_CHROOT);
-
-               isinit++;
-
-               if(sv == CAPABILITY_SET_ORIGINAL) return 0;
-       }
-
-       if(isinit==0) {
-               _E("__adjust_process_capability init failed");
-               return -1;
-       }
-
-       if(sv == CAPABILITY_SET_ORIGINAL) {
-               h.pid = getpid();
-               if (capset(&h, ori_d) < 0) {
-                       _E("Capability setting error");
-                       return -1;
-               }
-       }
-       else if (sv == CAPABILITY_SET_INHERITABLE) {
-               h.pid = getpid();
-               if (capset(&h, inh_d) < 0) {
-                       _E("Capability setting error");
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-int __adjust_file_capability(const char * path)
-{
-       if(cap_set_file(path,cap_from_text("CAP_NET_RAW,CAP_SYS_CHROOT+i"))) {
-               _E("cap_set_file failed : %s", path);
-               return -1;
-       }
-       return 0;
-}
-
-int __prepare_fork(bundle *kb, char *appid)
-{
-       const char *str = NULL;
-       const char **str_array = NULL;
-       int len = 0;
-       int i;
-
-       need_to_set_inh_cap_after_fork=0;
-       poll_outputfile = 0;
-       if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
-               str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
-       } else {
-               str = bundle_get_val(kb, AUL_K_SDK);
-               if(str) {
-                       str_array = &str;
-                       len = 1;
-               }
-       }
-       if(str_array == NULL) return 0;
-
-       is_gdbserver_launched = 0;
-       gdbserver_pid = -1;
-       gdbserver_app_pid = -1;
-
-       for (i = 0; i < len; i++) {
-               if(str_array[i] == NULL) break;
-               /* gdbserver */
-               if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0)
-               {
-                       if(apply_smack_rules("sdbd",appid,"w")) {
-                               _E("unable to set sdbd rules");
-                               return -1;
-                       }
-
-                       // FIXME: set gdbfolder to 755 also
-                       if(dlp_chmod(PATH_GDBSERVER
-                               , S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP
-                               |S_IROTH|S_IXOTH
-                               , 1))
-                       {
-                               _D("unable to set 755 to %s", PATH_GDBSERVER);
-                       }
-                       __adjust_file_capability(PATH_GDBSERVER);
-                       need_to_set_inh_cap_after_fork++;
-                       is_gdbserver_launched++;
-               }
-               /* valgrind */
-               else if (strncmp(str_array[i], SDK_VALGRIND
-                       , strlen(str_array[i])) == 0)
-               {
-                       if (__prepare_valgrind_outputfile(kb) == -1) 
-                               return -1;
-                       __adjust_file_capability(PATH_MEMCHECK);
-               }
-       }
-       return 0;
-}
-
-
-/* waiting for creating outputfile by child process */
-void __waiting_outputfile()
-{
-       int wait_count = 0;
-       while(poll_outputfile && wait_count<10) {
-               /* valgrind log file */
-               if( (poll_outputfile & POLL_VALGRIND_LOGFILE) 
-                       && (access(PATH_VALGRIND_LOGFILE,F_OK)==0) )
-               {
-                       __chmod_chsmack_toread(PATH_VALGRIND_LOGFILE);
-                       poll_outputfile &= ~POLL_VALGRIND_LOGFILE;
-               }
-
-               /* valgrind xml file */
-               if( (poll_outputfile & POLL_VALGRIND_XMLFILE)
-                       && (access(PATH_VALGRIND_XMLFILE,F_OK)==0) )
-               {
-                       __chmod_chsmack_toread(PATH_VALGRIND_XMLFILE);
-                       poll_outputfile &= ~POLL_VALGRIND_XMLFILE;
-               }
-
-               if(poll_outputfile) {
-                       _D("-- now wait for creating the file --");
-                       usleep(50 * 1000);      /* 50ms sleep*/
-                       wait_count++;
-               }
-       }
-
-       if(wait_count==10) _E("faild to waiting");
-       return;
-}
-
-int __stdout_stderr_redirection(int defpid)
-{
-       char defpath[UNIX_PATH_MAX];
-       int deffd, result=0; 
-
-       /* stdout */
-       snprintf(defpath, UNIX_PATH_MAX, "/proc/%d/fd/1", defpid);
-       deffd = open(defpath,O_WRONLY);
-       if(deffd < 0) {
-               _E("opening caller(%d) stdout failed due to %s"
-                       , defpid, strerror(errno));
-               result++;
-       }else{
-               dup2(deffd, 1);
-               close(deffd);
-       }
-
-       /* stderr */
-       snprintf(defpath, UNIX_PATH_MAX, "/proc/%d/fd/2", defpid);
-       deffd = open(defpath,O_WRONLY);
-       if(deffd < 0) {
-               _E("opening caller(%d) stderr failed due to %s"
-                       , defpid,strerror(errno));
-               result+=2;
-       }else{
-               dup2(deffd, 2);
-               close(deffd);
-       }
-
-       return result;
-}
-
-void __launchpad_main_loop(int main_fd)
-{
-       bundle *kb = NULL;
-       app_pkt_t *pkt = NULL;
-       app_info_from_db *menu_info = NULL;
-
-       const char *pkg_name = NULL;
-       const char *app_path = NULL;
-       int pid = -1;
-       int clifd = -1;
-       struct ucred cr;
-       int is_real_launch = 0;
-
-       char sock_path[UNIX_PATH_MAX] = {0,};
-       char * appid = NULL;
-
-       pkt = __app_recv_raw(main_fd, &clifd, &cr);
-       if (!pkt) {
-               _D("packet is NULL");
-               goto end;
-       }
-
-       kb = bundle_decode(pkt->data, pkt->len);
-       if (!kb) {
-               _D("bundle decode error");
-               goto end;
-       }
-
-       INIT_PERF(kb);
-       PERF("packet processing start");
-
-       pkg_name = bundle_get_val(kb, AUL_K_PKG_NAME);
-       _D("pkg name : %s\n", pkg_name);
-
-       menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb);
-       if (menu_info == NULL) {
-               _D("such pkg no found");
-               goto end;
-       }
-
-       app_path = _get_app_path(menu_info);
-       if(app_path == NULL) {
-               _E("app_path is NULL");
-               goto end;
-       }
-       if (app_path[0] != '/') {
-               _D("app_path is not absolute path");
-               goto end;
-       }
-
-       {
-               int rc = get_native_appid(app_path,&appid);
-               if(rc!=0 || appid==NULL) {
-                       _E("unable to get native appid");
-                       if(appid){
-                               free(appid);
-                               appid = NULL;
-                       }
-                       goto end;
-               }
-       }
-
-       __modify_bundle(kb, cr.pid, menu_info, pkt->cmd);
-       pkg_name = _get_pkgname(menu_info);
-
-       PERF("get package information & modify bundle done");
-
-       if(__prepare_fork(kb,appid) == -1) goto end;
-
-       pid = fork();
-       if (pid == 0) {
-               if(need_to_set_inh_cap_after_fork) {
-                       __adjust_process_capability(CAPABILITY_SET_INHERITABLE);
-               }
-               PERF("fork done");
-               _D("lock up test log(no error) : fork done");
-
-               close(clifd);
-               close(main_fd);
-               __signal_unset_sigchld();
-               __signal_fini();
-
-               snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX
-                       , getpid());
-               unlink(sock_path);
-
-               if(__stdout_stderr_redirection(__get_caller_pid(kb))) {
-                       _E("__stdout_stderr_redirection fail");
-               }
-
-               PERF("prepare exec - first done");
-               _D("lock up test log(no error) : prepare exec - first done");
-
-               if (__prepare_exec(pkg_name, app_path,
-                                  menu_info, kb) < 0) {
-                       _E("preparing work fail to launch - "
-                          "can not launch %s\n", pkg_name);
-                       exit(-1);
-               }
-
-               PERF("prepare exec - second done");
-               _D("lock up test log(no error) : prepare exec - second done");
-
-               __real_launch(app_path, kb);
-
-               exit(-1);
-       }
-
-       if(is_gdbserver_launched) {
-               char buf[MAX_LOCAL_BUFSZ];
-
-               usleep(100 * 1000);     /* 100ms sleep */
-               snprintf(buf, MAX_LOCAL_BUFSZ, "%s.exe", app_path);
-               gdbserver_app_pid = __proc_iter_cmdline(NULL, buf);
-
-               if(gdbserver_app_pid == -1) {
-                       _E("faild to get app pid");
-               } else {
-                       gdbserver_pid = pid;
-                       pid = gdbserver_app_pid;
-               }
-       }
-
-       _D("==> real launch pid : %d %s\n", pid, app_path);
-       is_real_launch = 1;
-
- end:
-       __send_result_to_caller(clifd, pid);
-
-       if (pid > 0) {
-               if (is_real_launch) {
-                       /*TODO: retry*/
-                       __signal_block_sigchld();
-                       __send_app_launch_signal(pid);
-                       __signal_unblock_sigchld();
-               }
-       }
-
-       if (menu_info != NULL)
-               _free_app_info_from_db(menu_info);
-
-       if (kb != NULL)
-               bundle_free(kb);
-       if (pkt != NULL)
-               free(pkt);
-       if (appid != NULL) 
-               free(appid);
-
-       /* Active Flusing for Daemon */
-       if (initialized > AUL_POLL_CNT) {
-               sqlite3_release_memory(SQLITE_FLUSH_MAX);
-               malloc_trim(0);
-               initialized = 1;
-       }
-
-       if(poll_outputfile) __waiting_outputfile();
-}
-
-int __launchpad_pre_init(int argc, char **argv)
-{
-       int fd;
-
-       /* signal init*/
-       __signal_init();
-
-       /* get my(launchpad) command line*/
-       launchpad_cmdline = __proc_get_cmdline_bypid(getpid());
-       if (launchpad_cmdline == NULL) {
-               _E("launchpad cmdline fail to get");
-               return -1;
-       }
-       _D("launchpad cmdline = %s", launchpad_cmdline);
-
-       /* create launchpad sock        */
-       fd = __create_server_sock(DEBUG_LAUNCHPAD_PID);
-       if (fd < 0) {
-               _E("server sock error");
-               return -1;
-       }
-
-       __preload_init(argc, argv);
-
-       __preexec_init(argc, argv);
-
-       return fd;
-}
-
-int __launchpad_post_init()
-{
-       /* Setting this as a global variable to keep track 
-       of launchpad poll cnt */
-       /* static int initialized = 0;*/
-
-       if (initialized) {
-               initialized++;
-               return 0;
-       }
-
-       if (__signal_set_sigchld() < 0)
-               return -1;
-
-       initialized++;
-
-       return 0;
-}
-
-int main(int argc, char **argv)
-{
-       int main_fd;
-       struct pollfd pfds[POLLFD_MAX];
-       int i;
-
-       __adjust_process_capability(CAPABILITY_SET_ORIGINAL);
-
-       /* init without concerning X & EFL*/
-       main_fd = __launchpad_pre_init(argc, argv);
-       if (main_fd < 0) {
-               _E("launchpad pre init failed");
-               exit(-1);
-       }
-
-       pfds[0].fd = main_fd;
-       pfds[0].events = POLLIN;
-       pfds[0].revents = 0;
-
-       while (1) {
-               if (poll(pfds, POLLFD_MAX, -1) < 0)
-                       continue;
-
-               /* init with concerning X & EFL (because of booting 
-               sequence problem)*/
-               if (__launchpad_post_init() < 0) {
-                       _E("launcpad post init failed");
-                       exit(-1);
-               }
-
-               for (i = 0; i < POLLFD_MAX; i++) {
-                       if ((pfds[i].revents & POLLIN) != 0) {
-                               __launchpad_main_loop(pfds[i].fd);
-                       }
-               }
-       }
-}
-
diff --git a/src/security_util.c b/src/security_util.c
new file mode 100644 (file)
index 0000000..3269a9f
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/smack.h>
+#include <security-manager.h>
+
+#include "common.h"
+#include "security_util.h"
+
+int _set_smack_access_label(const char *path, const char *label)
+{
+       return smack_setlabel(path, label, SMACK_LABEL_ACCESS);
+}
+
+int _apply_smack_rules(const char *subject, const char *object,
+               const char *access_type)
+{
+       int r;
+       struct smack_accesses *rules = NULL;
+
+       _D("%s %s %s", subject, object, access_type);
+
+       r = smack_accesses_new(&rules);
+       if (r != 0) {
+               _E("smack_accesses_new() is failed.");
+               return -1;
+       }
+
+       r = smack_accesses_add(rules, subject, object, access_type);
+       if (r != 0) {
+               _E("smack_accesses_add() is failed.");
+               smack_accesses_free(rules);
+               return -1;
+       }
+
+       r = smack_accesses_apply(rules);
+       if (r != 0) {
+               _E("smack_accesses_apply() is failed.");
+               smack_accesses_free(rules);
+               return -1;
+       }
+
+       smack_accesses_free(rules);
+
+       return 0;
+}
+
+int _set_access(const char *appid)
+{
+       return security_manager_prepare_app(appid);
+}
diff --git a/src/sigchild.h b/src/sigchild.h
deleted file mode 100755 (executable)
index 903d105..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include <pthread.h>
-#include <sys/smack.h>
-#include "app_signal.h"
-
-static struct sigaction old_sigchild;
-static DBusConnection *bus = NULL;
-sigset_t oldmask;
-static int gdbserver_pid;
-static int gdbserver_app_pid;
-
-static inline void __socket_garbage_collector()
-{
-       DIR *dp;
-       struct dirent *dentry;
-       char tmp[MAX_LOCAL_BUFSZ];
-
-       dp = opendir(AUL_SOCK_PREFIX);
-       if (dp == NULL)
-               return;
-
-       while ((dentry = readdir(dp)) != NULL) {
-               if (!isdigit(dentry->d_name[0]))
-                       continue;
-
-               snprintf(tmp, MAX_LOCAL_BUFSZ, "/proc/%s", dentry->d_name);
-               if (access(tmp, F_OK) < 0) {    /* Flawfinder: ignore */
-                       snprintf(tmp, MAX_LOCAL_BUFSZ, "%s/%s", AUL_SOCK_PREFIX,
-                                dentry->d_name);
-                       unlink(tmp);
-                       continue;
-               }
-       }
-       closedir(dp);
-}
-
-static inline int __send_app_dead_signal(int dead_pid)
-{
-       DBusMessage *message;
-
-       if (bus == NULL)
-               return -1;
-
-       message = dbus_message_new_signal(AUL_DBUS_PATH,
-                                         AUL_DBUS_SIGNAL_INTERFACE,
-                                         AUL_DBUS_APPDEAD_SIGNAL);
-
-       if (dbus_message_append_args(message,
-                                    DBUS_TYPE_UINT32, &dead_pid,
-                                    DBUS_TYPE_INVALID) == FALSE) {
-               _E("Failed to load data error");
-               return -1;
-       }
-
-       if (dbus_connection_send(bus, message, NULL) == FALSE) {
-               _E("dbus send error");
-               return -1;
-       }
-
-       dbus_connection_flush(bus);
-       dbus_message_unref(message);
-
-       _D("send dead signal done\n");
-
-       return 0;
-}
-
-static inline int __send_app_launch_signal(int launch_pid)
-{
-       DBusMessage *message;
-
-       if (bus == NULL)
-               return -1;
-
-       message = dbus_message_new_signal(AUL_DBUS_PATH,
-                                         AUL_DBUS_SIGNAL_INTERFACE,
-                                         AUL_DBUS_APPLAUNCH_SIGNAL);
-
-       if (dbus_message_append_args(message,
-                                    DBUS_TYPE_UINT32, &launch_pid,
-                                    DBUS_TYPE_INVALID) == FALSE) {
-               _E("Failed to load data error");
-               return -1;
-       }
-
-       if (dbus_connection_send(bus, message, NULL) == FALSE) {
-               _E("dbus send error");
-               return -1;
-       }
-
-       dbus_connection_flush(bus);
-       dbus_message_unref(message);
-
-       _D("send launch signal done\n");
-
-       return 0;
-}
-
-/* chmod and chsmack to read file without root privilege */
-static void __chmod_chsmack_toread(const char * path)
-{
-       /* chmod */
-       if(dlp_chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 0))
-       {
-               _E("unable to set 644 to %s", path);
-       }else{
-               _D("set 644 to %s", path);
-       }
-
-       /* chsmack */
-       if(smack_setlabel(path, "*", SMACK_LABEL_ACCESS))
-       {
-               _E("failed chsmack -a \"*\" %s", path);
-       }else{
-               _D("chsmack -a \"*\" %s", path);
-       }
-
-       return;
-}
-
-static int __sigchild_action(void *data)
-{
-       pid_t dead_pid;
-       char buf[MAX_LOCAL_BUFSZ];
-
-       dead_pid = (pid_t) data;
-       if (dead_pid <= 0)
-               goto end;
-
-       /* send app pid instead of gdbserver pid */
-       if(dead_pid == gdbserver_pid)
-               dead_pid = gdbserver_app_pid;
-
-       /* valgrind xml file */
-       if(access(PATH_VALGRIND_XMLFILE,F_OK)==0)
-       {
-               __chmod_chsmack_toread(PATH_VALGRIND_XMLFILE);
-       }
-
-       __send_app_dead_signal(dead_pid);
-
-       snprintf(buf, MAX_LOCAL_BUFSZ, "%s/%d", AUL_SOCK_PREFIX, dead_pid);
-       unlink(buf);
-
-       __socket_garbage_collector();
- end:
-       return 0;
-}
-
-static void __launchpad_sig_child(int signo, siginfo_t *info, void *data)
-{
-       int status;
-       pid_t child_pid;
-       pid_t child_pgid;
-
-       child_pgid = getpgid(info->si_pid);
-       _D("dead_pid = %d pgid = %d", info->si_pid, child_pgid);
-
-       while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
-               if (child_pid == child_pgid)
-                       killpg(child_pgid, SIGKILL);
-               __sigchild_action((void *)child_pid);
-       }
-
-       return;
-}
-
-static inline int __signal_init(void)
-{
-       int i;
-       for (i = 0; i < _NSIG; i++) {
-               switch (i) {
-                       /* controlled by sys-assert package*/
-               case SIGQUIT:
-               case SIGILL:
-               case SIGABRT:
-               case SIGBUS:
-               case SIGFPE:
-               case SIGSEGV:
-               case SIGPIPE:
-                       break;
-               default:
-                       signal(i, SIG_DFL);
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-static inline int __signal_set_sigchld(void)
-{
-       struct sigaction act;
-       DBusError error;
-
-       dbus_error_init(&error);
-       dbus_threads_init_default();
-       bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
-       if (!bus) {
-               _E("Failed to connect to the D-BUS daemon: %s", error.message);
-               dbus_error_free(&error);
-               return -1;
-       }
-       /* TODO: if process stop mechanism is included, 
-       should be modified (SA_NOCLDSTOP)*/
-       act.sa_handler = NULL;
-       act.sa_sigaction = __launchpad_sig_child;
-       sigemptyset(&act.sa_mask);
-       act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
-
-       if (sigaction(SIGCHLD, &act, &old_sigchild) < 0)
-               return -1;
-
-       return 0;
-}
-
-static inline int __signal_unset_sigchld(void)
-{
-       struct sigaction dummy;
-
-       if (bus == NULL)
-               return 0;
-
-       dbus_connection_close(bus);
-       if (sigaction(SIGCHLD, &old_sigchild, &dummy) < 0)
-               return -1;
-
-       return 0;
-}
-
-static inline int __signal_block_sigchld(void)
-{
-       sigset_t newmask;
-
-       sigemptyset(&newmask);
-       sigaddset(&newmask, SIGCHLD);
-
-       if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
-               _E("SIG_BLOCK error");
-               return -1;
-       }
-
-       _D("SIGCHLD blocked");
-
-       return 0;
-}
-
-static inline int __signal_unblock_sigchld(void)
-{
-       if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
-               _E("SIG_SETMASK error");
-               return -1;
-       }
-
-       _D("SIGCHLD unblocked");
-       return 0;
-}
-
-static inline int __signal_fini(void)
-{
-#ifndef PRELOAD_ACTIVATE
-       int i;
-       for (i = 0; i < _NSIG; i++)
-               signal(i, SIG_DFL);
-#endif
-       return 0;
-}
-
diff --git a/src/signal_util.c b/src/signal_util.c
new file mode 100644 (file)
index 0000000..3a7cf74
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/smack.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/signalfd.h>
+#include <dirent.h>
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "defs.h"
+#include "common.h"
+#include "file_util.h"
+#include "debug_util.h"
+#include "signal_util.h"
+
+#define AUL_DBUS_PATH "/aul/dbus_handler"
+#define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal"
+#define AUL_DBUS_APPDEAD_SIGNAL "app_dead"
+#define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch"
+
+static DBusConnection *bus = NULL;
+static sigset_t oldmask;
+
+static void __socket_garbage_collector(void)
+{
+       DIR *dp;
+       struct dirent *dentry;
+       char path[PATH_MAX];
+
+       snprintf(path, sizeof(path), "%s/%d", SOCKET_PATH, getuid());
+       dp = opendir(path);
+       if (dp == NULL)
+               return;
+
+       while ((dentry = readdir(dp)) != NULL) {
+               if (!isdigit(dentry->d_name[0]))
+                       continue;
+
+               snprintf(path, sizeof(path), "/proc/%s", dentry->d_name);
+               if (access(path, F_OK) != 0) { /* Flawfinder: ignore */
+                       snprintf(path, sizeof(path), "%s/%d/%s",
+                                       SOCKET_PATH, getuid(), dentry->d_name);
+                       unlink(path);
+                       continue;
+               }
+       }
+
+       closedir(dp);
+}
+
+int _send_app_dead_signal(int dead_pid)
+{
+       DBusMessage *message;
+
+       if (bus == NULL)
+               return -1;
+
+       message = dbus_message_new_signal(AUL_DBUS_PATH,
+                       AUL_DBUS_SIGNAL_INTERFACE,
+                       AUL_DBUS_APPDEAD_SIGNAL);
+
+       if (dbus_message_append_args(message,
+                               DBUS_TYPE_UINT32, &dead_pid,
+                               DBUS_TYPE_INVALID) == FALSE) {
+               _E("Failed to load data error");
+               return -1;
+       }
+
+       if (dbus_connection_send(bus, message, NULL) == FALSE) {
+               _E("dbus send error");
+               return -1;
+       }
+
+       dbus_connection_flush(bus);
+       dbus_message_unref(message);
+
+       _D("send dead signal done\n");
+
+       return 0;
+}
+
+int _send_app_launch_signal(int launch_pid)
+{
+       DBusMessage *message;
+
+       if (bus == NULL)
+               return -1;
+
+       message = dbus_message_new_signal(AUL_DBUS_PATH,
+                       AUL_DBUS_SIGNAL_INTERFACE,
+                       AUL_DBUS_APPLAUNCH_SIGNAL);
+
+       if (dbus_message_append_args(message,
+                               DBUS_TYPE_UINT32, &launch_pid,
+                               DBUS_TYPE_INVALID) == FALSE) {
+               _E("Failed to load data error");
+               return -1;
+       }
+
+       if (dbus_connection_send(bus, message, NULL) == FALSE) {
+               _E("dbus send error");
+               return -1;
+       }
+
+       dbus_connection_flush(bus);
+       dbus_message_unref(message);
+
+       _D("send launch signal done\n");
+
+       return 0;
+}
+
+static int __sigchild_action(void *data)
+{
+       pid_t dead_pid;
+       char buf[MAX_LOCAL_BUFSZ];
+
+       dead_pid = (pid_t)(intptr_t)data;
+       if (dead_pid <= 0)
+               return -1;
+
+       /* send app pid instead of gdbserver pid */
+       if (dead_pid == _get_gdbserver_pid())
+               dead_pid = _get_gdbserver_app_pid();
+
+       /* valgrind xml file */
+       if (access(PATH_VALGRIND_XMLFILE, F_OK) == 0)
+               _change_file(PATH_VALGRIND_XMLFILE);
+
+       _send_app_dead_signal(dead_pid);
+
+       snprintf(buf, MAX_LOCAL_BUFSZ, "%s/%d/%d", SOCKET_PATH, getuid(), dead_pid);
+       unlink(buf);
+
+       __socket_garbage_collector();
+
+       return 0;
+}
+
+void _debug_launchpad_sigchld(struct signalfd_siginfo *info)
+{
+       int status;
+       pid_t child_pid;
+       pid_t child_pgid;
+
+       child_pgid = getpgid(info->ssi_pid);
+       _D("dead pid = %d pgid = %d", info->ssi_pid, child_pgid);
+
+       while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
+               if (child_pid == child_pgid)
+                       killpg(child_pgid, SIGKILL);
+               __sigchild_action((void *)(intptr_t)child_pid);
+       }
+}
+
+int _signal_init(void)
+{
+       int i;
+       DBusError error;
+
+       dbus_error_init(&error);
+       dbus_threads_init_default();
+       bus = dbus_bus_get_private(DBUS_BUS_SESSION, &error);
+       if (!bus) {
+               _E("Failed to connect to the D-BUS daemon: %s", error.message);
+               dbus_error_free(&error);
+               return -1;
+       }
+
+       for (i = 0; i < _NSIG; i++) {
+               switch (i) {
+               /* controlled by sys-assert package*/
+               case SIGQUIT:
+               case SIGILL:
+               case SIGABRT:
+               case SIGBUS:
+               case SIGFPE:
+               case SIGSEGV:
+               case SIGPIPE:
+                       break;
+               default:
+                       signal(i, SIG_DFL);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+int _signal_get_sigchld_fd(void)
+{
+       sigset_t mask;
+       int sfd;
+
+       sigemptyset(&mask);
+       sigaddset(&mask, SIGCHLD);
+
+       if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1)
+               _E("sigprocmask() is failed.");
+
+       sfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
+       if (sfd == -1) {
+               _E("Failed to create signal fd");
+               return -1;
+       }
+
+       return sfd;
+}
+
+int _signal_unblock_sigchld(void)
+{
+       if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
+               _E("SIG_SETMASK error");
+               return -1;
+       }
+
+       _D("SIGCHLD unblocked");
+
+       return 0;
+}
+
+int _signal_fini(void)
+{
+       int i;
+
+       if (bus)
+               dbus_connection_close(bus);
+
+#ifndef PRELOAD_ACTIVATE
+       for (i = 0; i < _NSIG; i++)
+               signal(i, SIG_DFL);
+#endif
+       return 0;
+}
diff --git a/src/simple_util.c b/src/simple_util.c
deleted file mode 100755 (executable)
index dadc183..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- *  debug-launchpad
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "simple_util.h"
-
-#define BINSH_NAME     "/bin/sh"
-#define BINSH_SIZE     7
-
-#define PROC_STAT_GID_POS      5
-
-
-static inline int __read_proc(const char *path, char *buf, int size);
-static inline int __find_pid_by_cmdline(const char *dname,
-                                     const char *cmdline, void *priv);
-static inline int __get_pgid_from_stat(int pid);
-
-
-static inline int __read_proc(const char *path, char *buf, int size)
-{
-       int fd;
-       int ret;
-
-       if (buf == NULL || path == NULL)
-               return -1;
-
-       fd = open(path, O_RDONLY);
-       if (fd < 0)
-               return -1;
-
-       ret = read(fd, buf, size - 1);
-       if (ret <= 0) {
-               close(fd);
-               return -1;
-       } else
-               buf[ret] = 0;
-
-       close(fd);
-
-       return ret;
-}
-
-static inline int __find_pid_by_cmdline(const char *dname,
-                                     const char *cmdline, void *priv)
-{
-       char *apppath;
-       int pid = 0;
-
-       apppath = (char *)priv;
-       if (strncmp(cmdline, apppath, MAX_LOCAL_BUFSZ-1) == 0) {
-               pid = atoi(dname);
-               if (pid != getpgid(pid))
-                       pid = 0;
-       }
-
-       return pid;
-}
-
-int __proc_iter_cmdline(
-       int (*iterfunc)(const char *dname, const char *cmdline, void *priv),
-                   void *priv)
-{
-       DIR *dp;
-       struct dirent *dentry;
-       int pid;
-       int ret;
-       char buf[MAX_LOCAL_BUFSZ];
-
-       dp = opendir("/proc");
-       if (dp == NULL) {
-               return -1;
-       }
-
-       if (iterfunc == NULL)
-               iterfunc = __find_pid_by_cmdline;
-
-       while ((dentry = readdir(dp)) != NULL) {
-               if (!isdigit(dentry->d_name[0]))
-                       continue;
-
-               snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry->d_name);
-               ret = __read_proc(buf, buf, sizeof(buf));
-               if (ret <= 0)
-                       continue;
-
-               /* support app launched by shell script*/
-               if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0)
-                       pid =
-                           iterfunc(dentry->d_name, &buf[BINSH_SIZE + 1],
-                                    priv);
-               else
-                       pid = iterfunc(dentry->d_name, buf, priv);
-
-               if (pid > 0) {
-                       closedir(dp);
-                       return pid;
-               }
-       }
-
-       closedir(dp);
-       return -1;
-}
-
-char *__proc_get_cmdline_bypid(int pid)
-{
-       char buf[MAX_LOCAL_BUFSZ];
-       int ret;
-
-       snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
-       ret = __read_proc(buf, buf, sizeof(buf));
-       if (ret <= 0)
-               return NULL;
-
-       /* support app launched by shell script*/
-       if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0)
-               return strdup(&buf[BINSH_SIZE + 1]);
-       else
-               return strdup(buf);
-}
-
-static inline int __get_pgid_from_stat(int pid)
-{
-       char buf[MAX_LOCAL_BUFSZ];
-       char *str;
-       int ret;
-       int i;
-       int count = 0;
-
-       if (pid <= 1)
-               return -1;
-
-       snprintf(buf, sizeof(buf), "/proc/%d/stat", pid);
-       ret = __read_proc(buf, buf, sizeof(buf));
-       if (ret < 0)
-               return -1;
-
-       for (i = 0; i < (ret - 1); i++) {
-               if (buf[i] == ' ') {
-                       count++;
-                       if (count == PROC_STAT_GID_POS - 1)
-                               str = &(buf[i + 1]);
-                       else if (count == PROC_STAT_GID_POS) {
-                               buf[i] = 0;
-                               break;
-                       }
-               }
-       }
-
-       if (count == PROC_STAT_GID_POS)
-               pid = atoi(str);
-       else
-               pid = -1;
-
-       return pid;
-}
-
-int __proc_iter_pgid(int pgid, int (*iterfunc) (int pid, void *priv),
-                    void *priv)
-{
-       DIR *dp;
-       struct dirent *dentry;
-       int _pgid;
-       int ret = -1;
-
-       dp = opendir("/proc");
-       if (dp == NULL) {
-               return -1;
-       }
-
-       while ((dentry = readdir(dp)) != NULL) {
-               if (!isdigit(dentry->d_name[0]))
-                       continue;
-
-               _pgid = __get_pgid_from_stat(atoi(dentry->d_name));
-               if (pgid == _pgid) {
-                       ret = iterfunc(atoi(dentry->d_name), priv);
-                       if (ret >= 0)
-                               break;
-               }
-       }
-
-       closedir(dp);
-       return ret;
-}
-