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.
19 #include <sys/smack.h>
20 #include <sys/types.h>
22 #include <sys/signalfd.h>
29 #include "file_util.h"
30 #include "debug_util.h"
31 #include "signal_util.h"
33 #define AUL_DBUS_PATH "/aul/dbus_handler"
34 #define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal"
35 #define AUL_DBUS_APPDEAD_SIGNAL "app_dead"
36 #define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch"
38 static GDBusConnection *bus = NULL;
39 static sigset_t oldmask;
41 static void __socket_garbage_collector(void)
44 struct dirent *dentry;
47 snprintf(path, sizeof(path), "%s/%d", SOCKET_PATH, getuid());
52 while ((dentry = readdir(dp)) != NULL) {
53 if (!isdigit(dentry->d_name[0]))
56 snprintf(path, sizeof(path), "/proc/%s", dentry->d_name);
57 if (access(path, F_OK) != 0) { /* Flawfinder: ignore */
58 snprintf(path, sizeof(path), "%s/%d/%s",
59 SOCKET_PATH, getuid(), dentry->d_name);
68 int _send_app_dead_signal(int dead_pid)
75 if (g_dbus_connection_emit_signal(bus,
78 AUL_DBUS_SIGNAL_INTERFACE,
79 AUL_DBUS_APPDEAD_SIGNAL,
80 g_variant_new("(u)", dead_pid),
82 _E("g_dbus_connection_emit_signal() is failed: %s",
88 if (g_dbus_connection_flush_sync(bus, NULL, &err) == FALSE) {
89 _E("g_dbus_connection_flush_sync() is failed: %s",
95 _D("send dead signal done (pid: %d)", dead_pid);
100 int _send_app_launch_signal(int launch_pid, const char *app_id)
107 if (g_dbus_connection_emit_signal(bus,
110 AUL_DBUS_SIGNAL_INTERFACE,
111 AUL_DBUS_APPLAUNCH_SIGNAL,
112 g_variant_new("(us)", launch_pid, app_id),
114 _E("g_dbus_connection_emit_signal() is failed: %s",
120 if (g_dbus_connection_flush_sync(bus, NULL, &err) == FALSE) {
121 _E("g_dbus_connection_flush_sync() is failed: %s",
127 _D("send launch signal done (pid: %d, app_id: %s)", launch_pid, app_id);
132 static int __sigchild_action(pid_t dead_pid)
134 char buf[MAX_LOCAL_BUFSZ];
139 /* send app pid instead of gdbserver pid */
140 if (dead_pid == _get_gdbserver_pid())
141 dead_pid = _get_gdbserver_app_pid();
143 /* valgrind xml file */
144 if (access(PATH_VALGRIND_XMLFILE, F_OK) == 0)
145 _change_file(PATH_VALGRIND_XMLFILE);
147 _send_app_dead_signal(dead_pid);
149 snprintf(buf, MAX_LOCAL_BUFSZ, "%s/%d/%d",
150 SOCKET_PATH, getuid(), dead_pid);
153 __socket_garbage_collector();
158 void _debug_launchpad_sigchld(struct signalfd_siginfo *info)
164 child_pgid = getpgid(info->ssi_pid);
165 _D("dead pid = %d pgid = %d", info->ssi_pid, child_pgid);
167 while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
168 if (child_pid == child_pgid)
169 killpg(child_pgid, SIGKILL);
170 __sigchild_action(child_pid);
174 int _signal_init(void)
177 GError *error = NULL;
179 bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
181 _E("Failed to connect to the D-BUS daemon: %s", error->message);
186 for (i = 0; i < _NSIG; i++) {
188 /* controlled by sys-assert package*/
206 int _signal_get_sigchld_fd(void)
212 sigaddset(&mask, SIGCHLD);
214 if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1)
215 _E("sigprocmask() is failed.");
217 sfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
219 _E("Failed to create signal fd");
226 int _signal_unblock_sigchld(void)
228 if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
229 _E("SIG_SETMASK error");
233 _D("SIGCHLD unblocked");
238 int _signal_fini(void)
245 #ifndef PRELOAD_ACTIVATE
246 for (i = 0; i < _NSIG; i++)