diff options
author | Oren Laadan <orenl@cs.columbia.edu> | 2006-01-08 04:03:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-08 23:14:01 -0500 |
commit | e19f247a3dbd85485ec13174817ae9c2478fe541 (patch) | |
tree | 1d6f6fa28d70d51d1ce71264b07ec1afd768e9a6 | |
parent | ee0acf90d320c29916ba8c5c1b2e908d81f5057d (diff) |
[PATCH] setpgid: should work for sub-threads
setsid() does not work unless the calling process is a
thread_group_leader().
'man setpgid' does not tell anything about that, so I consider this
behaviour is a bug.
Signed-off-by: Oren Laadan <orenl@cs.columbia.edu>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Roland McGrath <roland@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | kernel/exit.c | 2 | ||||
-rw-r--r-- | kernel/sys.c | 16 |
2 files changed, 8 insertions, 10 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index a80824f6108b..caceabf3f230 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -257,7 +257,7 @@ static inline void reparent_to_init(void) | |||
257 | 257 | ||
258 | void __set_special_pids(pid_t session, pid_t pgrp) | 258 | void __set_special_pids(pid_t session, pid_t pgrp) |
259 | { | 259 | { |
260 | struct task_struct *curr = current; | 260 | struct task_struct *curr = current->group_leader; |
261 | 261 | ||
262 | if (curr->signal->session != session) { | 262 | if (curr->signal->session != session) { |
263 | detach_pid(curr, PIDTYPE_SID); | 263 | detach_pid(curr, PIDTYPE_SID); |
diff --git a/kernel/sys.c b/kernel/sys.c index 43e557211d8d..f497bf56ada1 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1215,24 +1215,22 @@ asmlinkage long sys_getsid(pid_t pid) | |||
1215 | 1215 | ||
1216 | asmlinkage long sys_setsid(void) | 1216 | asmlinkage long sys_setsid(void) |
1217 | { | 1217 | { |
1218 | struct task_struct *group_leader = current->group_leader; | ||
1218 | struct pid *pid; | 1219 | struct pid *pid; |
1219 | int err = -EPERM; | 1220 | int err = -EPERM; |
1220 | 1221 | ||
1221 | if (!thread_group_leader(current)) | ||
1222 | return -EINVAL; | ||
1223 | |||
1224 | down(&tty_sem); | 1222 | down(&tty_sem); |
1225 | write_lock_irq(&tasklist_lock); | 1223 | write_lock_irq(&tasklist_lock); |
1226 | 1224 | ||
1227 | pid = find_pid(PIDTYPE_PGID, current->pid); | 1225 | pid = find_pid(PIDTYPE_PGID, group_leader->pid); |
1228 | if (pid) | 1226 | if (pid) |
1229 | goto out; | 1227 | goto out; |
1230 | 1228 | ||
1231 | current->signal->leader = 1; | 1229 | group_leader->signal->leader = 1; |
1232 | __set_special_pids(current->pid, current->pid); | 1230 | __set_special_pids(group_leader->pid, group_leader->pid); |
1233 | current->signal->tty = NULL; | 1231 | group_leader->signal->tty = NULL; |
1234 | current->signal->tty_old_pgrp = 0; | 1232 | group_leader->signal->tty_old_pgrp = 0; |
1235 | err = process_group(current); | 1233 | err = process_group(group_leader); |
1236 | out: | 1234 | out: |
1237 | write_unlock_irq(&tasklist_lock); | 1235 | write_unlock_irq(&tasklist_lock); |
1238 | up(&tty_sem); | 1236 | up(&tty_sem); |