From: Oren Laadan 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 Cc: Oleg Nesterov Cc: Roland McGrath Signed-off-by: Andrew Morton --- kernel/exit.c | 2 +- kernel/sys.c | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff -puN kernel/exit.c~setsid-should-work-for-sub-threads kernel/exit.c --- devel/kernel/exit.c~setsid-should-work-for-sub-threads 2005-12-22 05:09:27.000000000 -0800 +++ devel-akpm/kernel/exit.c 2005-12-22 05:09:27.000000000 -0800 @@ -257,7 +257,7 @@ static inline void reparent_to_init(void void __set_special_pids(pid_t session, pid_t pgrp) { - struct task_struct *curr = current; + struct task_struct *curr = current->group_leader; if (curr->signal->session != session) { detach_pid(curr, PIDTYPE_SID); diff -puN kernel/sys.c~setsid-should-work-for-sub-threads kernel/sys.c --- devel/kernel/sys.c~setsid-should-work-for-sub-threads 2005-12-22 05:09:27.000000000 -0800 +++ devel-akpm/kernel/sys.c 2005-12-22 05:09:27.000000000 -0800 @@ -1210,24 +1210,22 @@ asmlinkage long sys_getsid(pid_t pid) asmlinkage long sys_setsid(void) { + struct task_struct *group_leader = current->group_leader; struct pid *pid; int err = -EPERM; - if (!thread_group_leader(current)) - return -EINVAL; - down(&tty_sem); write_lock_irq(&tasklist_lock); - pid = find_pid(PIDTYPE_PGID, current->pid); + pid = find_pid(PIDTYPE_PGID, group_leader->pid); if (pid) goto out; - current->signal->leader = 1; - __set_special_pids(current->pid, current->pid); - current->signal->tty = NULL; - current->signal->tty_old_pgrp = 0; - err = process_group(current); + group_leader->signal->leader = 1; + __set_special_pids(group_leader->pid, group_leader->pid); + group_leader->signal->tty = NULL; + group_leader->signal->tty_old_pgrp = 0; + err = process_group(group_leader); out: write_unlock_irq(&tasklist_lock); up(&tty_sem); _