Add a new fo_fill_kinfo fileops method to add type-specific information to
struct kinfo_file. - Move the various fill_*_info() methods out of kern_descrip.c and into the various file type implementations. - Rework the support for kinfo_ofile to generate a suitable kinfo_file object for each file and then convert that to a kinfo_ofile structure rather than keeping a second, different set of code that directly manipulates type-specific file information. - Remove the shm_path() and ksem_info() layering violations. Differential Revision: https://reviews.freebsd.org/D775 Reviewed by: kib, glebius (earlier version)
This commit is contained in:
parent
447666f08b
commit
9696feebe2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=271976
@ -1700,6 +1700,7 @@ static struct fileops devfs_ops_f = {
|
||||
.fo_chown = vn_chown,
|
||||
.fo_sendfile = vn_sendfile,
|
||||
.fo_seek = vn_seek,
|
||||
.fo_fill_kinfo = vn_fill_kinfo,
|
||||
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
|
||||
};
|
||||
|
||||
|
@ -47,27 +47,21 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/filedesc.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/ksem.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mqueue.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/selinfo.h>
|
||||
#include <sys/pipe.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/procdesc.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/racct.h>
|
||||
#include <sys/resourcevar.h>
|
||||
@ -79,10 +73,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/unpcb.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/vnode.h>
|
||||
#ifdef KTRACE
|
||||
@ -91,9 +82,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <net/vnet.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
|
||||
#include <security/audit/audit.h>
|
||||
|
||||
#include <vm/uma.h>
|
||||
@ -111,8 +99,6 @@ MALLOC_DECLARE(M_FADVISE);
|
||||
|
||||
static uma_zone_t file_zone;
|
||||
|
||||
void (*ksem_info)(struct ksem *ks, char *path, size_t size, uint32_t *value);
|
||||
|
||||
static int closefp(struct filedesc *fdp, int fd, struct file *fp,
|
||||
struct thread *td, int holdleaders);
|
||||
static int fd_first_free(struct filedesc *fdp, int low, int size);
|
||||
@ -121,14 +107,6 @@ static void fdgrowtable(struct filedesc *fdp, int nfd);
|
||||
static void fdgrowtable_exp(struct filedesc *fdp, int nfd);
|
||||
static void fdunused(struct filedesc *fdp, int fd);
|
||||
static void fdused(struct filedesc *fdp, int fd);
|
||||
static int fill_pipe_info(struct pipe *pi, struct kinfo_file *kif);
|
||||
static int fill_procdesc_info(struct procdesc *pdp,
|
||||
struct kinfo_file *kif);
|
||||
static int fill_pts_info(struct tty *tp, struct kinfo_file *kif);
|
||||
static int fill_sem_info(struct file *fp, struct kinfo_file *kif);
|
||||
static int fill_shm_info(struct file *fp, struct kinfo_file *kif);
|
||||
static int fill_socket_info(struct socket *so, struct kinfo_file *kif);
|
||||
static int fill_vnode_info(struct vnode *vp, struct kinfo_file *kif);
|
||||
static int getmaxfd(struct proc *p);
|
||||
|
||||
/*
|
||||
@ -2945,280 +2923,14 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
|
||||
SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE,
|
||||
0, 0, sysctl_kern_file, "S,xfile", "Entire file table");
|
||||
|
||||
#ifdef KINFO_OFILE_SIZE
|
||||
CTASSERT(sizeof(struct kinfo_ofile) == KINFO_OFILE_SIZE);
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_FREEBSD7
|
||||
static int
|
||||
export_vnode_for_osysctl(struct vnode *vp, int type,
|
||||
struct kinfo_ofile *kif, struct filedesc *fdp, struct sysctl_req *req)
|
||||
{
|
||||
int error;
|
||||
char *fullpath, *freepath;
|
||||
|
||||
bzero(kif, sizeof(*kif));
|
||||
kif->kf_structsize = sizeof(*kif);
|
||||
|
||||
vref(vp);
|
||||
kif->kf_fd = type;
|
||||
kif->kf_type = KF_TYPE_VNODE;
|
||||
/* This function only handles directories. */
|
||||
if (vp->v_type != VDIR) {
|
||||
vrele(vp);
|
||||
return (ENOTDIR);
|
||||
}
|
||||
kif->kf_vnode_type = KF_VTYPE_VDIR;
|
||||
|
||||
/*
|
||||
* This is not a true file descriptor, so we set a bogus refcount
|
||||
* and offset to indicate these fields should be ignored.
|
||||
*/
|
||||
kif->kf_ref_count = -1;
|
||||
kif->kf_offset = -1;
|
||||
|
||||
freepath = NULL;
|
||||
fullpath = "-";
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
vn_fullpath(curthread, vp, &fullpath, &freepath);
|
||||
vrele(vp);
|
||||
strlcpy(kif->kf_path, fullpath, sizeof(kif->kf_path));
|
||||
if (freepath != NULL)
|
||||
free(freepath, M_TEMP);
|
||||
error = SYSCTL_OUT(req, kif, sizeof(*kif));
|
||||
FILEDESC_SLOCK(fdp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get per-process file descriptors for use by procstat(1), et al.
|
||||
*/
|
||||
static int
|
||||
sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
char *fullpath, *freepath;
|
||||
struct kinfo_ofile *kif;
|
||||
struct filedesc *fdp;
|
||||
int error, i, *name;
|
||||
struct shmfd *shmfd;
|
||||
struct socket *so;
|
||||
struct vnode *vp;
|
||||
struct ksem *ks;
|
||||
struct file *fp;
|
||||
struct proc *p;
|
||||
struct tty *tp;
|
||||
|
||||
name = (int *)arg1;
|
||||
error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
fdp = fdhold(p);
|
||||
PROC_UNLOCK(p);
|
||||
if (fdp == NULL)
|
||||
return (ENOENT);
|
||||
kif = malloc(sizeof(*kif), M_TEMP, M_WAITOK);
|
||||
FILEDESC_SLOCK(fdp);
|
||||
if (fdp->fd_cdir != NULL)
|
||||
export_vnode_for_osysctl(fdp->fd_cdir, KF_FD_TYPE_CWD, kif,
|
||||
fdp, req);
|
||||
if (fdp->fd_rdir != NULL)
|
||||
export_vnode_for_osysctl(fdp->fd_rdir, KF_FD_TYPE_ROOT, kif,
|
||||
fdp, req);
|
||||
if (fdp->fd_jdir != NULL)
|
||||
export_vnode_for_osysctl(fdp->fd_jdir, KF_FD_TYPE_JAIL, kif,
|
||||
fdp, req);
|
||||
for (i = 0; fdp->fd_refcnt > 0 && i <= fdp->fd_lastfile; i++) {
|
||||
if ((fp = fdp->fd_ofiles[i].fde_file) == NULL)
|
||||
continue;
|
||||
bzero(kif, sizeof(*kif));
|
||||
kif->kf_structsize = sizeof(*kif);
|
||||
ks = NULL;
|
||||
vp = NULL;
|
||||
so = NULL;
|
||||
tp = NULL;
|
||||
shmfd = NULL;
|
||||
kif->kf_fd = i;
|
||||
|
||||
switch (fp->f_type) {
|
||||
case DTYPE_VNODE:
|
||||
kif->kf_type = KF_TYPE_VNODE;
|
||||
vp = fp->f_vnode;
|
||||
break;
|
||||
|
||||
case DTYPE_SOCKET:
|
||||
kif->kf_type = KF_TYPE_SOCKET;
|
||||
so = fp->f_data;
|
||||
break;
|
||||
|
||||
case DTYPE_PIPE:
|
||||
kif->kf_type = KF_TYPE_PIPE;
|
||||
break;
|
||||
|
||||
case DTYPE_FIFO:
|
||||
kif->kf_type = KF_TYPE_FIFO;
|
||||
vp = fp->f_vnode;
|
||||
break;
|
||||
|
||||
case DTYPE_KQUEUE:
|
||||
kif->kf_type = KF_TYPE_KQUEUE;
|
||||
break;
|
||||
|
||||
case DTYPE_CRYPTO:
|
||||
kif->kf_type = KF_TYPE_CRYPTO;
|
||||
break;
|
||||
|
||||
case DTYPE_MQUEUE:
|
||||
kif->kf_type = KF_TYPE_MQUEUE;
|
||||
break;
|
||||
|
||||
case DTYPE_SHM:
|
||||
kif->kf_type = KF_TYPE_SHM;
|
||||
shmfd = fp->f_data;
|
||||
break;
|
||||
|
||||
case DTYPE_SEM:
|
||||
kif->kf_type = KF_TYPE_SEM;
|
||||
ks = fp->f_data;
|
||||
break;
|
||||
|
||||
case DTYPE_PTS:
|
||||
kif->kf_type = KF_TYPE_PTS;
|
||||
tp = fp->f_data;
|
||||
break;
|
||||
|
||||
case DTYPE_PROCDESC:
|
||||
kif->kf_type = KF_TYPE_PROCDESC;
|
||||
break;
|
||||
|
||||
default:
|
||||
kif->kf_type = KF_TYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
kif->kf_ref_count = fp->f_count;
|
||||
if (fp->f_flag & FREAD)
|
||||
kif->kf_flags |= KF_FLAG_READ;
|
||||
if (fp->f_flag & FWRITE)
|
||||
kif->kf_flags |= KF_FLAG_WRITE;
|
||||
if (fp->f_flag & FAPPEND)
|
||||
kif->kf_flags |= KF_FLAG_APPEND;
|
||||
if (fp->f_flag & FASYNC)
|
||||
kif->kf_flags |= KF_FLAG_ASYNC;
|
||||
if (fp->f_flag & FFSYNC)
|
||||
kif->kf_flags |= KF_FLAG_FSYNC;
|
||||
if (fp->f_flag & FNONBLOCK)
|
||||
kif->kf_flags |= KF_FLAG_NONBLOCK;
|
||||
if (fp->f_flag & O_DIRECT)
|
||||
kif->kf_flags |= KF_FLAG_DIRECT;
|
||||
if (fp->f_flag & FHASLOCK)
|
||||
kif->kf_flags |= KF_FLAG_HASLOCK;
|
||||
kif->kf_offset = foffset_get(fp);
|
||||
if (vp != NULL) {
|
||||
vref(vp);
|
||||
switch (vp->v_type) {
|
||||
case VNON:
|
||||
kif->kf_vnode_type = KF_VTYPE_VNON;
|
||||
break;
|
||||
case VREG:
|
||||
kif->kf_vnode_type = KF_VTYPE_VREG;
|
||||
break;
|
||||
case VDIR:
|
||||
kif->kf_vnode_type = KF_VTYPE_VDIR;
|
||||
break;
|
||||
case VBLK:
|
||||
kif->kf_vnode_type = KF_VTYPE_VBLK;
|
||||
break;
|
||||
case VCHR:
|
||||
kif->kf_vnode_type = KF_VTYPE_VCHR;
|
||||
break;
|
||||
case VLNK:
|
||||
kif->kf_vnode_type = KF_VTYPE_VLNK;
|
||||
break;
|
||||
case VSOCK:
|
||||
kif->kf_vnode_type = KF_VTYPE_VSOCK;
|
||||
break;
|
||||
case VFIFO:
|
||||
kif->kf_vnode_type = KF_VTYPE_VFIFO;
|
||||
break;
|
||||
case VBAD:
|
||||
kif->kf_vnode_type = KF_VTYPE_VBAD;
|
||||
break;
|
||||
default:
|
||||
kif->kf_vnode_type = KF_VTYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* It is OK to drop the filedesc lock here as we will
|
||||
* re-validate and re-evaluate its properties when
|
||||
* the loop continues.
|
||||
*/
|
||||
freepath = NULL;
|
||||
fullpath = "-";
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
vn_fullpath(curthread, vp, &fullpath, &freepath);
|
||||
vrele(vp);
|
||||
strlcpy(kif->kf_path, fullpath,
|
||||
sizeof(kif->kf_path));
|
||||
if (freepath != NULL)
|
||||
free(freepath, M_TEMP);
|
||||
FILEDESC_SLOCK(fdp);
|
||||
}
|
||||
if (so != NULL) {
|
||||
struct sockaddr *sa;
|
||||
|
||||
if (so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa)
|
||||
== 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) {
|
||||
bcopy(sa, &kif->kf_sa_local, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
}
|
||||
if (so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa)
|
||||
== 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
|
||||
bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
}
|
||||
kif->kf_sock_domain =
|
||||
so->so_proto->pr_domain->dom_family;
|
||||
kif->kf_sock_type = so->so_type;
|
||||
kif->kf_sock_protocol = so->so_proto->pr_protocol;
|
||||
}
|
||||
if (tp != NULL) {
|
||||
strlcpy(kif->kf_path, tty_devname(tp),
|
||||
sizeof(kif->kf_path));
|
||||
}
|
||||
if (shmfd != NULL)
|
||||
shm_path(shmfd, kif->kf_path, sizeof(kif->kf_path));
|
||||
if (ks != NULL && ksem_info != NULL)
|
||||
ksem_info(ks, kif->kf_path, sizeof(kif->kf_path), NULL);
|
||||
error = SYSCTL_OUT(req, kif, sizeof(*kif));
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
fddrop(fdp);
|
||||
free(kif, M_TEMP);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_OFILEDESC, ofiledesc,
|
||||
CTLFLAG_RD||CTLFLAG_MPSAFE, sysctl_kern_proc_ofiledesc,
|
||||
"Process ofiledesc entries");
|
||||
#endif /* COMPAT_FREEBSD7 */
|
||||
|
||||
#ifdef KINFO_FILE_SIZE
|
||||
CTASSERT(sizeof(struct kinfo_file) == KINFO_FILE_SIZE);
|
||||
#endif
|
||||
|
||||
struct export_fd_buf {
|
||||
struct filedesc *fdp;
|
||||
struct sbuf *sb;
|
||||
ssize_t remainder;
|
||||
struct kinfo_file kif;
|
||||
};
|
||||
|
||||
static int
|
||||
export_fd_to_sb(void *data, int type, int fd, int fflags, int refcnt,
|
||||
int64_t offset, cap_rights_t *rightsp, struct export_fd_buf *efbuf)
|
||||
xlate_fflags(int fflags)
|
||||
{
|
||||
struct {
|
||||
static const struct {
|
||||
int fflag;
|
||||
int kf_fflag;
|
||||
} fflags_table[] = {
|
||||
@ -3238,83 +2950,126 @@ export_fd_to_sb(void *data, int type, int fd, int fflags, int refcnt,
|
||||
{ O_SHLOCK, KF_FLAG_SHLOCK },
|
||||
{ O_TRUNC, KF_FLAG_TRUNC }
|
||||
};
|
||||
#define NFFLAGS (sizeof(fflags_table) / sizeof(*fflags_table))
|
||||
struct kinfo_file *kif;
|
||||
struct vnode *vp;
|
||||
int error, locked;
|
||||
unsigned int i;
|
||||
int kflags;
|
||||
|
||||
if (efbuf->remainder == 0)
|
||||
return (0);
|
||||
kif = &efbuf->kif;
|
||||
bzero(kif, sizeof(*kif));
|
||||
locked = efbuf->fdp != NULL;
|
||||
switch (type) {
|
||||
case KF_TYPE_FIFO:
|
||||
case KF_TYPE_VNODE:
|
||||
if (locked) {
|
||||
FILEDESC_SUNLOCK(efbuf->fdp);
|
||||
locked = 0;
|
||||
}
|
||||
vp = (struct vnode *)data;
|
||||
error = fill_vnode_info(vp, kif);
|
||||
vrele(vp);
|
||||
break;
|
||||
case KF_TYPE_SOCKET:
|
||||
error = fill_socket_info((struct socket *)data, kif);
|
||||
break;
|
||||
case KF_TYPE_PIPE:
|
||||
error = fill_pipe_info((struct pipe *)data, kif);
|
||||
break;
|
||||
case KF_TYPE_PTS:
|
||||
error = fill_pts_info((struct tty *)data, kif);
|
||||
break;
|
||||
case KF_TYPE_PROCDESC:
|
||||
error = fill_procdesc_info((struct procdesc *)data, kif);
|
||||
break;
|
||||
case KF_TYPE_SEM:
|
||||
error = fill_sem_info((struct file *)data, kif);
|
||||
break;
|
||||
case KF_TYPE_SHM:
|
||||
error = fill_shm_info((struct file *)data, kif);
|
||||
break;
|
||||
default:
|
||||
error = 0;
|
||||
}
|
||||
if (error == 0)
|
||||
kif->kf_status |= KF_ATTR_VALID;
|
||||
|
||||
/*
|
||||
* Translate file access flags.
|
||||
*/
|
||||
for (i = 0; i < NFFLAGS; i++)
|
||||
kflags = 0;
|
||||
for (i = 0; i < nitems(fflags_table); i++)
|
||||
if (fflags & fflags_table[i].fflag)
|
||||
kif->kf_flags |= fflags_table[i].kf_fflag;
|
||||
kflags |= fflags_table[i].kf_fflag;
|
||||
return (kflags);
|
||||
}
|
||||
|
||||
/* Trim unused data from kf_path by truncating the structure size. */
|
||||
static void
|
||||
pack_kinfo(struct kinfo_file *kif)
|
||||
{
|
||||
|
||||
kif->kf_structsize = offsetof(struct kinfo_file, kf_path) +
|
||||
strlen(kif->kf_path) + 1;
|
||||
kif->kf_structsize = roundup(kif->kf_structsize, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
static void
|
||||
export_file_to_kinfo(struct file *fp, int fd, cap_rights_t *rightsp,
|
||||
struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
int error;
|
||||
|
||||
bzero(kif, sizeof(*kif));
|
||||
|
||||
/* Set a default type to allow for empty fill_kinfo() methods. */
|
||||
kif->kf_type = KF_TYPE_UNKNOWN;
|
||||
kif->kf_flags = xlate_fflags(fp->f_flag);
|
||||
if (rightsp != NULL)
|
||||
kif->kf_cap_rights = *rightsp;
|
||||
else
|
||||
cap_rights_init(&kif->kf_cap_rights);
|
||||
kif->kf_fd = fd;
|
||||
kif->kf_type = type;
|
||||
kif->kf_ref_count = refcnt;
|
||||
kif->kf_offset = offset;
|
||||
/* Pack record size down */
|
||||
kif->kf_structsize = offsetof(struct kinfo_file, kf_path) +
|
||||
strlen(kif->kf_path) + 1;
|
||||
kif->kf_structsize = roundup(kif->kf_structsize, sizeof(uint64_t));
|
||||
kif->kf_ref_count = fp->f_count;
|
||||
kif->kf_offset = foffset_get(fp);
|
||||
|
||||
/*
|
||||
* This may drop the filedesc lock, so the 'fp' cannot be
|
||||
* accessed after this call.
|
||||
*/
|
||||
error = fo_fill_kinfo(fp, kif, fdp);
|
||||
if (error == 0)
|
||||
kif->kf_status |= KF_ATTR_VALID;
|
||||
pack_kinfo(kif);
|
||||
}
|
||||
|
||||
static void
|
||||
export_vnode_to_kinfo(struct vnode *vp, int fd, int fflags,
|
||||
struct kinfo_file *kif)
|
||||
{
|
||||
int error;
|
||||
|
||||
bzero(kif, sizeof(*kif));
|
||||
|
||||
kif->kf_type = KF_TYPE_VNODE;
|
||||
error = vn_fill_kinfo_vnode(vp, kif);
|
||||
if (error == 0)
|
||||
kif->kf_status |= KF_ATTR_VALID;
|
||||
kif->kf_flags = xlate_fflags(fflags);
|
||||
kif->kf_fd = fd;
|
||||
kif->kf_ref_count = -1;
|
||||
kif->kf_offset = -1;
|
||||
pack_kinfo(kif);
|
||||
vrele(vp);
|
||||
}
|
||||
|
||||
struct export_fd_buf {
|
||||
struct filedesc *fdp;
|
||||
struct sbuf *sb;
|
||||
ssize_t remainder;
|
||||
struct kinfo_file kif;
|
||||
};
|
||||
|
||||
static int
|
||||
export_kinfo_to_sb(struct export_fd_buf *efbuf)
|
||||
{
|
||||
struct kinfo_file *kif;
|
||||
|
||||
kif = &efbuf->kif;
|
||||
if (efbuf->remainder != -1) {
|
||||
if (efbuf->remainder < kif->kf_structsize) {
|
||||
/* Terminate export. */
|
||||
efbuf->remainder = 0;
|
||||
if (efbuf->fdp != NULL && !locked)
|
||||
FILEDESC_SLOCK(efbuf->fdp);
|
||||
return (0);
|
||||
}
|
||||
efbuf->remainder -= kif->kf_structsize;
|
||||
}
|
||||
if (locked)
|
||||
return (sbuf_bcat(efbuf->sb, kif, kif->kf_structsize));
|
||||
}
|
||||
|
||||
static int
|
||||
export_file_to_sb(struct file *fp, int fd, cap_rights_t *rightsp,
|
||||
struct export_fd_buf *efbuf)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (efbuf->remainder == 0)
|
||||
return (0);
|
||||
export_file_to_kinfo(fp, fd, rightsp, &efbuf->kif, efbuf->fdp);
|
||||
FILEDESC_SUNLOCK(efbuf->fdp);
|
||||
error = export_kinfo_to_sb(efbuf);
|
||||
FILEDESC_SLOCK(efbuf->fdp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
export_vnode_to_sb(struct vnode *vp, int fd, int fflags,
|
||||
struct export_fd_buf *efbuf)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (efbuf->remainder == 0)
|
||||
return (0);
|
||||
if (efbuf->fdp != NULL)
|
||||
FILEDESC_SUNLOCK(efbuf->fdp);
|
||||
error = sbuf_bcat(efbuf->sb, kif, kif->kf_structsize);
|
||||
export_vnode_to_kinfo(vp, fd, fflags, &efbuf->kif);
|
||||
error = export_kinfo_to_sb(efbuf);
|
||||
if (efbuf->fdp != NULL)
|
||||
FILEDESC_SLOCK(efbuf->fdp);
|
||||
return (error);
|
||||
@ -3328,16 +3083,15 @@ export_fd_to_sb(void *data, int type, int fd, int fflags, int refcnt,
|
||||
int
|
||||
kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen)
|
||||
{
|
||||
struct thread *td;
|
||||
struct file *fp;
|
||||
struct filedesc *fdp;
|
||||
struct export_fd_buf *efbuf;
|
||||
struct vnode *cttyvp, *textvp, *tracevp;
|
||||
int64_t offset;
|
||||
void *data;
|
||||
int error, i;
|
||||
int type, refcnt, fflags;
|
||||
cap_rights_t rights;
|
||||
|
||||
td = curthread;
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
|
||||
/* ktrace vnode */
|
||||
@ -3362,14 +3116,13 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen)
|
||||
efbuf->sb = sb;
|
||||
efbuf->remainder = maxlen;
|
||||
if (tracevp != NULL)
|
||||
export_fd_to_sb(tracevp, KF_TYPE_VNODE, KF_FD_TYPE_TRACE,
|
||||
FREAD | FWRITE, -1, -1, NULL, efbuf);
|
||||
export_vnode_to_sb(tracevp, KF_FD_TYPE_TRACE, FREAD | FWRITE,
|
||||
efbuf);
|
||||
if (textvp != NULL)
|
||||
export_fd_to_sb(textvp, KF_TYPE_VNODE, KF_FD_TYPE_TEXT,
|
||||
FREAD, -1, -1, NULL, efbuf);
|
||||
export_vnode_to_sb(textvp, KF_FD_TYPE_TEXT, FREAD, efbuf);
|
||||
if (cttyvp != NULL)
|
||||
export_fd_to_sb(cttyvp, KF_TYPE_VNODE, KF_FD_TYPE_CTTY,
|
||||
FREAD | FWRITE, -1, -1, NULL, efbuf);
|
||||
export_vnode_to_sb(cttyvp, KF_FD_TYPE_CTTY, FREAD | FWRITE,
|
||||
efbuf);
|
||||
error = 0;
|
||||
if (fdp == NULL)
|
||||
goto fail;
|
||||
@ -3378,105 +3131,34 @@ kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen)
|
||||
/* working directory */
|
||||
if (fdp->fd_cdir != NULL) {
|
||||
vref(fdp->fd_cdir);
|
||||
data = fdp->fd_cdir;
|
||||
export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_CWD,
|
||||
FREAD, -1, -1, NULL, efbuf);
|
||||
export_vnode_to_sb(fdp->fd_cdir, KF_FD_TYPE_CWD, FREAD, efbuf);
|
||||
}
|
||||
/* root directory */
|
||||
if (fdp->fd_rdir != NULL) {
|
||||
vref(fdp->fd_rdir);
|
||||
data = fdp->fd_rdir;
|
||||
export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_ROOT,
|
||||
FREAD, -1, -1, NULL, efbuf);
|
||||
export_vnode_to_sb(fdp->fd_rdir, KF_FD_TYPE_ROOT, FREAD, efbuf);
|
||||
}
|
||||
/* jail directory */
|
||||
if (fdp->fd_jdir != NULL) {
|
||||
vref(fdp->fd_jdir);
|
||||
data = fdp->fd_jdir;
|
||||
export_fd_to_sb(data, KF_TYPE_VNODE, KF_FD_TYPE_JAIL,
|
||||
FREAD, -1, -1, NULL, efbuf);
|
||||
export_vnode_to_sb(fdp->fd_jdir, KF_FD_TYPE_JAIL, FREAD, efbuf);
|
||||
}
|
||||
for (i = 0; fdp->fd_refcnt > 0 && i <= fdp->fd_lastfile; i++) {
|
||||
if ((fp = fdp->fd_ofiles[i].fde_file) == NULL)
|
||||
continue;
|
||||
data = NULL;
|
||||
#ifdef CAPABILITIES
|
||||
rights = *cap_rights(fdp, i);
|
||||
#else /* !CAPABILITIES */
|
||||
cap_rights_init(&rights);
|
||||
#endif
|
||||
switch (fp->f_type) {
|
||||
case DTYPE_VNODE:
|
||||
type = KF_TYPE_VNODE;
|
||||
vref(fp->f_vnode);
|
||||
data = fp->f_vnode;
|
||||
break;
|
||||
|
||||
case DTYPE_SOCKET:
|
||||
type = KF_TYPE_SOCKET;
|
||||
data = fp->f_data;
|
||||
break;
|
||||
|
||||
case DTYPE_PIPE:
|
||||
type = KF_TYPE_PIPE;
|
||||
data = fp->f_data;
|
||||
break;
|
||||
|
||||
case DTYPE_FIFO:
|
||||
type = KF_TYPE_FIFO;
|
||||
vref(fp->f_vnode);
|
||||
data = fp->f_vnode;
|
||||
break;
|
||||
|
||||
case DTYPE_KQUEUE:
|
||||
type = KF_TYPE_KQUEUE;
|
||||
break;
|
||||
|
||||
case DTYPE_CRYPTO:
|
||||
type = KF_TYPE_CRYPTO;
|
||||
break;
|
||||
|
||||
case DTYPE_MQUEUE:
|
||||
type = KF_TYPE_MQUEUE;
|
||||
break;
|
||||
|
||||
case DTYPE_SHM:
|
||||
type = KF_TYPE_SHM;
|
||||
data = fp;
|
||||
break;
|
||||
|
||||
case DTYPE_SEM:
|
||||
type = KF_TYPE_SEM;
|
||||
data = fp;
|
||||
break;
|
||||
|
||||
case DTYPE_PTS:
|
||||
type = KF_TYPE_PTS;
|
||||
data = fp->f_data;
|
||||
break;
|
||||
|
||||
case DTYPE_PROCDESC:
|
||||
type = KF_TYPE_PROCDESC;
|
||||
data = fp->f_data;
|
||||
break;
|
||||
|
||||
default:
|
||||
type = KF_TYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
refcnt = fp->f_count;
|
||||
fflags = fp->f_flag;
|
||||
offset = foffset_get(fp);
|
||||
|
||||
/*
|
||||
* Create sysctl entry.
|
||||
* It is OK to drop the filedesc lock here as we will
|
||||
* re-validate and re-evaluate its properties when
|
||||
* the loop continues.
|
||||
* Create sysctl entry. It is OK to drop the filedesc
|
||||
* lock inside of export_file_to_sb() as we will
|
||||
* re-validate and re-evaluate its properties when the
|
||||
* loop continues.
|
||||
*/
|
||||
error = export_fd_to_sb(data, type, i, fflags, refcnt,
|
||||
offset, &rights, efbuf);
|
||||
if (error != 0)
|
||||
error = export_file_to_sb(fp, i, &rights, efbuf);
|
||||
if (error != 0 || efbuf->remainder == 0)
|
||||
break;
|
||||
}
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
@ -3514,6 +3196,105 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS)
|
||||
return (error != 0 ? error : error2);
|
||||
}
|
||||
|
||||
#ifdef KINFO_OFILE_SIZE
|
||||
CTASSERT(sizeof(struct kinfo_ofile) == KINFO_OFILE_SIZE);
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_FREEBSD7
|
||||
static void
|
||||
kinfo_to_okinfo(struct kinfo_file *kif, struct kinfo_ofile *okif)
|
||||
{
|
||||
|
||||
okif->kf_structsize = sizeof(*okif);
|
||||
okif->kf_type = kif->kf_type;
|
||||
okif->kf_fd = kif->kf_fd;
|
||||
okif->kf_ref_count = kif->kf_ref_count;
|
||||
okif->kf_flags = kif->kf_flags & (KF_FLAG_READ | KF_FLAG_WRITE |
|
||||
KF_FLAG_APPEND | KF_FLAG_ASYNC | KF_FLAG_FSYNC | KF_FLAG_NONBLOCK |
|
||||
KF_FLAG_DIRECT | KF_FLAG_HASLOCK);
|
||||
okif->kf_offset = kif->kf_offset;
|
||||
okif->kf_vnode_type = kif->kf_vnode_type;
|
||||
okif->kf_sock_domain = kif->kf_sock_domain;
|
||||
okif->kf_sock_type = kif->kf_sock_type;
|
||||
okif->kf_sock_protocol = kif->kf_sock_protocol;
|
||||
strlcpy(okif->kf_path, kif->kf_path, sizeof(okif->kf_path));
|
||||
okif->kf_sa_local = kif->kf_sa_local;
|
||||
okif->kf_sa_peer = kif->kf_sa_peer;
|
||||
}
|
||||
|
||||
static int
|
||||
export_vnode_for_osysctl(struct vnode *vp, int type, struct kinfo_file *kif,
|
||||
struct kinfo_ofile *okif, struct filedesc *fdp, struct sysctl_req *req)
|
||||
{
|
||||
int error;
|
||||
|
||||
vref(vp);
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
export_vnode_to_kinfo(vp, type, 0, kif);
|
||||
kinfo_to_okinfo(kif, okif);
|
||||
error = SYSCTL_OUT(req, okif, sizeof(*okif));
|
||||
FILEDESC_SLOCK(fdp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get per-process file descriptors for use by procstat(1), et al.
|
||||
*/
|
||||
static int
|
||||
sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct kinfo_ofile *okif;
|
||||
struct kinfo_file *kif;
|
||||
struct filedesc *fdp;
|
||||
struct thread *td;
|
||||
int error, i, *name;
|
||||
struct file *fp;
|
||||
struct proc *p;
|
||||
|
||||
td = curthread;
|
||||
name = (int *)arg1;
|
||||
error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
fdp = fdhold(p);
|
||||
PROC_UNLOCK(p);
|
||||
if (fdp == NULL)
|
||||
return (ENOENT);
|
||||
kif = malloc(sizeof(*kif), M_TEMP, M_WAITOK);
|
||||
okif = malloc(sizeof(*okif), M_TEMP, M_WAITOK);
|
||||
FILEDESC_SLOCK(fdp);
|
||||
if (fdp->fd_cdir != NULL)
|
||||
export_vnode_for_osysctl(fdp->fd_cdir, KF_FD_TYPE_CWD, kif,
|
||||
okif, fdp, req);
|
||||
if (fdp->fd_rdir != NULL)
|
||||
export_vnode_for_osysctl(fdp->fd_rdir, KF_FD_TYPE_ROOT, kif,
|
||||
okif, fdp, req);
|
||||
if (fdp->fd_jdir != NULL)
|
||||
export_vnode_for_osysctl(fdp->fd_jdir, KF_FD_TYPE_JAIL, kif,
|
||||
okif, fdp, req);
|
||||
for (i = 0; fdp->fd_refcnt > 0 && i <= fdp->fd_lastfile; i++) {
|
||||
if ((fp = fdp->fd_ofiles[i].fde_file) == NULL)
|
||||
continue;
|
||||
export_file_to_kinfo(fp, i, NULL, kif, fdp);
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
kinfo_to_okinfo(kif, okif);
|
||||
error = SYSCTL_OUT(req, okif, sizeof(*okif));
|
||||
FILEDESC_SLOCK(fdp);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
fddrop(fdp);
|
||||
free(kif, M_TEMP);
|
||||
free(okif, M_TEMP);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_OFILEDESC, ofiledesc,
|
||||
CTLFLAG_RD||CTLFLAG_MPSAFE, sysctl_kern_proc_ofiledesc,
|
||||
"Process ofiledesc entries");
|
||||
#endif /* COMPAT_FREEBSD7 */
|
||||
|
||||
int
|
||||
vntype_to_kinfo(int vtype)
|
||||
{
|
||||
@ -3543,170 +3324,6 @@ vntype_to_kinfo(int vtype)
|
||||
return (KF_VTYPE_UNKNOWN);
|
||||
}
|
||||
|
||||
static int
|
||||
fill_vnode_info(struct vnode *vp, struct kinfo_file *kif)
|
||||
{
|
||||
struct vattr va;
|
||||
char *fullpath, *freepath;
|
||||
int error;
|
||||
|
||||
if (vp == NULL)
|
||||
return (1);
|
||||
kif->kf_vnode_type = vntype_to_kinfo(vp->v_type);
|
||||
freepath = NULL;
|
||||
fullpath = "-";
|
||||
error = vn_fullpath(curthread, vp, &fullpath, &freepath);
|
||||
if (error == 0) {
|
||||
strlcpy(kif->kf_path, fullpath, sizeof(kif->kf_path));
|
||||
}
|
||||
if (freepath != NULL)
|
||||
free(freepath, M_TEMP);
|
||||
|
||||
/*
|
||||
* Retrieve vnode attributes.
|
||||
*/
|
||||
va.va_fsid = VNOVAL;
|
||||
va.va_rdev = NODEV;
|
||||
vn_lock(vp, LK_SHARED | LK_RETRY);
|
||||
error = VOP_GETATTR(vp, &va, curthread->td_ucred);
|
||||
VOP_UNLOCK(vp, 0);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (va.va_fsid != VNOVAL)
|
||||
kif->kf_un.kf_file.kf_file_fsid = va.va_fsid;
|
||||
else
|
||||
kif->kf_un.kf_file.kf_file_fsid =
|
||||
vp->v_mount->mnt_stat.f_fsid.val[0];
|
||||
kif->kf_un.kf_file.kf_file_fileid = va.va_fileid;
|
||||
kif->kf_un.kf_file.kf_file_mode = MAKEIMODE(va.va_type, va.va_mode);
|
||||
kif->kf_un.kf_file.kf_file_size = va.va_size;
|
||||
kif->kf_un.kf_file.kf_file_rdev = va.va_rdev;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fill_socket_info(struct socket *so, struct kinfo_file *kif)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
struct inpcb *inpcb;
|
||||
struct unpcb *unpcb;
|
||||
int error;
|
||||
|
||||
if (so == NULL)
|
||||
return (1);
|
||||
kif->kf_sock_domain = so->so_proto->pr_domain->dom_family;
|
||||
kif->kf_sock_type = so->so_type;
|
||||
kif->kf_sock_protocol = so->so_proto->pr_protocol;
|
||||
kif->kf_un.kf_sock.kf_sock_pcb = (uintptr_t)so->so_pcb;
|
||||
switch(kif->kf_sock_domain) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
if (kif->kf_sock_protocol == IPPROTO_TCP) {
|
||||
if (so->so_pcb != NULL) {
|
||||
inpcb = (struct inpcb *)(so->so_pcb);
|
||||
kif->kf_un.kf_sock.kf_sock_inpcb =
|
||||
(uintptr_t)inpcb->inp_ppcb;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AF_UNIX:
|
||||
if (so->so_pcb != NULL) {
|
||||
unpcb = (struct unpcb *)(so->so_pcb);
|
||||
if (unpcb->unp_conn) {
|
||||
kif->kf_un.kf_sock.kf_sock_unpconn =
|
||||
(uintptr_t)unpcb->unp_conn;
|
||||
kif->kf_un.kf_sock.kf_sock_rcv_sb_state =
|
||||
so->so_rcv.sb_state;
|
||||
kif->kf_un.kf_sock.kf_sock_snd_sb_state =
|
||||
so->so_snd.sb_state;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
|
||||
if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) {
|
||||
bcopy(sa, &kif->kf_sa_local, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
}
|
||||
error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
|
||||
if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
|
||||
bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
}
|
||||
strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name,
|
||||
sizeof(kif->kf_path));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fill_pts_info(struct tty *tp, struct kinfo_file *kif)
|
||||
{
|
||||
|
||||
if (tp == NULL)
|
||||
return (1);
|
||||
kif->kf_un.kf_pts.kf_pts_dev = tty_udev(tp);
|
||||
strlcpy(kif->kf_path, tty_devname(tp), sizeof(kif->kf_path));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fill_pipe_info(struct pipe *pi, struct kinfo_file *kif)
|
||||
{
|
||||
|
||||
if (pi == NULL)
|
||||
return (1);
|
||||
kif->kf_un.kf_pipe.kf_pipe_addr = (uintptr_t)pi;
|
||||
kif->kf_un.kf_pipe.kf_pipe_peer = (uintptr_t)pi->pipe_peer;
|
||||
kif->kf_un.kf_pipe.kf_pipe_buffer_cnt = pi->pipe_buffer.cnt;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fill_procdesc_info(struct procdesc *pdp, struct kinfo_file *kif)
|
||||
{
|
||||
|
||||
if (pdp == NULL)
|
||||
return (1);
|
||||
kif->kf_un.kf_proc.kf_pid = pdp->pd_pid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fill_sem_info(struct file *fp, struct kinfo_file *kif)
|
||||
{
|
||||
struct thread *td;
|
||||
struct stat sb;
|
||||
|
||||
td = curthread;
|
||||
if (fp->f_data == NULL)
|
||||
return (1);
|
||||
if (fo_stat(fp, &sb, td->td_ucred, td) != 0)
|
||||
return (1);
|
||||
if (ksem_info == NULL)
|
||||
return (1);
|
||||
ksem_info(fp->f_data, kif->kf_path, sizeof(kif->kf_path),
|
||||
&kif->kf_un.kf_sem.kf_sem_value);
|
||||
kif->kf_un.kf_sem.kf_sem_mode = sb.st_mode;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fill_shm_info(struct file *fp, struct kinfo_file *kif)
|
||||
{
|
||||
struct thread *td;
|
||||
struct stat sb;
|
||||
|
||||
td = curthread;
|
||||
if (fp->f_data == NULL)
|
||||
return (1);
|
||||
if (fo_stat(fp, &sb, td->td_ucred, td) != 0)
|
||||
return (1);
|
||||
shm_path(fp->f_data, kif->kf_path, sizeof(kif->kf_path));
|
||||
kif->kf_un.kf_file.kf_file_mode = sb.st_mode;
|
||||
kif->kf_un.kf_file.kf_file_size = sb.st_size;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_FILEDESC, filedesc,
|
||||
CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc_filedesc,
|
||||
"Process filedesc entries");
|
||||
@ -3926,6 +3543,13 @@ badfo_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
|
||||
return (EBADF);
|
||||
}
|
||||
|
||||
static int
|
||||
badfo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct fileops badfileops = {
|
||||
.fo_read = badfo_readwrite,
|
||||
.fo_write = badfo_readwrite,
|
||||
@ -3938,6 +3562,7 @@ struct fileops badfileops = {
|
||||
.fo_chmod = badfo_chmod,
|
||||
.fo_chown = badfo_chown,
|
||||
.fo_sendfile = badfo_sendfile,
|
||||
.fo_fill_kinfo = badfo_fill_kinfo,
|
||||
};
|
||||
|
||||
int
|
||||
|
@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/user.h>
|
||||
#ifdef KTRACE
|
||||
#include <sys/ktrace.h>
|
||||
#endif
|
||||
@ -114,6 +115,7 @@ static fo_poll_t kqueue_poll;
|
||||
static fo_kqfilter_t kqueue_kqfilter;
|
||||
static fo_stat_t kqueue_stat;
|
||||
static fo_close_t kqueue_close;
|
||||
static fo_fill_kinfo_t kqueue_fill_kinfo;
|
||||
|
||||
static struct fileops kqueueops = {
|
||||
.fo_read = invfo_rdwr,
|
||||
@ -127,6 +129,7 @@ static struct fileops kqueueops = {
|
||||
.fo_chmod = invfo_chmod,
|
||||
.fo_chown = invfo_chown,
|
||||
.fo_sendfile = invfo_sendfile,
|
||||
.fo_fill_kinfo = kqueue_fill_kinfo,
|
||||
};
|
||||
|
||||
static int knote_attach(struct knote *kn, struct kqueue *kq);
|
||||
@ -1802,6 +1805,14 @@ kqueue_close(struct file *fp, struct thread *td)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
kqueue_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
|
||||
kif->kf_type = KF_TYPE_KQUEUE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
kqueue_wakeup(struct kqueue *kq)
|
||||
{
|
||||
|
@ -115,6 +115,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/proc.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/event.h>
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
@ -152,6 +153,7 @@ static fo_stat_t pipe_stat;
|
||||
static fo_close_t pipe_close;
|
||||
static fo_chmod_t pipe_chmod;
|
||||
static fo_chown_t pipe_chown;
|
||||
static fo_fill_kinfo_t pipe_fill_kinfo;
|
||||
|
||||
struct fileops pipeops = {
|
||||
.fo_read = pipe_read,
|
||||
@ -165,6 +167,7 @@ struct fileops pipeops = {
|
||||
.fo_chmod = pipe_chmod,
|
||||
.fo_chown = pipe_chown,
|
||||
.fo_sendfile = invfo_sendfile,
|
||||
.fo_fill_kinfo = pipe_fill_kinfo,
|
||||
.fo_flags = DFLAG_PASSABLE
|
||||
};
|
||||
|
||||
@ -1607,6 +1610,21 @@ pipe_chown(fp, uid, gid, active_cred, td)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
pipe_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
struct pipe *pi;
|
||||
|
||||
if (fp->f_type == DTYPE_FIFO)
|
||||
return (vn_fill_kinfo(fp, kif, fdp));
|
||||
kif->kf_type = KF_TYPE_PIPE;
|
||||
pi = fp->f_data;
|
||||
kif->kf_un.kf_pipe.kf_pipe_addr = (uintptr_t)pi;
|
||||
kif->kf_un.kf_pipe.kf_pipe_peer = (uintptr_t)pi->pipe_peer;
|
||||
kif->kf_un.kf_pipe.kf_pipe_buffer_cnt = pi->pipe_buffer.cnt;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
pipe_free_kmem(cpipe)
|
||||
struct pipe *cpipe;
|
||||
|
@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
#include <security/audit/audit.h>
|
||||
|
||||
@ -91,6 +92,7 @@ static fo_poll_t procdesc_poll;
|
||||
static fo_kqfilter_t procdesc_kqfilter;
|
||||
static fo_stat_t procdesc_stat;
|
||||
static fo_close_t procdesc_close;
|
||||
static fo_fill_kinfo_t procdesc_fill_kinfo;
|
||||
|
||||
static struct fileops procdesc_ops = {
|
||||
.fo_read = invfo_rdwr,
|
||||
@ -104,6 +106,7 @@ static struct fileops procdesc_ops = {
|
||||
.fo_chmod = invfo_chmod,
|
||||
.fo_chown = invfo_chown,
|
||||
.fo_sendfile = invfo_sendfile,
|
||||
.fo_fill_kinfo = procdesc_fill_kinfo,
|
||||
.fo_flags = DFLAG_PASSABLE,
|
||||
};
|
||||
|
||||
@ -531,3 +534,14 @@ procdesc_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
procdesc_fill_kinfo(struct file *fp, struct kinfo_file *kif,
|
||||
struct filedesc *fdp)
|
||||
{
|
||||
struct procdesc *pdp;
|
||||
|
||||
kif->kf_type = KF_TYPE_PROCDESC;
|
||||
pdp = fp->f_data;
|
||||
kif->kf_un.kf_proc.kf_pid = pdp->pd_pid;
|
||||
return (0);
|
||||
}
|
||||
|
@ -34,8 +34,10 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/filedesc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/sigio.h>
|
||||
@ -48,12 +50,18 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/unpcb.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/route.h>
|
||||
#include <net/vnet.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
static fo_rdwr_t soo_read;
|
||||
@ -63,6 +71,7 @@ static fo_poll_t soo_poll;
|
||||
extern fo_kqfilter_t soo_kqfilter;
|
||||
static fo_stat_t soo_stat;
|
||||
static fo_close_t soo_close;
|
||||
static fo_fill_kinfo_t soo_fill_kinfo;
|
||||
|
||||
struct fileops socketops = {
|
||||
.fo_read = soo_read,
|
||||
@ -76,6 +85,7 @@ struct fileops socketops = {
|
||||
.fo_chmod = invfo_chmod,
|
||||
.fo_chown = invfo_chown,
|
||||
.fo_sendfile = invfo_sendfile,
|
||||
.fo_fill_kinfo = soo_fill_kinfo,
|
||||
.fo_flags = DFLAG_PASSABLE
|
||||
};
|
||||
|
||||
@ -293,3 +303,58 @@ soo_close(struct file *fp, struct thread *td)
|
||||
error = soclose(so);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
struct inpcb *inpcb;
|
||||
struct unpcb *unpcb;
|
||||
struct socket *so;
|
||||
int error;
|
||||
|
||||
kif->kf_type = KF_TYPE_SOCKET;
|
||||
so = fp->f_data;
|
||||
kif->kf_sock_domain = so->so_proto->pr_domain->dom_family;
|
||||
kif->kf_sock_type = so->so_type;
|
||||
kif->kf_sock_protocol = so->so_proto->pr_protocol;
|
||||
kif->kf_un.kf_sock.kf_sock_pcb = (uintptr_t)so->so_pcb;
|
||||
switch (kif->kf_sock_domain) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
if (kif->kf_sock_protocol == IPPROTO_TCP) {
|
||||
if (so->so_pcb != NULL) {
|
||||
inpcb = (struct inpcb *)(so->so_pcb);
|
||||
kif->kf_un.kf_sock.kf_sock_inpcb =
|
||||
(uintptr_t)inpcb->inp_ppcb;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AF_UNIX:
|
||||
if (so->so_pcb != NULL) {
|
||||
unpcb = (struct unpcb *)(so->so_pcb);
|
||||
if (unpcb->unp_conn) {
|
||||
kif->kf_un.kf_sock.kf_sock_unpconn =
|
||||
(uintptr_t)unpcb->unp_conn;
|
||||
kif->kf_un.kf_sock.kf_sock_rcv_sb_state =
|
||||
so->so_rcv.sb_state;
|
||||
kif->kf_un.kf_sock.kf_sock_snd_sb_state =
|
||||
so->so_snd.sb_state;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
|
||||
if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) {
|
||||
bcopy(sa, &kif->kf_sa_local, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
}
|
||||
error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
|
||||
if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
|
||||
bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
|
||||
free(sa, M_SONAME);
|
||||
}
|
||||
strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name,
|
||||
sizeof(kif->kf_path));
|
||||
return (0);
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/ttycom.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
@ -580,6 +581,18 @@ ptsdev_close(struct file *fp, struct thread *td)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ptsdev_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
struct tty *tp;
|
||||
|
||||
kif->kf_type = KF_TYPE_PTS;
|
||||
tp = fp->f_data;
|
||||
kif->kf_un.kf_pts.kf_pts_dev = tty_udev(tp);
|
||||
strlcpy(kif->kf_path, tty_devname(tp), sizeof(kif->kf_path));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct fileops ptsdev_ops = {
|
||||
.fo_read = ptsdev_read,
|
||||
.fo_write = ptsdev_write,
|
||||
@ -592,6 +605,7 @@ static struct fileops ptsdev_ops = {
|
||||
.fo_chmod = invfo_chmod,
|
||||
.fo_chown = invfo_chown,
|
||||
.fo_sendfile = invfo_sendfile,
|
||||
.fo_fill_kinfo = ptsdev_fill_kinfo,
|
||||
.fo_flags = DFLAG_PASSABLE,
|
||||
};
|
||||
|
||||
|
@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <machine/atomic.h>
|
||||
|
||||
@ -2571,6 +2572,14 @@ filt_mqwrite(struct knote *kn, long hint)
|
||||
return (mq->mq_curmsgs < mq->mq_maxmsg);
|
||||
}
|
||||
|
||||
static int
|
||||
mqf_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
|
||||
kif->kf_type = KF_TYPE_MQUEUE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct fileops mqueueops = {
|
||||
.fo_read = invfo_rdwr,
|
||||
.fo_write = invfo_rdwr,
|
||||
@ -2583,6 +2592,7 @@ static struct fileops mqueueops = {
|
||||
.fo_chmod = mqf_chmod,
|
||||
.fo_chown = mqf_chown,
|
||||
.fo_sendfile = invfo_sendfile,
|
||||
.fo_fill_kinfo = mqf_fill_kinfo,
|
||||
};
|
||||
|
||||
static struct vop_vector mqfs_vnodeops = {
|
||||
|
@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
@ -130,6 +131,7 @@ static fo_stat_t ksem_stat;
|
||||
static fo_close_t ksem_closef;
|
||||
static fo_chmod_t ksem_chmod;
|
||||
static fo_chown_t ksem_chown;
|
||||
static fo_fill_kinfo_t ksem_fill_kinfo;
|
||||
|
||||
/* File descriptor operations. */
|
||||
static struct fileops ksem_ops = {
|
||||
@ -144,6 +146,7 @@ static struct fileops ksem_ops = {
|
||||
.fo_chmod = ksem_chmod,
|
||||
.fo_chown = ksem_chown,
|
||||
.fo_sendfile = invfo_sendfile,
|
||||
.fo_fill_kinfo = ksem_fill_kinfo,
|
||||
.fo_flags = DFLAG_PASSABLE
|
||||
};
|
||||
|
||||
@ -252,6 +255,26 @@ ksem_closef(struct file *fp, struct thread *td)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ksem_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
struct ksem *ks;
|
||||
|
||||
kif->kf_type = KF_TYPE_SEM;
|
||||
ks = fp->f_data;
|
||||
mtx_lock(&sem_lock);
|
||||
kif->kf_un.kf_sem.kf_sem_value = ks->ks_value;
|
||||
kif->kf_un.kf_sem.kf_sem_mode = S_IFREG | ks->ks_mode; /* XXX */
|
||||
mtx_unlock(&sem_lock);
|
||||
if (ks->ks_path != NULL) {
|
||||
sx_slock(&ksem_dict_lock);
|
||||
if (ks->ks_path != NULL)
|
||||
strlcpy(kif->kf_path, ks->ks_path, sizeof(kif->kf_path));
|
||||
sx_sunlock(&ksem_dict_lock);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ksem object management including creation and reference counting
|
||||
* routines.
|
||||
@ -388,20 +411,6 @@ ksem_remove(char *path, Fnv32_t fnv, struct ucred *ucred)
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
static void
|
||||
ksem_info_impl(struct ksem *ks, char *path, size_t size, uint32_t *value)
|
||||
{
|
||||
|
||||
if (ks->ks_path == NULL)
|
||||
return;
|
||||
sx_slock(&ksem_dict_lock);
|
||||
if (ks->ks_path != NULL)
|
||||
strlcpy(path, ks->ks_path, size);
|
||||
if (value != NULL)
|
||||
*value = ks->ks_value;
|
||||
sx_sunlock(&ksem_dict_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
ksem_create_copyout_semid(struct thread *td, semid_t *semidp, int fd,
|
||||
int compat32)
|
||||
@ -983,7 +992,6 @@ ksem_module_init(void)
|
||||
p31b_setcfg(CTL_P1003_1B_SEMAPHORES, 200112L);
|
||||
p31b_setcfg(CTL_P1003_1B_SEM_NSEMS_MAX, SEM_MAX);
|
||||
p31b_setcfg(CTL_P1003_1B_SEM_VALUE_MAX, SEM_VALUE_MAX);
|
||||
ksem_info = ksem_info_impl;
|
||||
|
||||
error = syscall_helper_register(ksem_syscalls);
|
||||
if (error)
|
||||
@ -1005,7 +1013,6 @@ ksem_module_destroy(void)
|
||||
#endif
|
||||
syscall_helper_unregister(ksem_syscalls);
|
||||
|
||||
ksem_info = NULL;
|
||||
p31b_setcfg(CTL_P1003_1B_SEMAPHORES, 0);
|
||||
hashdestroy(ksem_dictionary, M_KSEM, ksem_hash);
|
||||
sx_destroy(&ksem_dict_lock);
|
||||
|
@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/time.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
@ -125,6 +126,7 @@ static fo_close_t shm_close;
|
||||
static fo_chmod_t shm_chmod;
|
||||
static fo_chown_t shm_chown;
|
||||
static fo_seek_t shm_seek;
|
||||
static fo_fill_kinfo_t shm_fill_kinfo;
|
||||
|
||||
/* File descriptor operations. */
|
||||
static struct fileops shm_ops = {
|
||||
@ -140,6 +142,7 @@ static struct fileops shm_ops = {
|
||||
.fo_chown = shm_chown,
|
||||
.fo_sendfile = vn_sendfile,
|
||||
.fo_seek = shm_seek,
|
||||
.fo_fill_kinfo = shm_fill_kinfo,
|
||||
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
|
||||
};
|
||||
|
||||
@ -1022,14 +1025,24 @@ shm_unmap(struct file *fp, void *mem, size_t size)
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
shm_path(struct shmfd *shmfd, char *path, size_t size)
|
||||
static int
|
||||
shm_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
struct shmfd *shmfd;
|
||||
|
||||
if (shmfd->shm_path == NULL)
|
||||
return;
|
||||
sx_slock(&shm_dict_lock);
|
||||
if (shmfd->shm_path != NULL)
|
||||
strlcpy(path, shmfd->shm_path, size);
|
||||
sx_sunlock(&shm_dict_lock);
|
||||
kif->kf_type = KF_TYPE_SHM;
|
||||
shmfd = fp->f_data;
|
||||
|
||||
mtx_lock(&shm_timestamp_lock);
|
||||
kif->kf_un.kf_file.kf_file_mode = S_IFREG | shmfd->shm_mode; /* XXX */
|
||||
mtx_unlock(&shm_timestamp_lock);
|
||||
kif->kf_un.kf_file.kf_file_size = shmfd->shm_size;
|
||||
if (shmfd->shm_path != NULL) {
|
||||
sx_slock(&shm_dict_lock);
|
||||
if (shmfd->shm_path != NULL)
|
||||
strlcpy(kif->kf_path, shmfd->shm_path,
|
||||
sizeof(kif->kf_path));
|
||||
sx_sunlock(&shm_dict_lock);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/conf.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
#include <security/audit/audit.h>
|
||||
#include <security/mac/mac_framework.h>
|
||||
@ -103,6 +104,7 @@ struct fileops vnops = {
|
||||
.fo_chown = vn_chown,
|
||||
.fo_sendfile = vn_sendfile,
|
||||
.fo_seek = vn_seek,
|
||||
.fo_fill_kinfo = vn_fill_kinfo,
|
||||
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
|
||||
};
|
||||
|
||||
@ -2249,3 +2251,61 @@ vn_utimes_perm(struct vnode *vp, struct vattr *vap, struct ucred *cred,
|
||||
error = VOP_ACCESS(vp, VWRITE, cred, td);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
vn_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
struct vnode *vp;
|
||||
int error;
|
||||
|
||||
if (fp->f_type == DTYPE_FIFO)
|
||||
kif->kf_type = KF_TYPE_FIFO;
|
||||
else
|
||||
kif->kf_type = KF_TYPE_VNODE;
|
||||
vp = fp->f_vnode;
|
||||
vref(vp);
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
error = vn_fill_kinfo_vnode(vp, kif);
|
||||
vrele(vp);
|
||||
FILEDESC_SLOCK(fdp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif)
|
||||
{
|
||||
struct vattr va;
|
||||
char *fullpath, *freepath;
|
||||
int error;
|
||||
|
||||
kif->kf_vnode_type = vntype_to_kinfo(vp->v_type);
|
||||
freepath = NULL;
|
||||
fullpath = "-";
|
||||
error = vn_fullpath(curthread, vp, &fullpath, &freepath);
|
||||
if (error == 0) {
|
||||
strlcpy(kif->kf_path, fullpath, sizeof(kif->kf_path));
|
||||
}
|
||||
if (freepath != NULL)
|
||||
free(freepath, M_TEMP);
|
||||
|
||||
/*
|
||||
* Retrieve vnode attributes.
|
||||
*/
|
||||
va.va_fsid = VNOVAL;
|
||||
va.va_rdev = NODEV;
|
||||
vn_lock(vp, LK_SHARED | LK_RETRY);
|
||||
error = VOP_GETATTR(vp, &va, curthread->td_ucred);
|
||||
VOP_UNLOCK(vp, 0);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (va.va_fsid != VNOVAL)
|
||||
kif->kf_un.kf_file.kf_file_fsid = va.va_fsid;
|
||||
else
|
||||
kif->kf_un.kf_file.kf_file_fsid =
|
||||
vp->v_mount->mnt_stat.f_fsid.val[0];
|
||||
kif->kf_un.kf_file.kf_file_fileid = va.va_fileid;
|
||||
kif->kf_un.kf_file.kf_file_mode = MAKEIMODE(va.va_type, va.va_mode);
|
||||
kif->kf_un.kf_file.kf_file_size = va.va_size;
|
||||
kif->kf_un.kf_file.kf_file_rdev = va.va_rdev;
|
||||
return (0);
|
||||
}
|
||||
|
@ -576,6 +576,14 @@ linux_file_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static int
|
||||
linux_file_fill_kinfo(struct file *fp, struct kinfo_file *kif,
|
||||
struct filedesc *fdp)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct fileops linuxfileops = {
|
||||
.fo_read = linux_file_read,
|
||||
.fo_write = invfo_rdwr,
|
||||
@ -588,6 +596,7 @@ struct fileops linuxfileops = {
|
||||
.fo_chmod = invfo_chmod,
|
||||
.fo_chown = invfo_chown,
|
||||
.fo_sendfile = invfo_sendfile,
|
||||
.fo_fill_kinfo = linux_file_fill_kinfo,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -286,6 +286,8 @@ static int cryptof_ioctl(struct file *, u_long, void *,
|
||||
static int cryptof_stat(struct file *, struct stat *,
|
||||
struct ucred *, struct thread *);
|
||||
static int cryptof_close(struct file *, struct thread *);
|
||||
static int cryptof_fill_kinfo(struct file *, struct kinfo_file *,
|
||||
struct filedesc *);
|
||||
|
||||
static struct fileops cryptofops = {
|
||||
.fo_read = invfo_rdwr,
|
||||
@ -299,6 +301,7 @@ static struct fileops cryptofops = {
|
||||
.fo_chmod = invfo_chmod,
|
||||
.fo_chown = invfo_chown,
|
||||
.fo_sendfile = invfo_sendfile,
|
||||
.fo_fill_kinfo = cryptof_fill_kinfo,
|
||||
};
|
||||
|
||||
static struct csession *csefind(struct fcrypt *, u_int);
|
||||
@ -958,6 +961,14 @@ cryptof_close(struct file *fp, struct thread *td)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cryptof_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
|
||||
kif->kf_type = KF_TYPE_CRYPTO;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct csession *
|
||||
csefind(struct fcrypt *fcr, u_int ses)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include <sys/_lock.h>
|
||||
#include <sys/_mutex.h>
|
||||
|
||||
struct filedesc;
|
||||
struct stat;
|
||||
struct thread;
|
||||
struct uio;
|
||||
@ -70,6 +71,7 @@ struct socket;
|
||||
|
||||
struct file;
|
||||
struct filecaps;
|
||||
struct kinfo_file;
|
||||
struct ucred;
|
||||
|
||||
#define FOF_OFFSET 0x01 /* Use the offset in uio argument */
|
||||
@ -114,6 +116,8 @@ typedef int fo_sendfile_t(struct file *fp, int sockfd, struct uio *hdr_uio,
|
||||
struct sendfile_sync *sfs, struct thread *td);
|
||||
typedef int fo_seek_t(struct file *fp, off_t offset, int whence,
|
||||
struct thread *td);
|
||||
typedef int fo_fill_kinfo_t(struct file *fp, struct kinfo_file *kif,
|
||||
struct filedesc *fdp);
|
||||
typedef int fo_flags_t;
|
||||
|
||||
struct fileops {
|
||||
@ -129,6 +133,7 @@ struct fileops {
|
||||
fo_chown_t *fo_chown;
|
||||
fo_sendfile_t *fo_sendfile;
|
||||
fo_seek_t *fo_seek;
|
||||
fo_fill_kinfo_t *fo_fill_kinfo;
|
||||
fo_flags_t fo_flags; /* DFLAG_* below */
|
||||
};
|
||||
|
||||
@ -242,6 +247,8 @@ fo_sendfile_t invfo_sendfile;
|
||||
|
||||
fo_sendfile_t vn_sendfile;
|
||||
fo_seek_t vn_seek;
|
||||
fo_fill_kinfo_t vn_fill_kinfo;
|
||||
int vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif);
|
||||
|
||||
void finit(struct file *, u_int, short, void *, struct fileops *);
|
||||
int fgetvp(struct thread *td, int fd, cap_rights_t *rightsp,
|
||||
@ -378,6 +385,13 @@ fo_seek(struct file *fp, off_t offset, int whence, struct thread *td)
|
||||
return ((*fp->f_ops->fo_seek)(fp, offset, whence, td));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
fo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
|
||||
{
|
||||
|
||||
return ((*fp->f_ops->fo_fill_kinfo)(fp, kif, fdp));
|
||||
}
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !SYS_FILE_H */
|
||||
|
@ -63,9 +63,4 @@ struct ksem {
|
||||
#define KS_ANONYMOUS 0x0001 /* Anonymous (unnamed) semaphore. */
|
||||
#define KS_DEAD 0x0002 /* No new waiters allowed. */
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern void (*ksem_info)(struct ksem *ks, char *path, size_t size,
|
||||
uint32_t *value);
|
||||
#endif
|
||||
|
||||
#endif /* !_POSIX4_KSEM_H_ */
|
||||
|
@ -234,7 +234,6 @@ int shm_mmap(struct shmfd *shmfd, vm_size_t objsize, vm_ooffset_t foff,
|
||||
vm_object_t *obj);
|
||||
int shm_map(struct file *fp, size_t size, off_t offset, void **memp);
|
||||
int shm_unmap(struct file *fp, void *mem, size_t size);
|
||||
void shm_path(struct shmfd *shmfd, char *path, size_t size);
|
||||
|
||||
#else /* !_KERNEL */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user