diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 46 |
1 files changed, 18 insertions, 28 deletions
@@ -665,9 +665,7 @@ static int de_thread(struct task_struct *tsk) | |||
665 | * and to assume its PID: | 665 | * and to assume its PID: |
666 | */ | 666 | */ |
667 | if (!thread_group_leader(current)) { | 667 | if (!thread_group_leader(current)) { |
668 | struct task_struct *parent; | ||
669 | struct dentry *proc_dentry1, *proc_dentry2; | 668 | struct dentry *proc_dentry1, *proc_dentry2; |
670 | unsigned long ptrace; | ||
671 | 669 | ||
672 | /* | 670 | /* |
673 | * Wait for the thread group leader to be a zombie. | 671 | * Wait for the thread group leader to be a zombie. |
@@ -678,6 +676,18 @@ static int de_thread(struct task_struct *tsk) | |||
678 | while (leader->exit_state != EXIT_ZOMBIE) | 676 | while (leader->exit_state != EXIT_ZOMBIE) |
679 | yield(); | 677 | yield(); |
680 | 678 | ||
679 | /* | ||
680 | * The only record we have of the real-time age of a | ||
681 | * process, regardless of execs it's done, is start_time. | ||
682 | * All the past CPU time is accumulated in signal_struct | ||
683 | * from sister threads now dead. But in this non-leader | ||
684 | * exec, nothing survives from the original leader thread, | ||
685 | * whose birth marks the true age of this process now. | ||
686 | * When we take on its identity by switching to its PID, we | ||
687 | * also take its birthdate (always earlier than our own). | ||
688 | */ | ||
689 | current->start_time = leader->start_time; | ||
690 | |||
681 | spin_lock(&leader->proc_lock); | 691 | spin_lock(&leader->proc_lock); |
682 | spin_lock(¤t->proc_lock); | 692 | spin_lock(¤t->proc_lock); |
683 | proc_dentry1 = proc_pid_unhash(current); | 693 | proc_dentry1 = proc_pid_unhash(current); |
@@ -692,22 +702,6 @@ static int de_thread(struct task_struct *tsk) | |||
692 | * two threads with a switched PID, and release | 702 | * two threads with a switched PID, and release |
693 | * the former thread group leader: | 703 | * the former thread group leader: |
694 | */ | 704 | */ |
695 | ptrace = leader->ptrace; | ||
696 | parent = leader->parent; | ||
697 | if (unlikely(ptrace) && unlikely(parent == current)) { | ||
698 | /* | ||
699 | * Joker was ptracing his own group leader, | ||
700 | * and now he wants to be his own parent! | ||
701 | * We can't have that. | ||
702 | */ | ||
703 | ptrace = 0; | ||
704 | } | ||
705 | |||
706 | ptrace_unlink(current); | ||
707 | ptrace_unlink(leader); | ||
708 | remove_parent(current); | ||
709 | remove_parent(leader); | ||
710 | |||
711 | 705 | ||
712 | /* Become a process group leader with the old leader's pid. | 706 | /* Become a process group leader with the old leader's pid. |
713 | * Note: The old leader also uses thispid until release_task | 707 | * Note: The old leader also uses thispid until release_task |
@@ -718,19 +712,15 @@ static int de_thread(struct task_struct *tsk) | |||
718 | attach_pid(current, PIDTYPE_PID, current->pid); | 712 | attach_pid(current, PIDTYPE_PID, current->pid); |
719 | attach_pid(current, PIDTYPE_PGID, current->signal->pgrp); | 713 | attach_pid(current, PIDTYPE_PGID, current->signal->pgrp); |
720 | attach_pid(current, PIDTYPE_SID, current->signal->session); | 714 | attach_pid(current, PIDTYPE_SID, current->signal->session); |
721 | list_add_tail(¤t->tasks, &init_task.tasks); | 715 | list_add_tail_rcu(¤t->tasks, &init_task.tasks); |
722 | 716 | ||
723 | current->parent = current->real_parent = leader->real_parent; | ||
724 | leader->parent = leader->real_parent = child_reaper; | ||
725 | current->group_leader = current; | 717 | current->group_leader = current; |
726 | leader->group_leader = leader; | 718 | leader->group_leader = current; |
727 | 719 | ||
728 | add_parent(current); | 720 | /* Reduce leader to a thread */ |
729 | add_parent(leader); | 721 | detach_pid(leader, PIDTYPE_PGID); |
730 | if (ptrace) { | 722 | detach_pid(leader, PIDTYPE_SID); |
731 | current->ptrace = ptrace; | 723 | list_del_init(&leader->tasks); |
732 | __ptrace_link(current, parent); | ||
733 | } | ||
734 | 724 | ||
735 | current->exit_signal = SIGCHLD; | 725 | current->exit_signal = SIGCHLD; |
736 | 726 | ||