4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jungmin Cho <chivalry.cho@samsung.com>, Gwangho Hwang <gwang.hwang@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
24 #include <sys/smack.h>
25 #include "app_signal.h"
27 static struct sigaction old_sigchild;
28 static DBusConnection *bus = NULL;
30 static int gdbserver_pid;
31 static int gdbserver_app_pid;
33 static inline void __socket_garbage_collector()
36 struct dirent *dentry;
37 char tmp[MAX_LOCAL_BUFSZ];
39 dp = opendir(AUL_SOCK_PREFIX);
43 while ((dentry = readdir(dp)) != NULL) {
44 if (!isdigit(dentry->d_name[0]))
47 snprintf(tmp, MAX_LOCAL_BUFSZ, "/proc/%s", dentry->d_name);
48 if (access(tmp, F_OK) < 0) { /* Flawfinder: ignore */
49 snprintf(tmp, MAX_LOCAL_BUFSZ, "%s/%s", AUL_SOCK_PREFIX,
58 static inline int __send_app_dead_signal(int dead_pid)
65 message = dbus_message_new_signal(AUL_DBUS_PATH,
66 AUL_DBUS_SIGNAL_INTERFACE,
67 AUL_DBUS_APPDEAD_SIGNAL);
69 if (dbus_message_append_args(message,
70 DBUS_TYPE_UINT32, &dead_pid,
71 DBUS_TYPE_INVALID) == FALSE) {
72 _E("Failed to load data error");
76 if (dbus_connection_send(bus, message, NULL) == FALSE) {
77 _E("dbus send error");
81 dbus_connection_flush(bus);
82 dbus_message_unref(message);
84 _D("send dead signal done\n");
89 static inline int __send_app_launch_signal(int launch_pid)
96 message = dbus_message_new_signal(AUL_DBUS_PATH,
97 AUL_DBUS_SIGNAL_INTERFACE,
98 AUL_DBUS_APPLAUNCH_SIGNAL);
100 if (dbus_message_append_args(message,
101 DBUS_TYPE_UINT32, &launch_pid,
102 DBUS_TYPE_INVALID) == FALSE) {
103 _E("Failed to load data error");
107 if (dbus_connection_send(bus, message, NULL) == FALSE) {
108 _E("dbus send error");
112 dbus_connection_flush(bus);
113 dbus_message_unref(message);
115 _D("send launch signal done\n");
120 /* chmod and chsmack to read file without root privilege */
121 static void __chmod_chsmack_toread(const char * path)
124 if(dlp_chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 0))
126 _E("unable to set 644 to %s", path);
128 _D("set 644 to %s", path);
132 if(smack_setlabel(path, "*", SMACK_LABEL_ACCESS))
134 _E("failed chsmack -a \"*\" %s", path);
136 _D("chsmack -a \"*\" %s", path);
142 static int __sigchild_action(void *data)
145 char buf[MAX_LOCAL_BUFSZ];
147 dead_pid = (pid_t) data;
151 /* send app pid instead of gdbserver pid */
152 if(dead_pid == gdbserver_pid)
153 dead_pid = gdbserver_app_pid;
155 /* valgrind xml file */
156 if(access(PATH_VALGRIND_XMLFILE,F_OK)==0)
158 __chmod_chsmack_toread(PATH_VALGRIND_XMLFILE);
161 __send_app_dead_signal(dead_pid);
163 snprintf(buf, MAX_LOCAL_BUFSZ, "%s/%d", AUL_SOCK_PREFIX, dead_pid);
166 __socket_garbage_collector();
171 static void __launchpad_sig_child(int signo, siginfo_t *info, void *data)
177 child_pgid = getpgid(info->si_pid);
178 _D("dead_pid = %d pgid = %d", info->si_pid, child_pgid);
180 while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
181 if (child_pid == child_pgid)
182 killpg(child_pgid, SIGKILL);
183 __sigchild_action((void *)child_pid);
189 static inline int __signal_init(void)
192 for (i = 0; i < _NSIG; i++) {
194 /* controlled by sys-assert package*/
212 static inline int __signal_set_sigchld(void)
214 struct sigaction act;
217 dbus_error_init(&error);
218 dbus_threads_init_default();
219 bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
221 _E("Failed to connect to the D-BUS daemon: %s", error.message);
222 dbus_error_free(&error);
225 /* TODO: if process stop mechanism is included,
226 should be modified (SA_NOCLDSTOP)*/
227 act.sa_handler = NULL;
228 act.sa_sigaction = __launchpad_sig_child;
229 sigemptyset(&act.sa_mask);
230 act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
232 if (sigaction(SIGCHLD, &act, &old_sigchild) < 0)
238 static inline int __signal_unset_sigchld(void)
240 struct sigaction dummy;
245 dbus_connection_close(bus);
246 if (sigaction(SIGCHLD, &old_sigchild, &dummy) < 0)
252 static inline int __signal_block_sigchld(void)
256 sigemptyset(&newmask);
257 sigaddset(&newmask, SIGCHLD);
259 if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
260 _E("SIG_BLOCK error");
264 _D("SIGCHLD blocked");
269 static inline int __signal_unblock_sigchld(void)
271 if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
272 _E("SIG_SETMASK error");
276 _D("SIGCHLD unblocked");
280 static inline int __signal_fini(void)
282 #ifndef PRELOAD_ACTIVATE
284 for (i = 0; i < _NSIG; i++)