diff options
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r-- | sys/kern/kern_descrip.c | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index f87ad1f45143..f007b22f90ec 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -34,14 +34,11 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> #include "opt_capsicum.h" #include "opt_ddb.h" #include "opt_ktrace.h" -#include <sys/param.h> #include <sys/systm.h> - #include <sys/capsicum.h> #include <sys/conf.h> #include <sys/fcntl.h> @@ -1621,6 +1618,7 @@ kern_fstat(struct thread *td, int fd, struct stat *sbp) AUDIT_ARG_FILE(td->td_proc, fp); sbp->st_filerev = 0; + sbp->st_bsdflags = 0; error = fo_stat(fp, sbp, td->td_ucred); fdrop(fp, td); #ifdef __STAT_TIME_T_EXT @@ -2996,6 +2994,47 @@ fget_remote(struct thread *td, struct proc *p, int fd, struct file **fpp) return (error); } +int +fget_remote_foreach(struct thread *td, struct proc *p, + int (*fn)(struct proc *, int, struct file *, void *), void *arg) +{ + struct filedesc *fdp; + struct fdescenttbl *fdt; + struct file *fp; + int error, error1, fd, highfd; + + error = 0; + PROC_LOCK(p); + fdp = fdhold(p); + PROC_UNLOCK(p); + if (fdp == NULL) + return (ENOENT); + + FILEDESC_SLOCK(fdp); + if (refcount_load(&fdp->fd_refcnt) != 0) { + fdt = atomic_load_ptr(&fdp->fd_files); + highfd = fdt->fdt_nfiles - 1; + FILEDESC_SUNLOCK(fdp); + } else { + error = ENOENT; + FILEDESC_SUNLOCK(fdp); + goto out; + } + + for (fd = 0; fd <= highfd; fd++) { + error1 = fget_remote(td, p, fd, &fp); + if (error1 != 0) + continue; + error = fn(p, fd, fp, arg); + fdrop(fp, td); + if (error != 0) + break; + } +out: + fddrop(fdp); + return (error); +} + #ifdef CAPABILITIES int fgetvp_lookup_smr(struct nameidata *ndp, struct vnode **vpp, bool *fsearch) |