diff options
Diffstat (limited to 'sys/fs/procfs')
-rw-r--r-- | sys/fs/procfs/procfs.h | 50 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_ctl.c | 24 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_fpregs.c | 3 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_map.c | 2 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_mem.c | 10 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_regs.c | 3 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_status.c | 5 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_subr.c | 55 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_vfsops.c | 109 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_vnops.c | 466 |
10 files changed, 382 insertions, 345 deletions
diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h index df01a39..ef0d7eb 100644 --- a/sys/fs/procfs/procfs.h +++ b/sys/fs/procfs/procfs.h @@ -34,8 +34,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)procfs.h 8.6 (Berkeley) 2/3/94 + * @(#)procfs.h 8.9 (Berkeley) 5/14/95 * + * From: * $FreeBSD$ */ @@ -44,6 +45,7 @@ */ typedef enum { Proot, /* the filesystem root */ + Pcurproc, /* symbolic link for curproc */ Pproc, /* a process-specific sub-directory */ Pfile, /* the executable file */ Pmem, /* the process's memory image */ @@ -97,9 +99,9 @@ struct pfsdent { }; #define UIO_MX sizeof(struct pfsdent) #define PROCFS_FILENO(pid, type) \ - (((type) == Proot) ? \ - 2 : \ - ((((pid)+1) << 3) + ((int) (type)))) + (((type) < Pproc) ? \ + ((type) + 2) : \ + ((((pid)+1) << 4) + ((int) (type)))) /* * Convert between pfsnode vnode @@ -113,33 +115,33 @@ struct vfs_namemap { int nm_val; }; -extern int vfs_getuserstr __P((struct uio *, char *, int *)); -extern vfs_namemap_t *vfs_findname __P((vfs_namemap_t *, char *, int)); +int vfs_getuserstr __P((struct uio *, char *, int *)); +vfs_namemap_t *vfs_findname __P((vfs_namemap_t *, char *, int)); /* <machine/reg.h> */ struct reg; struct fpreg; #define PFIND(pid) ((pid) ? pfind(pid) : &proc0) -extern int procfs_freevp __P((struct vnode *)); -extern int procfs_allocvp __P((struct mount *, struct vnode **, long, pfstype)); -extern struct vnode *procfs_findtextvp __P((struct proc *)); -extern int procfs_sstep __P((struct proc *)); -extern void procfs_fix_sstep __P((struct proc *)); -extern int procfs_read_regs __P((struct proc *, struct reg *)); -extern int procfs_write_regs __P((struct proc *, struct reg *)); -extern int procfs_read_fpregs __P((struct proc *, struct fpreg *)); -extern int procfs_write_fpregs __P((struct proc *, struct fpreg *)); -extern int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_dofpregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -extern int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_freevp __P((struct vnode *)); +int procfs_allocvp __P((struct mount *, struct vnode **, long, pfstype)); +struct vnode *procfs_findtextvp __P((struct proc *)); +int procfs_sstep __P((struct proc *)); +void procfs_fix_sstep __P((struct proc *)); +int procfs_read_regs __P((struct proc *, struct reg *)); +int procfs_write_regs __P((struct proc *, struct reg *)); +int procfs_read_fpregs __P((struct proc *, struct fpreg *)); +int procfs_write_fpregs __P((struct proc *, struct fpreg *)); +int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_dofpregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -/* check to see if the process has the "items" (regs/file) */ +/* functions to check whether or not files should be displayed */ int procfs_validfile __P((struct proc *)); int procfs_validfpregs __P((struct proc *)); int procfs_validregs __P((struct proc *)); diff --git a/sys/fs/procfs/procfs_ctl.c b/sys/fs/procfs/procfs_ctl.c index 4ddf7a7..68b93dd 100644 --- a/sys/fs/procfs/procfs_ctl.c +++ b/sys/fs/procfs/procfs_ctl.c @@ -34,8 +34,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)procfs_ctl.c 8.3 (Berkeley) 1/21/94 + * @(#)procfs_ctl.c 8.4 (Berkeley) 6/15/94 * + * From: * $FreeBSD$ */ @@ -51,13 +52,13 @@ #include <sys/resourcevar.h> #include <sys/signal.h> #include <sys/signalvar.h> - -#include <vm/vm.h> -#include <vm/vm_param.h> -#include <vm/vm_extern.h> - +#include <sys/ptrace.h> #include <miscfs/procfs/procfs.h> +#ifndef FIX_SSTEP +#define FIX_SSTEP(p) +#endif + /* * True iff process (p) is in trace wait state * relative to process (curp) @@ -67,13 +68,6 @@ (p)->p_pptr == (curp) && \ ((p)->p_flag & P_TRACED)) -#ifdef notdef -#define FIX_SSTEP(p) { \ - procfs_fix_sstep(p); \ - } \ -} -#endif - #define PROCFS_CTL_ATTACH 1 #define PROCFS_CTL_DETACH 2 #define PROCFS_CTL_STEP 3 @@ -220,8 +214,10 @@ procfs_control(curp, p, op) */ case PROCFS_CTL_STEP: PHOLD(p); - procfs_sstep(p); + error = procfs_sstep(p); PRELE(p); + if (error) + return (error); break; /* diff --git a/sys/fs/procfs/procfs_fpregs.c b/sys/fs/procfs/procfs_fpregs.c index a3cad5f..841cf76 100644 --- a/sys/fs/procfs/procfs_fpregs.c +++ b/sys/fs/procfs/procfs_fpregs.c @@ -34,8 +34,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)procfs_fpregs.c 8.1 (Berkeley) 1/27/94 + * @(#)procfs_fpregs.c 8.2 (Berkeley) 6/15/94 * + * From: * $FreeBSD$ */ diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c index 27c44fa..40c40d8 100644 --- a/sys/fs/procfs/procfs_map.c +++ b/sys/fs/procfs/procfs_map.c @@ -59,7 +59,7 @@ #include <vm/vm_param.h> #include <vm/vm_prot.h> #include <vm/vm_inherit.h> -#include <vm/lock.h> +#include <sys/lock.h> #include <vm/pmap.h> #include <vm/vm_map.h> #include <vm/vm_page.h> diff --git a/sys/fs/procfs/procfs_mem.c b/sys/fs/procfs/procfs_mem.c index 4e8fac6..06364e5 100644 --- a/sys/fs/procfs/procfs_mem.c +++ b/sys/fs/procfs/procfs_mem.c @@ -35,7 +35,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)procfs_mem.c 8.4 (Berkeley) 1/21/94 + * @(#)procfs_mem.c 8.5 (Berkeley) 6/15/94 * * $FreeBSD$ */ @@ -55,7 +55,7 @@ #include <vm/vm.h> #include <vm/vm_param.h> #include <vm/vm_prot.h> -#include <vm/lock.h> +#include <sys/lock.h> #include <vm/pmap.h> #include <vm/vm_map.h> #include <vm/vm_kern.h> @@ -295,14 +295,11 @@ procfs_domem(curp, p, pfs, uio) struct pfsnode *pfs; struct uio *uio; { - int error; if (uio->uio_resid == 0) return (0); - error = procfs_rwmem(p, uio); - - return (error); + return (procfs_rwmem(p, uio)); } /* @@ -320,5 +317,6 @@ struct vnode * procfs_findtextvp(p) struct proc *p; { + return (p->p_textvp); } diff --git a/sys/fs/procfs/procfs_regs.c b/sys/fs/procfs/procfs_regs.c index 9282a3a..56ef233 100644 --- a/sys/fs/procfs/procfs_regs.c +++ b/sys/fs/procfs/procfs_regs.c @@ -34,8 +34,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)procfs_regs.c 8.3 (Berkeley) 1/27/94 + * @(#)procfs_regs.c 8.4 (Berkeley) 6/15/94 * + * From: * $FreeBSD$ */ diff --git a/sys/fs/procfs/procfs_status.c b/sys/fs/procfs/procfs_status.c index 432918d..76974b5 100644 --- a/sys/fs/procfs/procfs_status.c +++ b/sys/fs/procfs/procfs_status.c @@ -34,8 +34,9 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)procfs_status.c 8.3 (Berkeley) 2/17/94 + * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 * + * From: * $FreeBSD$ */ @@ -142,7 +143,7 @@ procfs_dostatus(curp, p, pfs, uio) xlen = ps - psbuf; xlen -= uio->uio_offset; ps = psbuf + uio->uio_offset; - xlen = min(xlen, uio->uio_resid); + xlen = imin(xlen, uio->uio_resid); if (xlen <= 0) error = 0; else diff --git a/sys/fs/procfs/procfs_subr.c b/sys/fs/procfs/procfs_subr.c index d9b3d2f..5ee78f0 100644 --- a/sys/fs/procfs/procfs_subr.c +++ b/sys/fs/procfs/procfs_subr.c @@ -34,7 +34,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)procfs_subr.c 8.4 (Berkeley) 1/27/94 + * @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95 * * $FreeBSD$ */ @@ -84,18 +84,21 @@ procfs_allocvp(mp, vpp, pid, pfs_type) long pid; pfstype pfs_type; { - int error; + struct proc *p = curproc; /* XXX */ struct pfsnode *pfs; + struct vnode *vp; struct pfsnode **pp; + int error; loop: for (pfs = pfshead; pfs != 0; pfs = pfs->pfs_next) { + vp = PFSTOV(pfs); if (pfs->pfs_pid == pid && pfs->pfs_type == pfs_type && - PFSTOV(pfs)->v_mount == mp) { - if (vget(pfs->pfs_vnode, 0)) + vp->v_mount == mp) { + if (vget(vp, 0, p)) goto loop; - *vpp = pfs->pfs_vnode; + *vpp = vp; return (0); } } @@ -118,17 +121,18 @@ loop: */ MALLOC(pfs, struct pfsnode *, sizeof(struct pfsnode), M_TEMP, M_WAITOK); - error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp); - if (error) { + if (error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp)) { FREE(pfs, M_TEMP); goto out; } + vp = *vpp; + + vp->v_data = pfs; - (*vpp)->v_data = pfs; pfs->pfs_next = 0; pfs->pfs_pid = (pid_t) pid; pfs->pfs_type = pfs_type; - pfs->pfs_vnode = *vpp; + pfs->pfs_vnode = vp; pfs->pfs_flags = 0; pfs->pfs_lockowner = 0; pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type); @@ -138,33 +142,41 @@ loop: pfs->pfs_mode = (VREAD|VEXEC) | (VREAD|VEXEC) >> 3 | (VREAD|VEXEC) >> 6; + vp->v_type = VDIR; + vp->v_flag = VROOT; + break; + + case Pcurproc: /* /proc/curproc = lr--r--r-- */ + pfs->pfs_mode = (VREAD) | + (VREAD >> 3) | + (VREAD >> 6); + vp->v_type = VLNK; break; case Pproc: pfs->pfs_mode = (VREAD|VEXEC) | (VREAD|VEXEC) >> 3 | (VREAD|VEXEC) >> 6; + vp->v_type = VDIR; break; case Pfile: - pfs->pfs_mode = (VREAD|VWRITE); - break; - case Pmem: pfs->pfs_mode = (VREAD|VWRITE) | (VREAD) >> 3;; break; case Pregs: - pfs->pfs_mode = (VREAD|VWRITE); - break; - case Pfpregs: pfs->pfs_mode = (VREAD|VWRITE); + vp->v_type = VREG; break; case Pctl: + case Pnote: + case Pnotepg: pfs->pfs_mode = (VWRITE); + vp->v_type = VREG; break; case Ptype: @@ -173,14 +185,7 @@ loop: pfs->pfs_mode = (VREAD) | (VREAD >> 3) | (VREAD >> 6); - break; - - case Pnote: - pfs->pfs_mode = (VWRITE); - break; - - case Pnotepg: - pfs->pfs_mode = (VWRITE); + vp->v_type = VREG; break; default: @@ -316,8 +321,7 @@ vfs_getuserstr(uio, buf, buflenp) return (EMSGSIZE); xlen = uio->uio_resid; - error = uiomove(buf, xlen, uio); - if (error) + if (error = uiomove(buf, xlen, uio)) return (error); /* allow multiple writes without seeks */ @@ -339,6 +343,7 @@ vfs_findname(nm, buf, buflen) char *buf; int buflen; { + for (; nm->nm_name; nm++) if (bcmp(buf, nm->nm_name, buflen+1) == 0) return (nm); diff --git a/sys/fs/procfs/procfs_vfsops.c b/sys/fs/procfs/procfs_vfsops.c index 433b391..5387126 100644 --- a/sys/fs/procfs/procfs_vfsops.c +++ b/sys/fs/procfs/procfs_vfsops.c @@ -34,7 +34,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)procfs_vfsops.c 8.4 (Berkeley) 1/21/94 + * @(#)procfs_vfsops.c 8.7 (Berkeley) 5/10/95 * * $FreeBSD$ */ @@ -56,24 +56,14 @@ #include <miscfs/procfs/procfs.h> #include <vm/vm.h> /* for PAGE_SIZE */ -static int procfs_fhtovp __P((struct mount *mp, struct fid *fhp, - struct mbuf *nam, struct vnode **vpp, - int *exflagsp, struct ucred **credanonp)); -static int procfs_init __P((void)); +static int procfs_init __P((struct vfsconf *vfsp)); static int procfs_mount __P((struct mount *mp, char *path, caddr_t data, struct nameidata *ndp, struct proc *p)); -static int procfs_quotactl __P((struct mount *mp, int cmds, uid_t uid, - caddr_t arg, struct proc *p)); static int procfs_start __P((struct mount *mp, int flags, struct proc *p)); static int procfs_statfs __P((struct mount *mp, struct statfs *sbp, struct proc *p)); -static int procfs_sync __P((struct mount *mp, int waitfor, - struct ucred *cred, struct proc *p)); static int procfs_unmount __P((struct mount *mp, int mntflags, struct proc *p)); -static int procfs_vget __P((struct mount *mp, ino_t ino, - struct vnode **vpp)); -static int procfs_vptofh __P((struct vnode *vp, struct fid *fhp)); /* * VFS Operations. @@ -101,7 +91,7 @@ procfs_mount(mp, path, data, ndp, p) mp->mnt_flag |= MNT_LOCAL; mp->mnt_data = 0; - getnewfsid(mp, MOUNT_PROCFS); + vfs_getnewfsid(mp); (void) copyinstr(path, (caddr_t)mp->mnt_stat.f_mntonname, MNAMELEN, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -125,12 +115,8 @@ procfs_unmount(mp, mntflags, p) int error; int flags = 0; - if (mntflags & MNT_FORCE) { - /* procfs can never be rootfs so don't check for it */ - if (!doforce) - return (EINVAL); + if (mntflags & MNT_FORCE) flags |= FORCECLOSE; - } error = vflush(mp, 0, flags); if (error) @@ -144,24 +130,10 @@ procfs_root(mp, vpp) struct mount *mp; struct vnode **vpp; { - struct pfsnode *pfs; - struct vnode *vp; - int error; - - error = procfs_allocvp(mp, &vp, (pid_t) 0, Proot); - if (error) - return (error); - - vp->v_type = VDIR; - vp->v_flag = VROOT; - pfs = VTOPFS(vp); - *vpp = vp; - return (0); + return (procfs_allocvp(mp, vpp, 0, Proot)); } -/* - */ /* ARGSUSED */ static int procfs_start(mp, flags, p) @@ -182,7 +154,6 @@ procfs_statfs(mp, sbp, p) struct statfs *sbp; struct proc *p; { - sbp->f_type = MOUNT_PROCFS; sbp->f_bsize = PAGE_SIZE; sbp->f_iosize = PAGE_SIZE; sbp->f_blocks = 1; /* avoid divide by zero in some df's */ @@ -192,6 +163,7 @@ procfs_statfs(mp, sbp, p) sbp->f_ffree = maxproc - nprocs; /* approx */ if (sbp != &mp->mnt_stat) { + sbp->f_type = mp->mnt_vfc->vfc_typenum; bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); @@ -200,68 +172,25 @@ procfs_statfs(mp, sbp, p) return (0); } - -static int -procfs_quotactl(mp, cmds, uid, arg, p) - struct mount *mp; - int cmds; - uid_t uid; - caddr_t arg; - struct proc *p; -{ - - return (EOPNOTSUPP); -} - static int -procfs_sync(mp, waitfor, cred, p) - struct mount *mp; - int waitfor; - struct ucred *cred; - struct proc *p; +procfs_init(vfsp) + struct vfsconf *vfsp; { return (0); } -static int -procfs_vget(mp, ino, vpp) - struct mount *mp; - ino_t ino; - struct vnode **vpp; -{ - - return (EOPNOTSUPP); -} - -static int -procfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) - struct mount *mp; - struct fid *fhp; - struct mbuf *nam; - struct vnode **vpp; - int *exflagsp; - struct ucred **credanonp; -{ - - return (EINVAL); -} - -static int -procfs_vptofh(vp, fhp) - struct vnode *vp; - struct fid *fhp; -{ - - return EINVAL; -} - -static int -procfs_init() -{ - - return (0); -} +#define procfs_fhtovp ((int (*) __P((struct mount *, struct fid *, \ + struct mbuf *, struct vnode **, int *, struct ucred **)))einval) +#define procfs_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ + struct proc *)))eopnotsupp) +#define procfs_sync ((int (*) __P((struct mount *, int, struct ucred *, \ + struct proc *)))nullop) +#define procfs_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ + size_t, struct proc *)))eopnotsupp) +#define procfs_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ + eopnotsupp) +#define procfs_vptofh ((int (*) __P((struct vnode *, struct fid *)))einval) static struct vfsops procfs_vfsops = { procfs_mount, diff --git a/sys/fs/procfs/procfs_vnops.c b/sys/fs/procfs/procfs_vnops.c index f497563..85be3ea 100644 --- a/sys/fs/procfs/procfs_vnops.c +++ b/sys/fs/procfs/procfs_vnops.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 + * Copyright (c) 1993, 1995 Jan-Simon Pendry + * Copyright (c) 1993, 1995 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by @@ -34,7 +34,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)procfs_vnops.c 8.6 (Berkeley) 2/7/94 + * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 * * $FreeBSD$ */ @@ -55,8 +55,9 @@ #include <sys/malloc.h> #include <sys/dirent.h> #include <sys/resourcevar.h> -#include <miscfs/procfs/procfs.h> #include <vm/vm.h> /* for PAGE_SIZE */ +#include <machine/reg.h> +#include <miscfs/procfs/procfs.h> static int procfs_abortop __P((struct vop_abortop_args *)); static int procfs_access __P((struct vop_access_args *)); @@ -78,29 +79,30 @@ static int procfs_setattr __P((struct vop_setattr_args *)); * process-specific sub-directories. It is * used in procfs_lookup and procfs_readdir */ -static struct pfsnames { - u_short d_namlen; - char d_name[PROCFS_NAMELEN]; - pfstype d_pfstype; - int (*d_valid) __P((struct proc *)); -} procent[] = { +struct proc_target { + u_char pt_type; + u_char pt_namlen; + char *pt_name; + pfstype pt_pfstype; + int (*pt_valid) __P((struct proc *p)); +} proc_targets[] = { #define N(s) sizeof(s)-1, s - /* namlen, nam, type validp */ - { N("."), Pproc, NULL }, - { N(".."), Proot, NULL }, - { N("file"), Pfile, procfs_validfile }, - { N("mem"), Pmem, NULL }, - { N("regs"), Pregs, procfs_validregs }, - { N("fpregs"), Pfpregs, procfs_validfpregs }, - { N("ctl"), Pctl, NULL }, - { N("status"), Pstatus, NULL }, - { N("note"), Pnote, NULL }, - { N("notepg"), Pnotepg, NULL }, - { N("map"), Pmap, procfs_validmap }, - { N("etype"), Ptype, procfs_validtype }, + /* name type validp */ + { DT_DIR, N("."), Pproc, NULL }, + { DT_DIR, N(".."), Proot, NULL }, + { DT_REG, N("file"), Pfile, procfs_validfile }, + { DT_REG, N("mem"), Pmem, NULL }, + { DT_REG, N("regs"), Pregs, procfs_validregs }, + { DT_REG, N("fpregs"), Pfpregs, procfs_validfpregs }, + { DT_REG, N("ctl"), Pctl, NULL }, + { DT_REG, N("status"), Pstatus, NULL }, + { DT_REG, N("note"), Pnote, NULL }, + { DT_REG, N("notepg"), Pnotepg, NULL }, + { DT_REG, N("map"), Pmap, procfs_validmap }, + { DT_REG, N("etype"), Ptype, procfs_validtype }, #undef N }; -#define Nprocent (sizeof(procent)/sizeof(procent[0])) +static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]); static pid_t atopid __P((const char *, u_int)); @@ -117,7 +119,12 @@ static pid_t atopid __P((const char *, u_int)); */ static int procfs_open(ap) - struct vop_open_args *ap; + struct vop_open_args /* { + struct vnode *a_vp; + int a_mode; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { struct pfsnode *pfs = VTOPFS(ap->a_vp); @@ -126,11 +133,10 @@ procfs_open(ap) if (PFIND(pfs->pfs_pid) == 0) return (ENOENT); /* was ESRCH, jsp */ - if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) || - ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) + if ((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL) || + (pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE)) return (EBUSY); - if (ap->a_mode & FWRITE) pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); @@ -152,7 +158,12 @@ procfs_open(ap) */ static int procfs_close(ap) - struct vop_close_args *ap; + struct vop_close_args /* { + struct vnode *a_vp; + int a_fflag; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { struct pfsnode *pfs = VTOPFS(ap->a_vp); @@ -174,14 +185,51 @@ procfs_close(ap) */ static int procfs_ioctl(ap) - struct vop_ioctl_args *ap; + struct vop_ioctl_args /* { + struct vnode *a_vp; + int a_command; + caddr_t a_data; + int a_fflag; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { return (ENOTTY); } /* - * _inactive is called when the pfsnode + * do block mapping for pfsnode (vp). + * since we don't use the buffer cache + * for procfs this function should never + * be called. in any case, it's not clear + * what part of the kernel ever makes use + * of this function. for sanity, this is the + * usual no-op bmap, although returning + * (EIO) would be a reasonable alternative. + */ +int +procfs_bmap(ap) + struct vop_bmap_args /* { + struct vnode *a_vp; + daddr_t a_bn; + struct vnode **a_vpp; + daddr_t *a_bnp; + int *a_runp; + } */ *ap; +{ + + if (ap->a_vpp != NULL) + *ap->a_vpp = ap->a_vp; + if (ap->a_bnp != NULL) + *ap->a_bnp = ap->a_bn; + if (ap->a_runp != NULL) + *ap->a_runp = 0; + return (0); +} + +/* + * procfs_inactive is called when the pfsnode * is vrele'd and the reference count goes * to zero. (vp) will be on the vnode free * list, so to get it back vget() must be @@ -194,16 +242,20 @@ procfs_ioctl(ap) * chances are that the process will still be * there and PFIND is not free. * - * (vp) is not locked on entry or exit. + * (vp) is locked on entry, but must be unlocked on exit. */ static int procfs_inactive(ap) - struct vop_inactive_args *ap; + struct vop_inactive_args /* { + struct vnode *a_vp; + } */ *ap; { - struct pfsnode *pfs = VTOPFS(ap->a_vp); + struct vnode *vp = ap->a_vp; + struct pfsnode *pfs = VTOPFS(vp); + VOP_UNLOCK(vp, 0, ap->a_p); if (PFIND(pfs->pfs_pid) == 0) - vgone(ap->a_vp); + vgone(vp); return (0); } @@ -217,12 +269,12 @@ procfs_inactive(ap) */ static int procfs_reclaim(ap) - struct vop_reclaim_args *ap; + struct vop_reclaim_args /* { + struct vnode *a_vp; + } */ *ap; { - int error; - error = procfs_freevp(ap->a_vp); - return (error); + return (procfs_freevp(ap->a_vp)); } /* @@ -269,13 +321,14 @@ procfs_pathconf(ap) */ static int procfs_print(ap) - struct vop_print_args *ap; + struct vop_print_args /* { + struct vnode *a_vp; + } */ *ap; { struct pfsnode *pfs = VTOPFS(ap->a_vp); - printf("tag VT_PROCFS, pid %lu, mode %x, flags %lx\n", - pfs->pfs_pid, - pfs->pfs_mode, pfs->pfs_flags); + printf("tag VT_PROCFS, type %s, pid %d, mode %x, flags %x\n", + pfs->pfs_type, pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags); return (0); } @@ -287,7 +340,10 @@ procfs_print(ap) */ static int procfs_abortop(ap) - struct vop_abortop_args *ap; + struct vop_abortop_args /* { + struct vnode *a_dvp; + struct componentname *a_cnp; + } */ *ap; { if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) @@ -316,7 +372,12 @@ procfs_badop() */ static int procfs_getattr(ap) - struct vop_getattr_args *ap; + struct vop_getattr_args /* { + struct vnode *a_vp; + struct vattr *a_vap; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { struct pfsnode *pfs = VTOPFS(ap->a_vp); struct vattr *vap = ap->a_vap; @@ -329,6 +390,7 @@ procfs_getattr(ap) */ switch (pfs->pfs_type) { case Proot: + case Pcurproc: procp = 0; break; @@ -353,6 +415,21 @@ procfs_getattr(ap) vap->va_bytes = vap->va_size = 0; /* + * Make all times be current TOD. + * It would be possible to get the process start + * time from the p_stat structure, but there's + * no "file creation" time stamp anyway, and the + * p_stat structure is not addressible if u. gets + * swapped out for that process. + */ + { + struct timeval tv; + microtime(&tv); + TIMEVAL_TO_TIMESPEC(&tv, &vap->va_ctime); + } + vap->va_atime = vap->va_mtime = vap->va_ctime; + + /* * If the process has exercised some setuid or setgid * privilege, then rip away read/write permission so * that only root can gain access. @@ -376,21 +453,6 @@ procfs_getattr(ap) } /* - * Make all times be current TOD. - * It would be possible to get the process start - * time from the p_stat structure, but there's - * no "file creation" time stamp anyway, and the - * p_stat structure is not addressible if u. gets - * swapped out for that process. - */ - { - struct timeval tv; - microtime(&tv); - TIMEVAL_TO_TIMESPEC(&tv, &vap->va_ctime); - } - vap->va_atime = vap->va_mtime = vap->va_ctime; - - /* * now do the object specific fields * * The size could be set from struct reg, but it's hardly @@ -402,17 +464,30 @@ procfs_getattr(ap) switch (pfs->pfs_type) { case Proot: - vap->va_nlink = nprocs + 3; + /* + * Set nlink to 1 to tell fts(3) we don't actually know. + */ + vap->va_nlink = 1; + vap->va_uid = 0; + vap->va_gid = 0; + vap->va_size = vap->va_bytes = DEV_BSIZE; + break; + + case Pcurproc: { + char buf[16]; /* should be enough */ + vap->va_nlink = 1; vap->va_uid = 0; vap->va_gid = 0; - vap->va_bytes = vap->va_size = DEV_BSIZE; + vap->va_size = vap->va_bytes = + sprintf(buf, "%ld", (long)curproc->p_pid); break; + } case Pproc: - vap->va_nlink = Nprocent; + vap->va_nlink = nproc_targets; vap->va_uid = procp->p_ucred->cr_uid; vap->va_gid = procp->p_ucred->cr_gid; - vap->va_bytes = vap->va_size = DEV_BSIZE; + vap->va_size = vap->va_bytes = DEV_BSIZE; break; case Pfile: @@ -436,7 +511,15 @@ procfs_getattr(ap) case Ptype: case Pmap: case Pregs: + vap->va_bytes = vap->va_size = sizeof(struct reg); + vap->va_nlink = 1; + vap->va_uid = procp->p_ucred->cr_uid; + vap->va_gid = procp->p_ucred->cr_gid; + break; + case Pfpregs: + vap->va_bytes = vap->va_size = sizeof(struct fpreg); + case Pctl: case Pstatus: case Pnote: @@ -455,7 +538,12 @@ procfs_getattr(ap) static int procfs_setattr(ap) - struct vop_setattr_args *ap; + struct vop_setattr_args /* { + struct vnode *a_vp; + struct vattr *a_vap; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { /* * just fake out attribute setting @@ -484,7 +572,12 @@ procfs_setattr(ap) */ static int procfs_access(ap) - struct vop_access_args *ap; + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { struct vattr *vap; struct vattr vattr; @@ -494,8 +587,9 @@ procfs_access(ap) * If you're the super-user, * you always get access. */ - if (ap->a_cred->cr_uid == (uid_t) 0) + if (ap->a_cred->cr_uid == 0) return (0); + vap = &vattr; error = VOP_GETATTR(ap->a_vp, vap, ap->a_cred, ap->a_p); if (error) @@ -510,7 +604,7 @@ procfs_access(ap) gid_t *gp; int i; - (ap->a_mode) >>= 3; + ap->a_mode >>= 3; gp = ap->a_cred->cr_groups; for (i = 0; i < ap->a_cred->cr_ngroups; i++, gp++) if (vap->va_gid == *gp) @@ -537,18 +631,23 @@ found: */ static int procfs_lookup(ap) - struct vop_lookup_args *ap; + struct vop_lookup_args /* { + struct vnode * a_dvp; + struct vnode ** a_vpp; + struct componentname * a_cnp; + } */ *ap; { struct componentname *cnp = ap->a_cnp; struct vnode **vpp = ap->a_vpp; struct vnode *dvp = ap->a_dvp; char *pname = cnp->cn_nameptr; + struct proc *curp = cnp->cn_proc; int error = 0; + struct proc_target *pt; + struct vnode *fvp; pid_t pid; - struct vnode *nvp; struct pfsnode *pfs; - struct proc *procp; - pfstype pfs_type; + struct proc *p; int i; *vpp = NULL; @@ -559,7 +658,7 @@ procfs_lookup(ap) if (cnp->cn_namelen == 1 && *pname == '.') { *vpp = dvp; VREF(dvp); - /*VOP_LOCK(dvp);*/ + /* vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, curp); */ return (0); } @@ -570,72 +669,52 @@ procfs_lookup(ap) return (EIO); if (CNEQ(cnp, "curproc", 7)) - pid = cnp->cn_proc->p_pid; - else - pid = atopid(pname, cnp->cn_namelen); - if (pid == NO_PID) - return (ENOENT); + return (procfs_allocvp(dvp->v_mount, vpp, 0, Pcurproc)); - procp = PFIND(pid); - if (procp == 0) - return (ENOENT); - - error = procfs_allocvp(dvp->v_mount, &nvp, pid, Pproc); - if (error) - return (error); + pid = atopid(pname, cnp->cn_namelen); + if (pid == NO_PID) + break; - nvp->v_type = VDIR; - pfs = VTOPFS(nvp); + p = PFIND(pid); + if (p == 0) + break; - *vpp = nvp; - return (0); + return (procfs_allocvp(dvp->v_mount, vpp, pid, Pproc)); case Pproc: - if (cnp->cn_flags & ISDOTDOT) { - error = procfs_root(dvp->v_mount, vpp); - return (error); - } - - procp = PFIND(pfs->pfs_pid); - if (procp == 0) - return (ENOENT); + if (cnp->cn_flags & ISDOTDOT) + return (procfs_root(dvp->v_mount, vpp)); - for (i = 0; i < Nprocent; i++) { - struct pfsnames *dp = &procent[i]; + p = PFIND(pfs->pfs_pid); + if (p == 0) + break; - if (cnp->cn_namelen == dp->d_namlen && - bcmp(pname, dp->d_name, dp->d_namlen) == 0 && - (dp->d_valid == NULL || (*dp->d_valid)(procp))) { - pfs_type = dp->d_pfstype; + for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) { + if (cnp->cn_namelen == pt->pt_namlen && + bcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 && + (pt->pt_valid == NULL || (*pt->pt_valid)(p))) goto found; - } } - return (ENOENT); + break; found: - if (pfs_type == Pfile) { - nvp = procfs_findtextvp(procp); - if (nvp) { - VREF(nvp); - VOP_LOCK(nvp); - } else { - error = ENXIO; - } - } else { - error = procfs_allocvp(dvp->v_mount, &nvp, - pfs->pfs_pid, pfs_type); - if (error) - return (error); - - nvp->v_type = VREG; - pfs = VTOPFS(nvp); + if (pt->pt_pfstype == Pfile) { + fvp = procfs_findtextvp(p); + /* We already checked that it exists. */ + VREF(fvp); + vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curp); + *vpp = fvp; + return (0); } - *vpp = nvp; - return (error); + + return (procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, + pt->pt_pfstype)); default: return (ENOTDIR); } + + return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS); } /* @@ -645,6 +724,7 @@ int procfs_validfile(p) struct proc *p; { + return (procfs_findtextvp(p) != NULLVP); } @@ -662,7 +742,14 @@ procfs_validfile(p) */ static int procfs_readdir(ap) - struct vop_readdir_args *ap; + struct vop_readdir_args /* { + struct vnode *a_vp; + struct uio *a_uio; + struct ucred *a_cred; + int *a_eofflag; + u_long *a_cookies; + int a_ncookies; + } */ *ap; { struct uio *uio = ap->a_uio; struct pfsdent d; @@ -672,6 +759,13 @@ procfs_readdir(ap) int count; int i; + /* + * We don't allow exporting procfs mounts, and currently local + * requests do not need cookies. + */ + if (ap->a_ncookies) + panic("procfs_readdir: not hungry"); + pfs = VTOPFS(ap->a_vp); if (uio->uio_resid < UIO_MX) @@ -693,39 +787,28 @@ procfs_readdir(ap) */ case Pproc: { struct proc *p; + struct proc_target *pt; p = PFIND(pfs->pfs_pid); if (p == NULL) break; - while (uio->uio_resid >= UIO_MX) { - struct pfsnames *dt; - - if (i >= Nprocent) - break; - - dt = &procent[i]; - - /* see if we should show this one. */ - if (dt->d_valid && (*dt->d_valid)(p) == 0) { - i++; + for (pt = &proc_targets[i]; + uio->uio_resid >= UIO_MX && i < nproc_targets; pt++, i++) { + if (pt->pt_valid && (*pt->pt_valid)(p) == 0) continue; - } dp->d_reclen = UIO_MX; - dp->d_fileno = PROCFS_FILENO(pfs->pfs_pid, dt->d_pfstype); - dp->d_type = DT_REG; - dp->d_namlen = dt->d_namlen; - bcopy(dt->d_name, dp->d_name, sizeof(dt->d_name)-1); - error = uiomove((caddr_t) dp, UIO_MX, uio); - if (error) + dp->d_fileno = PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype); + dp->d_namlen = pt->pt_namlen; + bcopy(pt->pt_name, dp->d_name, pt->pt_namlen + 1); + dp->d_type = pt->pt_type; + + if (error = uiomove((caddr_t)dp, UIO_MX, uio)) break; - count += UIO_MX; - i++; } break; - } /* @@ -738,63 +821,61 @@ procfs_readdir(ap) */ case Proot: { - int pcnt; #ifdef PROCFS_ZOMBIE int doingzomb = 0; #endif + int pcnt = 0; volatile struct proc *p = allproc.lh_first; -#define PROCFS_XFILES 3 /* number of other entries, like "curproc" */ - pcnt = PROCFS_XFILES; - - while (p && uio->uio_resid >= UIO_MX) { + again: + for (; p && uio->uio_resid >= UIO_MX; i++, pcnt++) { bzero((char *) dp, UIO_MX); - dp->d_type = DT_DIR; dp->d_reclen = UIO_MX; switch (i) { - case 0: + case 0: /* `.' */ + case 1: /* `..' */ dp->d_fileno = PROCFS_FILENO(0, Proot); - dp->d_namlen = sprintf(dp->d_name, "."); - break; - - case 1: - dp->d_fileno = PROCFS_FILENO(0, Proot); - dp->d_namlen = sprintf(dp->d_name, ".."); + dp->d_namlen = i + 1; + bcopy("..", dp->d_name, dp->d_namlen); + dp->d_name[i + 1] = '\0'; + dp->d_type = DT_DIR; break; case 2: - /* ship out entry for "curproc" */ - dp->d_fileno = PROCFS_FILENO(PID_MAX+1, Pproc); - dp->d_namlen = sprintf(dp->d_name, "curproc"); + dp->d_fileno = PROCFS_FILENO(0, Pcurproc); + dp->d_namlen = 7; + bcopy("curproc", dp->d_name, 8); + dp->d_type = DT_LNK; break; default: - if (pcnt >= i) { - dp->d_fileno = PROCFS_FILENO(p->p_pid, Pproc); - dp->d_namlen = sprintf(dp->d_name, "%ld", (long) p->p_pid); + while (pcnt < i) { + pcnt++; + p = p->p_list.le_next; + if (!p) + goto done; } - + dp->d_fileno = PROCFS_FILENO(p->p_pid, Pproc); + dp->d_namlen = sprintf(dp->d_name, "%ld", + (long)p->p_pid); + dp->d_type = DT_REG; p = p->p_list.le_next; - -#ifdef PROCFS_ZOMBIE - if (p == 0 && doingzomb == 0) { - doingzomb = 1; - p = zombproc.lh_first; - } -#endif - - if (pcnt++ < i) - continue; - break; } - error = uiomove((caddr_t) dp, UIO_MX, uio); - if (error) + + if (error = uiomove((caddr_t)dp, UIO_MX, uio)) break; - count += UIO_MX; - i++; } + done: + +#ifdef PROCFS_ZOMBIE + if (p == 0 && doingzomb == 0) { + doingzomb = 1; + p = zombproc.lh_first; + goto again; + } +#endif break; @@ -811,6 +892,25 @@ procfs_readdir(ap) } /* + * readlink reads the link of `curproc' + */ +int +procfs_readlink(ap) + struct vop_readlink_args *ap; +{ + struct uio *uio = ap->a_uio; + char buf[16]; /* should be enough */ + int len; + + if (VTOPFS(ap->a_vp)->pfs_fileno != PROCFS_FILENO(0, Pcurproc)) + return (EINVAL); + + len = sprintf(buf, "%ld", (long)curproc->p_pid); + + return (uiomove((caddr_t)buf, len, ap->a_uio)); +} + +/* * convert decimal ascii to pid_t */ static pid_t @@ -838,6 +938,7 @@ atopid(b, len) #define procfs_write procfs_rw #define procfs_select ((int (*) __P((struct vop_select_args *))) procfs_badop) #define procfs_mmap ((int (*) __P((struct vop_mmap_args *))) procfs_badop) +#define procfs_revoke vop_revoke #define procfs_fsync ((int (*) __P((struct vop_fsync_args *))) procfs_badop) #define procfs_seek ((int (*) __P((struct vop_seek_args *))) procfs_badop) #define procfs_remove ((int (*) __P((struct vop_remove_args *))) procfs_badop) @@ -849,7 +950,6 @@ atopid(b, len) #define procfs_readlink ((int (*) __P((struct vop_readlink_args *))) procfs_badop) #define procfs_lock ((int (*) __P((struct vop_lock_args *))) nullop) #define procfs_unlock ((int (*) __P((struct vop_unlock_args *))) nullop) -#define procfs_bmap ((int (*) __P((struct vop_bmap_args *))) procfs_badop) #define procfs_strategy ((int (*) __P((struct vop_strategy_args *))) procfs_badop) #define procfs_islocked ((int (*) __P((struct vop_islocked_args *))) nullop) #define procfs_advlock ((int (*) __P((struct vop_advlock_args *))) procfs_badop) @@ -859,6 +959,9 @@ atopid(b, len) #define procfs_truncate ((int (*) __P((struct vop_truncate_args *))) procfs_badop) #define procfs_update ((int (*) __P((struct vop_update_args *))) nullop) +/* + * procfs vnode operations. + */ vop_t **procfs_vnodeop_p; static struct vnodeopv_entry_desc procfs_vnodeop_entries[] = { { &vop_default_desc, (vop_t *)vn_default_error }, @@ -875,6 +978,7 @@ static struct vnodeopv_entry_desc procfs_vnodeop_entries[] = { { &vop_ioctl_desc, (vop_t *)procfs_ioctl }, /* ioctl */ { &vop_select_desc, (vop_t *)procfs_select }, /* select */ { &vop_mmap_desc, (vop_t *)procfs_mmap }, /* mmap */ + { &vop_revoke_desc, (vop_t *)procfs_revoke }, /* revoke */ { &vop_fsync_desc, (vop_t *)procfs_fsync }, /* fsync */ { &vop_seek_desc, (vop_t *)procfs_seek }, /* seek */ { &vop_remove_desc, (vop_t *)procfs_remove }, /* remove */ |