mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-28 11:57:28 +00:00
Replace ffind_* with fget calls.
Make fget MPsafe. Make fgetvp and fgetsock use the fget subsystem to reduce code bloat. Push giant down in fpathconf().
This commit is contained in:
parent
59047ccade
commit
a4db49537b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=89319
@ -672,10 +672,8 @@ osf1_fstat(td, uap)
|
||||
struct osf1_stat oub;
|
||||
int error;
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
return (error);
|
||||
error = fo_stat(fp, &ub, td);
|
||||
fdrop(fp, td);
|
||||
cvtstat2osf1(&ub, &oub);
|
||||
|
@ -137,11 +137,13 @@ linux_open(struct thread *td, struct linux_open_args *args)
|
||||
SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
|
||||
struct file *fp;
|
||||
|
||||
fp = ffind_hold(td, td->td_retval[0]);
|
||||
error = fget(td, td->td_retval[0], &fp);
|
||||
PROC_UNLOCK(p);
|
||||
if (fp->f_type == DTYPE_VNODE)
|
||||
fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td);
|
||||
fdrop(fp, td);
|
||||
if (!error) {
|
||||
if (fp->f_type == DTYPE_VNODE)
|
||||
fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td);
|
||||
fdrop(fp, td);
|
||||
}
|
||||
} else
|
||||
PROC_UNLOCK(p);
|
||||
#ifdef DEBUG
|
||||
@ -996,9 +998,9 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args)
|
||||
* significant effect for pipes (SIGIO is not delivered for
|
||||
* pipes under Linux-2.2.35 at least).
|
||||
*/
|
||||
fp = ffind_hold(td, args->fd);
|
||||
if (fp == NULL)
|
||||
return EBADF;
|
||||
error = fget(td, args->fd, &fp);
|
||||
if (error)
|
||||
return (error);
|
||||
if (fp->f_type == DTYPE_PIPE) {
|
||||
fdrop(fp, td);
|
||||
return (EINVAL);
|
||||
|
@ -109,9 +109,8 @@ linux_ioctl_disk(struct thread *td, struct linux_ioctl_args *args)
|
||||
int error;
|
||||
struct disklabel dl;
|
||||
|
||||
fp = ffind_hold(td, args->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
switch (args->cmd & 0xffff) {
|
||||
case LINUX_BLKGETSIZE:
|
||||
error = fo_ioctl(fp, DIOCGDINFO, (caddr_t)&dl, td);
|
||||
@ -555,9 +554,9 @@ linux_ioctl_termio(struct thread *td, struct linux_ioctl_args *args)
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
fp = ffind_hold(td, args->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
|
||||
switch (args->cmd & 0xffff) {
|
||||
|
||||
case LINUX_TCGETS:
|
||||
@ -1249,9 +1248,8 @@ linux_ioctl_cdrom(struct thread *td, struct linux_ioctl_args *args)
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
fp = ffind_hold(td, args->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
switch (args->cmd & 0xffff) {
|
||||
|
||||
case LINUX_CDROMPAUSE:
|
||||
@ -1706,9 +1704,8 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
fp = ffind_hold(td, args->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
switch (args->cmd & 0xffff) {
|
||||
|
||||
case LINUX_KIOCSOUND:
|
||||
@ -2259,9 +2256,8 @@ linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
|
||||
(unsigned long)args->cmd);
|
||||
#endif
|
||||
|
||||
fp = ffind_hold(td, args->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
|
||||
fdrop(fp, td);
|
||||
return (EBADF);
|
||||
|
@ -160,9 +160,8 @@ linux_newfstat(struct thread *td, struct linux_newfstat_args *args)
|
||||
printf(ARGS(newfstat, "%d, *"), args->fd);
|
||||
#endif
|
||||
|
||||
fp = ffind_hold(td, args->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
|
||||
error = fo_stat(fp, &buf, td);
|
||||
fdrop(fp, td);
|
||||
|
@ -246,23 +246,14 @@ fd_revoke(td, fd)
|
||||
struct thread *td;
|
||||
int fd;
|
||||
{
|
||||
struct file *fp;
|
||||
struct vnode *vp;
|
||||
struct mount *mp;
|
||||
struct vattr vattr;
|
||||
int error, *retval;
|
||||
|
||||
retval = td->td_retval;
|
||||
fp = ffind_hold(td, fd);
|
||||
if (fp == NULL)
|
||||
return EBADF;
|
||||
|
||||
if (fp->f_type != DTYPE_VNODE) {
|
||||
fdrop(fp, td);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
vp = (struct vnode *) fp->f_data;
|
||||
if ((error = fgetvp(td, fd, &vp)) != 0)
|
||||
return (error);
|
||||
|
||||
if (vp->v_type != VCHR && vp->v_type != VBLK) {
|
||||
error = EINVAL;
|
||||
@ -283,7 +274,6 @@ fd_revoke(td, fd)
|
||||
vn_finished_write(mp);
|
||||
out:
|
||||
vrele(vp);
|
||||
fdrop(fp, td);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -294,7 +284,6 @@ fd_truncate(td, fd, flp)
|
||||
int fd;
|
||||
struct flock *flp;
|
||||
{
|
||||
struct file *fp;
|
||||
off_t start, length;
|
||||
struct vnode *vp;
|
||||
struct vattr vattr;
|
||||
@ -306,18 +295,16 @@ fd_truncate(td, fd, flp)
|
||||
/*
|
||||
* We only support truncating the file.
|
||||
*/
|
||||
fp = ffind_hold(td, fd);
|
||||
if (fp == NULL)
|
||||
return EBADF;
|
||||
if ((error = fgetvp(td, uap->fd, &vp)) != 0)
|
||||
return (error);
|
||||
|
||||
vp = (struct vnode *)fp->f_data;
|
||||
if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
|
||||
fdrop(fp, td);
|
||||
if (vp->v_type == VFIFO) {
|
||||
vrele(vp);
|
||||
return ESPIPE;
|
||||
}
|
||||
|
||||
if ((error = VOP_GETATTR(vp, &vattr, td->td_proc->p_ucred, td)) != 0)
|
||||
fdrop(fp, td);
|
||||
vrele(vp);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -337,7 +324,7 @@ fd_truncate(td, fd, flp)
|
||||
break;
|
||||
|
||||
default:
|
||||
fdrop(fp, td);
|
||||
vrele(vp);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
@ -351,7 +338,7 @@ fd_truncate(td, fd, flp)
|
||||
|
||||
error = ftruncate(td, &ft);
|
||||
|
||||
fdrop(fp, td);
|
||||
vrele(vp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -386,13 +373,13 @@ svr4_sys_open(td, uap)
|
||||
#if defined(NOTYET)
|
||||
struct file *fp;
|
||||
|
||||
fp = ffind_hold(td, retval);
|
||||
error = fget(td, retval, &fp);
|
||||
PROC_UNLOCK(p);
|
||||
/*
|
||||
* we may have lost a race the above open() and
|
||||
* another thread issuing a close()
|
||||
*/
|
||||
if (fp == NULL)
|
||||
if (error)
|
||||
return (EBADF); /* XXX: correct errno? */
|
||||
/* ignore any error, just give it a try */
|
||||
if (fp->f_type == DTYPE_VNODE)
|
||||
|
@ -107,8 +107,7 @@ svr4_sys_read(td, uap)
|
||||
SCARG(&ra, buf) = SCARG(uap, buf);
|
||||
SCARG(&ra, nbyte) = SCARG(uap, nbyte);
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL) {
|
||||
if (fget(td, uap->fd, &fp) != 0) {
|
||||
DPRINTF(("Something fishy with the user-supplied file descriptor...\n"));
|
||||
return EBADF;
|
||||
}
|
||||
|
@ -102,9 +102,8 @@ svr4_sys_ioctl(td, uap)
|
||||
retval = td->td_retval;
|
||||
cmd = SCARG(uap, com);
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL)
|
||||
return EBADF;
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
return (error);
|
||||
|
||||
if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
|
||||
fdrop(fp, td);
|
||||
|
@ -1717,8 +1717,7 @@ svr4_sys_putmsg(td, uap)
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL) {
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0) {
|
||||
#ifdef DEBUG_SVR4
|
||||
uprintf("putmsg: bad fp\n");
|
||||
#endif
|
||||
@ -1905,8 +1904,7 @@ svr4_sys_getmsg(td, uap)
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL) {
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0) {
|
||||
#ifdef DEBUG_SVR4
|
||||
uprintf("getmsg: bad fp\n");
|
||||
#endif
|
||||
|
@ -2582,9 +2582,8 @@ aac_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
|
||||
|
||||
debug_called(2);
|
||||
|
||||
fp = ffind_hold(td, args->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
cmd = args->cmd;
|
||||
|
||||
/*
|
||||
|
@ -844,9 +844,8 @@ linux_ioctl_tdfx(struct thread *td, struct linux_ioctl_args* args)
|
||||
|
||||
struct file *fp;
|
||||
|
||||
fp = ffind_hold(td, args->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, args->fd, &fp)) != 0)
|
||||
return (error);
|
||||
/* We simply copy the data and send it right to ioctl */
|
||||
copyin((caddr_t)args->arg, &d_pio, sizeof(d_pio));
|
||||
error = fo_ioctl(fp, cmd, (caddr_t)&d_pio, td);
|
||||
|
@ -213,11 +213,8 @@ fdesc_lookup(ap)
|
||||
fd = 10 * fd + *pname++ - '0';
|
||||
}
|
||||
|
||||
fp = ffind_hold(td, fd);
|
||||
if (fp == NULL) {
|
||||
error = EBADF;
|
||||
if ((error = fget(td, fd, &fp)) != 0)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
error = fdesc_allocvp(Fdesc, FD_DESC+fd, dvp->v_mount, &fvp, td);
|
||||
fdrop(fp, td);
|
||||
@ -301,9 +298,8 @@ fdesc_getattr(ap)
|
||||
case Fdesc:
|
||||
fd = VTOFDESC(vp)->fd_fd;
|
||||
|
||||
fp = ffind_hold(ap->a_td, fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(ap->a_td, fd, &fp)) != 0)
|
||||
return (error);
|
||||
|
||||
bzero(&stb, sizeof(stb));
|
||||
error = fo_stat(fp, &stb, ap->a_td);
|
||||
|
@ -402,11 +402,8 @@ portal_open(ap)
|
||||
* Check that the mode the file is being opened for is a subset
|
||||
* of the mode of the existing descriptor.
|
||||
*/
|
||||
fp = ffind_hold(td, fd);
|
||||
if (fp == NULL) {
|
||||
error = EBADF;
|
||||
if ((error = fget(td, fd, &fp)) != 0)
|
||||
goto bad;
|
||||
}
|
||||
if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) {
|
||||
fdrop(fp, td);
|
||||
portal_closefd(td, fd);
|
||||
|
@ -194,10 +194,11 @@ ibcs2_open(td, uap)
|
||||
PROC_LOCK(p);
|
||||
if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
fp = ffind_hold(td, td->td_retval[0]);
|
||||
error = fget(td, td->td_retval[0], &fp);
|
||||
PROC_UNLOCK(p);
|
||||
if (fp == NULL)
|
||||
if (error)
|
||||
return (EBADF);
|
||||
|
||||
/* ignore any error, just give it a try */
|
||||
|
@ -346,8 +346,7 @@ ibcs2_ioctl(td, uap)
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL) {
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0) {
|
||||
DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid,
|
||||
SCARG(uap, fd)));
|
||||
return EBADF;
|
||||
|
@ -843,36 +843,31 @@ fpathconf(td, uap)
|
||||
struct vnode *vp;
|
||||
int error;
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
mtx_lock(&Giant);
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
goto done2;
|
||||
return (error);
|
||||
|
||||
switch (fp->f_type) {
|
||||
case DTYPE_PIPE:
|
||||
case DTYPE_SOCKET:
|
||||
if (uap->name != _PC_PIPE_BUF) {
|
||||
fdrop(fp, td);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
} else {
|
||||
td->td_retval[0] = PIPE_BUF;
|
||||
error = 0;
|
||||
}
|
||||
td->td_retval[0] = PIPE_BUF;
|
||||
error = 0;
|
||||
break;
|
||||
case DTYPE_FIFO:
|
||||
case DTYPE_VNODE:
|
||||
vp = (struct vnode *)fp->f_data;
|
||||
mtx_lock(&Giant);
|
||||
error = VOP_PATHCONF(vp, uap->name, td->td_retval);
|
||||
mtx_unlock(&Giant);
|
||||
break;
|
||||
default:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
fdrop(fp, td);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return(error);
|
||||
}
|
||||
|
||||
@ -1455,50 +1450,6 @@ closef(fp, td)
|
||||
return (fdrop(fp, td));
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the struct file 'fd' in process 'p' and bump it's refcount
|
||||
* struct file is not locked on return.
|
||||
*/
|
||||
struct file *
|
||||
ffind_hold(td, fd)
|
||||
struct thread *td;
|
||||
int fd;
|
||||
{
|
||||
struct file *fp;
|
||||
|
||||
fp = ffind_lock(td, fd);
|
||||
if (fp != NULL)
|
||||
FILE_UNLOCK(fp);
|
||||
return (fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the struct file 'fd' in process 'p' and bump it's refcount,
|
||||
* struct file is locked on return.
|
||||
*/
|
||||
struct file *
|
||||
ffind_lock(td, fd)
|
||||
struct thread *td;
|
||||
int fd;
|
||||
{
|
||||
struct filedesc *fdp;
|
||||
struct file *fp;
|
||||
|
||||
if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
|
||||
return (NULL);
|
||||
FILEDESC_LOCK(fdp);
|
||||
if (fd < 0 || fd >= fdp->fd_nfiles ||
|
||||
(fp = fdp->fd_ofiles[fd]) == NULL ||
|
||||
fp->f_ops == &badfileops) {
|
||||
fp = NULL;
|
||||
} else {
|
||||
FILE_LOCK(fp);
|
||||
fhold_locked(fp);
|
||||
}
|
||||
FILEDESC_UNLOCK(fdp);
|
||||
return (fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop reference on struct file passed in, may call closef if the
|
||||
* reference hits zero.
|
||||
@ -1515,29 +1466,38 @@ fdrop(fp, td)
|
||||
|
||||
/*
|
||||
* Extract the file pointer associated with the specified descriptor for
|
||||
* the current user process. If no error occured 0 is returned, *fpp
|
||||
* will be set to the file pointer, and the file pointer's ref count
|
||||
* will be bumped. Use fdrop() to drop it. If an error occured the
|
||||
* non-zero error is returned and *fpp is set to NULL.
|
||||
* the current user process.
|
||||
*
|
||||
* This routine requires Giant for the moment. Once enough of the
|
||||
* system is converted over to this and other encapsulated APIs we
|
||||
* will be able to mutex it and call it without Giant.
|
||||
* If the descriptor doesn't exist, EBADF is returned.
|
||||
*
|
||||
* If the descriptor exists but doesn't match 'flags' then
|
||||
* return EBADF for read attempts and EINVAL for write attempts.
|
||||
*
|
||||
* If 'hold' is set (non-zero) the file's refcount will be bumped on return.
|
||||
* It should be droped with fdrop().
|
||||
* If it is not set, then the refcount will not be bumped however the
|
||||
* thread's filedesc struct will be returned locked (for fgetsock).
|
||||
*
|
||||
* If an error occured the non-zero error is returned and *fpp is set to NULL.
|
||||
* Otherwise *fpp is set and zero is returned.
|
||||
*/
|
||||
static __inline
|
||||
int
|
||||
_fget(struct thread *td, int fd, struct file **fpp, int flags)
|
||||
_fget(struct thread *td, int fd, struct file **fpp, int flags, int hold)
|
||||
{
|
||||
struct filedesc *fdp;
|
||||
struct file *fp;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
fdp = td->td_proc->p_fd;
|
||||
*fpp = NULL;
|
||||
if ((u_int)fd >= fdp->fd_nfiles)
|
||||
if (td == NULL || (fdp = td->td_proc->p_fd) == NULL)
|
||||
return(EBADF);
|
||||
if ((fp = fdp->fd_ofiles[fd]) == NULL)
|
||||
FILEDESC_LOCK(fdp);
|
||||
if (fd < 0 || (u_int)fd >= fdp->fd_nfiles ||
|
||||
(fp = fdp->fd_ofiles[fd]) == NULL ||
|
||||
fp->f_ops == &badfileops) {
|
||||
FILEDESC_UNLOCK(fdp);
|
||||
return(EBADF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: FREAD failures returns EBADF to maintain backwards
|
||||
@ -1545,11 +1505,18 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags)
|
||||
*
|
||||
* Only one flag, or 0, may be specified.
|
||||
*/
|
||||
if (flags == FREAD && (fp->f_flag & FREAD) == 0)
|
||||
if (flags == FREAD && (fp->f_flag & FREAD) == 0) {
|
||||
FILEDESC_UNLOCK(fdp);
|
||||
return(EBADF);
|
||||
if (flags == FWRITE && (fp->f_flag & FWRITE) == 0)
|
||||
}
|
||||
if (flags == FWRITE && (fp->f_flag & FWRITE) == 0) {
|
||||
FILEDESC_UNLOCK(fdp);
|
||||
return(EINVAL);
|
||||
++fp->f_count;
|
||||
}
|
||||
if (hold) {
|
||||
fhold(fp);
|
||||
FILEDESC_UNLOCK(fdp);
|
||||
}
|
||||
*fpp = fp;
|
||||
return(0);
|
||||
}
|
||||
@ -1557,19 +1524,19 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags)
|
||||
int
|
||||
fget(struct thread *td, int fd, struct file **fpp)
|
||||
{
|
||||
return(_fget(td, fd, fpp, 0));
|
||||
return(_fget(td, fd, fpp, 0, 1));
|
||||
}
|
||||
|
||||
int
|
||||
fget_read(struct thread *td, int fd, struct file **fpp)
|
||||
{
|
||||
return(_fget(td, fd, fpp, FREAD));
|
||||
return(_fget(td, fd, fpp, FREAD, 1));
|
||||
}
|
||||
|
||||
int
|
||||
fget_write(struct thread *td, int fd, struct file **fpp)
|
||||
{
|
||||
return(_fget(td, fd, fpp, FWRITE));
|
||||
return(_fget(td, fd, fpp, FWRITE, 1));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1583,34 +1550,20 @@ static __inline
|
||||
int
|
||||
_fgetvp(struct thread *td, int fd, struct vnode **vpp, int flags)
|
||||
{
|
||||
struct filedesc *fdp;
|
||||
struct file *fp;
|
||||
int error;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
fdp = td->td_proc->p_fd;
|
||||
*vpp = NULL;
|
||||
if ((u_int)fd >= fdp->fd_nfiles)
|
||||
return(EBADF);
|
||||
if ((fp = fdp->fd_ofiles[fd]) == NULL)
|
||||
return(EBADF);
|
||||
if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO)
|
||||
return(EINVAL);
|
||||
if (fp->f_data == NULL)
|
||||
return(EINVAL);
|
||||
|
||||
/*
|
||||
* Note: FREAD failures returns EBADF to maintain backwards
|
||||
* compatibility with what routines returned before.
|
||||
*
|
||||
* Only one flag, or 0, may be specified.
|
||||
*/
|
||||
if (flags == FREAD && (fp->f_flag & FREAD) == 0)
|
||||
return(EBADF);
|
||||
if (flags == FWRITE && (fp->f_flag & FWRITE) == 0)
|
||||
return(EINVAL);
|
||||
*vpp = (struct vnode *)fp->f_data;
|
||||
vref(*vpp);
|
||||
return(0);
|
||||
if ((error = _fget(td, fd, &fp, 0, 0)) != 0)
|
||||
return (error);
|
||||
if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
*vpp = (struct vnode *)fp->f_data;
|
||||
vref(*vpp);
|
||||
}
|
||||
FILEDESC_UNLOCK(td->td_proc->p_fd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1641,29 +1594,24 @@ fgetvp_write(struct thread *td, int fd, struct vnode **vpp)
|
||||
int
|
||||
fgetsock(struct thread *td, int fd, struct socket **spp, u_int *fflagp)
|
||||
{
|
||||
struct filedesc *fdp;
|
||||
struct file *fp;
|
||||
struct socket *so;
|
||||
int error;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
fdp = td->td_proc->p_fd;
|
||||
*spp = NULL;
|
||||
if (fflagp)
|
||||
*fflagp = 0;
|
||||
if ((u_int)fd >= fdp->fd_nfiles)
|
||||
return(EBADF);
|
||||
if ((fp = fdp->fd_ofiles[fd]) == NULL)
|
||||
return(EBADF);
|
||||
if (fp->f_type != DTYPE_SOCKET)
|
||||
return(ENOTSOCK);
|
||||
if (fp->f_data == NULL)
|
||||
return(EINVAL);
|
||||
so = (struct socket *)fp->f_data;
|
||||
if (fflagp)
|
||||
*fflagp = fp->f_flag;
|
||||
soref(so);
|
||||
*spp = so;
|
||||
return(0);
|
||||
if ((error = _fget(td, fd, &fp, 0, 0)) != 0)
|
||||
return (error);
|
||||
if (fp->f_type != DTYPE_SOCKET) {
|
||||
error = ENOTSOCK;
|
||||
} else {
|
||||
*spp = (struct socket *)fp->f_data;
|
||||
if (fflagp)
|
||||
*fflagp = fp->f_flag;
|
||||
soref(*spp);
|
||||
}
|
||||
FILEDESC_UNLOCK(td->td_proc->p_fd);
|
||||
return(error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1737,14 +1685,13 @@ flock(td, uap)
|
||||
struct thread *td;
|
||||
register struct flock_args *uap;
|
||||
{
|
||||
register struct file *fp;
|
||||
struct file *fp;
|
||||
struct vnode *vp;
|
||||
struct flock lf;
|
||||
int error;
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
return (error);
|
||||
if (fp->f_type != DTYPE_VNODE) {
|
||||
fdrop(fp, td);
|
||||
return (EOPNOTSUPP);
|
||||
|
@ -414,10 +414,10 @@ kevent(struct thread *td, struct kevent_args *uap)
|
||||
struct timespec ts;
|
||||
int i, n, nerrors, error;
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL || fp->f_type != DTYPE_KQUEUE) {
|
||||
if (fp != NULL)
|
||||
fdrop(fp, td);
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
return (error);
|
||||
if (fp->f_type != DTYPE_KQUEUE) {
|
||||
fdrop(fp, td);
|
||||
return (EBADF);
|
||||
}
|
||||
if (uap->timeout != NULL) {
|
||||
|
@ -603,7 +603,7 @@ ioctl(td, uap)
|
||||
struct thread *td;
|
||||
register struct ioctl_args *uap;
|
||||
{
|
||||
register struct file *fp;
|
||||
struct file *fp;
|
||||
register struct filedesc *fdp;
|
||||
register u_long com;
|
||||
int error = 0;
|
||||
@ -616,9 +616,8 @@ ioctl(td, uap)
|
||||
long align;
|
||||
} ubuf;
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
return (error);
|
||||
if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
|
||||
fdrop(fp, td);
|
||||
return (EBADF);
|
||||
@ -992,8 +991,7 @@ selscan(td, ibits, obits, nfd)
|
||||
for (fd = i; bits && fd < nfd; fd++, bits >>= 1) {
|
||||
if (!(bits & 1))
|
||||
continue;
|
||||
fp = ffind_hold(td, fd);
|
||||
if (fp == NULL)
|
||||
if (fget(td, fd, &fp))
|
||||
return (EBADF);
|
||||
if (fo_poll(fp, flag[msk], fp->f_cred, td)) {
|
||||
obits[msk][(fd)/NFDBITS] |=
|
||||
|
@ -1704,15 +1704,14 @@ lseek(td, uap)
|
||||
} */ *uap;
|
||||
{
|
||||
struct ucred *cred = td->td_proc->p_ucred;
|
||||
register struct file *fp;
|
||||
struct file *fp;
|
||||
struct vnode *vp;
|
||||
struct vattr vattr;
|
||||
off_t offset;
|
||||
int error, noneg;
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
return (error);
|
||||
if (fp->f_type != DTYPE_VNODE) {
|
||||
fdrop(fp, td);
|
||||
return (ESPIPE);
|
||||
|
@ -1704,15 +1704,14 @@ lseek(td, uap)
|
||||
} */ *uap;
|
||||
{
|
||||
struct ucred *cred = td->td_proc->p_ucred;
|
||||
register struct file *fp;
|
||||
struct file *fp;
|
||||
struct vnode *vp;
|
||||
struct vattr vattr;
|
||||
off_t offset;
|
||||
int error, noneg;
|
||||
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
return (error);
|
||||
if (fp->f_type != DTYPE_VNODE) {
|
||||
fdrop(fp, td);
|
||||
return (ESPIPE);
|
||||
|
@ -591,9 +591,8 @@ ng_internalize(struct mbuf *control, struct thread *td)
|
||||
/* Check that the FD given is legit. and change it to a pointer to a
|
||||
* struct file. */
|
||||
fd = CMSG_DATA(cm);
|
||||
fp = ffind_hold(td, fd);
|
||||
if (fp == NULL)
|
||||
return (EBADF);
|
||||
if ((error = fget(td, fd, &fp)) != 0)
|
||||
return (error);
|
||||
|
||||
/* Depending on what kind of resource it is, act differently. For
|
||||
* devices, we treat it as a file. For a AF_NETGRAPH socket,
|
||||
|
@ -166,8 +166,6 @@ static __inline int fo_stat __P((struct file *fp, struct stat *sb,
|
||||
static __inline int fo_close __P((struct file *fp, struct thread *td));
|
||||
static __inline int fo_kqfilter __P((struct file *fp, struct knote *kn));
|
||||
struct proc;
|
||||
struct file *ffind_hold(struct thread *, int fd);
|
||||
struct file *ffind_lock(struct thread *, int fd);
|
||||
|
||||
static __inline int
|
||||
fo_read(fp, uio, cred, flags, td)
|
||||
|
@ -292,11 +292,8 @@ mmap(td, uap)
|
||||
* sure it is of appropriate type.
|
||||
* don't let the descriptor disappear on us if we block
|
||||
*/
|
||||
fp = ffind_hold(td, uap->fd);
|
||||
if (fp == NULL) {
|
||||
error = EBADF;
|
||||
if ((error = fget(td, uap->fd, &fp)) != 0)
|
||||
goto done;
|
||||
}
|
||||
if (fp->f_type != DTYPE_VNODE) {
|
||||
error = EINVAL;
|
||||
goto done;
|
||||
|
Loading…
Reference in New Issue
Block a user