summaryrefslogtreecommitdiffstats
path: root/sys/compat/svr4/svr4_fcntl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/svr4/svr4_fcntl.c')
-rw-r--r--sys/compat/svr4/svr4_fcntl.c39
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);
OpenPOWER on IntegriCloud