Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 165686
b: refs/heads/master
c: 4a30deb
h: refs/heads/master
v: v3
  • Loading branch information
Oleg Nesterov authored and Linus Torvalds committed Sep 24, 2009
1 parent b6f1ef8 commit 44854de
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 964ee7df90d799e38fb1556c57cd5c45fc736436
refs/heads/master: 4a30debfb778240a4b1767d4b0c5a5b25ab97160
2 changes: 2 additions & 0 deletions trunk/include/linux/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ static inline int valid_signal(unsigned long sig)
}

extern int next_signal(struct sigpending *pending, sigset_t *mask);
extern int do_send_sig_info(int sig, struct siginfo *info,
struct task_struct *p, bool group);
extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig,
Expand Down
56 changes: 27 additions & 29 deletions trunk/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,20 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
return send_signal(sig, info, t, 0);
}

int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p,
bool group)
{
unsigned long flags;
int ret = -ESRCH;

if (lock_task_sighand(p, &flags)) {
ret = send_signal(sig, info, p, group);
unlock_task_sighand(p, &flags);
}

return ret;
}

/*
* Force a signal that the process can't ignore: if necessary
* we unblock the signal and change any SIG_IGN to SIG_DFL.
Expand Down Expand Up @@ -1068,18 +1082,10 @@ struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long
*/
int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
{
unsigned long flags;
int ret;

ret = check_kill_permission(sig, info, p);
int ret = check_kill_permission(sig, info, p);

if (!ret && sig) {
ret = -ESRCH;
if (lock_task_sighand(p, &flags)) {
ret = __group_send_sig_info(sig, info, p);
unlock_task_sighand(p, &flags);
}
}
if (!ret && sig)
ret = do_send_sig_info(sig, info, p, true);

return ret;
}
Expand Down Expand Up @@ -1224,26 +1230,17 @@ static int kill_something_info(int sig, struct siginfo *info, pid_t pid)
* These are for backward compatibility with the rest of the kernel source.
*/

/*
* The caller must ensure the task can't exit.
*/
int
send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
{
int ret;
unsigned long flags;

/*
* Make sure legacy kernel users don't send in bad values
* (normal paths check this in check_kill_permission).
*/
if (!valid_signal(sig))
return -EINVAL;

spin_lock_irqsave(&p->sighand->siglock, flags);
ret = specific_send_sig_info(sig, info, p);
spin_unlock_irqrestore(&p->sighand->siglock, flags);
return ret;
return do_send_sig_info(sig, info, p, false);
}

#define __si_special(priv) \
Expand Down Expand Up @@ -2278,7 +2275,6 @@ static int
do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
{
struct task_struct *p;
unsigned long flags;
int error = -ESRCH;

rcu_read_lock();
Expand All @@ -2288,14 +2284,16 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
/*
* The null signal is a permissions and process existence
* probe. No signal is actually delivered.
*
* If lock_task_sighand() fails we pretend the task dies
* after receiving the signal. The window is tiny, and the
* signal is private anyway.
*/
if (!error && sig && lock_task_sighand(p, &flags)) {
error = specific_send_sig_info(sig, info, p);
unlock_task_sighand(p, &flags);
if (!error && sig) {
error = do_send_sig_info(sig, info, p, false);
/*
* If lock_task_sighand() failed we pretend the task
* dies after receiving the signal. The window is tiny,
* and the signal is private anyway.
*/
if (unlikely(error == -ESRCH))
error = 0;
}
}
rcu_read_unlock();
Expand Down

0 comments on commit 44854de

Please sign in to comment.