patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / kernel / vserver / signal.c
1 /*
2  *  linux/kernel/vserver/signal.c
3  *
4  *  Virtual Server: Signal Support
5  *
6  *  Copyright (C) 2003-2004  Herbert Pƶtzl
7  *
8  *  V0.01  broken out from vcontext V0.05
9  *
10  */
11
12 #include <linux/config.h>
13 #include <linux/sched.h>
14
15 #include <asm/errno.h>
16 #include <asm/uaccess.h>
17
18 #include <linux/vs_base.h>
19 #include <linux/vs_context.h>
20 #include <linux/vserver/signal.h>
21
22
23 int vc_ctx_kill(uint32_t id, void __user *data)
24 {
25         int retval, count=0;
26         struct vcmd_ctx_kill_v0 vc_data;
27         struct siginfo info;
28         struct task_struct *p;
29         struct vx_info *vxi;
30
31         if (!vx_check(0, VX_ADMIN))
32                 return -ENOSYS;
33         if (copy_from_user (&vc_data, data, sizeof(vc_data)))
34                 return -EFAULT;
35         
36         info.si_signo = vc_data.sig;
37         info.si_errno = 0;
38         info.si_code = SI_USER;
39         info.si_pid = current->pid;
40         info.si_uid = current->uid;
41
42         vxi = locate_vx_info(id);
43         if (!vxi)
44                 return -ESRCH;
45
46         retval = -ESRCH;
47         read_lock(&tasklist_lock);
48         switch (vc_data.pid) {
49         case -1:
50         case  0:
51                 for_each_process(p) {
52                         int err = 0;
53
54                         if (vx_task_xid(p) != id || p->pid <= 1 ||
55                                 (vc_data.pid && vxi->vx_initpid == p->pid) ||
56                                 !thread_group_leader(p))
57                                 continue;
58
59                         err = send_sig_info(vc_data.sig, &info, p);
60                         ++count;
61                         if (err != -EPERM)
62                                 retval = err;
63                 }
64                 break;
65                 
66         default:
67         p = find_task_by_pid(vc_data.pid);
68                 if (p) {
69                         if (!thread_group_leader(p)) {
70                                 struct task_struct *tg;
71                         
72                                 tg = find_task_by_pid(p->tgid);
73                                 if (tg)
74                                         p = tg;
75                         }
76                         if ((id == -1) || (vx_task_xid(p) == id))
77                                 retval = send_sig_info(vc_data.sig, &info, p);
78                 }
79                 break;
80         }
81         read_unlock(&tasklist_lock);
82         put_vx_info(vxi);
83         return retval;
84 }
85
86