2 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <sys/types.h>
22 #include <sys/signalfd.h>
29 #include "debug_util.h"
30 #include "signal_util.h"
32 #define AUL_DBUS_PATH "/aul/dbus_handler"
33 #define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal"
34 #define AUL_DBUS_APPDEAD_SIGNAL "app_dead"
35 #define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch"
37 static GDBusConnection *bus;
38 static sigset_t oldmask;
40 static void __socket_garbage_collector(void)
43 struct dirent *dentry;
46 snprintf(path, sizeof(path), "%s/apps/%d", SOCKET_PATH, getuid());
51 while ((dentry = readdir(dp)) != NULL) {
52 if (!isdigit(dentry->d_name[0]))
55 snprintf(path, sizeof(path), "/proc/%s", dentry->d_name);
56 if (access(path, F_OK) != 0) { /* Flawfinder: ignore */
57 _delete_sock_path(atoi(dentry->d_name), getuid());
65 int _send_app_dead_signal(int dead_pid)
72 if (g_dbus_connection_emit_signal(bus,
75 AUL_DBUS_SIGNAL_INTERFACE,
76 AUL_DBUS_APPDEAD_SIGNAL,
77 g_variant_new("(u)", dead_pid),
79 _E("g_dbus_connection_emit_signal() is failed: %s",
85 if (g_dbus_connection_flush_sync(bus, NULL, &err) == FALSE) {
86 _E("g_dbus_connection_flush_sync() is failed: %s",
92 _D("send dead signal done (pid: %d)", dead_pid);
97 int _send_app_launch_signal(int launch_pid, const char *app_id)
104 if (g_dbus_connection_emit_signal(bus,
107 AUL_DBUS_SIGNAL_INTERFACE,
108 AUL_DBUS_APPLAUNCH_SIGNAL,
109 g_variant_new("(us)", launch_pid, app_id),
111 _E("g_dbus_connection_emit_signal() is failed: %s",
117 if (g_dbus_connection_flush_sync(bus, NULL, &err) == FALSE) {
118 _E("g_dbus_connection_flush_sync() is failed: %s",
124 _D("send launch signal done (pid: %d, app_id: %s)", launch_pid, app_id);
129 static int __sigchild_action(pid_t dead_pid)
134 /* send app pid instead of gdbserver pid */
135 if (dead_pid == _get_gdbserver_pid())
136 dead_pid = _get_gdbserver_app_pid();
138 _send_app_dead_signal(dead_pid);
140 _delete_sock_path(dead_pid, getuid());
142 __socket_garbage_collector();
147 void _debug_launchpad_sigchld(struct signalfd_siginfo *info)
153 child_pgid = getpgid(info->ssi_pid);
154 _D("dead pid = %d pgid = %d", info->ssi_pid, child_pgid);
156 while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
157 if (child_pid == child_pgid)
158 killpg(child_pgid, SIGKILL);
159 __sigchild_action(child_pid);
163 int _signal_init(void)
166 GError *error = NULL;
168 bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
170 _E("Failed to connect to the D-BUS daemon: %s", error->message);
175 for (i = 0; i < _NSIG; i++) {
177 /* controlled by sys-assert package*/
195 int _signal_get_sigchld_fd(void)
201 sigaddset(&mask, SIGCHLD);
203 if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1)
204 _E("sigprocmask() is failed.");
206 sfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
208 _E("Failed to create signal fd");
215 int _signal_unblock_sigchld(void)
217 if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
218 _E("SIG_SETMASK error");
222 _D("SIGCHLD unblocked");
227 int _signal_fini(void)
234 #ifndef PRELOAD_ACTIVATE
235 for (i = 0; i < _NSIG; i++)