diff options
author | des <des@FreeBSD.org> | 2000-05-24 07:37:02 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2000-05-24 07:37:02 +0000 |
commit | f3c347774d20861e7f6983abd463f775b0b1e796 (patch) | |
tree | c1ea8bc9963f339793f4aed77bd1a0109c0fe5f0 /sys | |
parent | f84c12deda673f8103d06563efebe0bc6b83b1ac (diff) | |
download | FreeBSD-src-f3c347774d20861e7f6983abd463f775b0b1e796.zip FreeBSD-src-f3c347774d20861e7f6983abd463f775b0b1e796.tar.gz |
Make exe a symlink.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/compat/linprocfs/linprocfs.c | 9 | ||||
-rw-r--r-- | sys/compat/linprocfs/linprocfs.h | 1 | ||||
-rw-r--r-- | sys/compat/linprocfs/linprocfs_misc.c | 9 | ||||
-rw-r--r-- | sys/compat/linprocfs/linprocfs_subr.c | 6 | ||||
-rw-r--r-- | sys/compat/linprocfs/linprocfs_vnops.c | 69 | ||||
-rw-r--r-- | sys/i386/linux/linprocfs/linprocfs.h | 1 | ||||
-rw-r--r-- | sys/i386/linux/linprocfs/linprocfs_misc.c | 9 | ||||
-rw-r--r-- | sys/i386/linux/linprocfs/linprocfs_subr.c | 6 | ||||
-rw-r--r-- | sys/i386/linux/linprocfs/linprocfs_vnops.c | 69 |
9 files changed, 134 insertions, 45 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 225f845..4babe74 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -52,6 +52,7 @@ #include <vm/vm.h> #include <vm/pmap.h> #include <vm/vm_param.h> +#include <vm/vm_object.h> #include <vm/swap_pager.h> #include <sys/vmmeter.h> #include <sys/exec.h> @@ -80,6 +81,7 @@ linprocfs_domeminfo(curp, p, pfs, uio) unsigned long swaptotal; /* total swap space in bytes */ unsigned long swapused; /* used swap space in bytes */ unsigned long swapfree; /* free swap space in bytes */ + vm_object_t object; if (uio->uio_rw != UIO_READ) return (EOPNOTSUPP); @@ -100,7 +102,12 @@ linprocfs_domeminfo(curp, p, pfs, uio) swaptotal = swapblist->bl_blocks * 1024; /* XXX why 1024? */ swapfree = swapblist->bl_root->u.bmu_avail * PAGE_SIZE; swapused = swaptotal - swapfree; - memshared = 0; /* XXX what's this supposed to be? */ + memshared = 0; + for (object = TAILQ_FIRST(&vm_object_list); object != NULL; + object = TAILQ_NEXT(object, object_list)) + if (object->shadow_count > 1) + memshared += object->resident_page_count; + memshared *= PAGE_SIZE; /* * We'd love to be able to write: * diff --git a/sys/compat/linprocfs/linprocfs.h b/sys/compat/linprocfs/linprocfs.h index e7f70bc..14ef1a0 100644 --- a/sys/compat/linprocfs/linprocfs.h +++ b/sys/compat/linprocfs/linprocfs.h @@ -108,7 +108,6 @@ struct dbreg; void linprocfs_exit __P((struct proc *)); int linprocfs_freevp __P((struct vnode *)); int linprocfs_allocvp __P((struct mount *, struct vnode **, long, pfstype)); -struct vnode *linprocfs_findtextvp __P((struct proc *)); int linprocfs_sstep __P((struct proc *)); void linprocfs_fix_sstep __P((struct proc *)); #if 0 diff --git a/sys/compat/linprocfs/linprocfs_misc.c b/sys/compat/linprocfs/linprocfs_misc.c index 225f845..4babe74 100644 --- a/sys/compat/linprocfs/linprocfs_misc.c +++ b/sys/compat/linprocfs/linprocfs_misc.c @@ -52,6 +52,7 @@ #include <vm/vm.h> #include <vm/pmap.h> #include <vm/vm_param.h> +#include <vm/vm_object.h> #include <vm/swap_pager.h> #include <sys/vmmeter.h> #include <sys/exec.h> @@ -80,6 +81,7 @@ linprocfs_domeminfo(curp, p, pfs, uio) unsigned long swaptotal; /* total swap space in bytes */ unsigned long swapused; /* used swap space in bytes */ unsigned long swapfree; /* free swap space in bytes */ + vm_object_t object; if (uio->uio_rw != UIO_READ) return (EOPNOTSUPP); @@ -100,7 +102,12 @@ linprocfs_domeminfo(curp, p, pfs, uio) swaptotal = swapblist->bl_blocks * 1024; /* XXX why 1024? */ swapfree = swapblist->bl_root->u.bmu_avail * PAGE_SIZE; swapused = swaptotal - swapfree; - memshared = 0; /* XXX what's this supposed to be? */ + memshared = 0; + for (object = TAILQ_FIRST(&vm_object_list); object != NULL; + object = TAILQ_NEXT(object, object_list)) + if (object->shadow_count > 1) + memshared += object->resident_page_count; + memshared *= PAGE_SIZE; /* * We'd love to be able to write: * diff --git a/sys/compat/linprocfs/linprocfs_subr.c b/sys/compat/linprocfs/linprocfs_subr.c index 7a0c98d..87d6134 100644 --- a/sys/compat/linprocfs/linprocfs_subr.c +++ b/sys/compat/linprocfs/linprocfs_subr.c @@ -161,6 +161,12 @@ loop: break; case Pexe: + pfs->pfs_mode = (VREAD|VEXEC) | + (VREAD|VEXEC) >> 3 | + (VREAD|VEXEC) >> 6; + vp->v_type = VLNK; + break; + case Pmem: pfs->pfs_mode = (VREAD|VWRITE) | (VREAD) >> 3;; diff --git a/sys/compat/linprocfs/linprocfs_vnops.c b/sys/compat/linprocfs/linprocfs_vnops.c index 82eb8ac..5ba499d 100644 --- a/sys/compat/linprocfs/linprocfs_vnops.c +++ b/sys/compat/linprocfs/linprocfs_vnops.c @@ -55,6 +55,7 @@ #include <sys/mount.h> #include <sys/namei.h> #include <sys/dirent.h> +#include <sys/malloc.h> #include <machine/reg.h> #include <vm/vm_zone.h> #include <i386/linux/linprocfs/linprocfs.h> @@ -94,8 +95,8 @@ static struct proc_target { /* name type validp */ { DT_DIR, N("."), Pproc, NULL }, { DT_DIR, N(".."), Proot, NULL }, - { DT_REG, N("exe"), Pexe, linprocfs_validfile }, { DT_REG, N("mem"), Pmem, NULL }, + { DT_LNK, N("exe"), Pexe, NULL }, #undef N }; static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]); @@ -513,9 +514,19 @@ linprocfs_getattr(ap) vap->va_size = vap->va_bytes = DEV_BSIZE; break; - case Pexe: - error = EOPNOTSUPP; + case Pexe: { + char *fullpath, *freepath; + error = textvp_fullpath(procp, &fullpath, &freepath); + if (error == 0) { + vap->va_size = strlen(fullpath); + free(freepath, M_TEMP); + } else { + vap->va_size = sizeof("unknown") - 1; + error = 0; + } + vap->va_bytes = vap->va_size; break; + } case Pmeminfo: case Pcpuinfo: @@ -650,9 +661,7 @@ linprocfs_lookup(ap) struct vnode **vpp = ap->a_vpp; struct vnode *dvp = ap->a_dvp; char *pname = cnp->cn_nameptr; - struct proc *curp = cnp->cn_proc; struct proc_target *pt; - struct vnode *fvp; pid_t pid; struct pfsnode *pfs; struct proc *p; @@ -710,15 +719,6 @@ linprocfs_lookup(ap) break; found: - if (pt->pt_pfstype == Pexe) { - fvp = procfs_findtextvp(p); - /* We already checked that it exists. */ - VREF(fvp); - vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curp); - *vpp = fvp; - return (0); - } - return (linprocfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, pt->pt_pfstype)); @@ -916,21 +916,50 @@ linprocfs_readdir(ap) } /* - * readlink reads the link of `self' + * readlink reads the link of `self' or `exe' */ static int linprocfs_readlink(ap) struct vop_readlink_args *ap; { char buf[16]; /* should be enough */ - int len; + struct proc *procp; + struct vnode *vp = ap->a_vp; + struct pfsnode *pfs = VTOPFS(vp); + char *fullpath, *freepath; + int error, len; - if (VTOPFS(ap->a_vp)->pfs_fileno != PROCFS_FILENO(0, Pself)) - return (EINVAL); + switch (pfs->pfs_type) { + case Pself: + if (pfs->pfs_fileno != PROCFS_FILENO(0, Pself)) + return (EINVAL); - len = snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid); + len = snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid); - return (uiomove((caddr_t)buf, len, ap->a_uio)); + return (uiomove(buf, len, ap->a_uio)); + /* + * There _should_ be no way for an entire process to disappear + * from under us... + */ + case Pexe: + procp = PFIND(pfs->pfs_pid); + if (procp == NULL || procp->p_cred == NULL || + procp->p_ucred == NULL) { + printf("linprocfs_readlink: pid %d disappeared\n", + pfs->pfs_pid); + return (uiomove("unknown", sizeof("unknown") - 1, + ap->a_uio)); + } + error = textvp_fullpath(procp, &fullpath, &freepath); + if (error != 0) + return (uiomove("unknown", sizeof("unknown") - 1, + ap->a_uio)); + error = uiomove(fullpath, strlen(fullpath), ap->a_uio); + free(freepath, M_TEMP); + return (error); + default: + return (EINVAL); + } } /* diff --git a/sys/i386/linux/linprocfs/linprocfs.h b/sys/i386/linux/linprocfs/linprocfs.h index e7f70bc..14ef1a0 100644 --- a/sys/i386/linux/linprocfs/linprocfs.h +++ b/sys/i386/linux/linprocfs/linprocfs.h @@ -108,7 +108,6 @@ struct dbreg; void linprocfs_exit __P((struct proc *)); int linprocfs_freevp __P((struct vnode *)); int linprocfs_allocvp __P((struct mount *, struct vnode **, long, pfstype)); -struct vnode *linprocfs_findtextvp __P((struct proc *)); int linprocfs_sstep __P((struct proc *)); void linprocfs_fix_sstep __P((struct proc *)); #if 0 diff --git a/sys/i386/linux/linprocfs/linprocfs_misc.c b/sys/i386/linux/linprocfs/linprocfs_misc.c index 225f845..4babe74 100644 --- a/sys/i386/linux/linprocfs/linprocfs_misc.c +++ b/sys/i386/linux/linprocfs/linprocfs_misc.c @@ -52,6 +52,7 @@ #include <vm/vm.h> #include <vm/pmap.h> #include <vm/vm_param.h> +#include <vm/vm_object.h> #include <vm/swap_pager.h> #include <sys/vmmeter.h> #include <sys/exec.h> @@ -80,6 +81,7 @@ linprocfs_domeminfo(curp, p, pfs, uio) unsigned long swaptotal; /* total swap space in bytes */ unsigned long swapused; /* used swap space in bytes */ unsigned long swapfree; /* free swap space in bytes */ + vm_object_t object; if (uio->uio_rw != UIO_READ) return (EOPNOTSUPP); @@ -100,7 +102,12 @@ linprocfs_domeminfo(curp, p, pfs, uio) swaptotal = swapblist->bl_blocks * 1024; /* XXX why 1024? */ swapfree = swapblist->bl_root->u.bmu_avail * PAGE_SIZE; swapused = swaptotal - swapfree; - memshared = 0; /* XXX what's this supposed to be? */ + memshared = 0; + for (object = TAILQ_FIRST(&vm_object_list); object != NULL; + object = TAILQ_NEXT(object, object_list)) + if (object->shadow_count > 1) + memshared += object->resident_page_count; + memshared *= PAGE_SIZE; /* * We'd love to be able to write: * diff --git a/sys/i386/linux/linprocfs/linprocfs_subr.c b/sys/i386/linux/linprocfs/linprocfs_subr.c index 7a0c98d..87d6134 100644 --- a/sys/i386/linux/linprocfs/linprocfs_subr.c +++ b/sys/i386/linux/linprocfs/linprocfs_subr.c @@ -161,6 +161,12 @@ loop: break; case Pexe: + pfs->pfs_mode = (VREAD|VEXEC) | + (VREAD|VEXEC) >> 3 | + (VREAD|VEXEC) >> 6; + vp->v_type = VLNK; + break; + case Pmem: pfs->pfs_mode = (VREAD|VWRITE) | (VREAD) >> 3;; diff --git a/sys/i386/linux/linprocfs/linprocfs_vnops.c b/sys/i386/linux/linprocfs/linprocfs_vnops.c index 82eb8ac..5ba499d 100644 --- a/sys/i386/linux/linprocfs/linprocfs_vnops.c +++ b/sys/i386/linux/linprocfs/linprocfs_vnops.c @@ -55,6 +55,7 @@ #include <sys/mount.h> #include <sys/namei.h> #include <sys/dirent.h> +#include <sys/malloc.h> #include <machine/reg.h> #include <vm/vm_zone.h> #include <i386/linux/linprocfs/linprocfs.h> @@ -94,8 +95,8 @@ static struct proc_target { /* name type validp */ { DT_DIR, N("."), Pproc, NULL }, { DT_DIR, N(".."), Proot, NULL }, - { DT_REG, N("exe"), Pexe, linprocfs_validfile }, { DT_REG, N("mem"), Pmem, NULL }, + { DT_LNK, N("exe"), Pexe, NULL }, #undef N }; static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]); @@ -513,9 +514,19 @@ linprocfs_getattr(ap) vap->va_size = vap->va_bytes = DEV_BSIZE; break; - case Pexe: - error = EOPNOTSUPP; + case Pexe: { + char *fullpath, *freepath; + error = textvp_fullpath(procp, &fullpath, &freepath); + if (error == 0) { + vap->va_size = strlen(fullpath); + free(freepath, M_TEMP); + } else { + vap->va_size = sizeof("unknown") - 1; + error = 0; + } + vap->va_bytes = vap->va_size; break; + } case Pmeminfo: case Pcpuinfo: @@ -650,9 +661,7 @@ linprocfs_lookup(ap) struct vnode **vpp = ap->a_vpp; struct vnode *dvp = ap->a_dvp; char *pname = cnp->cn_nameptr; - struct proc *curp = cnp->cn_proc; struct proc_target *pt; - struct vnode *fvp; pid_t pid; struct pfsnode *pfs; struct proc *p; @@ -710,15 +719,6 @@ linprocfs_lookup(ap) break; found: - if (pt->pt_pfstype == Pexe) { - fvp = procfs_findtextvp(p); - /* We already checked that it exists. */ - VREF(fvp); - vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curp); - *vpp = fvp; - return (0); - } - return (linprocfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, pt->pt_pfstype)); @@ -916,21 +916,50 @@ linprocfs_readdir(ap) } /* - * readlink reads the link of `self' + * readlink reads the link of `self' or `exe' */ static int linprocfs_readlink(ap) struct vop_readlink_args *ap; { char buf[16]; /* should be enough */ - int len; + struct proc *procp; + struct vnode *vp = ap->a_vp; + struct pfsnode *pfs = VTOPFS(vp); + char *fullpath, *freepath; + int error, len; - if (VTOPFS(ap->a_vp)->pfs_fileno != PROCFS_FILENO(0, Pself)) - return (EINVAL); + switch (pfs->pfs_type) { + case Pself: + if (pfs->pfs_fileno != PROCFS_FILENO(0, Pself)) + return (EINVAL); - len = snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid); + len = snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid); - return (uiomove((caddr_t)buf, len, ap->a_uio)); + return (uiomove(buf, len, ap->a_uio)); + /* + * There _should_ be no way for an entire process to disappear + * from under us... + */ + case Pexe: + procp = PFIND(pfs->pfs_pid); + if (procp == NULL || procp->p_cred == NULL || + procp->p_ucred == NULL) { + printf("linprocfs_readlink: pid %d disappeared\n", + pfs->pfs_pid); + return (uiomove("unknown", sizeof("unknown") - 1, + ap->a_uio)); + } + error = textvp_fullpath(procp, &fullpath, &freepath); + if (error != 0) + return (uiomove("unknown", sizeof("unknown") - 1, + ap->a_uio)); + error = uiomove(fullpath, strlen(fullpath), ap->a_uio); + free(freepath, M_TEMP); + return (error); + default: + return (EINVAL); + } } /* |