patch-2.4.19 linux-2.4.19/kernel/signal.c
Next file: linux-2.4.19/kernel/softirq.c
Previous file: linux-2.4.19/kernel/sched.c
Back to the patch index
Back to the overall index
- Lines: 125
- Date:
Fri Aug 2 17:39:46 2002
- Orig file:
linux-2.4.18/kernel/signal.c
- Orig date:
Wed Nov 21 16:26:27 2001
diff -urN linux-2.4.18/kernel/signal.c linux-2.4.19/kernel/signal.c
@@ -142,6 +142,35 @@
}
}
+/*
+ * sig_exit - cause the current task to exit due to a signal.
+ */
+
+void
+sig_exit(int sig, int exit_code, struct siginfo *info)
+{
+ struct task_struct *t;
+
+ sigaddset(¤t->pending.signal, sig);
+ recalc_sigpending(current);
+ current->flags |= PF_SIGNALED;
+
+ /* Propagate the signal to all the tasks in
+ * our thread group
+ */
+ if (info && (unsigned long)info != 1
+ && info->si_code != SI_TKILL) {
+ read_lock(&tasklist_lock);
+ for_each_thread(t) {
+ force_sig_info(sig, info, t);
+ }
+ read_unlock(&tasklist_lock);
+ }
+
+ do_exit(exit_code);
+ /* NOTREACHED */
+}
+
/* Notify the system that a driver wants to block all signals for this
* process, and wants to be notified if any signals at all were to be
* sent/acted upon. If the notifier routine returns non-zero, then the
@@ -519,7 +548,7 @@
if (bad_signal(sig, info, t))
goto out_nolock;
- /* The null signal is a permissions and process existance probe.
+ /* The null signal is a permissions and process existence probe.
No signal is actually delivered. Same goes for zombies. */
ret = 0;
if (!sig || !t->sig)
@@ -592,7 +621,7 @@
retval = -ESRCH;
read_lock(&tasklist_lock);
for_each_task(p) {
- if (p->pgrp == pgrp) {
+ if (p->pgrp == pgrp && thread_group_leader(p)) {
int err = send_sig_info(sig, info, p);
if (retval)
retval = err;
@@ -639,8 +668,15 @@
read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
error = -ESRCH;
- if (p)
+ if (p) {
+ if (!thread_group_leader(p)) {
+ struct task_struct *tg;
+ tg = find_task_by_pid(p->tgid);
+ if (tg)
+ p = tg;
+ }
error = send_sig_info(sig, info, p);
+ }
read_unlock(&tasklist_lock);
return error;
}
@@ -663,7 +699,7 @@
read_lock(&tasklist_lock);
for_each_task(p) {
- if (p->pid > 1 && p != current) {
+ if (p->pid > 1 && p != current && thread_group_leader(p)) {
int err = send_sig_info(sig, info, p);
++count;
if (err != -EPERM)
@@ -988,6 +1024,36 @@
return kill_something_info(sig, &info, pid);
}
+/*
+ * Kill only one task, even if it's a CLONE_THREAD task.
+ */
+asmlinkage long
+sys_tkill(int pid, int sig)
+{
+ struct siginfo info;
+ int error;
+ struct task_struct *p;
+
+ /* This is only valid for single tasks */
+ if (pid <= 0)
+ return -EINVAL;
+
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = SI_TKILL;
+ info.si_pid = current->pid;
+ info.si_uid = current->uid;
+
+ read_lock(&tasklist_lock);
+ p = find_task_by_pid(pid);
+ error = -ESRCH;
+ if (p) {
+ error = send_sig_info(sig, &info, p);
+ }
+ read_unlock(&tasklist_lock);
+ return error;
+}
+
asmlinkage long
sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo)
{
@@ -1047,6 +1113,7 @@
|| (k->sa.sa_handler == SIG_DFL
&& (sig == SIGCONT ||
sig == SIGCHLD ||
+ sig == SIGURG ||
sig == SIGWINCH))) {
spin_lock_irq(¤t->sigmask_lock);
if (rm_sig_from_queue(sig, current))
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)