diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 22 |
1 files changed, 10 insertions, 12 deletions
@@ -616,6 +616,15 @@ static int de_thread(struct task_struct *tsk) | |||
616 | kmem_cache_free(sighand_cachep, newsighand); | 616 | kmem_cache_free(sighand_cachep, newsighand); |
617 | return -EAGAIN; | 617 | return -EAGAIN; |
618 | } | 618 | } |
619 | |||
620 | /* | ||
621 | * child_reaper ignores SIGKILL, change it now. | ||
622 | * Reparenting needs write_lock on tasklist_lock, | ||
623 | * so it is safe to do it under read_lock. | ||
624 | */ | ||
625 | if (unlikely(current->group_leader == child_reaper)) | ||
626 | child_reaper = current; | ||
627 | |||
619 | zap_other_threads(current); | 628 | zap_other_threads(current); |
620 | read_unlock(&tasklist_lock); | 629 | read_unlock(&tasklist_lock); |
621 | 630 | ||
@@ -660,23 +669,12 @@ static int de_thread(struct task_struct *tsk) | |||
660 | struct dentry *proc_dentry1, *proc_dentry2; | 669 | struct dentry *proc_dentry1, *proc_dentry2; |
661 | unsigned long ptrace; | 670 | unsigned long ptrace; |
662 | 671 | ||
663 | leader = current->group_leader; | ||
664 | /* | ||
665 | * If our leader is the child_reaper become | ||
666 | * the child_reaper and resend SIGKILL signal. | ||
667 | */ | ||
668 | if (unlikely(leader == child_reaper)) { | ||
669 | write_lock(&tasklist_lock); | ||
670 | child_reaper = current; | ||
671 | zap_other_threads(current); | ||
672 | write_unlock(&tasklist_lock); | ||
673 | } | ||
674 | |||
675 | /* | 672 | /* |
676 | * Wait for the thread group leader to be a zombie. | 673 | * Wait for the thread group leader to be a zombie. |
677 | * It should already be zombie at this point, most | 674 | * It should already be zombie at this point, most |
678 | * of the time. | 675 | * of the time. |
679 | */ | 676 | */ |
677 | leader = current->group_leader; | ||
680 | while (leader->exit_state != EXIT_ZOMBIE) | 678 | while (leader->exit_state != EXIT_ZOMBIE) |
681 | yield(); | 679 | yield(); |
682 | 680 | ||