aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-10-02 05:17:10 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-02 10:57:13 -0400
commitc4b92fc112f7be5cce308128236ff75cc98535c3 (patch)
treeea4dfac4355c64decbf6aa1ca65af76af43b90fb /kernel/signal.c
parent558cb325485aaf655130f140e8ddd25392f6c972 (diff)
[PATCH] pid: implement signal functions that take a struct pid *
Currently the signal functions all either take a task or a pid_t argument. This patch implements variants that take a struct pid *. After all of the users have been update it is my intention to remove the variants that take a pid_t as using pid_t can be more work (an extra hash table lookup) and difficult to get right in the presence of multiple pid namespaces. There are two kinds of functions introduced in this patch. The are the general use functions kill_pgrp and kill_pid which take a priv argument that is ultimately used to create the appropriate siginfo information, Then there are _kill_pgrp_info, kill_pgrp_info, kill_pid_info the internal implementation helpers that take an explicit siginfo. The distinction is made because filling out an explcit siginfo is tricky, and will be even more tricky when pid namespaces are introduced. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index fb5da6d19f14..5230ddcb1757 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1055,28 +1055,44 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
1055} 1055}
1056 1056
1057/* 1057/*
1058 * kill_pg_info() sends a signal to a process group: this is what the tty 1058 * kill_pgrp_info() sends a signal to a process group: this is what the tty
1059 * control characters do (^C, ^Z etc) 1059 * control characters do (^C, ^Z etc)
1060 */ 1060 */
1061 1061
1062int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) 1062int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
1063{ 1063{
1064 struct task_struct *p = NULL; 1064 struct task_struct *p = NULL;
1065 int retval, success; 1065 int retval, success;
1066 1066
1067 if (pgrp <= 0)
1068 return -EINVAL;
1069
1070 success = 0; 1067 success = 0;
1071 retval = -ESRCH; 1068 retval = -ESRCH;
1072 do_each_task_pid(pgrp, PIDTYPE_PGID, p) { 1069 do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
1073 int err = group_send_sig_info(sig, info, p); 1070 int err = group_send_sig_info(sig, info, p);
1074 success |= !err; 1071 success |= !err;
1075 retval = err; 1072 retval = err;
1076 } while_each_task_pid(pgrp, PIDTYPE_PGID, p); 1073 } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
1077 return success ? 0 : retval; 1074 return success ? 0 : retval;
1078} 1075}
1079 1076
1077int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
1078{
1079 int retval;
1080
1081 read_lock(&tasklist_lock);
1082 retval = __kill_pgrp_info(sig, info, pgrp);
1083 read_unlock(&tasklist_lock);
1084
1085 return retval;
1086}
1087
1088int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
1089{
1090 if (pgrp <= 0)
1091 return -EINVAL;
1092
1093 return __kill_pgrp_info(sig, info, find_pid(pgrp));
1094}
1095
1080int 1096int
1081kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) 1097kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
1082{ 1098{
@@ -1089,8 +1105,7 @@ kill_pg_info(int sig, struct siginfo *info, pid_t pgrp)
1089 return retval; 1105 return retval;
1090} 1106}
1091 1107
1092int 1108int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
1093kill_proc_info(int sig, struct siginfo *info, pid_t pid)
1094{ 1109{
1095 int error; 1110 int error;
1096 int acquired_tasklist_lock = 0; 1111 int acquired_tasklist_lock = 0;
@@ -1101,7 +1116,7 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
1101 read_lock(&tasklist_lock); 1116 read_lock(&tasklist_lock);
1102 acquired_tasklist_lock = 1; 1117 acquired_tasklist_lock = 1;
1103 } 1118 }
1104 p = find_task_by_pid(pid); 1119 p = pid_task(pid, PIDTYPE_PID);
1105 error = -ESRCH; 1120 error = -ESRCH;
1106 if (p) 1121 if (p)
1107 error = group_send_sig_info(sig, info, p); 1122 error = group_send_sig_info(sig, info, p);
@@ -1111,6 +1126,16 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
1111 return error; 1126 return error;
1112} 1127}
1113 1128
1129int
1130kill_proc_info(int sig, struct siginfo *info, pid_t pid)
1131{
1132 int error;
1133 rcu_read_lock();
1134 error = kill_pid_info(sig, info, find_pid(pid));
1135 rcu_read_unlock();
1136 return error;
1137}
1138
1114/* like kill_proc_info(), but doesn't use uid/euid of "current" */ 1139/* like kill_proc_info(), but doesn't use uid/euid of "current" */
1115int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid, 1140int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid,
1116 uid_t uid, uid_t euid, u32 secid) 1141 uid_t uid, uid_t euid, u32 secid)
@@ -1264,6 +1289,18 @@ force_sigsegv(int sig, struct task_struct *p)
1264 return 0; 1289 return 0;
1265} 1290}
1266 1291
1292int kill_pgrp(struct pid *pid, int sig, int priv)
1293{
1294 return kill_pgrp_info(sig, __si_special(priv), pid);
1295}
1296EXPORT_SYMBOL(kill_pgrp);
1297
1298int kill_pid(struct pid *pid, int sig, int priv)
1299{
1300 return kill_pid_info(sig, __si_special(priv), pid);
1301}
1302EXPORT_SYMBOL(kill_pid);
1303
1267int 1304int
1268kill_pg(pid_t pgrp, int sig, int priv) 1305kill_pg(pid_t pgrp, int sig, int priv)
1269{ 1306{