-/* $OpenBSD: kern_exec.c,v 1.41 2000/03/23 15:55:52 art Exp $ */
+/* $OpenBSD: kern_exec.c,v 1.42 2000/04/20 10:03:42 art Exp $ */
/* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */
/*-
*/
if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) {
p->p_traceflag = 0;
- vrele(p->p_tracep);
- p->p_tracep = NULL;
+ ktrsettracevnode(p, NULL);
}
#endif
p->p_ucred = crcopy(cred);
-/* $OpenBSD: kern_exit.c,v 1.22 2000/03/23 15:55:52 art Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.23 2000/04/20 10:03:43 art Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
#include <sys/filedesc.h>
#include <sys/signalvar.h>
#include <sys/sched.h>
+#include <sys/ktrace.h>
#ifdef SYSVSHM
#include <sys/shm.h>
#endif
*/
p->p_traceflag = 0; /* don't trace the vrele() */
if (p->p_tracep)
- vrele(p->p_tracep);
+ ktrsettracevnode(p, NULL);
#endif
/*
* Remove proc from allproc queue and pidhash chain.
-/* $OpenBSD: kern_ktrace.c,v 1.17 2000/04/19 10:56:41 art Exp $ */
+/* $OpenBSD: kern_ktrace.c,v 1.18 2000/04/20 10:03:42 art Exp $ */
/* $NetBSD: kern_ktrace.c,v 1.23 1996/02/09 18:59:36 christos Exp $ */
/*
int ktrwrite __P((struct vnode *, struct ktr_header *));
int ktrcanset __P((struct proc *, struct proc *));
+/*
+ * Change the trace vnode in a correct way (to avoid races).
+ */
+void
+ktrsettracevnode(p, newvp)
+ struct proc *p;
+ struct vnode *newvp;
+{
+ struct vnode *vp;
+
+ if (p->p_tracep == newvp) /* avoid work */
+ return;
+
+ if (newvp != NULL)
+ VREF(newvp);
+
+ vp = p->p_tracep;
+ p->p_tracep = newvp;
+
+ if (vp != NULL)
+ vrele(vp);
+}
+
void
ktrinitheader(kth, p, type)
struct ktr_header *kth;
for (p = LIST_FIRST(&allproc); p; p = LIST_NEXT(p, p_list)) {
if (p->p_tracep == vp) {
if (ktrcanset(curp, p)) {
- p->p_tracep = NULL;
p->p_traceflag = 0;
- vrele(vp);
+ ktrsettracevnode(p, NULL);
} else
error = EPERM;
}
if (!ktrcanset(curp, p))
return (0);
if (ops == KTROP_SET) {
- if (p->p_tracep != vp) {
- /*
- * if trace file already in use, relinquish
- */
- if (p->p_tracep != NULL)
- vrele(p->p_tracep);
- VREF(vp);
- p->p_tracep = vp;
- }
+ ktrsettracevnode(p, vp);
p->p_traceflag |= facs;
if (curp->p_ucred->cr_uid == 0)
p->p_traceflag |= KTRFAC_ROOT;
if (((p->p_traceflag &= ~facs) & KTRFAC_MASK) == 0) {
/* no more tracing */
p->p_traceflag = 0;
- if (p->p_tracep != NULL) {
- vrele(p->p_tracep);
- p->p_tracep = NULL;
- }
+ ktrsettracevnode(p, NULL);
}
}
error);
for (p = LIST_FIRST(&allproc); p != NULL; p = LIST_NEXT(p, p_list)) {
if (p->p_tracep == vp) {
- p->p_tracep = NULL;
p->p_traceflag = 0;
- vrele(vp);
+ ktrsettracevnode(p, NULL);
}
}
-/* $OpenBSD: ktrace.h,v 1.2 1996/03/03 12:11:54 niklas Exp $ */
+/* $OpenBSD: ktrace.h,v 1.3 2000/04/20 10:03:41 art Exp $ */
/* $NetBSD: ktrace.h,v 1.12 1996/02/04 02:12:29 christos Exp $ */
/*
void ktrsyscall __P((struct vnode *, register_t, size_t, register_t []));
void ktrsysret __P((struct vnode *, register_t, int, register_t));
+void ktrsettracevnode __P((struct proc *, struct vnode *));
+
#endif /* !_KERNEL */