summaryrefslogtreecommitdiff
path: root/sys/kern/sys_process.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2012-04-06 20:28:52 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2012-04-06 20:28:52 +0000
commitc5c76f908e51cea9bc8bc7699ce0a2a1ad32023e (patch)
tree55813a39bfa18821dc763f622a00b26ddfcc63fb /sys/kern/sys_process.c
parenta80d0d269a925bf54b33b60a968368e2db109ad0 (diff)
Implement PT_GET_THREAD_FIRS and PT_GET_THREAD_NEXT.
ok miod@
Diffstat (limited to 'sys/kern/sys_process.c')
-rw-r--r--sys/kern/sys_process.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 79ee654ac55..1610ad88f17 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_process.c,v 1.51 2012/03/10 05:54:28 guenther Exp $ */
+/* $OpenBSD: sys_process.c,v 1.52 2012/04/06 20:28:51 kettenis Exp $ */
/* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */
/*-
@@ -89,6 +89,7 @@ sys_ptrace(struct proc *p, void *v, register_t *retval)
struct iovec iov;
struct ptrace_io_desc piod;
struct ptrace_event pe;
+ struct ptrace_thread_state pts;
struct reg *regs;
#if defined (PT_SETFPREGS) || defined (PT_GETFPREGS)
struct fpreg *fpregs;
@@ -269,7 +270,8 @@ sys_ptrace(struct proc *p, void *v, register_t *retval)
/*
* (3) it's not currently stopped.
*/
- if (t->p_stat != SSTOP || !ISSET(t->p_flag, P_WAITED))
+ if (t->p_stat != SSTOP ||
+ !ISSET(tr->ps_mainproc->p_flag, P_WAITED))
return (EBUSY);
break;
@@ -291,12 +293,28 @@ sys_ptrace(struct proc *p, void *v, register_t *retval)
/*
* Do the work here because the request isn't actually
* associated with 't'
- * XXX
*/
+ if (SCARG(uap, data) != sizeof(pts))
+ return (EINVAL);
- return (ENOTSUP); /* XXX */
+ if (req == PT_GET_THREAD_NEXT) {
+ error = copyin(SCARG(uap, addr), &pts, sizeof(pts));
+ if (error)
+ return (error);
- break;
+ t = pfind(pts.pts_tid - THREAD_PID_OFFSET);
+ if (t == NULL)
+ return (ESRCH);
+ if (t->p_p != tr)
+ return (EINVAL);
+ t = TAILQ_NEXT(t, p_thr_link);
+ }
+
+ if (t == NULL)
+ pts.pts_tid = -1;
+ else
+ pts.pts_tid = t->p_pid + THREAD_PID_OFFSET;
+ return (copyout(&pts, SCARG(uap, addr), sizeof(pts)));
default: /* It was not a legal request. */
return (EINVAL);