diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2006-10-02 05:17:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-02 10:57:13 -0400 |
commit | c4b92fc112f7be5cce308128236ff75cc98535c3 (patch) | |
tree | ea4dfac4355c64decbf6aa1ca65af76af43b90fb /kernel/signal.c | |
parent | 558cb325485aaf655130f140e8ddd25392f6c972 (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.c | 57 |
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 | ||
1062 | int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) | 1062 | int __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 | ||
1077 | int 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 | |||
1088 | int __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 | |||
1080 | int | 1096 | int |
1081 | kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) | 1097 | kill_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 | ||
1092 | int | 1108 | int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) |
1093 | kill_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 | ||
1129 | int | ||
1130 | kill_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" */ |
1115 | int kill_proc_info_as_uid(int sig, struct siginfo *info, pid_t pid, | 1140 | int 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 | ||
1292 | int kill_pgrp(struct pid *pid, int sig, int priv) | ||
1293 | { | ||
1294 | return kill_pgrp_info(sig, __si_special(priv), pid); | ||
1295 | } | ||
1296 | EXPORT_SYMBOL(kill_pgrp); | ||
1297 | |||
1298 | int kill_pid(struct pid *pid, int sig, int priv) | ||
1299 | { | ||
1300 | return kill_pid_info(sig, __si_special(priv), pid); | ||
1301 | } | ||
1302 | EXPORT_SYMBOL(kill_pid); | ||
1303 | |||
1267 | int | 1304 | int |
1268 | kill_pg(pid_t pgrp, int sig, int priv) | 1305 | kill_pg(pid_t pgrp, int sig, int priv) |
1269 | { | 1306 | { |