diff options
-rw-r--r-- | include/linux/sched.h | 5 | ||||
-rw-r--r-- | kernel/signal.c | 57 |
2 files changed, 52 insertions, 10 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 660b02f80523..dd6c2164e4a4 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1267,6 +1267,11 @@ extern int send_sig_info(int, struct siginfo *, struct task_struct *); | |||
1267 | extern int send_group_sig_info(int, struct siginfo *, struct task_struct *); | 1267 | extern int send_group_sig_info(int, struct siginfo *, struct task_struct *); |
1268 | extern int force_sigsegv(int, struct task_struct *); | 1268 | extern int force_sigsegv(int, struct task_struct *); |
1269 | extern int force_sig_info(int, struct siginfo *, struct task_struct *); | 1269 | extern int force_sig_info(int, struct siginfo *, struct task_struct *); |
1270 | extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp); | ||
1271 | extern int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp); | ||
1272 | extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid); | ||
1273 | extern int kill_pgrp(struct pid *pid, int sig, int priv); | ||
1274 | extern int kill_pid(struct pid *pid, int sig, int priv); | ||
1270 | extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp); | 1275 | extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp); |
1271 | extern int kill_pg_info(int, struct siginfo *, pid_t); | 1276 | extern int kill_pg_info(int, struct siginfo *, pid_t); |
1272 | extern int kill_proc_info(int, struct siginfo *, pid_t); | 1277 | extern int kill_proc_info(int, struct siginfo *, pid_t); |
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 | { |