--- /dev/null
+/*
+ * Copyright (c) 2020 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 __AUL_UNIX_SIGNAL_H__
+#define __AUL_UNIX_SIGNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Called when the signal is occurred.
+ * @since_tizen 5.5
+ *
+ * @param[in] signum The signal number
+ * @param[in] user_data The user data passed from the callback registration function
+ *
+ * @see aul_unix_signal_set_event_cb()
+ */
+typedef void (*aul_unix_signal_cb)(int signum, void *user_data);
+
+/**
+ * @brief Initializes AUL unix signal handler.
+ * @since_tizen 5.5
+ *
+ * @return @c 0 on success,
+ * otherwise a negative error value.
+ *
+ * @remarks This function is only for App Framework internally.
+ */
+int aul_unix_signal_init(void);
+
+/**
+ * @brief Finalizes AUL unix signal handler.
+ * @since_tizen 5.5
+ *
+ * @remarks This function is only for App Framework internally.
+ */
+void aul_unix_signal_fini(void);
+
+/**
+ * @brief Sets the event callback of AUL unix signal.
+ * @since_tizen 5.5
+ *
+ * @param[in] callback The callback function to be called when the signal is occurred
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ *
+ * @remarks This function is only for App Framework internally.
+ */
+int aul_unix_signal_set_event_cb(aul_unix_signal_cb callback, void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AUL_UNIX_SIGNAL_H__ */
#include "aul_watch_control_internal.h"
#include "aul_worker.h"
#include "aul_watchdog.h"
+#include "aul_unix_signal.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
return true;
}
+static void __aul_signal_handler(int signum, void *user_data)
+{
+ char buf[12];
+ bundle *b;
+ int ret;
+
+ aul_sock_destroy_server(-1);
+
+ b = bundle_create();
+ if (!b) {
+ _E("Failed to create bundle");
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "%d", signum);
+ bundle_add(b, AUL_K_SIGNAL, buf);
+
+ ret = aul_sock_send_bundle(AUL_UTIL_PID, getuid(),
+ APP_NOTIFY_SIGNAL, b, AUL_SOCK_NOREPLY);
+ if (ret != AUL_R_OK)
+ _E("Failed to notify signal. error(%d)", ret);
+
+ bundle_free(b);
+}
+
static void __finalize_context(void)
{
if (__context.worker) {
__context.worker = NULL;
}
+ aul_unix_signal_fini();
+
__context.initialized = false;
}
return fd;
}
+ ret = aul_unix_signal_init();
+ if (ret < 0)
+ return AUL_R_ERROR;
+
+ aul_unix_signal_set_event_cb(__aul_signal_handler, NULL);
+
__context.worker = aul_worker_create("aul+");
if (!__context.worker) {
__finalize_context();
--- /dev/null
+/*
+ * Copyright (c) 2020 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 <signal.h>
+#include <stdio.h>
+
+#include "aul_unix_signal.h"
+#include "aul_util.h"
+
+#ifdef TIZEN_FEATURE_DEBUG_MODE
+#include <dlfcn.h>
+#include <execinfo.h>
+
+#define BT_BUF_SIZE 128
+
+#define PRINT_BACKTRACE() do { \
+ int i; \
+ int nptrs; \
+ void *buffer[BT_BUF_SIZE]; \
+ char **strings; \
+ Dl_info info; \
+ \
+ nptrs = backtrace(buffer, BT_BUF_SIZE); \
+ strings = backtrace_symbols(buffer, nptrs); \
+ if (!strings) { \
+ dlog_print(DLOG_ERROR, "AUL_BACKTRACE", "backtrace_symbols"); \
+ break; \
+ } \
+ \
+ i = (nptrs > 2) ? 2 : 0; \
+ dlog_print(DLOG_ERROR, "AUL_BACKTRACE", \
+ "%s backtrace() returns %d address", \
+ strings[i], nptrs - i); \
+ \
+ for (i = 0; i < nptrs; i++) { \
+ dladdr(buffer[i], &info); \
+ if (i > 1) { \
+ dlog_print(DLOG_ERROR, "AUL_BACKTRACE", \
+ "[%2d] %s %s\n", \
+ i - 2, \
+ info.dli_sname ? info.dli_sname : "?", \
+ strings[i]); \
+ } \
+ } \
+} while (0)
+#endif /* TIZEN_FEATURE_DEBUG_MODE */
+
+typedef enum {
+ AUL_SIGHUP,
+ AUL_SIGINT,
+ AUL_SIGQUIT,
+ AUL_SIGILL,
+ AUL_SIGABRT,
+ AUL_SIGFPE,
+ AUL_SIGBUS,
+ AUL_SIGSEGV,
+ AUL_SIGALRM,
+ AUL_SIGTERM,
+ AUL_SIGXCPU,
+ AUL_SIGXFSZ,
+ AUL_SIGSYS,
+ AUL_SIGMAX,
+} aul_signo_e;
+
+static aul_unix_signal_cb __callback;
+static void *__user_data;
+static struct sigaction __old_action[AUL_SIGMAX];
+
+static int __get_unix_signo(aul_signo_e aul_signo)
+{
+ static int unix_signo[AUL_SIGMAX] = {
+ [AUL_SIGHUP] = SIGHUP,
+ [AUL_SIGINT] = SIGINT,
+ [AUL_SIGQUIT] = SIGQUIT,
+ [AUL_SIGILL] = SIGILL,
+ [AUL_SIGABRT] = SIGABRT,
+ [AUL_SIGFPE] = SIGFPE,
+ [AUL_SIGBUS] = SIGBUS,
+ [AUL_SIGSEGV] = SIGSEGV,
+ [AUL_SIGALRM] = SIGALRM,
+ [AUL_SIGTERM] = SIGTERM,
+ [AUL_SIGXCPU] = SIGXCPU,
+ [AUL_SIGXFSZ] = SIGXFSZ,
+ [AUL_SIGSYS] = SIGSYS,
+ };
+
+ if (aul_signo >= AUL_SIGMAX)
+ return -1;
+
+ return unix_signo[aul_signo];
+}
+
+static int __get_aul_signo(int signo)
+{
+ int i;
+
+ for (i = 0; i < AUL_SIGMAX; i++)
+ if (__get_unix_signo(i) == signo)
+ return i;
+
+ return -1;
+}
+
+static const char *__get_aul_signo_string(aul_signo_e aul_signo)
+{
+ static const char *aul_signo_string[] = {
+ [AUL_SIGHUP] = "SIGHUP",
+ [AUL_SIGINT] = "SIGINT",
+ [AUL_SIGQUIT] = "SIGQUIT",
+ [AUL_SIGILL] = "SIGILL",
+ [AUL_SIGABRT] = "SIGABRT",
+ [AUL_SIGFPE] = "SIGFPE",
+ [AUL_SIGBUS] = "SIGBUS",
+ [AUL_SIGSEGV] = "SIGSEGV",
+ [AUL_SIGALRM] = "SIGALRM",
+ [AUL_SIGTERM] = "SIGTERM",
+ [AUL_SIGXCPU] = "SIGXCPU",
+ [AUL_SIGXFSZ] = "SIGXFSZ",
+ [AUL_SIGSYS] = "SIGSYS",
+ };
+
+ if (aul_signo >= AUL_SIGMAX)
+ return "Unknown";
+
+ return aul_signo_string[aul_signo];
+}
+
+static void __aul_unix_signal_handler(int signo, siginfo_t *info, void *arg)
+{
+ int aul_signo;
+
+ _E("[__SIGNAL__] signal: %d(%s)",
+ signo, __get_aul_signo_string(__get_aul_signo(signo)));
+
+#ifdef TIZEN_FEATURE_DEBUG_MODE
+ PRINT_BACKTRACE();
+#endif /* TIZEN_FEATURE_DEBUG_MODE */
+
+ if (__callback)
+ __callback(signo, __user_data);
+
+ aul_signo = __get_aul_signo(signo);
+ if (aul_signo != -1) {
+ sigaction(signo, &__old_action[aul_signo], NULL);
+ raise(signo);
+ }
+}
+
+int aul_unix_signal_set_event_cb(aul_unix_signal_cb callback,
+ void *user_data)
+{
+ __callback = callback;
+ __user_data = user_data;
+
+ return 0;
+}
+
+int aul_unix_signal_init(void)
+{
+ struct sigaction action = { 0, };
+ int signo;
+ int i;
+
+ sigemptyset(&action.sa_mask);
+ action.sa_sigaction = __aul_unix_signal_handler;
+ action.sa_flags = SA_RESTART | SA_SIGINFO;
+
+ for (i = 0; i < AUL_SIGMAX; i++) {
+ signo = __get_unix_signo(i);
+ if (signo != -1)
+ sigaction(signo, &action, &__old_action[i]);
+ }
+
+ return 0;
+}
+
+void aul_unix_signal_fini(void)
+{
+ int signo;
+ int i;
+
+ aul_unix_signal_set_event_cb(NULL, NULL);
+
+ for (i = 0; i < AUL_SIGMAX; i++) {
+ signo = __get_unix_signo(i);
+ if (signo != -1)
+ sigaction(signo, &__old_action[i], NULL);
+ }
+}