summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorJens Axboe <axboe@burns.home.kernel.dk>2002-02-07 10:37:19 +0100
committerJens Axboe <axboe@burns.home.kernel.dk>2002-02-07 10:37:19 +0100
commit2adf779dd193e1c8673f5896da4fef1dda830774 (patch)
treef8014bbf33b023dd09bda6f9145bb776f73389d2 /kernel
parent07916eb45f4a6c63acb93e269c10490e4e623a0c (diff)
parent0ec120046dee44027a28b66a3c28d1031982a9eb (diff)
Merge http://linux.bkbits.net/linux-2.5
into burns.home.kernel.dk:/usr/local/kernel/BK/linux-2.5
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c4
-rw-r--r--kernel/ksyms.c4
-rw-r--r--kernel/signal.c72
-rw-r--r--kernel/sysctl.c2
4 files changed, 76 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 8c10cad0e021..bfbae1b15439 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -724,10 +724,10 @@ int do_fork(unsigned long clone_flags, unsigned long stack_start,
/* Need tasklist lock for parent etc handling! */
write_lock_irq(&tasklist_lock);
- /* CLONE_PARENT and CLONE_THREAD re-use the old parent */
+ /* CLONE_PARENT re-uses the old parent */
p->p_opptr = current->p_opptr;
p->p_pptr = current->p_pptr;
- if (!(clone_flags & (CLONE_PARENT | CLONE_THREAD))) {
+ if (!(clone_flags & CLONE_PARENT)) {
p->p_opptr = current;
if (!(p->ptrace & PT_PTRACED))
p->p_pptr = current;
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index c271a8e6f6fc..42ebfe7f746c 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -251,6 +251,7 @@ EXPORT_SYMBOL(vfs_rename);
EXPORT_SYMBOL(vfs_statfs);
EXPORT_SYMBOL(generic_read_dir);
EXPORT_SYMBOL(generic_file_llseek);
+EXPORT_SYMBOL(remote_llseek);
EXPORT_SYMBOL(no_llseek);
EXPORT_SYMBOL(__pollwait);
EXPORT_SYMBOL(poll_freewait);
@@ -274,6 +275,9 @@ EXPORT_SYMBOL(lock_may_write);
EXPORT_SYMBOL(dcache_readdir);
EXPORT_SYMBOL(fd_install);
EXPORT_SYMBOL(put_unused_fd);
+EXPORT_SYMBOL(get_sb_bdev);
+EXPORT_SYMBOL(get_sb_nodev);
+EXPORT_SYMBOL(get_sb_single);
/* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
EXPORT_SYMBOL(default_llseek);
diff --git a/kernel/signal.c b/kernel/signal.c
index 3741c8a4a6ac..d648cff08eb6 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -142,6 +142,35 @@ flush_signal_handlers(struct task_struct *t)
}
}
+/*
+ * 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(&current->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
@@ -589,7 +618,7 @@ kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
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;
@@ -636,8 +665,15 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
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;
}
@@ -660,7 +696,7 @@ static int kill_something_info(int sig, struct siginfo *info, int pid)
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)
@@ -985,6 +1021,36 @@ sys_kill(int pid, int sig)
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)
{
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 9035ae798d0e..21a5c8fe6543 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -677,7 +677,7 @@ static ssize_t do_rw_proc(int write, struct file * file, char * buf,
size_t res;
ssize_t error;
- de = (struct proc_dir_entry*) file->f_dentry->d_inode->u.generic_ip;
+ de = PDE(file->f_dentry->d_inode);
if (!de || !de->data)
return -ENOTDIR;
table = (struct ctl_table *) de->data;