static int ptrace_detach(struct task_struct *child, unsigned int data) { bool dead = false; if (!valid_signal(data)) return -EIO; /* Architecture-specific hardware disable .. */ ptrace_disable(child); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); write_lock_irq(&tasklist_lock); /* * This child can be already killed. Make sure de_thread() or * our sub-thread doing do_wait() didn't do release_task() yet. */ if (child->ptrace) { child->exit_code = data; dead = __ptrace_detach(current, child); } write_unlock_irq(&tasklist_lock); if (unlikely(dead)) release_task(child); return 0; }
int ptrace_detach(struct task_struct *child, unsigned int data) { int dead = 0; if (!valid_signal(data)) return -EIO; /* Architecture-specific hardware disable .. */ ptrace_disable(child); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); write_lock_irq(&tasklist_lock); /* protect against de_thread()->release_task() */ if (child->ptrace) { child->exit_code = data; dead = __ptrace_detach(current, child); if (!child->exit_state) wake_up_process(child); } write_unlock_irq(&tasklist_lock); if (unlikely(dead)) release_task(child); return 0; }
int ptrace_detach(struct task_struct *child, unsigned int data) { if (!valid_signal(data)) return -EIO; /* Architecture-specific hardware disable .. */ ptrace_disable(child); write_lock_irq(&tasklist_lock); /* protect against de_thread()->release_task() */ if (child->ptrace) __ptrace_detach(child, data); write_unlock_irq(&tasklist_lock); return 0; }
int ptrace_detach(struct task_struct *child, unsigned int data) { int ret; if ((unsigned long) data > _NSIG) return -EIO; /* Architecture-specific hardware disable .. */ ptrace_disable(child); clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); ret = -ESRCH; write_lock_irq(&tasklist_lock); /* protect against de_thread()->release_task() */ if (child->ptrace && !child->exit_state) { __ptrace_detach(child, data); ret = 0; } write_unlock_irq(&tasklist_lock); return ret; }