diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2012-02-15 04:26:28 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2012-02-15 04:26:28 +0000 |
commit | b861cd7b54c3de28426491f9752a022262f3dc88 (patch) | |
tree | 1d33033d095b99ded617a883d8dd5c8770958218 /sys/kern/sys_generic.c | |
parent | 9db6da3ecdf09727884dc8eb4e22146c7707b98b (diff) |
Hold struct filedesc's fd_lock when writing to the fd_ofiles, fd_ofileflags,
or fd_{lo,hi}maps members, or when doing a read for a write. Fixes hangs
when an rthreaded processes sleeps while copying the fd table for fork()
and catches another thread with the lock.
ok jsing@ tedu@
Diffstat (limited to 'sys/kern/sys_generic.c')
-rw-r--r-- | sys/kern/sys_generic.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 962645dba50..4fbc127dae0 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_generic.c,v 1.73 2011/11/06 12:10:04 guenther Exp $ */ +/* $OpenBSD: sys_generic.c,v 1.74 2012/02/15 04:26:27 guenther Exp $ */ /* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */ /* @@ -408,10 +408,13 @@ sys_ioctl(struct proc *p, void *v, register_t *retval) switch (com = SCARG(uap, com)) { case FIONCLEX: - fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE; - return (0); case FIOCLEX: - fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE; + fdplock(fdp); + if (com == FIONCLEX) + fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE; + else + fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE; + fdpunlock(fdp); return (0); } |