aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sched.h5
-rw-r--r--kernel/signal.c57
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 *);
1267extern int send_group_sig_info(int, struct siginfo *, struct task_struct *); 1267extern int send_group_sig_info(int, struct siginfo *, struct task_struct *);
1268extern int force_sigsegv(int, struct task_struct *); 1268extern int force_sigsegv(int, struct task_struct *);
1269extern int force_sig_info(int, struct siginfo *, struct task_struct *); 1269extern int force_sig_info(int, struct siginfo *, struct task_struct *);
1270extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp);
1271extern int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp);
1272extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid);
1273extern int kill_pgrp(struct pid *pid, int sig, int priv);
1274extern int kill_pid(struct pid *pid, int sig, int priv);
1270extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp); 1275extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp);
1271extern int kill_pg_info(int, struct siginfo *, pid_t); 1276extern int kill_pg_info(int, struct siginfo *, pid_t);
1272extern int kill_proc_info(int, struct siginfo *, pid_t); 1277extern 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
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{