diff options
author | netchild <netchild@FreeBSD.org> | 2006-10-28 10:59:59 +0000 |
---|---|---|
committer | netchild <netchild@FreeBSD.org> | 2006-10-28 10:59:59 +0000 |
commit | 963ac453db05c1bc7038ec526ac5fc55192d4171 (patch) | |
tree | 35564ebb9838ad07de84ad6a3cd948742bc6dc50 /sys/compat/linux/linux_emul.c | |
parent | d6a1b3d7dc16f096b80af154e8f00218f56c9e1a (diff) | |
download | FreeBSD-src-963ac453db05c1bc7038ec526ac5fc55192d4171.zip FreeBSD-src-963ac453db05c1bc7038ec526ac5fc55192d4171.tar.gz |
MFP4:
Implement prctl().
Submitted by: rdivacky
Tested with: LTP
Diffstat (limited to 'sys/compat/linux/linux_emul.c')
-rw-r--r-- | sys/compat/linux/linux_emul.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/compat/linux/linux_emul.c b/sys/compat/linux/linux_emul.c index 2f92ebd..a2471ac 100644 --- a/sys/compat/linux/linux_emul.c +++ b/sys/compat/linux/linux_emul.c @@ -84,6 +84,7 @@ linux_proc_init(struct thread *td, pid_t child, int flags) /* non-exec call */ em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO); em->pid = child; + em->pdeath_signal = 0; if (flags & CLONE_VM) { /* handled later in the code */ } else { @@ -151,6 +152,7 @@ linux_proc_exit(void *arg __unused, struct proc *p) int error; struct thread *td = FIRST_THREAD_IN_PROC(p); int *child_clear_tid; + struct proc *q, *nq; if (__predict_true(p->p_sysent != &elf_linux_sysvec)) return; @@ -204,6 +206,26 @@ linux_proc_exit(void *arg __unused, struct proc *p) /* clean the stuff up */ free(em, M_LINUX); + + /* this is a little weird but rewritten from exit1() */ + sx_xlock(&proctree_lock); + q = LIST_FIRST(&p->p_children); + for (; q != NULL; q = nq) { + nq = LIST_NEXT(q, p_sibling); + if (q->p_flag & P_WEXIT) + continue; + if (__predict_false(q->p_sysent != &elf_linux_sysvec)) + continue; + em = em_find(q, EMUL_UNLOCKED); + KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid)); + if (em->pdeath_signal != 0) { + PROC_LOCK(q); + psignal(q, em->pdeath_signal); + PROC_UNLOCK(q); + } + EMUL_UNLOCK(&emul_lock); + } + sx_xunlock(&proctree_lock); } /* @@ -251,7 +273,7 @@ linux_schedtail(void *arg __unused, struct proc *p) int error = 0; int *child_set_tid; - if (p->p_sysent != &elf_linux_sysvec) + if (__predict_true(p->p_sysent != &elf_linux_sysvec)) return; retry: |