diff options
Diffstat (limited to 'sys/compat/svr4/svr4_fcntl.c')
-rw-r--r-- | sys/compat/svr4/svr4_fcntl.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c index 465bae5..a13cd23 100644 --- a/sys/compat/svr4/svr4_fcntl.c +++ b/sys/compat/svr4/svr4_fcntl.c @@ -246,7 +246,6 @@ fd_revoke(td, fd) struct thread *td; int fd; { - struct filedesc *fdp = td->td_proc->p_fd; struct file *fp; struct vnode *vp; struct mount *mp; @@ -254,11 +253,14 @@ fd_revoke(td, fd) int error, *retval; retval = td->td_retval; - if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) + fp = ffind_hold(td, fd); + if (fp == NULL) return EBADF; - if (fp->f_type != DTYPE_VNODE) + if (fp->f_type != DTYPE_VNODE) { + fdrop(fp, td); return EINVAL; + } vp = (struct vnode *) fp->f_data; @@ -281,6 +283,7 @@ fd_revoke(td, fd) vn_finished_write(mp); out: vrele(vp); + fdrop(fp, td); return error; } @@ -291,7 +294,6 @@ fd_truncate(td, fd, flp) int fd; struct flock *flp; { - struct filedesc *fdp = td->td_proc->p_fd; struct file *fp; off_t start, length; struct vnode *vp; @@ -304,15 +306,20 @@ fd_truncate(td, fd, flp) /* * We only support truncating the file. */ - if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) + fp = ffind_hold(td, fd); + if (fp == NULL) return EBADF; vp = (struct vnode *)fp->f_data; - if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) + if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { + fdrop(fp, td); return ESPIPE; + } if ((error = VOP_GETATTR(vp, &vattr, td->td_proc->p_ucred, td)) != 0) + fdrop(fp, td); return error; + } length = vattr.va_size; @@ -330,6 +337,7 @@ fd_truncate(td, fd, flp) break; default: + fdrop(fp, td); return EINVAL; } @@ -341,7 +349,10 @@ fd_truncate(td, fd, flp) SCARG(&ft, fd) = fd; SCARG(&ft, length) = start; - return ftruncate(td, &ft); + error = ftruncate(td, &ft); + + fdrop(fp, td); + return (error); } int @@ -373,15 +384,23 @@ svr4_sys_open(td, uap) if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) && !(td->td_proc->p_flag & P_CONTROLT)) { #if defined(NOTYET) - struct filedesc *fdp = td->td_proc->p_fd; - struct file *fp = fdp->fd_ofiles[retval]; + struct file *fp; + fp = ffind_hold(td, retval); PROC_UNLOCK(p); + /* + * we may have lost a race the above open() and + * another thread issuing a close() + */ + if (fp == NULL) + return (EBADF); /* XXX: correct errno? */ /* ignore any error, just give it a try */ if (fp->f_type == DTYPE_VNODE) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td); - } else + fdrop(fp, td); + } else { PROC_UNLOCK(p); + } #else } PROC_UNLOCK(p); |