Skip site navigation (1)Skip section navigation (2)
Date:      30 Oct 2001 17:36:36 +0100
From:      Dag-Erling Smorgrav <des@ofug.org>
To:        arch@freebsd.org
Cc:        audit@freebsd.org
Subject:   procfs megapatch
Message-ID:  <xzpr8rlytij.fsf@flood.ping.uio.no>

next in thread | raw e-mail | index | archive | help
--=-=-=

The attached patch replaces procfs with a pseudofs-based version.  It
is fully equivalent except for the lack of debugging support, which is
intentional (I have working debugging support in my tree, and part of
it is in fact included in this patch, but disabled).  This means truss
will not work with this patch in place.  I am working on revamping
ptrace and have written a new version of truss which works with ptrace
instead of procfs.  I will am also thinking of writing a separate
module that grafts onto procfs and implements the legacy debugging
interface, to cater for strace et al.

DES
-- 
Dag-Erling Smorgrav - des@ofug.org


--=-=-=
Content-Type: text/x-patch; charset=iso-8859-1
Content-Disposition: attachment; filename=procfs-20011030.diff
Content-Transfer-Encoding: quoted-printable

Index: sys/conf/files
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/conf/files,v
retrieving revision 1.576
diff -u -r1.576 files
--- sys/conf/files	20 Oct 2001 18:50:31 -0000	1.576
+++ sys/conf/files	22 Oct 2001 13:01:43 -0000
@@ -640,6 +640,7 @@
 fs/nwfs/nwfs_vnops.c		optional nwfs
 fs/portalfs/portal_vfsops.c	optional portalfs
 fs/portalfs/portal_vnops.c	optional portalfs
+fs/procfs/procfs.c	optional procfs
 fs/procfs/procfs_ctl.c	optional procfs
 fs/procfs/procfs_dbregs.c	optional procfs
 fs/procfs/procfs_fpregs.c	optional procfs
@@ -649,10 +650,7 @@
 fs/procfs/procfs_regs.c	optional procfs
 fs/procfs/procfs_rlimit.c	optional procfs
 fs/procfs/procfs_status.c	optional procfs
-fs/procfs/procfs_subr.c	optional procfs
 fs/procfs/procfs_type.c	optional procfs
-fs/procfs/procfs_vfsops.c	optional procfs
-fs/procfs/procfs_vnops.c	optional procfs
 fs/pseudofs/pseudofs.c		optional pseudofs
 fs/pseudofs/pseudofs_fileno.c	optional pseudofs
 fs/pseudofs/pseudofs_vncache.c	optional pseudofs
Index: sys/fs/procfs/procfs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: sys/fs/procfs/procfs.c
diff -N sys/fs/procfs/procfs.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/fs/procfs/procfs.c	30 Oct 2001 16:34:19 -0000
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2001 Dag-Erling Sm=F8rgrav
+ * Copyright (c) 1993 Jan-Simon Pendry
+ * Copyright (c) 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP=
OSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT=
IAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STR=
ICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W=
AY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)procfs_vfsops.c	8.7 (Berkeley) 5/10/95
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/exec.h>
+#include <sys/lock.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/mutex.h>
+#include <sys/pioctl.h>
+#include <sys/proc.h>
+#include <sys/sbuf.h>
+#include <sys/sysproto.h>
+#include <sys/systm.h>
+#include <sys/vnode.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_param.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+/*
+ * Filler function for proc/pid/self
+ */
+static int
+procfs_doprocfile(PFS_FILL_ARGS)
+{
+	char *fullpath =3D "unknown";
+	char *freepath =3D NULL;
+
+	vn_fullpath(td, td->td_proc->p_textvp, &fullpath, &freepath);
+	sbuf_printf(sb, "%s", fullpath);
+	if (freepath)
+		free(freepath, M_TEMP);
+	return (0);
+}
+
+/*
+ * Filler function for proc/curproc
+ */
+static int
+procfs_docurproc(PFS_FILL_ARGS)
+{
+	sbuf_printf(sb, "%ld", (long)td->td_proc->p_pid);
+	return (0);
+}
+
+/*
+ * Adjust mode for some nodes that need it
+ */
+int
+procfs_attr(PFS_ATTR_ARGS)
+{
+	/* XXX inefficient, split into separate functions */
+	if (strcmp(pn->pn_name, "ctl") =3D=3D 0 ||
+	    strcmp(pn->pn_name, "note") =3D=3D 0 ||
+	    strcmp(pn->pn_name, "notepg") =3D=3D 0)
+		vap->va_mode =3D 0200;
+	else if (strcmp(pn->pn_name, "mem") =3D=3D 0 ||
+	    strcmp(pn->pn_name, "regs") =3D=3D 0 ||
+	    strcmp(pn->pn_name, "dbregs") =3D=3D 0 ||
+	    strcmp(pn->pn_name, "fpregs") =3D=3D 0)
+		vap->va_mode =3D 0600;
+
+	/* p is locked by caller */
+	vap->va_uid =3D p->p_ucred->cr_uid;
+	vap->va_gid =3D p->p_ucred->cr_gid;
+=09
+	return (0);
+}
+
+/*
+ * Visibility: some files only exist for non-system processes
+ * Non-static because linprocfs uses it.
+ */
+int
+procfs_notsystem(PFS_VIS_ARGS)
+{
+	return ((p->p_flag & P_SYSTEM) =3D=3D 0);
+}
+
+/*
+ * Visibility: some files are only visible to process that can debug
+ * the target process.
+ */
+int
+procfs_candebug(PFS_VIS_ARGS)
+{
+	return ((p->p_flag & P_SYSTEM) =3D=3D 0 &&
+	    p_candebug(td->td_proc, p) =3D=3D 0);
+}
+
+/*
+ * Constructor
+ */
+static int
+procfs_init(PFS_INIT_ARGS)
+{
+	struct pfs_node *root;
+	struct pfs_node *dir;
+	struct pfs_node *node;
+
+	root =3D pi->pi_root;
+
+	pfs_create_link(root, "curproc", &procfs_docurproc,
+	    NULL, NULL, 0);
+=09
+	dir =3D pfs_create_dir(root, "pid",
+	    &procfs_attr, NULL, PFS_PROCDEP);
+	pfs_create_file(dir, "cmdline", &procfs_doproccmdline,
+	    NULL, NULL, PFS_RD);
+#if 0
+	pfs_create_file(dir, "ctl", &procfs_doprocctl,
+	    &procfs_attr, NULL, PFS_WR);
+#endif
+	pfs_create_file(dir, "dbregs", &procfs_doprocdbregs,
+	    &procfs_attr, &procfs_candebug, PFS_RDWR|PFS_RAW);
+	pfs_create_file(dir, "etype", &procfs_doproctype,
+	    NULL, NULL, PFS_RD);
+	pfs_create_file(dir, "fpregs", &procfs_doprocfpregs,
+	    &procfs_attr, &procfs_candebug, PFS_RDWR|PFS_RAW);
+	pfs_create_file(dir, "map", &procfs_doprocmap,
+	    NULL, &procfs_notsystem, PFS_RD);
+	pfs_create_file(dir, "mem", &procfs_doprocmem,
+	    &procfs_attr, &procfs_candebug, PFS_RDWR|PFS_RAW);
+	pfs_create_file(dir, "note", &procfs_doprocnote,
+	    &procfs_attr, &procfs_candebug, PFS_WR);
+	pfs_create_file(dir, "notepg", &procfs_doprocnote,
+	    &procfs_attr, &procfs_candebug, PFS_WR);
+	pfs_create_file(dir, "regs", &procfs_doprocregs,
+	    &procfs_attr, &procfs_candebug, PFS_RDWR|PFS_RAW);
+	pfs_create_file(dir, "rlimit", &procfs_doprocrlimit,
+	    NULL, NULL, PFS_RD);
+	pfs_create_file(dir, "status", &procfs_doprocstatus,
+	    NULL, NULL, PFS_RD);
+=09
+	pfs_create_link(dir, "file", &procfs_doprocfile,
+	    NULL, procfs_notsystem, 0);
+=09
+	return (0);
+}
+
+/*
+ * Destructor
+ */
+static int
+procfs_uninit(PFS_INIT_ARGS)
+{
+
+	/* nothing to do, pseudofs will GC */
+	return (0);
+}
+
+PSEUDOFS(procfs, 1);
Index: sys/fs/procfs/procfs.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs.h,v
retrieving revision 1.39
diff -u -r1.39 procfs.h
--- sys/fs/procfs/procfs.h	7 Oct 2001 20:08:37 -0000	1.39
+++ sys/fs/procfs/procfs.h	12 Oct 2001 13:11:03 -0000
@@ -40,109 +40,28 @@
  * $FreeBSD: src/sys/fs/procfs/procfs.h,v 1.39 2001/10/07 20:08:37 des Exp=
 $
  */
=20
-/*
- * The different types of node in a procfs filesystem
- */
-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 */
-	Pregs,		/* the process's register set */
-	Pfpregs,	/* the process's FP register set */
-	Pdbregs,	/* the process's debug register set */
-	Pctl,		/* process control */
-	Pstatus,	/* process status */
-	Pnote,		/* process notifier */
-	Pnotepg,	/* process group notifier */
-	Pmap,		/* memory map */
-	Ptype,		/* executable type */
-	Pcmdline,	/* command line */
-	Prlimit		/* resource limits */
-} pfstype;
-
-/*
- * control data for the proc file system.
- */
-struct pfsnode {
-	struct pfsnode	*pfs_next;	/* next on list */
-	struct vnode	*pfs_vnode;	/* vnode associated with this pfsnode */
-	pfstype		pfs_type;	/* type of procfs node */
-	pid_t		pfs_pid;	/* associated process */
-	u_short		pfs_mode;	/* mode bits for stat() */
-	u_long		pfs_flags;	/* open flags */
-	u_long		pfs_fileno;	/* unique file id */
-	pid_t		pfs_lockowner;	/* pfs lock owner */
-};
-
-#define PROCFS_NOTELEN	64	/* max length of a note (/proc/$pid/note) */
-#define PROCFS_CTLLEN 	8	/* max length of a ctl msg (/proc/$pid/ctl */
-#define PROCFS_NAMELEN 	8	/* max length of a filename component */
-
-/*
- * Kernel stuff follows
- */
 #ifdef _KERNEL
-#define CNEQ(cnp, s, len) \
-	 ((cnp)->cn_namelen =3D=3D (len) && \
-	  (bcmp((s), (cnp)->cn_nameptr, (len)) =3D=3D 0))
-
-#define PROCFS_FILENO(pid, type) \
-	(((type) < Pproc) ? \
-			((type) + 2) : \
-			((((pid)+1) << 4) + ((int) (type))))
-
-/*
- * Convert between pfsnode vnode
- */
-#define VTOPFS(vp)	((struct pfsnode *)(vp)->v_data)
-#define PFSTOV(pfs)	((pfs)->pfs_vnode)
-
-typedef struct vfs_namemap vfs_namemap_t;
-struct vfs_namemap {
-	const char *nm_name;
-	int nm_val;
-};
-
-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;
-struct dbreg;
-
-#define PFIND(pid) (pfind(pid))
-
-void procfs_exit __P((struct proc *));
-int procfs_freevp __P((struct vnode *));
-int procfs_allocvp __P((struct mount *, struct vnode **, long, pfstype));
-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 *pfs=
p, struct uio *uio));
-int procfs_dodbregs __P((struct proc *, struct proc *, struct pfsnode *pfs=
p, 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 *pfs=
p, 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));
-int procfs_docmdline __P((struct proc *, struct proc *, struct pfsnode *pf=
sp, struct uio *uio));
-int procfs_dorlimit __P((struct proc *, struct proc *, struct pfsnode *pfs=
p, struct uio *uio));
-
-/* functions to check whether or not files should be displayed */
-int procfs_validfile __P((struct thread *));
-int procfs_validfpregs __P((struct thread *));
-int procfs_validregs __P((struct thread *));
-int procfs_validdbregs __P((struct thread *));
-int procfs_validmap __P((struct thread *));
-int procfs_validtype __P((struct thread *));
-
-#define PROCFS_LOCKED	0x01
-#define PROCFS_WANT	0x02
=20
-extern vop_t **procfs_vnodeop_p;
+int	 procfs_doproccmdline(PFS_FILL_ARGS);
+int	 procfs_doprocctl(PFS_FILL_ARGS);
+int	 procfs_doprocdbregs(PFS_FILL_ARGS);
+int	 procfs_doprocfpregs(PFS_FILL_ARGS);
+int	 procfs_doprocmap(PFS_FILL_ARGS);
+int	 procfs_doprocmem(PFS_FILL_ARGS);
+int	 procfs_doprocnote(PFS_FILL_ARGS);
+int	 procfs_doprocregs(PFS_FILL_ARGS);
+int	 procfs_doprocrlimit(PFS_FILL_ARGS);
+int	 procfs_doprocstatus(PFS_FILL_ARGS);
+int	 procfs_doproctype(PFS_FILL_ARGS);
+
+/* Return 1 if process has special kernel digging privileges */
+int	 procfs_kmemaccess(struct proc *);
+
+/* Attributes */
+int	 procfs_attr(PFS_ATTR_ARGS);
+
+/* Visbility */
+int	 procfs_notsystem(PFS_VIS_ARGS);
+int	 procfs_candebug(PFS_VIS_ARGS);
=20
-int	procfs_root __P((struct mount *, struct vnode **));
-int	procfs_rw __P((struct vop_read_args *));
 #endif /* _KERNEL */
Index: sys/fs/procfs/procfs_ctl.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_ctl.c,v
retrieving revision 1.33
diff -u -r1.33 procfs_ctl.c
--- sys/fs/procfs/procfs_ctl.c	21 Oct 2001 23:57:11 -0000	1.33
+++ sys/fs/procfs/procfs_ctl.c	22 Oct 2001 00:03:41 -0000
@@ -41,13 +41,16 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/lock.h>
+#include <sys/mount.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/ptrace.h>
+#include <sys/sbuf.h>
 #include <sys/signalvar.h>
 #include <sys/sx.h>
 #include <sys/vnode.h>
=20
+#include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
=20
 #include <vm/vm.h>
@@ -67,7 +70,12 @@
 #define PROCFS_CTL_RUN		4
 #define PROCFS_CTL_WAIT		5
=20
-static vfs_namemap_t ctlnames[] =3D {
+struct namemap {
+	const char *nm_name;
+	int nm_val;
+};
+
+static struct namemap ctlnames[] =3D {
 	/* special /proc commands */
 	{ "attach",	PROCFS_CTL_ATTACH },
 	{ "detach",	PROCFS_CTL_DETACH },
@@ -77,7 +85,7 @@
 	{ 0 },
 };
=20
-static vfs_namemap_t signames[] =3D {
+static struct namemap signames[] =3D {
 	/* regular signal names */
 	{ "hup",	SIGHUP },	{ "int",	SIGINT },
 	{ "quit",	SIGQUIT },	{ "ill",	SIGILL },
@@ -101,10 +109,7 @@
 static int	procfs_control __P((struct proc *curp, struct proc *p, int op));
=20
 static int
-procfs_control(curp, p, op)
-	struct proc *curp;
-	struct proc *p;
-	int op;
+procfs_control(struct proc *curp, struct proc *p, int op)
 {
 	int error =3D 0;
=20
@@ -240,7 +245,6 @@
 	 * Step.  Let the target process execute a single instruction.
 	 */
 	case PROCFS_CTL_STEP:
-		_PHOLD(p);
 		PROC_UNLOCK(p);
 		error =3D proc_sstep(&p->p_thread); /* XXXKSE */
 		PRELE(p);
@@ -301,26 +305,26 @@
 	return (0);
 }
=20
+static struct namemap *
+findname(struct namemap *nm, char *buf, int buflen)
+{
+
+	for (; nm->nm_name; nm++)
+		if (bcmp(buf, nm->nm_name, buflen+1) =3D=3D 0)
+			return (nm);
+
+	return (0);
+}
+
 int
-procfs_doctl(curp, p, pfs, uio)
-	struct proc *curp;
-	struct pfsnode *pfs;
-	struct uio *uio;
-	struct proc *p;
+procfs_doprocctl(PFS_FILL_ARGS)
 {
-	int xlen;
 	int error;
-	char msg[PROCFS_CTLLEN+1];
-	vfs_namemap_t *nm;
+	struct namemap *nm;
=20
-	if (uio->uio_rw !=3D UIO_WRITE)
+	if (uio =3D=3D NULL || uio->uio_rw !=3D UIO_WRITE)
 		return (EOPNOTSUPP);
=20
-	xlen =3D PROCFS_CTLLEN;
-	error =3D vfs_getuserstr(uio, msg, &xlen);
-	if (error)
-		return (error);
-
 	/*
 	 * Map signal names into signal generation
 	 * or debug control.  Unknown commands and/or signals
@@ -332,15 +336,19 @@
 	 */
 	error =3D EOPNOTSUPP;
=20
-	nm =3D vfs_findname(ctlnames, msg, xlen);
+	sbuf_trim(sb);
+	sbuf_finish(sb);
+	nm =3D findname(ctlnames, sbuf_data(sb), sbuf_len(sb));
 	if (nm) {
-		error =3D procfs_control(curp, p, nm->nm_val);
+		printf("procfs: got a %s command\n", sbuf_data(sb));
+		error =3D procfs_control(td->td_proc, p, nm->nm_val);
 	} else {
-		nm =3D vfs_findname(signames, msg, xlen);
+		nm =3D findname(signames, sbuf_data(sb), sbuf_len(sb));
 		if (nm) {
+			printf("procfs: got a sig%s\n", sbuf_data(sb));
 			PROC_LOCK(p);
 			mtx_lock_spin(&sched_lock);
-			if (TRACE_WAIT_P(curp, p)) {
+			if (TRACE_WAIT_P(td->td_proc, p)) {
 				p->p_xstat =3D nm->nm_val;
 #ifdef FIX_SSTEP
 				FIX_SSTEP(&p->p_thread);   /* XXXKSE */
Index: sys/fs/procfs/procfs_dbregs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_dbregs.c,v
retrieving revision 1.14
diff -u -r1.14 procfs_dbregs.c
--- sys/fs/procfs/procfs_dbregs.c	21 Oct 2001 23:57:11 -0000	1.14
+++ sys/fs/procfs/procfs_dbregs.c	22 Oct 2001 00:03:41 -0000
@@ -46,30 +46,29 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/lock.h>
+#include <sys/mount.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/ptrace.h>
+#include <sys/sbuf.h>
 #include <sys/vnode.h>
=20
 #include <machine/reg.h>
=20
+#include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
=20
 #include <vm/vm.h>
=20
 int
-procfs_dodbregs(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
+procfs_doprocdbregs(PFS_FILL_ARGS)
 {
 	int error;
 	struct dbreg r;
 	char *kv;
 	int kl;
=20
-	if (p_candebug(curp, p))
+	if (p_candebug(td->td_proc, p) !=3D 0)
 		return (EPERM);
 	kl =3D sizeof(r);
 	kv =3D (char *) &r;
@@ -79,8 +78,6 @@
 	if (kl > uio->uio_resid)
 		kl =3D uio->uio_resid;
=20
-	PHOLD(p);
-
 	if (kl < 0)
 		error =3D EINVAL;
 	else
@@ -93,15 +90,7 @@
 		else
 			error =3D proc_write_dbregs(&p->p_thread, &r); /* XXXKSE */
 	}
-	PRELE(p);
=20
 	uio->uio_offset =3D 0;
 	return (error);
-}
-
-int
-procfs_validdbregs(struct thread *td)
-{
-
-	return ((td->td_proc->p_flag & P_SYSTEM) =3D=3D 0);
 }
Index: sys/fs/procfs/procfs_fpregs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_fpregs.c,v
retrieving revision 1.21
diff -u -r1.21 procfs_fpregs.c
--- sys/fs/procfs/procfs_fpregs.c	21 Oct 2001 23:57:11 -0000	1.21
+++ sys/fs/procfs/procfs_fpregs.c	22 Oct 2001 00:03:41 -0000
@@ -43,30 +43,29 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/lock.h>
+#include <sys/mount.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/ptrace.h>
+#include <sys/sbuf.h>
 #include <sys/vnode.h>
=20
 #include <machine/reg.h>
=20
+#include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
=20
 #include <vm/vm.h>
=20
 int
-procfs_dofpregs(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
+procfs_doprocfpregs(PFS_FILL_ARGS)
 {
 	int error;
 	struct fpreg r;
 	char *kv;
 	int kl;
=20
-	if (p_candebug(curp, p))
+	if (p_candebug(td->td_proc, p))
 		return EPERM;
 	kl =3D sizeof(r);
 	kv =3D (char *) &r;
@@ -94,11 +93,4 @@
=20
 	uio->uio_offset =3D 0;
 	return (error);
-}
-
-int
-procfs_validfpregs(struct thread *td)
-{
-
-	return (( td->td_proc->p_flag & P_SYSTEM) =3D=3D 0);
 }
Index: sys/fs/procfs/procfs_map.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_map.c,v
retrieving revision 1.30
diff -u -r1.30 procfs_map.c
--- sys/fs/procfs/procfs_map.c	12 Sep 2001 08:37:20 -0000	1.30
+++ sys/fs/procfs/procfs_map.c	5 Oct 2001 11:08:38 -0000
@@ -42,10 +42,13 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/lock.h>
+#include <sys/mount.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
+#include <sys/sbuf.h>
 #include <sys/vnode.h>
=20
+#include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
=20
 #include <vm/vm.h>
@@ -68,11 +71,7 @@
  * can try a bigger buffer.
  */
 int
-procfs_domap(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
+procfs_doprocmap(PFS_FILL_ARGS)
 {
 	int len;
 	int error;
@@ -90,7 +89,7 @@
 		return (0);
=20=09
 	error =3D 0;
-	if (map !=3D &curproc->p_vmspace->vm_map)
+	if (map !=3D &curthread->td_proc->p_vmspace->vm_map)
 		vm_map_lock_read(map);
 	for (entry =3D map->header.next;
 		((uio->uio_resid > 0) && (entry !=3D &map->header));
@@ -118,23 +117,22 @@
 			addr +=3D PAGE_SIZE;
 		}
=20
-		for( lobj =3D tobj =3D obj; tobj; tobj =3D tobj->backing_object)
+		for (lobj =3D tobj =3D obj; tobj; tobj =3D tobj->backing_object)
 			lobj =3D tobj;
=20
 		if (lobj) {
 			switch(lobj->type) {
-
-default:
-case OBJT_DEFAULT:
+			default:
+			case OBJT_DEFAULT:
 				type =3D "default";
 				break;
-case OBJT_VNODE:
+			case OBJT_VNODE:
 				type =3D "vnode";
 				break;
-case OBJT_SWAP:
+			case OBJT_SWAP:
 				type =3D "swap";
 				break;
-case OBJT_DEVICE:
+			case OBJT_DEVICE:
 				type =3D "device";
 				break;
 			}
@@ -148,13 +146,12 @@
 			ref_count =3D 0;
 			shadow_count =3D 0;
 		}
-=09=09=09
=20
 		/*
 		 * format:
 		 *  start, end, resident, private resident, cow, access, type.
 		 */
-		snprintf(mebuffer, sizeof(mebuffer),
+		snprintf(mebuffer, sizeof mebuffer,
 		    "0x%lx 0x%lx %d %d %p %s%s%s %d %d 0x%x %s %s %s\n",
 			(u_long)entry->start, (u_long)entry->end,
 			resident, privateresident, obj,
@@ -175,14 +172,8 @@
 		if (error)
 			break;
 	}
-	if (map !=3D &curproc->p_vmspace->vm_map)
+	if (map !=3D &curthread->td_proc->p_vmspace->vm_map)
 		vm_map_unlock_read(map);
=20=09
-	return error;
-}
-
-int
-procfs_validmap(struct thread *td)
-{
-	return ((td->td_proc->p_flag & P_SYSTEM) =3D=3D 0);
+	return (error);
 }
Index: sys/fs/procfs/procfs_mem.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_mem.c,v
retrieving revision 1.54
diff -u -r1.54 procfs_mem.c
--- sys/fs/procfs/procfs_mem.c	7 Oct 2001 20:08:37 -0000	1.54
+++ sys/fs/procfs/procfs_mem.c	8 Oct 2001 00:00:00 -0000
@@ -43,12 +43,15 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/lock.h>
+#include <sys/mount.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/ptrace.h>
+#include <sys/sbuf.h>
 #include <sys/user.h>
 #include <sys/vnode.h>
=20
+#include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
=20
 /*
@@ -58,20 +61,17 @@
  * from the kernel address space.
  */
 int
-procfs_domem(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
+procfs_doprocmem(PFS_FILL_ARGS)
 {
 	int error;
=20
 	if (uio->uio_resid =3D=3D 0)
 		return (0);
=20
-	error =3D p_candebug(curp, p);
+	error =3D p_candebug(td->td_proc, p);
 	if (error)
 		return (error);
+	error =3D proc_rwmem(p, uio);
=20
-	return (proc_rwmem(p, uio));
+	return (error);
 }
Index: sys/fs/procfs/procfs_note.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_note.c,v
retrieving revision 1.7
diff -u -r1.7 procfs_note.c
--- sys/fs/procfs/procfs_note.c	23 May 2001 09:42:11 -0000	1.7
+++ sys/fs/procfs/procfs_note.c	4 Oct 2001 11:21:39 -0000
@@ -40,28 +40,18 @@
  */
=20
 #include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/sbuf.h>
 #include <sys/vnode.h>
+
+#include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
=20
 int
-procfs_donote(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
+procfs_doprocnote(PFS_FILL_ARGS)
 {
-	int xlen;
-	int error;
-	char note[PROCFS_NOTELEN+1];
-
-	if (uio->uio_rw !=3D UIO_WRITE)
-		return (EINVAL);
-
-	xlen =3D PROCFS_NOTELEN;
-	error =3D vfs_getuserstr(uio, note, &xlen);
-	if (error)
-		return (error);
-
+	sbuf_trim(sb);
+	sbuf_finish(sb);
 	/* send to process's notify function */
 	return (EOPNOTSUPP);
 }
Index: sys/fs/procfs/procfs_regs.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_regs.c,v
retrieving revision 1.20
diff -u -r1.20 procfs_regs.c
--- sys/fs/procfs/procfs_regs.c	21 Oct 2001 23:57:11 -0000	1.20
+++ sys/fs/procfs/procfs_regs.c	22 Oct 2001 00:03:41 -0000
@@ -43,9 +43,11 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/lock.h>
+#include <sys/mount.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/ptrace.h>
+#include <sys/sbuf.h>
 #include <sys/vnode.h>
=20
 #include <machine/reg.h>
@@ -53,21 +55,18 @@
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
=20
+#include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
=20
 int
-procfs_doregs(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
+procfs_doprocregs(PFS_FILL_ARGS)
 {
 	int error;
 	struct reg r;
 	char *kv;
 	int kl;
=20
-	if (p_candebug(curp, p))
+	if (p_candebug(td->td_proc, p))
 		return EPERM;
 	kl =3D sizeof(r);
 	kv =3D (char *) &r;
@@ -95,11 +94,4 @@
=20
 	uio->uio_offset =3D 0;
 	return (error);
-}
-
-int
-procfs_validregs(struct thread *td)
-{
-
-	return ((td->td_proc->p_flag & P_SYSTEM) =3D=3D 0);
 }
Index: sys/fs/procfs/procfs_rlimit.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_rlimit.c,v
retrieving revision 1.6
diff -u -r1.6 procfs_rlimit.c
--- sys/fs/procfs/procfs_rlimit.c	23 May 2001 09:42:11 -0000	1.6
+++ sys/fs/procfs/procfs_rlimit.c	28 Sep 2001 12:37:19 -0000
@@ -47,32 +47,22 @@
=20
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/mount.h>
 #include <sys/proc.h>
 #include <sys/vnode.h>
 #include <sys/resourcevar.h>
 #include <sys/resource.h>
+#include <sys/sbuf.h>
 #include <sys/types.h>
+
+#include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
=20
=20
 int
-procfs_dorlimit(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
+procfs_doprocrlimit(PFS_FILL_ARGS)
 {
-	char *ps;
 	int i;
-	int xlen;
-	int error;
-	char psbuf[512];		/* XXX - conservative */
-
-	if (uio->uio_rw !=3D UIO_READ)
-		return (EOPNOTSUPP);
-
-
-	ps =3D psbuf;
=20
 	for (i =3D 0; i < RLIM_NLIMITS; i++) {
=20
@@ -80,7 +70,7 @@
 		 * Add the rlimit ident
 		 */
=20
-		ps +=3D sprintf(ps, "%s ", rlimit_ident[i]);
+		sbuf_printf(sb, "%s ", rlimit_ident[i]);
=20
 		/*=20
 		 * Replace RLIM_INFINITY with -1 in the string
@@ -91,9 +81,9 @@
 		 */
=20
 		if (p->p_rlimit[i].rlim_cur =3D=3D RLIM_INFINITY) {
-			ps +=3D sprintf(ps, "-1 ");
+			sbuf_printf(sb, "-1 ");
 		} else {
-			ps +=3D sprintf(ps, "%llu ",
+			sbuf_printf(sb, "%llu ",
 				(unsigned long long)p->p_rlimit[i].rlim_cur);
 		}
=20
@@ -102,27 +92,13 @@
 		 */
=20
 		if (p->p_rlimit[i].rlim_max =3D=3D RLIM_INFINITY) {
-			ps +=3D sprintf(ps, "-1\n");
+			sbuf_printf(sb, "-1\n");
 		} else {
-			ps +=3D sprintf(ps, "%llu\n",
+			sbuf_printf(sb, "%llu\n",
 				(unsigned long long)p->p_rlimit[i].rlim_max);
 		}
 	}
=20
-	/*
-	 * This logic is rather tasty - but its from procfs_status.c, so
-	 * I guess I'll use it here.
-	 */
-
-	xlen =3D ps - psbuf;
-	xlen -=3D uio->uio_offset;
-	ps =3D psbuf + uio->uio_offset;
-	xlen =3D imin(xlen, uio->uio_resid);
-	if (xlen <=3D 0)
-		error =3D 0;
-	else
-		error =3D uiomove(ps, xlen, uio);
-
-	return (error);
+	return (0);
 }
=20
Index: sys/fs/procfs/procfs_status.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_status.c,v
retrieving revision 1.35
diff -u -r1.35 procfs_status.c
--- sys/fs/procfs/procfs_status.c	28 Oct 2001 22:53:45 -0000	1.35
+++ sys/fs/procfs/procfs_status.c	29 Oct 2001 19:02:08 -0000
@@ -46,9 +46,11 @@
 #include <sys/jail.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
+#include <sys/mount.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/resourcevar.h>
+#include <sys/sbuf.h>
 #include <sys/tty.h>
 #include <sys/vnode.h>
=20
@@ -56,29 +58,19 @@
 #include <vm/pmap.h>
 #include <vm/vm_param.h>
=20
+#include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
=20
-#define DOCHECK() do { if (ps >=3D psbuf+sizeof(psbuf)) goto bailout; } wh=
ile (0)
 int
-procfs_dostatus(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
+procfs_doprocstatus(PFS_FILL_ARGS)
 {
 	struct session *sess;
 	struct tty *tp;
 	struct ucred *cr;
-	char *ps, *pc;
+	char *pc;
 	char *sep;
 	int pid, ppid, pgid, sid;
 	int i;
-	int xlen;
-	int error;
-	char psbuf[256];	/* XXX - conservative */
-
-	if (uio->uio_rw !=3D UIO_READ)
-		return (EOPNOTSUPP);
=20
 	pid =3D p->p_pid;
 	PROC_LOCK(p);
@@ -91,45 +83,31 @@
 /* comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg=20
                                 euid ruid rgid,egid,groups[1 .. NGROUPS]
 */
-	KASSERT(sizeof(psbuf) > MAXCOMLEN,
-			("Too short buffer for new MAXCOMLEN"));
=20
-	ps =3D psbuf;
 	pc =3D p->p_comm;
-	xlen =3D strlen(p->p_comm);
 	do {
 		if (*pc < 33 || *pc > 126 || *pc =3D=3D '\\')
-			ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps, "\\%03o",
-			    *pc);
+			sbuf_printf(sb, "\\%03o", *pc);
 		else
-			*ps++ =3D *pc;
-		DOCHECK();
-	} while (++pc < p->p_comm + xlen);
-	ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps,
-	    " %d %d %d %d ", pid, ppid, pgid, sid);
-	DOCHECK();
+			sbuf_putc(sb, *pc);
+	} while (*++pc);
+	sbuf_printf(sb, " %d %d %d %d ", pid, ppid, pgid, sid);
 	if ((p->p_flag&P_CONTROLT) && (tp =3D sess->s_ttyp))
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps,
-		    "%d,%d ", major(tp->t_dev), minor(tp->t_dev));
+		sbuf_printf(sb, "%d,%d ", major(tp->t_dev), minor(tp->t_dev));
 	else
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps,
-		    "%d,%d ", -1, -1);
-	DOCHECK();
+		sbuf_printf(sb, "%d,%d ", -1, -1);
=20
 	sep =3D "";
 	if (sess->s_ttyvp) {
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps, "%sctty", sep);
+		sbuf_printf(sb, "%sctty", sep);
 		sep =3D ",";
-		DOCHECK();
 	}
 	if (SESS_LEADER(p)) {
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps, "%ssldr", sep);
+		sbuf_printf(sb, "%ssldr", sep);
 		sep =3D ",";
-		DOCHECK();
 	}
 	if (*sep !=3D ',') {
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps, "noflags");
-		DOCHECK();
+		sbuf_printf(sb, "noflags");
 	}
=20
 	mtx_lock_spin(&sched_lock);
@@ -138,89 +116,53 @@
=20
 		calcru(p, &ut, &st, (struct timeval *) NULL);
 		mtx_unlock_spin(&sched_lock);
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps,
-		    " %lld,%ld %lld,%ld %lld,%ld",
-		    (quad_t)p->p_stats->p_start.tv_sec,
+		sbuf_printf(sb, " %ld,%ld %ld,%ld %ld,%ld",
+		    p->p_stats->p_start.tv_sec,
 		    p->p_stats->p_start.tv_usec,
-		    (quad_t)ut.tv_sec, ut.tv_usec,
-		    (quad_t)st.tv_sec, st.tv_usec);
+		    ut.tv_sec, ut.tv_usec,
+		    st.tv_sec, st.tv_usec);
 	} else {
 		mtx_unlock_spin(&sched_lock);
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps,
-		    " -1,-1 -1,-1 -1,-1");
+		sbuf_printf(sb, " -1,-1 -1,-1 -1,-1");
 	}
-	DOCHECK();
=20
 	if (p->p_flag & P_KSES) {
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps, " %s",
-			"-kse- ");
+		sbuf_printf(sb, " %s", "-kse- ");
 	} else {
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps, " %s",
+		sbuf_printf(sb, " %s",
 			(p->p_thread.td_wchan && p->p_thread.td_wmesg) ?
 			    p->p_thread.td_wmesg : "nochan");
 	}
-	DOCHECK();
=20
 	cr =3D p->p_ucred;
=20
-	ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps, " %lu %lu %lu",=20
+	sbuf_printf(sb, " %lu %lu %lu",
 		(u_long)cr->cr_uid,
 		(u_long)cr->cr_ruid,
 		(u_long)cr->cr_rgid);
-	DOCHECK();
=20
 	/* egid (cr->cr_svgid) is equal to cr_ngroups[0]=20
 	   see also getegid(2) in /sys/kern/kern_prot.c */
=20
 	for (i =3D 0; i < cr->cr_ngroups; i++) {
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps,
-		    ",%lu", (u_long)cr->cr_groups[i]);
-		DOCHECK();
+		sbuf_printf(sb, ",%lu", (u_long)cr->cr_groups[i]);
 	}
=20
 	if (jailed(p->p_ucred))
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps,
-		    " %s", p->p_ucred->cr_prison->pr_host);
-	else
-		ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps, " -");
-	DOCHECK();
-	ps +=3D snprintf(ps, psbuf + sizeof(psbuf) - ps, "\n");
-	DOCHECK();
-
-	xlen =3D ps - psbuf;
-	xlen -=3D uio->uio_offset;
-	ps =3D psbuf + uio->uio_offset;
-	xlen =3D imin(xlen, uio->uio_resid);
-	if (xlen <=3D 0)
-		error =3D 0;
+		sbuf_printf(sb, " %s", p->p_ucred->cr_prison->pr_host);
 	else
-		error =3D uiomove(ps, xlen, uio);
-
-	return (error);
+		sbuf_printf(sb, " -");
+	sbuf_printf(sb, "\n");
=20
-bailout:
-	return (ENOMEM);
+	return (0);
 }
=20
 int
-procfs_docmdline(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
+procfs_doproccmdline(PFS_FILL_ARGS)
 {
-	char *ps;
-	int xlen;
-	int error;
-	char *buf, *bp;
-	int buflen;
 	struct ps_strings pstr;
-	int i;
-	size_t bytes_left, done;
+	int error, i;
=20
-	if (uio->uio_rw !=3D UIO_READ)
-		return (EOPNOTSUPP);
-=09
 	/*
 	 * If we are using the ps/cmdline caching, use that.  Otherwise
 	 * revert back to the old way which only implements full cmdline
@@ -231,47 +173,19 @@
 	 * Linux behaviour is to return zero-length in this case.
 	 */
=20
-	if (p->p_args && (ps_argsopen || !p_cansee(curp, p))) {
-		bp =3D p->p_args->ar_args;
-		buflen =3D p->p_args->ar_length;
-		buf =3D 0;
-	} else if (p !=3D curp) {
-		bp =3D p->p_comm;
-		buflen =3D MAXCOMLEN;
-		buf =3D 0;
+	if (p->p_args && (ps_argsopen || !p_cansee(td->td_proc, p))) {
+		sbuf_bcpy(sb, p->p_args->ar_args, p->p_args->ar_length);
+	} else if (p !=3D td->td_proc) {
+		sbuf_printf(sb, "%.*s", MAXCOMLEN, p->p_comm);
 	} else {
-		buflen =3D 256;
-		MALLOC(buf, char *, buflen + 1, M_TEMP, M_WAITOK);
-		bp =3D buf;
-		ps =3D buf;
 		error =3D copyin((void*)PS_STRINGS, &pstr, sizeof(pstr));
-		if (error) {
-			FREE(buf, M_TEMP);
+		if (error)
 			return (error);
+		for (i =3D 0; i < pstr.ps_nargvstr; i++) {
+			sbuf_copyin(sb, pstr.ps_argvstr[i], 0);
+			sbuf_printf(sb, "%c", '\0');
 		}
-		bytes_left =3D buflen;
-		for (i =3D 0; bytes_left && (i < pstr.ps_nargvstr); i++) {
-			error =3D copyinstr(pstr.ps_argvstr[i], ps,
-					  bytes_left, &done);
-			/* If too long or malformed, just truncate */
-			if (error) {
-				error =3D 0;
-				break;
-			}
-			ps +=3D done;
-			bytes_left -=3D done;
-		}
-		buflen =3D ps - buf;
 	}
=20
-	buflen -=3D uio->uio_offset;
-	ps =3D bp + uio->uio_offset;
-	xlen =3D min(buflen, uio->uio_resid);
-	if (xlen <=3D 0)
-		error =3D 0;
-	else
-		error =3D uiomove(ps, xlen, uio);
-	if (buf)
-		FREE(buf, M_TEMP);
-	return (error);
+	return (0);
 }
Index: sys/fs/procfs/procfs_subr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: sys/fs/procfs/procfs_subr.c
diff -N sys/fs/procfs/procfs_subr.c
--- sys/fs/procfs/procfs_subr.c	18 Sep 2001 19:53:10 -0000	1.37
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,413 +0,0 @@
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP=
OSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT=
IAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STR=
ICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W=
AY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)procfs_subr.c	8.6 (Berkeley) 5/14/95
- *
- * $FreeBSD: src/sys/fs/procfs/procfs_subr.c,v 1.37 2001/09/18 19:53:10 rw=
atson Exp $
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/vnode.h>
-
-#include <fs/procfs/procfs.h>
-
-static struct pfsnode *pfshead;
-static int pfsvplock;
-
-/*
- * allocate a pfsnode/vnode pair.  the vnode is
- * referenced, but not locked.
- *
- * the pid, pfs_type, and mount point uniquely
- * identify a pfsnode.  the mount point is needed
- * because someone might mount this filesystem
- * twice.
- *
- * all pfsnodes are maintained on a singly-linked
- * list.  new nodes are only allocated when they cannot
- * be found on this list.  entries on the list are
- * removed when the vfs reclaim entry is called.
- *
- * a single lock is kept for the entire list.  this is
- * needed because the getnewvnode() function can block
- * waiting for a vnode to become free, in which case there
- * may be more than one process trying to get the same
- * vnode.  this lock is only taken if we are going to
- * call getnewvnode, since the kernel itself is single-threaded.
- *
- * if an entry is found on the list, then call vget() to
- * take a reference.  this is done because there may be
- * zero references to it and so it needs to removed from
- * the vnode free list.
- */
-int
-procfs_allocvp(mp, vpp, pid, pfs_type)
-	struct mount *mp;
-	struct vnode **vpp;
-	long pid;
-	pfstype pfs_type;
-{
-	struct thread *td =3D curthread;	/* XXX */
-	struct pfsnode *pfs;
-	struct vnode *vp;
-	struct pfsnode **pp;
-	int error;
-
-loop:
-	for (pfs =3D pfshead; pfs !=3D 0; pfs =3D pfs->pfs_next) {
-		vp =3D PFSTOV(pfs);
-		if (pfs->pfs_pid =3D=3D pid &&
-		    pfs->pfs_type =3D=3D pfs_type &&
-		    vp->v_mount =3D=3D mp) {
-			if (vget(vp, 0, td))
-				goto loop;
-			*vpp =3D vp;
-			return (0);
-		}
-	}
-
-	/*
-	 * otherwise lock the vp list while we call getnewvnode
-	 * since that can block.
-	 */
-	if (pfsvplock & PROCFS_LOCKED) {
-		pfsvplock |=3D PROCFS_WANT;
-		(void) tsleep((caddr_t) &pfsvplock, PINOD, "pfsavp", 0);
-		goto loop;
-	}
-	pfsvplock |=3D PROCFS_LOCKED;
-
-	/*
-	 * Do the MALLOC before the getnewvnode since doing so afterward
-	 * might cause a bogus v_data pointer to get dereferenced
-	 * elsewhere if MALLOC should block.
-	 */
-	MALLOC(pfs, struct pfsnode *, sizeof(struct pfsnode), M_TEMP, M_WAITOK);
-
-	if ((error =3D getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp)) !=3D 0)=
 {
-		FREE(pfs, M_TEMP);
-		goto out;
-	}
-	vp =3D *vpp;
-
-	vp->v_data =3D pfs;
-
-	pfs->pfs_next =3D 0;
-	pfs->pfs_pid =3D (pid_t) pid;
-	pfs->pfs_type =3D pfs_type;
-	pfs->pfs_vnode =3D vp;
-	pfs->pfs_flags =3D 0;
-	pfs->pfs_lockowner =3D 0;
-	pfs->pfs_fileno =3D PROCFS_FILENO(pid, pfs_type);
-
-	switch (pfs_type) {
-	case Proot:	/* /proc =3D dr-xr-xr-x */
-		pfs->pfs_mode =3D (VREAD|VEXEC) |
-				(VREAD|VEXEC) >> 3 |
-				(VREAD|VEXEC) >> 6;
-		vp->v_type =3D VDIR;
-		vp->v_flag =3D VROOT;
-		break;
-
-	case Pcurproc:	/* /proc/curproc =3D lr--r--r-- */
-		pfs->pfs_mode =3D (VREAD) |
-				(VREAD >> 3) |
-				(VREAD >> 6);
-		vp->v_type =3D VLNK;
-		break;
-
-	case Pproc:
-		pfs->pfs_mode =3D (VREAD|VEXEC) |
-				(VREAD|VEXEC) >> 3 |
-				(VREAD|VEXEC) >> 6;
-		vp->v_type =3D VDIR;
-		break;
-
-	case Pfile:
-		pfs->pfs_mode =3D (VREAD|VEXEC) |
-				(VREAD|VEXEC) >> 3 |
-				(VREAD|VEXEC) >> 6;
-		vp->v_type =3D VLNK;
-		break;
-
-	case Pmem:
-		pfs->pfs_mode =3D (VREAD|VWRITE);
-		vp->v_type =3D VREG;
-		break;
-
-	case Pregs:
-	case Pfpregs:
-	case Pdbregs:
-		pfs->pfs_mode =3D (VREAD|VWRITE);
-		vp->v_type =3D VREG;
-		break;
-
-	case Pctl:
-	case Pnote:
-	case Pnotepg:
-		pfs->pfs_mode =3D (VWRITE);
-		vp->v_type =3D VREG;
-		break;
-
-	case Ptype:
-	case Pmap:
-	case Pstatus:
-	case Pcmdline:
-	case Prlimit:
-		pfs->pfs_mode =3D (VREAD) |
-				(VREAD >> 3) |
-				(VREAD >> 6);
-		vp->v_type =3D VREG;
-		break;
-
-	default:
-		panic("procfs_allocvp");
-	}
-
-	/* add to procfs vnode list */
-	for (pp =3D &pfshead; *pp; pp =3D &(*pp)->pfs_next)
-		continue;
-	*pp =3D pfs;
-
-out:
-	pfsvplock &=3D ~PROCFS_LOCKED;
-
-	if (pfsvplock & PROCFS_WANT) {
-		pfsvplock &=3D ~PROCFS_WANT;
-		wakeup((caddr_t) &pfsvplock);
-	}
-
-	return (error);
-}
-
-int
-procfs_freevp(vp)
-	struct vnode *vp;
-{
-	struct pfsnode **pfspp;
-	struct pfsnode *pfs =3D VTOPFS(vp);
-
-	for (pfspp =3D &pfshead; *pfspp !=3D 0; pfspp =3D &(*pfspp)->pfs_next) {
-		if (*pfspp =3D=3D pfs) {
-			*pfspp =3D pfs->pfs_next;
-			break;
-		}
-	}
-
-	FREE(vp->v_data, M_TEMP);
-	vp->v_data =3D 0;
-	return (0);
-}
-
-int
-procfs_rw(ap)
-	struct vop_read_args *ap;
-{
-	struct vnode *vp =3D ap->a_vp;
-	struct uio *uio =3D ap->a_uio;
-	struct proc *curp =3D uio->uio_td->td_proc;
-	struct pfsnode *pfs =3D VTOPFS(vp);
-	struct proc *p;
-	int rtval;
-
-	p =3D PFIND(pfs->pfs_pid);
-	if (p =3D=3D NULL)
-		return (EINVAL);
-	PROC_UNLOCK(p);
-
-	mp_fixme("pfs_lockowner needs a lock");
-	while (pfs->pfs_lockowner) {
-		tsleep(&pfs->pfs_lockowner, PRIBIO, "pfslck", 0);
-	}
-	pfs->pfs_lockowner =3D curproc->p_pid;
-
-	switch (pfs->pfs_type) {
-	case Pnote:
-	case Pnotepg:
-		rtval =3D procfs_donote(curp, p, pfs, uio);
-		break;
-
-	case Pregs:
-		rtval =3D procfs_doregs(curp, p, pfs, uio);
-		break;
-
-	case Pfpregs:
-		rtval =3D procfs_dofpregs(curp, p, pfs, uio);
-		break;
-
-        case Pdbregs:
-                rtval =3D procfs_dodbregs(curp, p, pfs, uio);
-                break;
-
-	case Pctl:
-		rtval =3D procfs_doctl(curp, p, pfs, uio);
-		break;
-
-	case Pstatus:
-		rtval =3D procfs_dostatus(curp, p, pfs, uio);
-		break;
-
-	case Pmap:
-		rtval =3D procfs_domap(curp, p, pfs, uio);
-		break;
-
-	case Pmem:
-		rtval =3D procfs_domem(curp, p, pfs, uio);
-		break;
-
-	case Ptype:
-		rtval =3D procfs_dotype(curp, p, pfs, uio);
-		break;
-
-	case Pcmdline:
-		rtval =3D procfs_docmdline(curp, p, pfs, uio);
-		break;
-
-	case Prlimit:
-		rtval =3D procfs_dorlimit(curp, p, pfs, uio);
-		break;
-
-	default:
-		rtval =3D EOPNOTSUPP;
-		break;
-	}
-	pfs->pfs_lockowner =3D 0;
-	wakeup(&pfs->pfs_lockowner);
-	return rtval;
-}
-
-/*
- * Get a string from userland into (buf).  Strip a trailing
- * nl character (to allow easy access from the shell).
- * The buffer should be *buflenp + 1 chars long.  vfs_getuserstr
- * will automatically add a nul char at the end.
- *
- * Returns 0 on success or the following errors
- *
- * EINVAL:    file offset is non-zero.
- * EMSGSIZE:  message is longer than kernel buffer
- * EFAULT:    user i/o buffer is not addressable
- */
-int
-vfs_getuserstr(uio, buf, buflenp)
-	struct uio *uio;
-	char *buf;
-	int *buflenp;
-{
-	int xlen;
-	int error;
-
-	if (uio->uio_offset !=3D 0)
-		return (EINVAL);
-
-	xlen =3D *buflenp;
-
-	/* must be able to read the whole string in one go */
-	if (xlen < uio->uio_resid)
-		return (EMSGSIZE);
-	xlen =3D uio->uio_resid;
-
-	if ((error =3D uiomove(buf, xlen, uio)) !=3D 0)
-		return (error);
-
-	/* allow multiple writes without seeks */
-	uio->uio_offset =3D 0;
-
-	/* cleanup string and remove trailing newline */
-	buf[xlen] =3D '\0';
-	xlen =3D strlen(buf);
-	if (xlen > 0 && buf[xlen-1] =3D=3D '\n')
-		buf[--xlen] =3D '\0';
-	*buflenp =3D xlen;
-
-	return (0);
-}
-
-vfs_namemap_t *
-vfs_findname(nm, buf, buflen)
-	vfs_namemap_t *nm;
-	char *buf;
-	int buflen;
-{
-
-	for (; nm->nm_name; nm++)
-		if (bcmp(buf, nm->nm_name, buflen+1) =3D=3D 0)
-			return (nm);
-
-	return (0);
-}
-
-void
-procfs_exit(struct proc *p)
-{
-	struct pfsnode *pfs;
-	pid_t pid =3D p->p_pid;
-
-	/*
-	 * The reason for this loop is not obvious -- basicly,
-	 * procfs_freevp(), which is called via vgone() (eventually),
-	 * removes the specified procfs node from the pfshead list.
-	 * It does this by *pfsp =3D pfs->pfs_next, meaning that it
-	 * overwrites the node.  So when we do pfs =3D pfs->next, we
-	 * end up skipping the node that replaces the one that was
-	 * vgone'd.  Since it may have been the last one on the list,
-	 * it may also have been set to null -- but *our* pfs pointer,
-	 * here, doesn't see this.  So the loop starts from the beginning
-	 * again.
-	 *
-	 * This is not a for() loop because the final event
-	 * would be "pfs =3D pfs->pfs_next"; in the case where
-	 * pfs is set to pfshead again, that would mean that
-	 * pfshead is skipped over.
-	 *
-	 */
-	pfs =3D pfshead;
-	while (pfs) {
-		if (pfs->pfs_pid =3D=3D pid) {
-			vgone(PFSTOV(pfs));
-			pfs =3D pfshead;
-		} else
-			pfs =3D pfs->pfs_next;
-	}
-}
Index: sys/fs/procfs/procfs_type.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_type.c,v
retrieving revision 1.8
diff -u -r1.8 procfs_type.c
--- sys/fs/procfs/procfs_type.c	12 Sep 2001 08:37:20 -0000	1.8
+++ sys/fs/procfs/procfs_type.c	1 Oct 2001 02:27:34 -0000
@@ -39,46 +39,25 @@
=20
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/mount.h>
 #include <sys/proc.h>
+#include <sys/sbuf.h>
 #include <sys/sysent.h>
 #include <sys/vnode.h>
+
+#include <fs/pseudofs/pseudofs.h>
 #include <fs/procfs/procfs.h>
=20
 int
-procfs_dotype(curp, p, pfs, uio)
-	struct proc *curp;
-	struct proc *p;
-	struct pfsnode *pfs;
-	struct uio *uio;
+procfs_doproctype(PFS_FILL_ARGS)
 {
-	int len;
-	int error;
-	/*
-	 * buffer for emulation type
-	 */
-	char mebuffer[256];
-	char *none =3D "Not Available";
-
-	if (uio->uio_rw !=3D UIO_READ)
-		return (EOPNOTSUPP);
-
-	if (uio->uio_offset !=3D 0)
-		return (0);
+	static const char *none =3D "Not Available";
=20
 	if (p && p->p_sysent && p->p_sysent->sv_name) {
-		len =3D strlen(p->p_sysent->sv_name);
-		bcopy(p->p_sysent->sv_name, mebuffer, len);
+		sbuf_printf(sb, p->p_sysent->sv_name);
 	} else {
-		len =3D strlen(none);
-		bcopy(none, mebuffer, len);
+		sbuf_printf(sb, none);
 	}
-	mebuffer[len++] =3D '\n';
-	error =3D uiomove(mebuffer, len, uio);
-	return error;
-}
-
-int
-procfs_validtype(struct thread *td)
-{
-	return ((td->td_proc->p_flag & P_SYSTEM) =3D=3D 0);
+	sbuf_putc(sb, '\n');
+	return (0);
 }
Index: sys/fs/procfs/procfs_vfsops.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: sys/fs/procfs/procfs_vfsops.c
diff -N sys/fs/procfs/procfs_vfsops.c
--- sys/fs/procfs/procfs_vfsops.c	12 Sep 2001 08:37:20 -0000	1.38
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 1993 Jan-Simon Pendry
- * Copyright (c) 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP=
OSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT=
IAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STR=
ICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W=
AY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)procfs_vfsops.c	8.7 (Berkeley) 5/10/95
- *
- * $FreeBSD: src/sys/fs/procfs/procfs_vfsops.c,v 1.38 2001/09/12 08:37:20 =
julian Exp $
- */
-
-/*
- * procfs VFS interface
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <fs/procfs/procfs.h>
-
-static int	procfs_mount __P((struct mount *mp, char *path, caddr_t data,
-				  struct nameidata *ndp, struct thread *td));
-static int	procfs_statfs __P((struct mount *mp, struct statfs *sbp,
-				   struct thread *td));
-static int	procfs_unmount __P((struct mount *mp, int mntflags,
-				    struct thread *td));
-
-/*
- * VFS Operations.
- *
- * mount system call
- */
-/* ARGSUSED */
-static int
-procfs_mount(mp, path, data, ndp, td)
-	struct mount *mp;
-	char *path;
-	caddr_t data;
-	struct nameidata *ndp;
-	struct thread *td;
-{
-	size_t size;
-	int error;
-
-	if (mp->mnt_flag & MNT_UPDATE)
-		return (EOPNOTSUPP);
-
-	if (mp->mnt_vfc->vfc_refcount =3D=3D 1 && (error =3D at_exit(procfs_exit)=
)) {
-		printf("procfs:  cannot register procfs_exit with at_exit\n");
-		return(error);
-	}
-
-	mp->mnt_flag |=3D MNT_LOCAL;
-	mp->mnt_data =3D 0;
-	vfs_getnewfsid(mp);
-
-	size =3D sizeof("procfs") - 1;
-	bcopy("procfs", mp->mnt_stat.f_mntfromname, size);
-	bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
-	(void)procfs_statfs(mp, &mp->mnt_stat, td);
-
-	return (0);
-}
-
-/*
- * unmount system call
- */
-static int
-procfs_unmount(mp, mntflags, td)
-	struct mount *mp;
-	int mntflags;
-	struct thread *td;
-{
-	int error;
-	int flags =3D 0;
-
-	if (mntflags & MNT_FORCE)
-		flags |=3D FORCECLOSE;
-
-	error =3D vflush(mp, 0, flags);
-	if (error)
-		return (error);
-
-	if (mp->mnt_vfc->vfc_refcount =3D=3D 1)
-		rm_at_exit(procfs_exit);
-
-	return (0);
-}
-
-int
-procfs_root(mp, vpp)
-	struct mount *mp;
-	struct vnode **vpp;
-{
-
-	return (procfs_allocvp(mp, vpp, 0, Proot));
-}
-
-/*
- * Get file system statistics.
- */
-static int
-procfs_statfs(mp, sbp, td)
-	struct mount *mp;
-	struct statfs *sbp;
-	struct thread *td;
-{
-	sbp->f_bsize =3D PAGE_SIZE;
-	sbp->f_iosize =3D PAGE_SIZE;
-	sbp->f_blocks =3D 1;	/* avoid divide by zero in some df's */
-	sbp->f_bfree =3D 0;
-	sbp->f_bavail =3D 0;
-	sbp->f_files =3D maxproc;			/* approx */
-	sbp->f_ffree =3D maxproc - nprocs;	/* approx */
-
-	if (sbp !=3D &mp->mnt_stat) {
-		sbp->f_type =3D 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);
-	}
-
-	return (0);
-}
-
-static struct vfsops procfs_vfsops =3D {
-	procfs_mount,
-	vfs_stdstart,
-	procfs_unmount,
-	procfs_root,
-	vfs_stdquotactl,
-	procfs_statfs,
-	vfs_stdsync,
-	vfs_stdvget,
-	vfs_stdfhtovp,
-	vfs_stdcheckexp,
-	vfs_stdvptofh,
-	vfs_stdinit,
-	vfs_stduninit,
-	vfs_stdextattrctl,
-};
-
-VFS_SET(procfs_vfsops, procfs, VFCF_SYNTHETIC);
-MODULE_VERSION(procfs, 1);
Index: sys/fs/procfs/procfs_vnops.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: sys/fs/procfs/procfs_vnops.c
diff -N sys/fs/procfs/procfs_vnops.c
--- sys/fs/procfs/procfs_vnops.c	22 Oct 2001 16:13:38 -0000	1.104
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,1023 +0,0 @@
-/*
- * 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
- * Jan-Simon Pendry.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP=
OSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT=
IAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STR=
ICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W=
AY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *	@(#)procfs_vnops.c	8.18 (Berkeley) 5/21/95
- *
- * $FreeBSD: src/sys/fs/procfs/procfs_vnops.c,v 1.104 2001/10/22 16:13:38 =
des Exp $
- */
-
-/*
- * procfs vnode interface
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/dirent.h>
-#include <sys/fcntl.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/namei.h>
-#include <sys/pioctl.h>
-#include <sys/proc.h>
-#include <sys/signalvar.h>
-#include <sys/socket.h>
-#include <sys/sx.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <sys/vnode.h>
-
-#include <machine/reg.h>
-
-#include <vm/vm_zone.h>
-
-#include <fs/procfs/procfs.h>
-
-static int	procfs_access __P((struct vop_access_args *));
-static int	procfs_badop __P((void));
-static int	procfs_close __P((struct vop_close_args *));
-static int	procfs_getattr __P((struct vop_getattr_args *));
-static int	procfs_ioctl __P((struct vop_ioctl_args *));
-static int	procfs_lookup __P((struct vop_lookup_args *));
-static int	procfs_open __P((struct vop_open_args *));
-static int	procfs_print __P((struct vop_print_args *));
-static int	procfs_readdir __P((struct vop_readdir_args *));
-static int	procfs_readlink __P((struct vop_readlink_args *));
-static int	procfs_reclaim __P((struct vop_reclaim_args *));
-static int	procfs_setattr __P((struct vop_setattr_args *));
-
-/*
- * This is a list of the valid names in the
- * process-specific sub-directories.  It is
- * used in procfs_lookup and procfs_readdir
- */
-static struct proc_target {
-	u_char	pt_type;
-	u_char	pt_namlen;
-	char	*pt_name;
-	pfstype	pt_pfstype;
-	int	(*pt_valid) __P((struct thread *p));
-} proc_targets[] =3D {
-#define N(s) sizeof(s)-1, s
-	/*	  name		type		validp */
-	{ DT_DIR, N("."),	Pproc,		NULL },
-	{ DT_DIR, N(".."),	Proot,		NULL },
-	{ DT_REG, N("mem"),	Pmem,		NULL },
-	{ DT_REG, N("regs"),	Pregs,		procfs_validregs },
-	{ DT_REG, N("fpregs"),	Pfpregs,	procfs_validfpregs },
-	{ DT_REG, N("dbregs"),	Pdbregs,	procfs_validdbregs },
-	{ 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 },
-	{ DT_REG, N("cmdline"),	Pcmdline,	NULL },
-	{ DT_REG, N("rlimit"),	Prlimit,	NULL },
-	{ DT_LNK, N("file"),	Pfile,		NULL },
-#undef N
-};
-static const int nproc_targets =3D sizeof(proc_targets) / sizeof(proc_targ=
ets[0]);
-
-static pid_t atopid __P((const char *, u_int));
-
-/*
- * set things up for doing i/o on
- * the pfsnode (vp).  (vp) is locked
- * on entry, and should be left locked
- * on exit.
- *
- * for procfs we don't need to do anything
- * in particular for i/o.  all that is done
- * is to support exclusive open on process
- * memory images.
- */
-static int
-procfs_open(ap)
-	struct vop_open_args /* {
-		struct vnode *a_vp;
-		int  a_mode;
-		struct ucred *a_cred;
-		struct thread *a_td;
-	} */ *ap;
-{
-	struct pfsnode *pfs =3D VTOPFS(ap->a_vp);
-	struct proc *p1, *p2;
-	int error =3D 0;
-
-	p2 =3D PFIND(pfs->pfs_pid);
-	if (p2 =3D=3D NULL)
-		return (ENOENT);
-	if (pfs->pfs_pid && p_cansee(ap->a_td->td_proc, p2)) {
-		error =3D ENOENT;
-		goto out;
-	}
-
-	switch (pfs->pfs_type) {
-	case Pmem:
-		if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) ||
-		    ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) {
-			error =3D EBUSY;
-			goto out;
-		}
-
-		p1 =3D ap->a_td->td_proc;
-		error =3D p_candebug(p1, p2);
-		if (error)
-			return (error);
-
-		if (ap->a_mode & FWRITE)
-			pfs->pfs_flags =3D ap->a_mode & (FWRITE|O_EXCL);
-
-	default:
-		break;
-	}
-out:
-	PROC_UNLOCK(p2);
-	return (error);
-}
-
-/*
- * close the pfsnode (vp) after doing i/o.
- * (vp) is not locked on entry or exit.
- *
- * nothing to do for procfs other than undo
- * any exclusive open flag (see _open above).
- */
-static int
-procfs_close(ap)
-	struct vop_close_args /* {
-		struct vnode *a_vp;
-		int  a_fflag;
-		struct ucred *a_cred;
-		struct thread *a_td;
-	} */ *ap;
-{
-	struct pfsnode *pfs =3D VTOPFS(ap->a_vp);
-	struct proc *p;
-
-	switch (pfs->pfs_type) {
-	case Pmem:
-		if ((ap->a_fflag & FWRITE) && (pfs->pfs_flags & O_EXCL))
-			pfs->pfs_flags &=3D ~(FWRITE|O_EXCL);
-		/*
-		 * If this is the last close, then it checks to see if
-		 * the target process has PF_LINGER set in p_pfsflags,
-		 * if this is *not* the case, then the process' stop flags
-		 * are cleared, and the process is woken up.  This is
-		 * to help prevent the case where a process has been
-		 * told to stop on an event, but then the requesting process
-		 * has gone away or forgotten about it.
-		 */
-		if ((ap->a_vp->v_usecount < 2) && (p =3D pfind(pfs->pfs_pid))) {
-			if (!(p->p_pfsflags & PF_LINGER)) {
-				p->p_stops =3D 0;
-				p->p_step =3D 0;
-				wakeup(&p->p_step);
-			}
-			PROC_UNLOCK(p);
-		}
-		break;
-	default:
-		break;
-	}
-
-	return (0);
-}
-
-/*
- * do an ioctl operation on a pfsnode (vp).
- * (vp) is not locked on entry or exit.
- */
-static int
-procfs_ioctl(ap)
-	struct vop_ioctl_args *ap;
-{
-	struct pfsnode *pfs =3D VTOPFS(ap->a_vp);
-	struct proc *procp, *p;
-	int error;
-	int signo;
-	struct procfs_status *psp;
-	unsigned char flags;
-
-	p =3D ap->a_td->td_proc;
-	procp =3D pfind(pfs->pfs_pid);
-	if (procp =3D=3D NULL) {
-		return ENOTTY;
-	}
-
-	if ((error =3D p_candebug(p, procp))) {
-		PROC_UNLOCK(procp);
-		return (error =3D=3D ESRCH ? ENOENT : error);
-	}
-
-	switch (ap->a_command) {
-	case PIOCBIS:
-	  procp->p_stops |=3D *(unsigned int*)ap->a_data;
-	  break;
-	case PIOCBIC:
-	  procp->p_stops &=3D ~*(unsigned int*)ap->a_data;
-	  break;
-	case PIOCSFL:
-	  /*
-	   * NFLAGS is "non-suser_xxx flags" -- currently, only
-	   * PFS_ISUGID ("ignore set u/g id");
-	   */
-#define NFLAGS	(PF_ISUGID)
-	  flags =3D (unsigned char)*(unsigned int*)ap->a_data;
-	  if (flags & NFLAGS && (error =3D suser(p))) {
-	    PROC_UNLOCK(procp);
-	    return error;
-	  }
-	  procp->p_pfsflags =3D flags;
-	  break;
-	case PIOCGFL:
-	  *(unsigned int*)ap->a_data =3D (unsigned int)procp->p_pfsflags;
-	  break;
-	case PIOCSTATUS:
-	  psp =3D (struct procfs_status *)ap->a_data;
-	  psp->state =3D (procp->p_step =3D=3D 0);
-	  psp->flags =3D procp->p_pfsflags;
-	  psp->events =3D procp->p_stops;
-	  if (procp->p_step) {
-	    psp->why =3D procp->p_stype;
-	    psp->val =3D procp->p_xstat;
-	  } else {
-	    psp->why =3D psp->val =3D 0;	/* Not defined values */
-	  }
-	  break;
-	case PIOCWAIT:
-	  psp =3D (struct procfs_status *)ap->a_data;
-	  if (procp->p_step =3D=3D 0) {
-	    error =3D msleep(&procp->p_stype, &procp->p_mtx, PWAIT | PCATCH,
-	      "piocwait", 0);
-	    if (error) {
-	      PROC_UNLOCK(procp);
-	      return error;
-	    }
-	  }
-	  psp->state =3D 1;	/* It stopped */
-	  psp->flags =3D procp->p_pfsflags;
-	  psp->events =3D procp->p_stops;
-	  psp->why =3D procp->p_stype;	/* why it stopped */
-	  psp->val =3D procp->p_xstat;	/* any extra info */
-	  break;
-	case PIOCCONT:	/* Restart a proc */
-	  if (procp->p_step =3D=3D 0) {
-	    PROC_UNLOCK(procp);
-	    return EINVAL;	/* Can only start a stopped process */
-	  }
-	  if ((signo =3D *(int*)ap->a_data) !=3D 0) {
-	    if (signo >=3D NSIG || signo <=3D 0) {
-	      PROC_UNLOCK(procp);
-	      return EINVAL;
-	    }
-	    psignal(procp, signo);
-	  }
-	  procp->p_step =3D 0;
-	  wakeup(&procp->p_step);
-	  break;
-	default:
-	  PROC_UNLOCK(procp);
-	  return (ENOTTY);
-	}
-	PROC_UNLOCK(procp);
-	return 0;
-}
-
-/*
- * _reclaim is called when getnewvnode()
- * wants to make use of an entry on the vnode
- * free list.  at this time the filesystem needs
- * to free any private data and remove the node
- * from any private lists.
- */
-static int
-procfs_reclaim(ap)
-	struct vop_reclaim_args /* {
-		struct vnode *a_vp;
-	} */ *ap;
-{
-
-	return (procfs_freevp(ap->a_vp));
-}
-
-/*
- * _print is used for debugging.
- * just print a readable description
- * of (vp).
- */
-static int
-procfs_print(ap)
-	struct vop_print_args /* {
-		struct vnode *a_vp;
-	} */ *ap;
-{
-	struct pfsnode *pfs =3D VTOPFS(ap->a_vp);
-
-	printf("tag VT_PROCFS, type %d, pid %ld, mode %x, flags %lx\n",
-	    pfs->pfs_type, (long)pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags);
-	return (0);
-}
-
-/*
- * generic entry point for unsupported operations
- */
-static int
-procfs_badop()
-{
-
-	return (EIO);
-}
-
-/*
- * Invent attributes for pfsnode (vp) and store
- * them in (vap).
- * Directories lengths are returned as zero since
- * any real length would require the genuine size
- * to be computed, and nothing cares anyway.
- *
- * this is relatively minimal for procfs.
- */
-static int
-procfs_getattr(ap)
-	struct vop_getattr_args /* {
-		struct vnode *a_vp;
-		struct vattr *a_vap;
-		struct ucred *a_cred;
-		struct thread *a_td;
-	} */ *ap;
-{
-	struct pfsnode *pfs =3D VTOPFS(ap->a_vp);
-	struct vattr *vap =3D ap->a_vap;
-	struct proc *procp;
-	int error;
-
-	/*
-	 * First make sure that the process and its credentials=20
-	 * still exist.
-	 */
-	switch (pfs->pfs_type) {
-	case Proot:
-	case Pcurproc:
-		procp =3D NULL;
-		break;
-
-	default:
-		procp =3D PFIND(pfs->pfs_pid);
-		if (procp =3D=3D NULL)
-			return (ENOENT);
-		if (procp->p_ucred =3D=3D NULL) {
-			PROC_UNLOCK(procp);
-			return (ENOENT);
-		}
-
-		if (p_cansee(ap->a_td->td_proc, procp)) {
-			PROC_UNLOCK(procp);
-			return (ENOENT);
-		}
-		PROC_UNLOCK(procp);
-	}
-
-	error =3D 0;
-
-	/* start by zeroing out the attributes */
-	VATTR_NULL(vap);
-
-	/* next do all the common fields */
-	vap->va_type =3D ap->a_vp->v_type;
-	vap->va_mode =3D pfs->pfs_mode;
-	vap->va_fileid =3D pfs->pfs_fileno;
-	vap->va_flags =3D 0;
-	vap->va_blocksize =3D PAGE_SIZE;
-	vap->va_bytes =3D vap->va_size =3D 0;
-	vap->va_fsid =3D ap->a_vp->v_mount->mnt_stat.f_fsid.val[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.
-	 */
-	nanotime(&vap->va_ctime);
-	vap->va_atime =3D vap->va_mtime =3D 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) {
-	case Pctl:
-	case Pregs:
-	case Pfpregs:
-	case Pdbregs:
-	case Pmem:
-		PROC_LOCK(procp);
-		if (procp->p_flag & P_SUGID)
-			vap->va_mode &=3D ~((VREAD|VWRITE)|
-					  ((VREAD|VWRITE)>>3)|
-					  ((VREAD|VWRITE)>>6));
-		PROC_UNLOCK(procp);
-		break;
-	default:
-		break;
-	}
-
-	/*
-	 * now do the object specific fields
-	 *
-	 * The size could be set from struct reg, but it's hardly
-	 * worth the trouble, and it puts some (potentially) machine
-	 * dependent data into this machine-independent code.  If it
-	 * becomes important then this function should break out into
-	 * a per-file stat function in the corresponding .c file.
-	 */
-
-	vap->va_nlink =3D 1;
-	if (procp) {
-		PROC_LOCK(procp);
-		vap->va_uid =3D procp->p_ucred->cr_uid;
-		vap->va_gid =3D procp->p_ucred->cr_gid;
-		PROC_UNLOCK(procp);
-	}
-
-	switch (pfs->pfs_type) {
-	case Proot:
-		/*
-		 * Set nlink to 1 to tell fts(3) we don't actually know.
-		 */
-		vap->va_nlink =3D 1;
-		vap->va_uid =3D 0;
-		vap->va_gid =3D 0;
-		vap->va_size =3D vap->va_bytes =3D DEV_BSIZE;
-		break;
-
-	case Pcurproc: {
-		char buf[16];		/* should be enough */
-		vap->va_uid =3D 0;
-		vap->va_gid =3D 0;
-		vap->va_size =3D vap->va_bytes =3D
-		    snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid);
-		break;
-	}
-
-	case Pproc:
-		vap->va_nlink =3D nproc_targets;
-		vap->va_size =3D vap->va_bytes =3D DEV_BSIZE;
-		break;
-
-	case Pfile: {
-		char *fullpath, *freepath;
-		error =3D textvp_fullpath(procp, &fullpath, &freepath);
-		if (error =3D=3D 0) {
-			vap->va_size =3D strlen(fullpath);
-			free(freepath, M_TEMP);
-		} else {
-			vap->va_size =3D sizeof("unknown") - 1;
-			error =3D 0;
-		}
-		vap->va_bytes =3D vap->va_size;
-		break;
-	}
-
-	case Pmem:
-		/*
-		 * If we denied owner access earlier, then we have to
-		 * change the owner to root - otherwise 'ps' and friends
-		 * will break even though they are setgid kmem. *SIGH*
-		 * XXX: ps and friends are no longer setgid kmem, why
-		 * is this needed?
-		 */
-		PROC_LOCK(procp);
-		if (procp->p_flag & P_SUGID)
-			vap->va_uid =3D 0;
-		else
-			vap->va_uid =3D procp->p_ucred->cr_uid;
-		PROC_UNLOCK(procp);
-		break;
-
-	case Pregs:
-		vap->va_bytes =3D vap->va_size =3D sizeof(struct reg);
-		break;
-
-	case Pfpregs:
-		vap->va_bytes =3D vap->va_size =3D sizeof(struct fpreg);
-		break;
-
-        case Pdbregs:
-                vap->va_bytes =3D vap->va_size =3D sizeof(struct dbreg);
-                break;
-
-	case Ptype:
-	case Pmap:
-	case Pctl:
-	case Pstatus:
-	case Pnote:
-	case Pnotepg:
-	case Pcmdline:
-	case Prlimit:
-		break;
-
-	default:
-		panic("procfs_getattr");
-	}
-
-	return (error);
-}
-
-static int
-procfs_setattr(ap)
-	struct vop_setattr_args /* {
-		struct vnode *a_vp;
-		struct vattr *a_vap;
-		struct ucred *a_cred;
-		struct thread *a_td;
-	} */ *ap;
-{
-
-	if (ap->a_vap->va_flags !=3D VNOVAL)
-		return (EOPNOTSUPP);
-
-	/*
-	 * just fake out attribute setting
-	 * it's not good to generate an error
-	 * return, otherwise things like creat()
-	 * will fail when they try to set the
-	 * file length to 0.  worse, this means
-	 * that echo $note > /proc/$pid/note will fail.
-	 */
-
-	return (0);
-}
-
-/*
- * implement access checking.
- *
- * actually, the check for super-user is slightly
- * broken since it will allow read access to write-only
- * objects.  this doesn't cause any particular trouble
- * but does mean that the i/o entry points need to check
- * that the operation really does make sense.
- */
-static int
-procfs_access(ap)
-	struct vop_access_args /* {
-		struct vnode *a_vp;
-		int a_mode;
-		struct ucred *a_cred;
-		struct thread *a_td;
-	} */ *ap;
-{
-	struct pfsnode *pfs =3D VTOPFS(ap->a_vp);
-	struct vnode *vp =3D ap->a_vp;
-	struct proc *procp;
-	struct vattr *vap;
-	struct vattr vattr;
-	int error;
-
-	switch (pfs->pfs_type) {
-	case Proot:
-       	case Pcurproc:
-		break;
-	default:
-		procp =3D PFIND(pfs->pfs_pid);
-		if (procp =3D=3D NULL)
-			return (ENOENT);
-		if (p_cansee(ap->a_td->td_proc, procp)) {
-			PROC_UNLOCK(procp);
-			return (ENOENT);
-		}
-		PROC_UNLOCK(procp);
-        }
-
-	vap =3D &vattr;
-	error =3D VOP_GETATTR(vp, vap, ap->a_cred, ap->a_td);
-	if (error)
-		return (error);
-
-	return (vaccess(vp->v_type, vap->va_mode, vap->va_uid, vap->va_gid,
-	    ap->a_mode, ap->a_cred, NULL));
-}
-
-/*
- * lookup.  this is incredibly complicated in the
- * general case, however for most pseudo-filesystems
- * very little needs to be done.
- *
- * unless you want to get a migraine, just make sure your
- * filesystem doesn't do any locking of its own.  otherwise
- * read and inwardly digest ufs_lookup().
- */
-static int
-procfs_lookup(ap)
-	struct vop_lookup_args /* {
-		struct vnode * a_dvp;
-		struct vnode ** a_vpp;
-		struct componentname * a_cnp;
-	} */ *ap;
-{
-	struct componentname *cnp =3D ap->a_cnp;
-	struct vnode **vpp =3D ap->a_vpp;
-	struct vnode *dvp =3D ap->a_dvp;
-	char *pname =3D cnp->cn_nameptr;
-	struct proc *curp =3D cnp->cn_thread->td_proc;
-	struct proc_target *pt;
-	pid_t pid;
-	struct pfsnode *pfs;
-	struct proc *p;
-	int i;
-	struct thread *td;
-
-	*vpp =3D NULL;
-
-	if (cnp->cn_nameiop =3D=3D DELETE || cnp->cn_nameiop =3D=3D RENAME ||
-	    cnp->cn_nameiop =3D=3D CREATE)
-		return (EROFS);
-
-	if (cnp->cn_namelen =3D=3D 1 && *pname =3D=3D '.') {
-		*vpp =3D dvp;
-		VREF(dvp);
-		/* vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, curp); */
-		return (0);
-	}
-
-	pfs =3D VTOPFS(dvp);
-	switch (pfs->pfs_type) {
-	case Proot:
-		if (cnp->cn_flags & ISDOTDOT)
-			return (EIO);
-
-		if (CNEQ(cnp, "curproc", 7))
-			return (procfs_allocvp(dvp->v_mount, vpp, 0, Pcurproc));
-
-		pid =3D atopid(pname, cnp->cn_namelen);
-		if (pid =3D=3D NO_PID)
-			break;
-
-		p =3D PFIND(pid);
-		if (p =3D=3D NULL)
-			break;
-
-		if (p_cansee(curp, p)) {
-			PROC_UNLOCK(p);
-			break;
-		}
-		PROC_UNLOCK(p);
-
-		return (procfs_allocvp(dvp->v_mount, vpp, pid, Pproc));
-
-	case Pproc:
-		if (cnp->cn_flags & ISDOTDOT)
-			return (procfs_root(dvp->v_mount, vpp));
-
-		p =3D PFIND(pfs->pfs_pid);
-		td =3D &p->p_thread;		/* XXXKSE */
-		if (p =3D=3D NULL)
-			break;
-
-		for (pt =3D proc_targets, i =3D 0; i < nproc_targets; pt++, i++) {
-			if (cnp->cn_namelen =3D=3D pt->pt_namlen &&
-			    bcmp(pt->pt_name, pname, cnp->cn_namelen) =3D=3D 0 &&
-			    (pt->pt_valid =3D=3D NULL || (*pt->pt_valid)(td)))
-				goto found;
-		}
-		PROC_UNLOCK(p);
-		break;
-	found:
-		PROC_UNLOCK(p);
-		return (procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
-		    pt->pt_pfstype));
-
-	default:
-		return (ENOTDIR);
-	}
-
-	return (cnp->cn_nameiop =3D=3D LOOKUP ? ENOENT : EROFS);
-}
-
-/*
- * Does this process have a text file?
- */
-int
-procfs_validfile(td)
-	struct thread *td;
-{
-
-	return (td->td_proc->p_textvp !=3D NULLVP);
-}
-
-/*
- * readdir() returns directory entries from pfsnode (vp).
- *
- * We generate just one directory entry at a time, as it would probably
- * not pay off to buffer several entries locally to save uiomove calls.
- */
-static int
-procfs_readdir(ap)
-	struct vop_readdir_args /* {
-		struct vnode *a_vp;
-		struct uio *a_uio;
-		struct ucred *a_cred;
-		int *a_eofflag;
-		int *a_ncookies;
-		u_long **a_cookies;
-	} */ *ap;
-{
-	struct uio *uio =3D ap->a_uio;
-	struct dirent d;
-	struct dirent *dp =3D &d;
-	struct pfsnode *pfs;
-	int count, error, i, off;
-	static u_int delen;
-	struct thread *td;
-
-	if (!delen) {
-
-		d.d_namlen =3D PROCFS_NAMELEN;
-		delen =3D GENERIC_DIRSIZ(&d);
-	}
-
-	pfs =3D VTOPFS(ap->a_vp);
-
-	off =3D (int)uio->uio_offset;
-	if (off !=3D uio->uio_offset || off < 0 ||=20
-	    off % delen !=3D 0 || uio->uio_resid < delen)
-		return (EINVAL);
-
-	error =3D 0;
-	count =3D 0;
-	i =3D off / delen;
-
-	switch (pfs->pfs_type) {
-	/*
-	 * this is for the process-specific sub-directories.
-	 * all that is needed to is copy out all the entries
-	 * from the procent[] table (top of this file).
-	 */
-	case Pproc: {
-		struct proc *p;
-		struct proc_target *pt;
-
-		p =3D PFIND(pfs->pfs_pid);
-		td =3D &p->p_thread;	/* XXXKSE */
-		if (p =3D=3D NULL)
-			break;
-		if (p_cansee(curthread->td_proc, p)) {
-			PROC_UNLOCK(p);
-			break;
-		}
-
-		for (pt =3D &proc_targets[i];
-		     uio->uio_resid >=3D delen && i < nproc_targets; pt++, i++) {
-			if (pt->pt_valid && (*pt->pt_valid)(td) =3D=3D 0)
-				continue;
-
-			dp->d_reclen =3D delen;
-			dp->d_fileno =3D PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype);
-			dp->d_namlen =3D pt->pt_namlen;
-			bcopy(pt->pt_name, dp->d_name, pt->pt_namlen + 1);
-			dp->d_type =3D pt->pt_type;
-
-			PROC_UNLOCK(p);
-			if ((error =3D uiomove((caddr_t)dp, delen, uio)) !=3D 0)
-				break;
-			PROC_LOCK(p);
-		}
-		PROC_UNLOCK(p);
-
-	    	break;
-	    }
-
-	/*
-	 * this is for the root of the procfs filesystem
-	 * what is needed is a special entry for "curproc"
-	 * followed by an entry for each process on allproc
-#ifdef PROCFS_ZOMBIE
-	 * and zombproc.
-#endif
-	 */
-
-	case Proot: {
-#ifdef PROCFS_ZOMBIE
-		int doingzomb =3D 0;
-#endif
-		int pcnt =3D 0;
-		struct proc *p;
-
-		sx_slock(&allproc_lock);
-		p =3D LIST_FIRST(&allproc);
-		for (; p && uio->uio_resid >=3D delen; i++, pcnt++) {
-			bzero((char *) dp, delen);
-			dp->d_reclen =3D delen;
-
-			switch (i) {
-			case 0:		/* `.' */
-			case 1:		/* `..' */
-				dp->d_fileno =3D PROCFS_FILENO(0, Proot);
-				dp->d_namlen =3D i + 1;
-				bcopy("..", dp->d_name, dp->d_namlen);
-				dp->d_name[i + 1] =3D '\0';
-				dp->d_type =3D DT_DIR;
-				break;
-
-			case 2:
-				dp->d_fileno =3D PROCFS_FILENO(0, Pcurproc);
-				dp->d_namlen =3D 7;
-				bcopy("curproc", dp->d_name, 8);
-				dp->d_type =3D DT_LNK;
-				break;
-
-			default:
-				while (pcnt < i) {
-					p =3D LIST_NEXT(p, p_list);
-					if (p =3D=3D NULL)
-						goto done;
-					if (p_cansee(curthread->td_proc, p))
-						continue;
-					pcnt++;
-				}
-				while (p_cansee(curthread->td_proc, p)) {
-					p =3D LIST_NEXT(p, p_list);
-					if (p =3D=3D NULL)
-						goto done;
-				}
-				dp->d_fileno =3D PROCFS_FILENO(p->p_pid, Pproc);
-				dp->d_namlen =3D sprintf(dp->d_name, "%ld",
-				    (long)p->p_pid);
-				dp->d_type =3D DT_DIR;
-				p =3D LIST_NEXT(p, p_list);
-				break;
-			}
-
-			if ((error =3D uiomove((caddr_t)dp, delen, uio)) !=3D 0)
-				break;
-		}
-	done:
-
-#ifdef PROCFS_ZOMBIE
-		if (p =3D=3D NULL && doingzomb =3D=3D 0) {
-			doingzomb =3D 1;
-			p =3D LIST_FIRST(&zombproc);
-			goto again;
-		}
-#endif
-
-		sx_sunlock(&allproc_lock);
-		break;
-
-	    }
-
-	default:
-		error =3D ENOTDIR;
-		break;
-	}
-
-	uio->uio_offset =3D i * delen;
-
-	return (error);
-}
-
-/*
- * readlink reads the link of `curproc' or `file'
- */
-static int
-procfs_readlink(ap)
-	struct vop_readlink_args *ap;
-{
-	char buf[16];		/* should be enough */
-	struct proc *procp;
-	struct vnode *vp =3D ap->a_vp;
-	struct pfsnode *pfs =3D VTOPFS(vp);
-	char *fullpath, *freepath;
-	int error, len;
-
-	switch (pfs->pfs_type) {
-	case Pcurproc:
-		if (pfs->pfs_fileno !=3D PROCFS_FILENO(0, Pcurproc))
-			return (EINVAL);
-
-		len =3D snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid);
-
-		return (uiomove(buf, len, ap->a_uio));
-	/*
-	 * There _should_ be no way for an entire process to disappear
-	 * from under us...
-	 */
-	case Pfile:
-		procp =3D PFIND(pfs->pfs_pid);
-		if (procp =3D=3D NULL || procp->p_ucred =3D=3D NULL) {
-			if (procp !=3D NULL)
-				PROC_UNLOCK(procp);
-			printf("procfs_readlink: pid %d disappeared\n",
-			    pfs->pfs_pid);
-			return (uiomove("unknown", sizeof("unknown") - 1,
-			    ap->a_uio));
-		}
-		PROC_UNLOCK(procp);
-		error =3D textvp_fullpath(procp, &fullpath, &freepath);
-		if (error !=3D 0)
-			return (uiomove("unknown", sizeof("unknown") - 1,
-			    ap->a_uio));
-		error =3D uiomove(fullpath, strlen(fullpath), ap->a_uio);
-		free(freepath, M_TEMP);
-		return (error);
-	default:
-		return (EINVAL);
-	}
-}
-
-/*
- * convert decimal ascii to pid_t
- */
-static pid_t
-atopid(b, len)
-	const char *b;
-	u_int len;
-{
-	pid_t p =3D 0;
-
-	while (len--) {
-		char c =3D *b++;
-		if (c < '0' || c > '9')
-			return (NO_PID);
-		p =3D 10 * p + (c - '0');
-		if (p > PID_MAX)
-			return (NO_PID);
-	}
-
-	return (p);
-}
-
-/*
- * procfs vnode operations.
- */
-vop_t **procfs_vnodeop_p;
-static struct vnodeopv_entry_desc procfs_vnodeop_entries[] =3D {
-	{ &vop_default_desc,		(vop_t *) vop_defaultop },
-	{ &vop_access_desc,		(vop_t *) procfs_access },
-	{ &vop_advlock_desc,		(vop_t *) procfs_badop },
-	{ &vop_close_desc,		(vop_t *) procfs_close },
-	{ &vop_create_desc,		(vop_t *) procfs_badop },
-	{ &vop_getattr_desc,		(vop_t *) procfs_getattr },
-	{ &vop_link_desc,		(vop_t *) procfs_badop },
-	{ &vop_lookup_desc,		(vop_t *) procfs_lookup },
-	{ &vop_mkdir_desc,		(vop_t *) procfs_badop },
-	{ &vop_mknod_desc,		(vop_t *) procfs_badop },
-	{ &vop_open_desc,		(vop_t *) procfs_open },
-	{ &vop_pathconf_desc,		(vop_t *) vop_stdpathconf },
-	{ &vop_print_desc,		(vop_t *) procfs_print },
-	{ &vop_read_desc,		(vop_t *) procfs_rw },
-	{ &vop_readdir_desc,		(vop_t *) procfs_readdir },
-	{ &vop_readlink_desc,		(vop_t *) procfs_readlink },
-	{ &vop_reclaim_desc,		(vop_t *) procfs_reclaim },
-	{ &vop_remove_desc,		(vop_t *) procfs_badop },
-	{ &vop_rename_desc,		(vop_t *) procfs_badop },
-	{ &vop_rmdir_desc,		(vop_t *) procfs_badop },
-	{ &vop_setattr_desc,		(vop_t *) procfs_setattr },
-	{ &vop_symlink_desc,		(vop_t *) procfs_badop },
-	{ &vop_write_desc,		(vop_t *) procfs_rw },
-	{ &vop_ioctl_desc,		(vop_t *) procfs_ioctl },
-	{ NULL, NULL }
-};
-static struct vnodeopv_desc procfs_vnodeop_opv_desc =3D
-	{ &procfs_vnodeop_p, procfs_vnodeop_entries };
-
-VNODEOP_SET(procfs_vnodeop_opv_desc);
Index: sys/modules/Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/modules/Makefile,v
retrieving revision 1.213
diff -u -r1.213 Makefile
--- sys/modules/Makefile	28 Oct 2001 04:34:24 -0000	1.213
+++ sys/modules/Makefile	29 Oct 2001 18:56:44 -0000
@@ -61,7 +61,6 @@
 	nullfs \
 	pcn \
 	portalfs \
-	procfs \
 	${_random} \
 	rl \
 	rp \
Index: sys/modules/fs/Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /home/ncvs/src/sys/modules/fs/Makefile,v
retrieving revision 1.3
diff -u -r1.3 Makefile
--- sys/modules/fs/Makefile	11 Jun 2001 21:57:18 -0000	1.3
+++ sys/modules/fs/Makefile	1 Jul 2001 22:33:41 -0000
@@ -2,6 +2,7 @@
=20
 SUBDIR =3D
 SUBDIR +=3D linprocfs
+SUBDIR +=3D procfs
 SUBDIR +=3D pseudofs
=20
 .include <bsd.subdir.mk>
Index: sys/modules/fs/procfs/Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: sys/modules/fs/procfs/Makefile
diff -N sys/modules/fs/procfs/Makefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/modules/fs/procfs/Makefile	5 Oct 2001 11:07:29 -0000
@@ -0,0 +1,19 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../fs/procfs
+
+KMOD=3D	procfs
+SRCS=3D	vnode_if.h \
+	procfs_ctl.c \
+	procfs_dbregs.c \
+	procfs_fpregs.c \
+	procfs_map.c \
+	procfs_mem.c \
+	procfs_note.c \
+	procfs_regs.c \
+	procfs_rlimit.c \
+	procfs_status.c \
+	procfs_type.c \
+	procfs.c
+
+.include <bsd.kmod.mk>

--=-=-=--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzpr8rlytij.fsf>