merge in netbsd changes.
authorJan-Simon Pendry <pendry@ucbvax.Berkeley.EDU>
Thu, 16 Jun 1994 03:30:54 +0000 (19:30 -0800)
committerJan-Simon Pendry <pendry@ucbvax.Berkeley.EDU>
Thu, 16 Jun 1994 03:30:54 +0000 (19:30 -0800)
security fixes, curproc becomes symlink, misc other trash.

SCCS-vsn: sys/miscfs/procfs/procfs.h 8.7
SCCS-vsn: sys/miscfs/procfs/README 8.2
SCCS-vsn: sys/miscfs/procfs/procfs_ctl.c 8.4
SCCS-vsn: sys/miscfs/procfs/procfs_mem.c 8.5
SCCS-vsn: sys/miscfs/procfs/procfs_regs.c 8.4
SCCS-vsn: sys/miscfs/procfs/procfs_subr.c 8.5
SCCS-vsn: sys/miscfs/procfs/procfs_vnops.c 8.8
SCCS-vsn: sys/miscfs/procfs/procfs_status.c 8.4
SCCS-vsn: sys/miscfs/procfs/procfs_vfsops.c 8.5
SCCS-vsn: sys/miscfs/procfs/procfs_fpregs.c 8.2

usr/src/sys/miscfs/procfs/procfs.h
usr/src/sys/miscfs/procfs/procfs_ctl.c
usr/src/sys/miscfs/procfs/procfs_fpregs.c
usr/src/sys/miscfs/procfs/procfs_mem.c
usr/src/sys/miscfs/procfs/procfs_regs.c
usr/src/sys/miscfs/procfs/procfs_status.c
usr/src/sys/miscfs/procfs/procfs_subr.c
usr/src/sys/miscfs/procfs/procfs_vfsops.c
usr/src/sys/miscfs/procfs/procfs_vnops.c

index d325a66..45b617c 100644 (file)
@@ -8,7 +8,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)procfs.h    8.6 (Berkeley) %G%
+ *     @(#)procfs.h    8.7 (Berkeley) %G%
  *
  * From:
  *     $Id: procfs.h,v 3.2 1993/12/15 09:40:17 jsp Exp $
  *
  * From:
  *     $Id: procfs.h,v 3.2 1993/12/15 09:40:17 jsp Exp $
@@ -19,6 +19,7 @@
  */
 typedef enum {
        Proot,          /* the filesystem root */
  */
 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 */
        Pproc,          /* a process-specific sub-directory */
        Pfile,          /* the executable file */
        Pmem,           /* the process's memory image */
@@ -68,9 +69,9 @@ struct pfsdent {
 };
 #define UIO_MX sizeof(struct pfsdent)
 #define PROCFS_FILENO(pid, type) \
 };
 #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
 
 /*
  * Convert between pfsnode vnode
@@ -84,29 +85,34 @@ struct vfs_namemap {
        int nm_val;
 };
 
        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)
 
 /* <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));
+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 *, int));
+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));
+
+/* 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 *));
 
 #define PROCFS_LOCKED  0x01
 #define PROCFS_WANT    0x02
 
 #define PROCFS_LOCKED  0x01
 #define PROCFS_WANT    0x02
@@ -141,7 +147,7 @@ int procfs_ioctl __P((struct vop_ioctl_args *));
 #define procfs_rmdir ((int (*) __P((struct vop_rmdir_args *))) procfs_badop)
 #define procfs_symlink ((int (*) __P((struct vop_symlink_args *))) procfs_badop)
 int    procfs_readdir __P((struct vop_readdir_args *));
 #define procfs_rmdir ((int (*) __P((struct vop_rmdir_args *))) procfs_badop)
 #define procfs_symlink ((int (*) __P((struct vop_symlink_args *))) procfs_badop)
 int    procfs_readdir __P((struct vop_readdir_args *));
-#define procfs_readlink ((int (*) __P((struct vop_readlink_args *))) procfs_badop)
+int    procfs_readlink __P((struct vop_readlink_args *));
 int    procfs_abortop __P((struct vop_abortop_args *));
 int    procfs_inactive __P((struct vop_inactive_args *));
 int    procfs_reclaim __P((struct vop_reclaim_args *));
 int    procfs_abortop __P((struct vop_abortop_args *));
 int    procfs_inactive __P((struct vop_inactive_args *));
 int    procfs_reclaim __P((struct vop_reclaim_args *));
index 11123e8..cce6ca6 100644 (file)
@@ -8,7 +8,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)procfs_ctl.c        8.3 (Berkeley) %G%
+ *     @(#)procfs_ctl.c        8.4 (Berkeley) %G%
  *
  * From:
  *     $Id: procfs_ctl.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
  *
  * From:
  *     $Id: procfs_ctl.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
 #include <sys/tty.h>
 #include <sys/resource.h>
 #include <sys/resourcevar.h>
 #include <sys/tty.h>
 #include <sys/resource.h>
 #include <sys/resourcevar.h>
+#include <sys/ptrace.h>
 #include <miscfs/procfs/procfs.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)
 /*
  * True iff process (p) is in trace wait state
  * relative to process (curp)
         (p)->p_pptr == (curp) && \
         ((p)->p_flag & P_TRACED))
 
         (p)->p_pptr == (curp) && \
         ((p)->p_flag & P_TRACED))
 
-#ifdef notdef
-#define FIX_SSTEP(p) { \
-               procfs_fix_sstep(p); \
-       } \
-}
-#else
-#define FIX_SSTEP(p)
-#endif
-
 #define PROCFS_CTL_ATTACH      1
 #define PROCFS_CTL_DETACH      2
 #define PROCFS_CTL_STEP                3
 #define PROCFS_CTL_ATTACH      1
 #define PROCFS_CTL_DETACH      2
 #define PROCFS_CTL_STEP                3
@@ -180,7 +177,8 @@ procfs_control(curp, p, op)
         * Step.  Let the target process execute a single instruction.
         */
        case PROCFS_CTL_STEP:
         * Step.  Let the target process execute a single instruction.
         */
        case PROCFS_CTL_STEP:
-               procfs_sstep(p);
+               if (error = procfs_sstep(p, 1))
+                       return (error);
                break;
 
        /*
                break;
 
        /*
index bf9b015..71e665c 100644 (file)
@@ -8,7 +8,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)procfs_fpregs.c     8.1 (Berkeley) %G%
+ *     @(#)procfs_fpregs.c     8.2 (Berkeley) %G%
  *
  * From:
  *     $Id: procfs_regs.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
  *
  * From:
  *     $Id: procfs_regs.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
@@ -59,3 +59,11 @@ procfs_dofpregs(curp, p, pfs, uio)
        uio->uio_offset = 0;
        return (error);
 }
        uio->uio_offset = 0;
        return (error);
 }
+
+int
+procfs_validfpregs(p)
+       struct proc *p;
+{
+
+       return ((p->p_flag & P_SYSTEM) == 0);
+}
index ff4ca33..ef8f24c 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)procfs_mem.c        8.4 (Berkeley) %G%
+ *     @(#)procfs_mem.c        8.5 (Berkeley) %G%
  *
  * From:
  *     $Id: procfs_mem.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
  *
  * From:
  *     $Id: procfs_mem.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
@@ -180,14 +180,11 @@ procfs_domem(curp, p, pfs, uio)
        struct pfsnode *pfs;
        struct uio *uio;
 {
        struct pfsnode *pfs;
        struct uio *uio;
 {
-       int error;
 
        if (uio->uio_resid == 0)
                return (0);
 
 
        if (uio->uio_resid == 0)
                return (0);
 
-       error = procfs_rwmem(p, uio);
-
-       return (error);
+       return (procfs_rwmem(p, uio));
 }
 
 /*
 }
 
 /*
@@ -205,6 +202,7 @@ struct vnode *
 procfs_findtextvp(p)
        struct proc *p;
 {
 procfs_findtextvp(p)
        struct proc *p;
 {
+
        return (p->p_textvp);
 }
 
        return (p->p_textvp);
 }
 
index 05a9657..34847bc 100644 (file)
@@ -8,7 +8,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)procfs_regs.c       8.3 (Berkeley) %G%
+ *     @(#)procfs_regs.c       8.4 (Berkeley) %G%
  *
  * From:
  *     $Id: procfs_regs.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
  *
  * From:
  *     $Id: procfs_regs.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
@@ -59,3 +59,11 @@ procfs_doregs(curp, p, pfs, uio)
        uio->uio_offset = 0;
        return (error);
 }
        uio->uio_offset = 0;
        return (error);
 }
+
+int
+procfs_validregs(p)
+       struct proc *p;
+{
+
+       return ((p->p_flag & P_SYSTEM) == 0);
+}
index b3ff071..f204664 100644 (file)
@@ -8,7 +8,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)procfs_status.c     8.3 (Berkeley) %G%
+ *     @(#)procfs_status.c     8.4 (Berkeley) %G%
  *
  * From:
  *     $Id: procfs_status.c,v 3.1 1993/12/15 09:40:17 jsp Exp $
  *
  * From:
  *     $Id: procfs_status.c,v 3.1 1993/12/15 09:40:17 jsp Exp $
@@ -101,7 +101,7 @@ procfs_dostatus(curp, p, pfs, uio)
 
        cr = p->p_ucred;
 
 
        cr = p->p_ucred;
 
-       ps += sprintf(ps, " %d", cr->cr_uid, cr->cr_gid);
+       ps += sprintf(ps, " %d", cr->cr_uid);
        for (i = 0; i < cr->cr_ngroups; i++)
                ps += sprintf(ps, ",%d", cr->cr_groups[i]);
        ps += sprintf(ps, "\n");
        for (i = 0; i < cr->cr_ngroups; i++)
                ps += sprintf(ps, ",%d", cr->cr_groups[i]);
        ps += sprintf(ps, "\n");
@@ -109,7 +109,7 @@ procfs_dostatus(curp, p, pfs, uio)
        xlen = ps - psbuf;
        xlen -= uio->uio_offset;
        ps = psbuf + uio->uio_offset;
        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
        if (xlen <= 0)
                error = 0;
        else
index 9505f33..6c4b989 100644 (file)
@@ -8,7 +8,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)procfs_subr.c       8.4 (Berkeley) %G%
+ *     @(#)procfs_subr.c       8.5 (Berkeley) %G%
  *
  * From:
  *     $Id: procfs_subr.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
  *
  * From:
  *     $Id: procfs_subr.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
@@ -59,18 +59,20 @@ procfs_allocvp(mp, vpp, pid, pfs_type)
        long pid;
        pfstype pfs_type;
 {
        long pid;
        pfstype pfs_type;
 {
-       int error;
        struct pfsnode *pfs;
        struct pfsnode *pfs;
+       struct vnode *vp;
        struct pfsnode **pp;
        struct pfsnode **pp;
+       int error;
 
 loop:
        for (pfs = pfshead; pfs != 0; pfs = pfs->pfs_next) {
 
 loop:
        for (pfs = pfshead; pfs != 0; pfs = pfs->pfs_next) {
+               vp = PFSTOV(pfs);
                if (pfs->pfs_pid == pid &&
                    pfs->pfs_type == pfs_type &&
                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))
                                goto loop;
                                goto loop;
-                       *vpp = pfs->pfs_vnode;
+                       *vpp = vp;
                        return (0);
                }
        }
                        return (0);
                }
        }
@@ -86,18 +88,17 @@ loop:
        }
        pfsvplock |= PROCFS_LOCKED;
 
        }
        pfsvplock |= PROCFS_LOCKED;
 
-       error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp);
-       if (error)
+       if (error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp))
                goto out;
                goto out;
+       vp = *vpp;
 
 
-       MALLOC((*vpp)->v_data, void *, sizeof(struct pfsnode),
-               M_TEMP, M_WAITOK);
+       MALLOC(pfs, void *, sizeof(struct pfsnode), M_TEMP, M_WAITOK);
+       vp->v_data = pfs;
 
 
-       pfs = VTOPFS(*vpp);
        pfs->pfs_next = 0;
        pfs->pfs_pid = (pid_t) pid;
        pfs->pfs_type = pfs_type;
        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_fileno = PROCFS_FILENO(pid, pfs_type);
 
        pfs->pfs_flags = 0;
        pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type);
 
@@ -106,46 +107,44 @@ loop:
                pfs->pfs_mode = (VREAD|VEXEC) |
                                (VREAD|VEXEC) >> 3 |
                                (VREAD|VEXEC) >> 6;
                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;
                break;
 
        case Pproc:
                pfs->pfs_mode = (VREAD|VEXEC) |
                                (VREAD|VEXEC) >> 3 |
                                (VREAD|VEXEC) >> 6;
+               vp->v_type = VDIR;
                break;
 
        case Pfile:
                break;
 
        case Pfile:
-               pfs->pfs_mode = (VREAD|VWRITE);
-               break;
-
        case Pmem:
        case Pmem:
-               pfs->pfs_mode = (VREAD|VWRITE);
-               break;
-
        case Pregs:
        case Pregs:
-               pfs->pfs_mode = (VREAD|VWRITE);
-               break;
-
        case Pfpregs:
                pfs->pfs_mode = (VREAD|VWRITE);
        case Pfpregs:
                pfs->pfs_mode = (VREAD|VWRITE);
+               vp->v_type = VREG;
                break;
 
        case Pctl:
                break;
 
        case Pctl:
+       case Pnote:
+       case Pnotepg:
                pfs->pfs_mode = (VWRITE);
                pfs->pfs_mode = (VWRITE);
+               vp->v_type = VREG;
                break;
 
        case Pstatus:
                pfs->pfs_mode = (VREAD) |
                                (VREAD >> 3) |
                                (VREAD >> 6);
                break;
 
        case Pstatus:
                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:
                break;
 
        default:
@@ -257,8 +256,7 @@ vfs_getuserstr(uio, buf, buflenp)
                return (EMSGSIZE);
        xlen = uio->uio_resid;
 
                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 */
                return (error);
 
        /* allow multiple writes without seeks */
@@ -280,6 +278,7 @@ vfs_findname(nm, buf, buflen)
        char *buf;
        int buflen;
 {
        char *buf;
        int buflen;
 {
+
        for (; nm->nm_name; nm++)
                if (bcmp(buf, (char *) nm->nm_name, buflen+1) == 0)
                        return (nm);
        for (; nm->nm_name; nm++)
                if (bcmp(buf, (char *) nm->nm_name, buflen+1) == 0)
                        return (nm);
index ea6b6d5..c60f093 100644 (file)
@@ -8,7 +8,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)procfs_vfsops.c     8.4 (Berkeley) %G%
+ *     @(#)procfs_vfsops.c     8.5 (Berkeley) %G%
  *
  * From:
  *     $Id: procfs_vfsops.c,v 3.1 1993/12/15 09:40:17 jsp Exp $
  *
  * From:
  *     $Id: procfs_vfsops.c,v 3.1 1993/12/15 09:40:17 jsp Exp $
@@ -96,24 +96,10 @@ procfs_root(mp, vpp)
        struct mount *mp;
        struct vnode **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 */
 procfs_start(mp, flags, p)
        struct mount *mp;
 /* ARGSUSED */
 procfs_start(mp, flags, p)
        struct mount *mp;
index 1d6a95d..1294d34 100644 (file)
@@ -8,7 +8,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)procfs_vnops.c      8.7 (Berkeley) %G%
+ *     @(#)procfs_vnops.c      8.8 (Berkeley) %G%
  *
  * From:
  *     $Id: procfs_vnops.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
  *
  * From:
  *     $Id: procfs_vnops.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
@@ -29,8 +29,9 @@
 #include <sys/malloc.h>
 #include <sys/dirent.h>
 #include <sys/resourcevar.h>
 #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 <vm/vm.h>     /* for PAGE_SIZE */
+#include <machine/reg.h>
+#include <miscfs/procfs/procfs.h>
 
 /*
  * Vnode Operations.
 
 /*
  * Vnode Operations.
  * used in procfs_lookup and procfs_readdir
  */
 static struct pfsnames {
  * used in procfs_lookup and procfs_readdir
  */
 static struct pfsnames {
-       u_short d_namlen;
+       u_char  d_type;
+       u_char  d_namlen;
        char    d_name[PROCFS_NAMELEN];
        pfstype d_pfstype;
        char    d_name[PROCFS_NAMELEN];
        pfstype d_pfstype;
+       int     (*d_valid) __P((struct proc *p));
 } procent[] = {
 #define N(s) sizeof(s)-1, s
        /* namlen, nam, type */
 } procent[] = {
 #define N(s) sizeof(s)-1, s
        /* namlen, nam, type */
-       {  N("file"),   Pfile },
-       {  N("mem"),    Pmem },
-       {  N("regs"),   Pregs },
-       {  N("fpregs"), Pfpregs },
-       {  N("ctl"),    Pctl },
-       {  N("status"), Pstatus },
-       {  N("note"),   Pnote },
-       {  N("notepg"), Pnotepg },
+       { 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 },
 #undef N
 };
 #define Nprocent (sizeof(procent)/sizeof(procent[0]))
 #undef N
 };
 #define Nprocent (sizeof(procent)/sizeof(procent[0]))
@@ -90,10 +95,9 @@ procfs_open(ap)
                        return (ENOENT);        /* was ESRCH, jsp */
 
                if ((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL) ||
                        return (ENOENT);        /* was ESRCH, jsp */
 
                if ((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL) ||
-                               (pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))
+                   (pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))
                        return (EBUSY);
 
                        return (EBUSY);
 
-
                if (ap->a_mode & FWRITE)
                        pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL);
 
                if (ap->a_mode & FWRITE)
                        pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL);
 
@@ -218,10 +222,8 @@ procfs_reclaim(ap)
                struct vnode *a_vp;
        } */ *ap;
 {
                struct vnode *a_vp;
        } */ *ap;
 {
-       int error;
 
 
-       error = procfs_freevp(ap->a_vp);
-       return (error);
+       return (procfs_freevp(ap->a_vp));
 }
 
 /*
 }
 
 /*
@@ -272,9 +274,8 @@ procfs_print(ap)
 {
        struct pfsnode *pfs = VTOPFS(ap->a_vp);
 
 {
        struct pfsnode *pfs = VTOPFS(ap->a_vp);
 
-       printf("tag VT_PROCFS, pid %d, mode %x, flags %x\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);
 }
 
 /*
 }
 
 /*
@@ -329,6 +330,7 @@ procfs_getattr(ap)
        /* first check the process still exists */
        switch (pfs->pfs_type) {
        case Proot:
        /* first check the process still exists */
        switch (pfs->pfs_type) {
        case Proot:
+       case Pcurproc:
                procp = 0;
                break;
 
                procp = 0;
                break;
 
@@ -351,33 +353,43 @@ procfs_getattr(ap)
        vap->va_blocksize = PAGE_SIZE;
        vap->va_bytes = vap->va_size = 0;
 
        vap->va_blocksize = PAGE_SIZE;
        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.
+        *
+        * XXX
+        * Note that microtime() returns a timeval, not a timespec.
+        */
+       microtime(&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.
         */
        switch (pfs->pfs_type) {
        /*
         * If the process has exercised some setuid or setgid
         * privilege, then rip away read/write permission so
         * that only root can gain access.
         */
        switch (pfs->pfs_type) {
+       case Pmem:
        case Pregs:
        case Pfpregs:
        case Pregs:
        case Pfpregs:
-       case Pmem:
                if (procp->p_flag & P_SUGID)
                        vap->va_mode &= ~((VREAD|VWRITE)|
                                          ((VREAD|VWRITE)>>3)|
                                          ((VREAD|VWRITE)>>6));
                if (procp->p_flag & P_SUGID)
                        vap->va_mode &= ~((VREAD|VWRITE)|
                                          ((VREAD|VWRITE)>>3)|
                                          ((VREAD|VWRITE)>>6));
+       case Pctl:
+       case Pstatus:
+       case Pnote:
+       case Pnotepg:
+               vap->va_nlink = 1;
+               vap->va_uid = procp->p_ucred->cr_uid;
+               vap->va_gid = procp->p_ucred->cr_gid;
                break;
        }
 
                break;
        }
 
-       /*
-        * 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.
-        */
-       microtime(&vap->va_ctime);
-       vap->va_atime = vap->va_mtime = vap->va_ctime;
-
        /*
         * now do the object specific fields
         *
        /*
         * now do the object specific fields
         *
@@ -390,15 +402,30 @@ procfs_getattr(ap)
 
        switch (pfs->pfs_type) {
        case Proot:
 
        switch (pfs->pfs_type) {
        case Proot:
-               vap->va_nlink = 2;
+               /*
+                * 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_uid = 0;
                vap->va_gid = 0;
+               vap->va_size = vap->va_bytes =
+                   sprintf(buf, "%ld", (long)curproc->p_pid);
                break;
                break;
+       }
 
        case Pproc:
                vap->va_nlink = 2;
                vap->va_uid = procp->p_ucred->cr_uid;
                vap->va_gid = procp->p_ucred->cr_gid;
 
        case Pproc:
                vap->va_nlink = 2;
                vap->va_uid = procp->p_ucred->cr_uid;
                vap->va_gid = procp->p_ucred->cr_gid;
+               vap->va_size = vap->va_bytes = DEV_BSIZE;
                break;
 
        case Pfile:
                break;
 
        case Pfile:
@@ -406,24 +433,24 @@ procfs_getattr(ap)
                break;
 
        case Pmem:
                break;
 
        case Pmem:
-               vap->va_nlink = 1;
                vap->va_bytes = vap->va_size =
                        ctob(procp->p_vmspace->vm_tsize +
                                    procp->p_vmspace->vm_dsize +
                                    procp->p_vmspace->vm_ssize);
                vap->va_bytes = vap->va_size =
                        ctob(procp->p_vmspace->vm_tsize +
                                    procp->p_vmspace->vm_dsize +
                                    procp->p_vmspace->vm_ssize);
-               vap->va_uid = procp->p_ucred->cr_uid;
-               vap->va_gid = procp->p_ucred->cr_gid;
                break;
 
        case Pregs:
                break;
 
        case Pregs:
+               vap->va_bytes = vap->va_size = sizeof(struct reg);
+               break;
+
        case Pfpregs:
        case Pfpregs:
+               vap->va_bytes = vap->va_size = sizeof(struct fpreg);
+               break;
+
        case Pctl:
        case Pstatus:
        case Pnote:
        case Pnotepg:
        case Pctl:
        case Pstatus:
        case Pnote:
        case Pnotepg:
-               vap->va_nlink = 1;
-               vap->va_uid = procp->p_ucred->cr_uid;
-               vap->va_gid = procp->p_ucred->cr_gid;
                break;
 
        default:
                break;
 
        default:
@@ -482,8 +509,9 @@ procfs_access(ap)
         * If you're the super-user,
         * you always get access.
         */
         * 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);
                return (0);
+
        vap = &vattr;
        if (error = VOP_GETATTR(ap->a_vp, vap, ap->a_cred, ap->a_p))
                return (error);
        vap = &vattr;
        if (error = VOP_GETATTR(ap->a_vp, vap, ap->a_cred, ap->a_p))
                return (error);
@@ -497,7 +525,7 @@ procfs_access(ap)
                gid_t *gp;
                int i;
 
                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)
                gp = ap->a_cred->cr_groups;
                for (i = 0; i < ap->a_cred->cr_ngroups; i++, gp++)
                        if (vap->va_gid == *gp)
@@ -557,9 +585,9 @@ procfs_lookup(ap)
                        return (EIO);
 
                if (CNEQ(cnp, "curproc", 7))
                        return (EIO);
 
                if (CNEQ(cnp, "curproc", 7))
-                       pid = cnp->cn_proc->p_pid;
-               else
-                       pid = atopid(pname, cnp->cn_namelen);
+                       return (procfs_allocvp(dvp->v_mount, vpp, 0, Pcurproc));
+
+               pid = atopid(pname, cnp->cn_namelen);
                if (pid == NO_PID)
                        return (ENOENT);
 
                if (pid == NO_PID)
                        return (ENOENT);
 
@@ -567,15 +595,7 @@ procfs_lookup(ap)
                if (procp == 0)
                        return (ENOENT);
 
                if (procp == 0)
                        return (ENOENT);
 
-               error = procfs_allocvp(dvp->v_mount, &nvp, pid, Pproc);
-               if (error)
-                       return (error);
-
-               nvp->v_type = VDIR;
-               pfs = VTOPFS(nvp);
-
-               *vpp = nvp;
-               return (0);
+               return (procfs_allocvp(dvp->v_mount, vpp, pid, Pproc));
 
        case Pproc:
                if (cnp->cn_flags & ISDOTDOT) {
 
        case Pproc:
                if (cnp->cn_flags & ISDOTDOT) {
@@ -591,7 +611,8 @@ procfs_lookup(ap)
                        struct pfsnames *dp = &procent[i];
 
                        if (cnp->cn_namelen == dp->d_namlen &&
                        struct pfsnames *dp = &procent[i];
 
                        if (cnp->cn_namelen == dp->d_namlen &&
-                           bcmp(pname, dp->d_name, dp->d_namlen) == 0) {
+                           bcmp(pname, dp->d_name, dp->d_namlen) == 0 &&
+                           (dp->d_valid == NULL || (*dp->d_valid)(procp))) {
                                pfs_type = dp->d_pfstype;
                                goto found;
                        }
                                pfs_type = dp->d_pfstype;
                                goto found;
                        }
@@ -601,29 +622,30 @@ procfs_lookup(ap)
        found:
                if (pfs_type == Pfile) {
                        nvp = procfs_findtextvp(procp);
        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 (nvp == NULLVP)
+                               return (ENXIO);
+                       VREF(nvp);
+                       VOP_LOCK(nvp);
+                       *vpp = nvp;
+                       return (0);
                }
                }
-               *vpp = nvp;
-               return (error);
+
+               return (procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
+                   pfs_type));
 
        default:
                return (ENOTDIR);
        }
 }
 
 
        default:
                return (ENOTDIR);
        }
 }
 
+int
+procfs_validfile(p)
+       struct proc *p;
+{
+
+       return (procfs_findtextvp(p) != NULLVP);
+}
+
 /*
  * readdir returns directory entries from pfsnode (vp).
  *
 /*
  * readdir returns directory entries from pfsnode (vp).
  *
@@ -681,24 +703,27 @@ procfs_readdir(ap)
         * from the procent[] table (top of this file).
         */
        case Pproc: {
         * from the procent[] table (top of this file).
         */
        case Pproc: {
-               while (uio->uio_resid >= UIO_MX) {
-                       struct pfsnames *dt;
+               pid_t pid = pfs->pfs_pid;
+               struct pfsnames *dt;
+
+               for (dt = &procent[i]; i < Nprocent && uio->uio_resid >= UIO_MX;
+                    dt++, i++) {
+                       struct proc *p = PFIND(pid);
 
 
-                       if (i >= Nprocent)
+                       if (p == NULL)
                                break;
 
                                break;
 
-                       dt = &procent[i];
+                       if (dt->d_valid && (*dt->d_valid)(p) == 0)
+                               continue;
                        
                        dp->d_reclen = UIO_MX;
                        
                        dp->d_reclen = UIO_MX;
-                       dp->d_fileno = PROCFS_FILENO(pfs->pfs_pid, dt->d_pfstype);
-                       dp->d_type = DT_REG;
+                       dp->d_fileno = PROCFS_FILENO(pid, dt->d_pfstype);
                        dp->d_namlen = dt->d_namlen;
                        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)
+                       bcopy(dt->d_name, dp->d_name, dt->d_namlen + 1);
+                       dp->d_type = dt->d_type;
+
+                       if (error = uiomove((caddr_t)dp, UIO_MX, uio))
                                break;
                                break;
-                       count += UIO_MX;
-                       i++;
                }
 
                break;
                }
 
                break;
@@ -715,55 +740,61 @@ procfs_readdir(ap)
         */
 
        case Proot: {
         */
 
        case Proot: {
-               int pcnt;
 #ifdef PROCFS_ZOMBIE
                int doingzomb = 0;
 #endif
 #ifdef PROCFS_ZOMBIE
                int doingzomb = 0;
 #endif
-               volatile struct proc *p;
-
-               p = allproc;
-
-#define PROCFS_XFILES  1       /* number of other entries, like "curproc" */
-               pcnt = PROCFS_XFILES;
+               int pcnt = 0;
+               volatile struct proc *p = allproc;
 
 
-               while (p && uio->uio_resid >= UIO_MX) {
+       again:
+               for (; p && uio->uio_resid >= UIO_MX; i++, pcnt++) {
                        bzero((char *) dp, UIO_MX);
                        bzero((char *) dp, UIO_MX);
-                       dp->d_type = DT_DIR;
                        dp->d_reclen = UIO_MX;
 
                        switch (i) {
                        dp->d_reclen = UIO_MX;
 
                        switch (i) {
-                       case 0:
-                               /* ship out entry for "curproc" */
-                               dp->d_fileno = PROCFS_FILENO(PID_MAX+1, Pproc);
-                               dp->d_namlen = sprintf(dp->d_name, "curproc");
+                       case 0:         /* `.' */
+                       case 1:         /* `..' */
+                               dp->d_fileno = PROCFS_FILENO(0, Proot);
+                               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:
+                               dp->d_fileno = PROCFS_FILENO(0, Pcurproc);
+                               dp->d_namlen = 7;
+                               bcopy("curproc", dp->d_name, 8);
+                               dp->d_type = DT_LNK;
                                break;
 
                        default:
                                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_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_next;
                                p = p->p_next;
-
-#ifdef PROCFS_ZOMBIE
-                               if (p == 0 && doingzomb == 0) {
-                                       doingzomb = 1;
-                                       p = zombproc;
-                               }
-#endif
-
-                               if (pcnt++ < i)
-                                       continue;
-
                                break;
                        }
                                break;
                        }
-                       error = uiomove((caddr_t) dp, UIO_MX, uio);
-                       if (error)
+
+                       if (error = uiomove((caddr_t)dp, UIO_MX, uio))
                                break;
                                break;
-                       count += UIO_MX;
-                       i++;
                }
                }
+       done:
+
+#ifdef PROCFS_ZOMBIE
+               if (p == 0 && doingzomb == 0) {
+                       doingzomb = 1;
+                       p = zombproc;
+                       goto again;
+               }
+#endif
 
                break;
 
 
                break;
 
@@ -779,6 +810,24 @@ procfs_readdir(ap)
        return (error);
 }
 
        return (error);
 }
 
+/*
+ * readlink reads the link of `curproc'
+ */
+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
  */
 /*
  * convert decimal ascii to pid_t
  */