summaryrefslogtreecommitdiffstats
path: root/sys/fs/procfs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/procfs')
-rw-r--r--sys/fs/procfs/README113
-rw-r--r--sys/fs/procfs/procfs.c212
-rw-r--r--sys/fs/procfs/procfs.h65
-rw-r--r--sys/fs/procfs/procfs_ctl.c358
-rw-r--r--sys/fs/procfs/procfs_dbregs.c133
-rw-r--r--sys/fs/procfs/procfs_fpregs.c132
-rw-r--r--sys/fs/procfs/procfs_ioctl.c220
-rw-r--r--sys/fs/procfs/procfs_map.c244
-rw-r--r--sys/fs/procfs/procfs_mem.c71
-rw-r--r--sys/fs/procfs/procfs_note.c53
-rw-r--r--sys/fs/procfs/procfs_osrel.c68
-rw-r--r--sys/fs/procfs/procfs_regs.c132
-rw-r--r--sys/fs/procfs/procfs_rlimit.c114
-rw-r--r--sys/fs/procfs/procfs_status.c197
-rw-r--r--sys/fs/procfs/procfs_type.c56
15 files changed, 2168 insertions, 0 deletions
diff --git a/sys/fs/procfs/README b/sys/fs/procfs/README
new file mode 100644
index 0000000..f816b32
--- /dev/null
+++ b/sys/fs/procfs/README
@@ -0,0 +1,113 @@
+saute procfs lyonnais
+
+procfs supports two levels of directory. the filesystem root
+directory contains a representation of the system process table.
+this consists of an entry for each active and zombie process, and
+an additional entry "curproc" which always represents the process
+making the lookup request.
+
+each of the sub-directories contains several files. these files
+are used to control and interrogate processes. the files implemented
+are:
+
+ file - xxx. the exec'ed file.
+
+ status - r/o. returns process status.
+
+ ctl - w/o. sends a control message to the process.
+ for example:
+ echo hup > /proc/curproc/note
+ will send a SIGHUP to the shell.
+ whereas
+ echo attach > /proc/1293/ctl
+ would set up process 1293 for debugging.
+ see below for more details.
+
+ mem - r/w. virtual memory image of the process.
+ parts of the address space are readable
+ only if they exist in the target process.
+ a more reasonable alternative might be
+ to return zero pages instead of an error.
+ comments?
+
+ note - w/o. writing a string here sends the
+ equivalent note to the process.
+ [ not implemented. ]
+
+ notepg - w/o. the same as note, but sends to all
+ members of the process group.
+ [ not implemented. ]
+
+ regs - r/w. process register set. this can be read
+ or written any time even if the process
+ is not stopped. since the bsd kernel
+ is single-processor, this implementation
+ will get the "right" register values.
+ a multi-proc kernel would need to do some
+ synchronisation.
+
+this then looks like:
+
+% ls -li /proc
+total 0
+ 9 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 0
+ 17 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 1
+ 89 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 10
+ 25 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 2
+2065 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 257
+2481 dr-xr-xr-x 2 jsp staff 0 Sep 21 15:06 309
+ 265 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 32
+3129 dr-xr-xr-x 2 jsp staff 0 Sep 21 15:06 390
+3209 dr-xr-xr-x 2 jsp staff 0 Sep 21 15:06 400
+3217 dr-xr-xr-x 2 jsp staff 0 Sep 21 15:06 401
+3273 dr-xr-xr-x 2 jsp staff 0 Sep 21 15:06 408
+ 393 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 48
+ 409 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 50
+ 465 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 57
+ 481 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 59
+ 537 dr-xr-xr-x 2 root kmem 0 Sep 21 15:06 66
+ 545 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 67
+ 657 dr-xr-xr-x 2 jsp staff 0 Sep 21 15:06 81
+ 665 dr-xr-xr-x 2 jsp staff 0 Sep 21 15:06 82
+ 673 dr-xr-xr-x 2 jsp staff 0 Sep 21 15:06 83
+ 681 dr-xr-xr-x 2 root wheel 0 Sep 21 15:06 84
+3273 dr-xr-xr-x 2 jsp staff 0 Sep 21 15:06 curproc
+% ls -li /proc/curproc
+total 408
+3341 --w------- 1 jsp staff 0 Sep 21 15:06 ctl
+1554 -r-xr-xr-x 1 bin bin 90112 Mar 29 04:52 file
+3339 -rw------- 1 jsp staff 118784 Sep 21 15:06 mem
+3343 --w------- 1 jsp staff 0 Sep 21 15:06 note
+3344 --w------- 1 jsp staff 0 Sep 21 15:06 notepg
+3340 -rw------- 1 jsp staff 0 Sep 21 15:06 regs
+3342 -r--r--r-- 1 jsp staff 0 Sep 21 15:06 status
+% df /proc/curproc /proc/curproc/file
+Filesystem 512-blocks Used Avail Capacity Mounted on
+proc 2 2 0 100% /proc
+/dev/wd0a 16186 13548 1018 93% /
+% cat /proc/curproc/status
+cat 446 439 400 81 12,0 ctty 748620684 270000 0 0 0 20000 nochan 11 20 20 20 0 21 117
+
+
+
+the basic sequence of commands written to "ctl" would be
+
+ attach - this stops the target process and
+ arranges for the sending process
+ to become the debug control process
+ wait - wait for the target process to come to
+ a steady state ready for debugging.
+ step - single step, with no signal delivery.
+ run - continue running, with no signal delivery,
+ until next trap or breakpoint.
+ <signame> - deliver signal <signame> and continue running.
+ detach - continue execution of the target process
+ and remove it from control by the debug process
+
+in a normal debugging environment, where the target is fork/exec'd by
+the debugger, the debugger should fork and the child should stop itself
+(with a self-inflicted SIGSTOP). the parent should do a "wait" then an
+"attach". as before, the child will hit a breakpoint on the first
+instruction in any newly exec'd image.
+
+$FreeBSD$
diff --git a/sys/fs/procfs/procfs.c b/sys/fs/procfs/procfs.c
new file mode 100644
index 0000000..a41e7d1
--- /dev/null
+++ b/sys/fs/procfs/procfs.c
@@ -0,0 +1,212 @@
+/*-
+ * Copyright (c) 2001 Dag-Erling Smørgrav
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * 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/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
+ */
+int
+procfs_doprocfile(PFS_FILL_ARGS)
+{
+ char *fullpath;
+ char *freepath;
+ struct vnode *textvp;
+ int error;
+
+ freepath = NULL;
+ PROC_LOCK(p);
+ textvp = p->p_textvp;
+ vhold(textvp);
+ PROC_UNLOCK(p);
+ error = vn_fullpath(td, textvp, &fullpath, &freepath);
+ vdrop(textvp);
+ if (error == 0)
+ sbuf_printf(sb, "%s", fullpath);
+ if (freepath != NULL)
+ free(freepath, M_TEMP);
+ return (error);
+}
+
+/*
+ * Filler function for proc/curproc
+ */
+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") == 0 ||
+ strcmp(pn->pn_name, "note") == 0 ||
+ strcmp(pn->pn_name, "notepg") == 0)
+ vap->va_mode = 0200;
+ else if (strcmp(pn->pn_name, "mem") == 0 ||
+ strcmp(pn->pn_name, "regs") == 0 ||
+ strcmp(pn->pn_name, "dbregs") == 0 ||
+ strcmp(pn->pn_name, "fpregs") == 0 ||
+ strcmp(pn->pn_name, "osrel") == 0)
+ vap->va_mode = 0600;
+
+ if (p != NULL) {
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ if ((p->p_flag & P_SUGID) && pn->pn_type != pfstype_procdir)
+ vap->va_mode = 0;
+ }
+
+ return (0);
+}
+
+/*
+ * Visibility: some files only exist for non-system processes
+ * Non-static because linprocfs uses it.
+ */
+int
+procfs_notsystem(PFS_VIS_ARGS)
+{
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ return ((p->p_flag & P_SYSTEM) == 0);
+}
+
+/*
+ * Visibility: some files are only visible to process that can debug
+ * the target process.
+ */
+int
+procfs_candebug(PFS_VIS_ARGS)
+{
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ return ((p->p_flag & P_SYSTEM) == 0 && p_candebug(td, p) == 0);
+}
+
+/*
+ * Constructor
+ */
+static int
+procfs_init(PFS_INIT_ARGS)
+{
+ struct pfs_node *root;
+ struct pfs_node *dir;
+ struct pfs_node *node;
+
+ root = pi->pi_root;
+
+ pfs_create_link(root, "curproc", procfs_docurproc,
+ NULL, NULL, NULL, 0);
+
+ dir = pfs_create_dir(root, "pid",
+ procfs_attr, NULL, NULL, PFS_PROCDEP);
+ pfs_create_file(dir, "cmdline", procfs_doproccmdline,
+ NULL, NULL, NULL, PFS_RD);
+ pfs_create_file(dir, "ctl", procfs_doprocctl,
+ procfs_attr, NULL, NULL, PFS_WR);
+ pfs_create_file(dir, "dbregs", procfs_doprocdbregs,
+ procfs_attr, procfs_candebug, NULL, PFS_RDWR|PFS_RAW);
+ pfs_create_file(dir, "etype", procfs_doproctype,
+ NULL, NULL, NULL, PFS_RD);
+ pfs_create_file(dir, "fpregs", procfs_doprocfpregs,
+ procfs_attr, procfs_candebug, NULL, PFS_RDWR|PFS_RAW);
+ pfs_create_file(dir, "map", procfs_doprocmap,
+ NULL, procfs_notsystem, NULL, PFS_RD);
+ node = pfs_create_file(dir, "mem", procfs_doprocmem,
+ procfs_attr, procfs_candebug, NULL, PFS_RDWR|PFS_RAW);
+ node->pn_ioctl = procfs_ioctl;
+ node->pn_close = procfs_close;
+ pfs_create_file(dir, "note", procfs_doprocnote,
+ procfs_attr, procfs_candebug, NULL, PFS_WR);
+ pfs_create_file(dir, "notepg", procfs_doprocnote,
+ procfs_attr, procfs_candebug, NULL, PFS_WR);
+ pfs_create_file(dir, "regs", procfs_doprocregs,
+ procfs_attr, procfs_candebug, NULL, PFS_RDWR|PFS_RAW);
+ pfs_create_file(dir, "rlimit", procfs_doprocrlimit,
+ NULL, NULL, NULL, PFS_RD);
+ pfs_create_file(dir, "status", procfs_doprocstatus,
+ NULL, NULL, NULL, PFS_RD);
+ pfs_create_file(dir, "osrel", procfs_doosrel,
+ procfs_attr, procfs_candebug, NULL, PFS_RDWR);
+
+ pfs_create_link(dir, "file", procfs_doprocfile,
+ NULL, procfs_notsystem, NULL, 0);
+
+ return (0);
+}
+
+/*
+ * Destructor
+ */
+static int
+procfs_uninit(PFS_INIT_ARGS)
+{
+ /* nothing to do, pseudofs will GC */
+ return (0);
+}
+
+PSEUDOFS(procfs, 1, PR_ALLOW_MOUNT_PROCFS);
diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h
new file mode 100644
index 0000000..2598224
--- /dev/null
+++ b/sys/fs/procfs/procfs.h
@@ -0,0 +1,65 @@
+/*-
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)procfs.h 8.9 (Berkeley) 5/14/95
+ *
+ * From:
+ * $FreeBSD$
+ */
+
+#ifdef _KERNEL
+
+int procfs_docurproc(PFS_FILL_ARGS);
+int procfs_doosrel(PFS_FILL_ARGS);
+int procfs_doproccmdline(PFS_FILL_ARGS);
+int procfs_doprocctl(PFS_FILL_ARGS);
+int procfs_doprocdbregs(PFS_FILL_ARGS);
+int procfs_doprocfile(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);
+int procfs_ioctl(PFS_IOCTL_ARGS);
+int procfs_close(PFS_CLOSE_ARGS);
+
+/* Attributes */
+int procfs_attr(PFS_ATTR_ARGS);
+
+/* Visibility */
+int procfs_notsystem(PFS_VIS_ARGS);
+int procfs_candebug(PFS_VIS_ARGS);
+
+#endif /* _KERNEL */
diff --git a/sys/fs/procfs/procfs_ctl.c b/sys/fs/procfs/procfs_ctl.c
new file mode 100644
index 0000000..dc267f6
--- /dev/null
+++ b/sys/fs/procfs/procfs_ctl.c
@@ -0,0 +1,358 @@
+/*-
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)procfs_ctl.c 8.4 (Berkeley) 6/15/94
+ *
+ * From:
+ * $Id: procfs_ctl.c,v 1.51 2003/12/07 17:40:00 des Exp $
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.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/uio.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+#include <vm/vm.h>
+
+/*
+ * True iff process (p) is in trace wait state
+ * relative to process (curp)
+ */
+#define TRACE_WAIT_P(curp, p) \
+ (P_SHOULDSTOP(p) && \
+ (p)->p_pptr == (curp) && \
+ ((p)->p_flag & P_TRACED))
+
+#define PROCFS_CTL_ATTACH 1
+#define PROCFS_CTL_DETACH 2
+#define PROCFS_CTL_STEP 3
+#define PROCFS_CTL_RUN 4
+#define PROCFS_CTL_WAIT 5
+
+struct namemap {
+ const char *nm_name;
+ int nm_val;
+};
+
+static struct namemap ctlnames[] = {
+ /* special /proc commands */
+ { "attach", PROCFS_CTL_ATTACH },
+ { "detach", PROCFS_CTL_DETACH },
+ { "step", PROCFS_CTL_STEP },
+ { "run", PROCFS_CTL_RUN },
+ { "wait", PROCFS_CTL_WAIT },
+ { 0 },
+};
+
+static struct namemap signames[] = {
+ /* regular signal names */
+ { "hup", SIGHUP }, { "int", SIGINT },
+ { "quit", SIGQUIT }, { "ill", SIGILL },
+ { "trap", SIGTRAP }, { "abrt", SIGABRT },
+ { "iot", SIGIOT }, { "emt", SIGEMT },
+ { "fpe", SIGFPE }, { "kill", SIGKILL },
+ { "bus", SIGBUS }, { "segv", SIGSEGV },
+ { "sys", SIGSYS }, { "pipe", SIGPIPE },
+ { "alrm", SIGALRM }, { "term", SIGTERM },
+ { "urg", SIGURG }, { "stop", SIGSTOP },
+ { "tstp", SIGTSTP }, { "cont", SIGCONT },
+ { "chld", SIGCHLD }, { "ttin", SIGTTIN },
+ { "ttou", SIGTTOU }, { "io", SIGIO },
+ { "xcpu", SIGXCPU }, { "xfsz", SIGXFSZ },
+ { "vtalrm", SIGVTALRM }, { "prof", SIGPROF },
+ { "winch", SIGWINCH }, { "info", SIGINFO },
+ { "usr1", SIGUSR1 }, { "usr2", SIGUSR2 },
+ { 0 },
+};
+
+static int procfs_control(struct thread *td, struct proc *p, int op);
+
+static int
+procfs_control(struct thread *td, struct proc *p, int op)
+{
+ int error = 0;
+ struct thread *temp;
+
+ /*
+ * Attach - attaches the target process for debugging
+ * by the calling process.
+ */
+ if (op == PROCFS_CTL_ATTACH) {
+ sx_xlock(&proctree_lock);
+ PROC_LOCK(p);
+ if ((error = p_candebug(td, p)) != 0)
+ goto out;
+ if (p->p_flag & P_TRACED) {
+ error = EBUSY;
+ goto out;
+ }
+
+ /* Can't trace yourself! */
+ if (p->p_pid == td->td_proc->p_pid) {
+ error = EINVAL;
+ goto out;
+ }
+
+ /*
+ * Go ahead and set the trace flag.
+ * Save the old parent (it's reset in
+ * _DETACH, and also in kern_exit.c:wait4()
+ * Reparent the process so that the tracing
+ * proc gets to see all the action.
+ * Stop the target.
+ */
+ p->p_flag |= P_TRACED;
+ faultin(p);
+ p->p_xstat = 0; /* XXX ? */
+ if (p->p_pptr != td->td_proc) {
+ p->p_oppid = p->p_pptr->p_pid;
+ proc_reparent(p, td->td_proc);
+ }
+ kern_psignal(p, SIGSTOP);
+out:
+ PROC_UNLOCK(p);
+ sx_xunlock(&proctree_lock);
+ return (error);
+ }
+
+ /*
+ * Authorization check: rely on normal debugging protection, except
+ * allow processes to disengage debugging on a process onto which
+ * they have previously attached, but no longer have permission to
+ * debug.
+ */
+ PROC_LOCK(p);
+ if (op != PROCFS_CTL_DETACH &&
+ ((error = p_candebug(td, p)))) {
+ PROC_UNLOCK(p);
+ return (error);
+ }
+
+ /*
+ * Target process must be stopped, owned by (td) and
+ * be set up for tracing (P_TRACED flag set).
+ * Allow DETACH to take place at any time for sanity.
+ * Allow WAIT any time, of course.
+ */
+ switch (op) {
+ case PROCFS_CTL_DETACH:
+ case PROCFS_CTL_WAIT:
+ break;
+
+ default:
+ if (!TRACE_WAIT_P(td->td_proc, p)) {
+ PROC_UNLOCK(p);
+ return (EBUSY);
+ }
+ }
+
+
+#ifdef FIX_SSTEP
+ /*
+ * do single-step fixup if needed
+ */
+ FIX_SSTEP(FIRST_THREAD_IN_PROC(p));
+#endif
+
+ /*
+ * Don't deliver any signal by default.
+ * To continue with a signal, just send
+ * the signal name to the ctl file
+ */
+ p->p_xstat = 0;
+
+ switch (op) {
+ /*
+ * Detach. Cleans up the target process, reparent it if possible
+ * and set it running once more.
+ */
+ case PROCFS_CTL_DETACH:
+ /* if not being traced, then this is a painless no-op */
+ if ((p->p_flag & P_TRACED) == 0) {
+ PROC_UNLOCK(p);
+ return (0);
+ }
+
+ /* not being traced any more */
+ p->p_flag &= ~(P_TRACED | P_STOPPED_TRACE);
+
+ /* remove pending SIGTRAP, else the process will die */
+ sigqueue_delete_proc(p, SIGTRAP);
+ FOREACH_THREAD_IN_PROC(p, temp)
+ temp->td_dbgflags &= ~TDB_SUSPEND;
+ PROC_UNLOCK(p);
+
+ /* give process back to original parent */
+ sx_xlock(&proctree_lock);
+ if (p->p_oppid != p->p_pptr->p_pid) {
+ struct proc *pp;
+
+ pp = pfind(p->p_oppid);
+ PROC_LOCK(p);
+ if (pp) {
+ PROC_UNLOCK(pp);
+ proc_reparent(p, pp);
+ }
+ } else
+ PROC_LOCK(p);
+ p->p_oppid = 0;
+ p->p_flag &= ~P_WAITED; /* XXX ? */
+ sx_xunlock(&proctree_lock);
+
+ wakeup(td->td_proc); /* XXX for CTL_WAIT below ? */
+
+ break;
+
+ /*
+ * Step. Let the target process execute a single instruction.
+ * What does it mean to single step a threaded program?
+ */
+ case PROCFS_CTL_STEP:
+ error = proc_sstep(FIRST_THREAD_IN_PROC(p));
+ if (error) {
+ PROC_UNLOCK(p);
+ return (error);
+ }
+ break;
+
+ /*
+ * Run. Let the target process continue running until a breakpoint
+ * or some other trap.
+ */
+ case PROCFS_CTL_RUN:
+ p->p_flag &= ~P_STOPPED_SIG; /* this uses SIGSTOP */
+ break;
+
+ /*
+ * Wait for the target process to stop.
+ * If the target is not being traced then just wait
+ * to enter
+ */
+ case PROCFS_CTL_WAIT:
+ if (p->p_flag & P_TRACED) {
+ while (error == 0 &&
+ (P_SHOULDSTOP(p)) &&
+ (p->p_flag & P_TRACED) &&
+ (p->p_pptr == td->td_proc))
+ error = msleep(p, &p->p_mtx,
+ PWAIT|PCATCH, "procfsx", 0);
+ if (error == 0 && !TRACE_WAIT_P(td->td_proc, p))
+ error = EBUSY;
+ } else {
+ while (error == 0 && P_SHOULDSTOP(p))
+ error = msleep(p, &p->p_mtx,
+ PWAIT|PCATCH, "procfs", 0);
+ }
+ PROC_UNLOCK(p);
+ return (error);
+ default:
+ panic("procfs_control");
+ }
+
+ PROC_SLOCK(p);
+ thread_unsuspend(p); /* If it can run, let it do so. */
+ PROC_SUNLOCK(p);
+ PROC_UNLOCK(p);
+ return (0);
+}
+
+static struct namemap *
+findname(struct namemap *nm, char *buf, int buflen)
+{
+
+ for (; nm->nm_name; nm++)
+ if (bcmp(buf, nm->nm_name, buflen+1) == 0)
+ return (nm);
+
+ return (0);
+}
+
+int
+procfs_doprocctl(PFS_FILL_ARGS)
+{
+ int error;
+ struct namemap *nm;
+
+ if (uio == NULL || uio->uio_rw != UIO_WRITE)
+ return (EOPNOTSUPP);
+
+ /*
+ * Map signal names into signal generation
+ * or debug control. Unknown commands and/or signals
+ * return EOPNOTSUPP.
+ *
+ * Sending a signal while the process is being debugged
+ * also has the side effect of letting the target continue
+ * to run. There is no way to single-step a signal delivery.
+ */
+ error = EOPNOTSUPP;
+
+ sbuf_trim(sb);
+ sbuf_finish(sb);
+ nm = findname(ctlnames, sbuf_data(sb), sbuf_len(sb));
+ if (nm) {
+ printf("procfs: got a %s command\n", sbuf_data(sb));
+ error = procfs_control(td, p, nm->nm_val);
+ } else {
+ nm = findname(signames, sbuf_data(sb), sbuf_len(sb));
+ if (nm) {
+ printf("procfs: got a sig%s\n", sbuf_data(sb));
+ PROC_LOCK(p);
+
+ if (TRACE_WAIT_P(td->td_proc, p)) {
+ p->p_xstat = nm->nm_val;
+#ifdef FIX_SSTEP
+ FIX_SSTEP(FIRST_THREAD_IN_PROC(p));
+#endif
+ p->p_flag &= ~P_STOPPED_SIG;
+ PROC_SLOCK(p);
+ thread_unsuspend(p);
+ PROC_SUNLOCK(p);
+ } else
+ kern_psignal(p, nm->nm_val);
+ PROC_UNLOCK(p);
+ error = 0;
+ }
+ }
+
+ return (error);
+}
diff --git a/sys/fs/procfs/procfs_dbregs.c b/sys/fs/procfs/procfs_dbregs.c
new file mode 100644
index 0000000..de5dc76
--- /dev/null
+++ b/sys/fs/procfs/procfs_dbregs.c
@@ -0,0 +1,133 @@
+/*-
+ * Copyright (c) 1999 Brian Scott Dean, brdean@unx.sas.com.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jan-Simon Pendry under the following copyrights and conditions:
+ *
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * From: @(#)procfs_regs.c 8.4 (Berkeley) 6/15/94
+ *
+ * From:
+ * $Id: procfs_regs.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
+ * $FreeBSD$
+ */
+
+#include "opt_compat.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/sysent.h>
+#include <sys/uio.h>
+
+#include <machine/reg.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+#ifdef COMPAT_FREEBSD32
+#include <sys/procfs.h>
+#include <machine/fpu.h>
+
+/*
+ * PROC(write, dbregs, td2, &r) becomes
+ * proc_write_dbregs(td2, &r) or
+ * proc_write_dbregs32(td2, &r32)
+ *
+ * UIOMOVE_FROMBUF(r, uio) becomes
+ * uiomove_frombuf(&r, sizeof(r), uio) or
+ * uiomove_frombuf(&r32, sizeof(r32), uio)
+ */
+#define PROC(d, w, t, r) wrap32 ? \
+ proc_ ## d ## _ ## w ## 32(t, r ## 32) : \
+ proc_ ## d ## _ ## w(t, r)
+#define UIOMOVE_FROMBUF(k, u) wrap32 ? \
+ uiomove_frombuf(& k ## 32, sizeof(k ## 32), u) : \
+ uiomove_frombuf(& k, sizeof(k), u)
+#else
+#define PROC(d, w, t, r) proc_ ## d ## _ ## w(t, r)
+#define UIOMOVE_FROMBUF(k, u) uiomove_frombuf(& k, sizeof(k), u)
+#endif
+
+int
+procfs_doprocdbregs(PFS_FILL_ARGS)
+{
+ int error;
+ struct dbreg r;
+ struct thread *td2;
+#ifdef COMPAT_FREEBSD32
+ struct dbreg32 r32;
+ int wrap32 = 0;
+#endif
+
+ if (uio->uio_offset != 0)
+ return (0);
+
+ PROC_LOCK(p);
+ KASSERT(p->p_lock > 0, ("proc not held"));
+ if (p_candebug(td, p) != 0) {
+ PROC_UNLOCK(p);
+ return (EPERM);
+ }
+
+ td2 = FIRST_THREAD_IN_PROC(p);
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ if (SV_PROC_FLAG(td2->td_proc, SV_ILP32) == 0) {
+ PROC_UNLOCK(p);
+ return (EINVAL);
+ }
+ wrap32 = 1;
+ }
+#endif
+ error = PROC(read, dbregs, td2, &r);
+ if (error == 0) {
+ PROC_UNLOCK(p);
+ error = UIOMOVE_FROMBUF(r, uio);
+ PROC_LOCK(p);
+ }
+ if (error == 0 && uio->uio_rw == UIO_WRITE) {
+ if (!P_SHOULDSTOP(p)) /* XXXKSE should be P_TRACED? */
+ error = EBUSY;
+ else
+ /* XXXKSE: */
+ error = PROC(write, dbregs, td2, &r);
+ }
+ PROC_UNLOCK(p);
+
+ return (error);
+}
diff --git a/sys/fs/procfs/procfs_fpregs.c b/sys/fs/procfs/procfs_fpregs.c
new file mode 100644
index 0000000..c89c8e7
--- /dev/null
+++ b/sys/fs/procfs/procfs_fpregs.c
@@ -0,0 +1,132 @@
+/*-
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)procfs_fpregs.c 8.2 (Berkeley) 6/15/94
+ *
+ * From:
+ * $Id: procfs_regs.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
+ * $FreeBSD$
+ */
+
+#include "opt_compat.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/sysent.h>
+#include <sys/uio.h>
+
+#include <machine/reg.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+#ifdef COMPAT_FREEBSD32
+#include <sys/procfs.h>
+#include <machine/fpu.h>
+
+/*
+ * PROC(write, fpregs, td2, &r) becomes
+ * proc_write_fpregs(td2, &r) or
+ * proc_write_fpregs32(td2, &r32)
+ *
+ * UIOMOVE_FROMBUF(r, uio) becomes
+ * uiomove_frombuf(&r, sizeof(r), uio) or
+ * uiomove_frombuf(&r32, sizeof(r32), uio)
+ */
+#define PROC(d, w, t, r) wrap32 ? \
+ proc_ ## d ## _ ## w ## 32(t, r ## 32) : \
+ proc_ ## d ## _ ## w(t, r)
+#define UIOMOVE_FROMBUF(k, u) wrap32 ? \
+ uiomove_frombuf(& k ## 32, sizeof(k ## 32), u) : \
+ uiomove_frombuf(& k, sizeof(k), u)
+#else
+#define PROC(d, w, t, r) proc_ ## d ## _ ## w(t, r)
+#define UIOMOVE_FROMBUF(k, u) uiomove_frombuf(& k, sizeof(k), u)
+#endif
+
+int
+procfs_doprocfpregs(PFS_FILL_ARGS)
+{
+ int error;
+ struct fpreg r;
+ struct thread *td2;
+#ifdef COMPAT_FREEBSD32
+ struct fpreg32 r32;
+ int wrap32 = 0;
+#endif
+
+ if (uio->uio_offset != 0)
+ return (0);
+
+ PROC_LOCK(p);
+ KASSERT(p->p_lock > 0, ("proc not held"));
+ if (p_candebug(td, p)) {
+ PROC_UNLOCK(p);
+ return (EPERM);
+ }
+ if (!P_SHOULDSTOP(p)) {
+ PROC_UNLOCK(p);
+ return (EBUSY);
+ }
+
+ /* XXXKSE: */
+ td2 = FIRST_THREAD_IN_PROC(p);
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ if (SV_PROC_FLAG(td2->td_proc, SV_ILP32) == 0) {
+ PROC_UNLOCK(p);
+ return (EINVAL);
+ }
+ wrap32 = 1;
+ }
+#endif
+ error = PROC(read, fpregs, td2, &r);
+ if (error == 0) {
+ PROC_UNLOCK(p);
+ error = UIOMOVE_FROMBUF(r, uio);
+ PROC_LOCK(p);
+ }
+ if (error == 0 && uio->uio_rw == UIO_WRITE) {
+ if (!P_SHOULDSTOP(p))
+ error = EBUSY;
+ else
+ /* XXXKSE: */
+ error = PROC(write, fpregs, td2, &r);
+ }
+ PROC_UNLOCK(p);
+
+ return (error);
+}
diff --git a/sys/fs/procfs/procfs_ioctl.c b/sys/fs/procfs/procfs_ioctl.c
new file mode 100644
index 0000000..3fa00bc
--- /dev/null
+++ b/sys/fs/procfs/procfs_ioctl.c
@@ -0,0 +1,220 @@
+/*-
+ * Copyright (c) 2001 Dag-Erling Coïdan Smørgrav
+ * All rights reserved.
+ *
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 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, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include "opt_compat.h"
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/pioctl.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/systm.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+#ifdef COMPAT_FREEBSD32
+struct procfs_status32 {
+ int state; /* Running, stopped, something else? */
+ int flags; /* Any flags */
+ unsigned int events; /* Events to stop on */
+ int why; /* What event, if any, proc stopped on */
+ unsigned int val; /* Any extra data */
+};
+
+#define PIOCWAIT32 _IOR('p', 4, struct procfs_status32)
+#define PIOCSTATUS32 _IOR('p', 6, struct procfs_status32)
+#endif
+
+/*
+ * Process ioctls
+ */
+int
+procfs_ioctl(PFS_IOCTL_ARGS)
+{
+ struct procfs_status *ps;
+#ifdef COMPAT_FREEBSD32
+ struct procfs_status32 *ps32;
+#endif
+ int error, flags, sig;
+#ifdef COMPAT_FREEBSD6
+ int ival;
+#endif
+
+ KASSERT(p != NULL,
+ ("%s() called without a process", __func__));
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ error = 0;
+ switch (cmd) {
+#if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+ case _IOC(IOC_IN, 'p', 1, 0):
+#endif
+#ifdef COMPAT_FREEBSD6
+ case _IO('p', 1):
+ ival = IOCPARM_IVAL(data);
+ data = &ival;
+#endif
+ case PIOCBIS:
+ p->p_stops |= *(unsigned int *)data;
+ break;
+#if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+ case _IOC(IOC_IN, 'p', 2, 0):
+#endif
+#ifdef COMPAT_FREEBSD6
+ case _IO('p', 2):
+ ival = IOCPARM_IVAL(data);
+ data = &ival;
+#endif
+ case PIOCBIC:
+ p->p_stops &= ~*(unsigned int *)data;
+ break;
+#if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+ case _IOC(IOC_IN, 'p', 3, 0):
+#endif
+#ifdef COMPAT_FREEBSD6
+ case _IO('p', 3):
+ ival = IOCPARM_IVAL(data);
+ data = &ival;
+#endif
+ case PIOCSFL:
+ flags = *(unsigned int *)data;
+ if (flags & PF_ISUGID) {
+ /*
+ * XXXRW: Is this specific check required here, as
+ * p_candebug() should implement it, or other checks
+ * are missing.
+ */
+ error = priv_check(td, PRIV_DEBUG_SUGID);
+ if (error)
+ break;
+ }
+ p->p_pfsflags = flags;
+ break;
+ case PIOCGFL:
+ *(unsigned int *)data = p->p_pfsflags;
+ break;
+ case PIOCWAIT:
+ while (p->p_step == 0 && (p->p_flag & P_WEXIT) == 0) {
+ /* sleep until p stops */
+ _PHOLD(p);
+ error = msleep(&p->p_stype, &p->p_mtx,
+ PWAIT|PCATCH, "pioctl", 0);
+ _PRELE(p);
+ if (error != 0)
+ break;
+ }
+ /* fall through to PIOCSTATUS */
+ case PIOCSTATUS:
+ ps = (struct procfs_status *)data;
+ ps->state = (p->p_step == 0);
+ ps->flags = 0; /* nope */
+ ps->events = p->p_stops;
+ ps->why = p->p_step ? p->p_stype : 0;
+ ps->val = p->p_step ? p->p_xstat : 0;
+ break;
+#ifdef COMPAT_FREEBSD32
+ case PIOCWAIT32:
+ while (p->p_step == 0 && (p->p_flag & P_WEXIT) == 0) {
+ /* sleep until p stops */
+ _PHOLD(p);
+ error = msleep(&p->p_stype, &p->p_mtx,
+ PWAIT|PCATCH, "pioctl", 0);
+ _PRELE(p);
+ if (error != 0)
+ break;
+ }
+ /* fall through to PIOCSTATUS32 */
+ case PIOCSTATUS32:
+ ps32 = (struct procfs_status32 *)data;
+ ps32->state = (p->p_step == 0);
+ ps32->flags = 0; /* nope */
+ ps32->events = p->p_stops;
+ ps32->why = p->p_step ? p->p_stype : 0;
+ ps32->val = p->p_step ? p->p_xstat : 0;
+ break;
+#endif
+#if defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
+ case _IOC(IOC_IN, 'p', 5, 0):
+#endif
+#ifdef COMPAT_FREEBSD6
+ case _IO('p', 5):
+ ival = IOCPARM_IVAL(data);
+ data = &ival;
+#endif
+ case PIOCCONT:
+ if (p->p_step == 0)
+ break;
+ sig = *(unsigned int *)data;
+ if (sig != 0 && !_SIG_VALID(sig)) {
+ error = EINVAL;
+ break;
+ }
+#if 0
+ p->p_step = 0;
+ if (P_SHOULDSTOP(p)) {
+ p->p_xstat = sig;
+ p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG);
+ PROC_SLOCK(p);
+ thread_unsuspend(p);
+ PROC_SUNLOCK(p);
+ } else if (sig)
+ kern_psignal(p, sig);
+#else
+ if (sig)
+ kern_psignal(p, sig);
+ p->p_step = 0;
+ wakeup(&p->p_step);
+#endif
+ break;
+ default:
+ error = (ENOTTY);
+ }
+
+ return (error);
+}
+
+/*
+ * Clean up on last close
+ */
+int
+procfs_close(PFS_CLOSE_ARGS)
+{
+ if (p != NULL && (p->p_pfsflags & PF_LINGER) == 0) {
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ p->p_pfsflags = 0;
+ p->p_stops = 0;
+ p->p_step = 0;
+ wakeup(&p->p_step);
+ }
+ return (0);
+}
diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c
new file mode 100644
index 0000000..542c8fe
--- /dev/null
+++ b/sys/fs/procfs/procfs_map.c
@@ -0,0 +1,244 @@
+/*-
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)procfs_status.c 8.3 (Berkeley) 2/17/94
+ *
+ * $FreeBSD$
+ */
+
+#include "opt_compat.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/filedesc.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <sys/resourcevar.h>
+#include <sys/rwlock.h>
+#include <sys/sbuf.h>
+#ifdef COMPAT_FREEBSD32
+#include <sys/sysent.h>
+#endif
+#include <sys/uio.h>
+#include <sys/vnode.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_page.h>
+#include <vm/vm_object.h>
+
+#define MEBUFFERSIZE 256
+
+/*
+ * The map entries can *almost* be read with programs like cat. However,
+ * large maps need special programs to read. It is not easy to implement
+ * a program that can sense the required size of the buffer, and then
+ * subsequently do a read with the appropriate size. This operation cannot
+ * be atomic. The best that we can do is to allow the program to do a read
+ * with an arbitrarily large buffer, and return as much as we can. We can
+ * return an error code if the buffer is too small (EFBIG), then the program
+ * can try a bigger buffer.
+ */
+int
+procfs_doprocmap(PFS_FILL_ARGS)
+{
+ struct vmspace *vm;
+ vm_map_t map;
+ vm_map_entry_t entry, tmp_entry;
+ struct vnode *vp;
+ char *fullpath, *freepath;
+ struct ucred *cred;
+ int error;
+ unsigned int last_timestamp;
+#ifdef COMPAT_FREEBSD32
+ int wrap32 = 0;
+#endif
+
+ PROC_LOCK(p);
+ error = p_candebug(td, p);
+ PROC_UNLOCK(p);
+ if (error)
+ return (error);
+
+ if (uio->uio_rw != UIO_READ)
+ return (EOPNOTSUPP);
+
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ if (!(SV_PROC_FLAG(p, SV_ILP32)))
+ return (EOPNOTSUPP);
+ wrap32 = 1;
+ }
+#endif
+
+ vm = vmspace_acquire_ref(p);
+ if (vm == NULL)
+ return (ESRCH);
+ map = &vm->vm_map;
+ vm_map_lock_read(map);
+ for (entry = map->header.next; entry != &map->header;
+ entry = entry->next) {
+ vm_object_t obj, tobj, lobj;
+ int ref_count, shadow_count, flags;
+ vm_offset_t e_start, e_end, addr;
+ int resident, privateresident;
+ char *type;
+ vm_eflags_t e_eflags;
+ vm_prot_t e_prot;
+
+ if (entry->eflags & MAP_ENTRY_IS_SUB_MAP)
+ continue;
+
+ e_eflags = entry->eflags;
+ e_prot = entry->protection;
+ e_start = entry->start;
+ e_end = entry->end;
+ privateresident = 0;
+ obj = entry->object.vm_object;
+ if (obj != NULL) {
+ VM_OBJECT_WLOCK(obj);
+ if (obj->shadow_count == 1)
+ privateresident = obj->resident_page_count;
+ }
+ cred = (entry->cred) ? entry->cred : (obj ? obj->cred : NULL);
+
+ resident = 0;
+ addr = entry->start;
+ while (addr < entry->end) {
+ if (pmap_extract(map->pmap, addr))
+ resident++;
+ addr += PAGE_SIZE;
+ }
+
+ for (lobj = tobj = obj; tobj; tobj = tobj->backing_object) {
+ if (tobj != obj)
+ VM_OBJECT_WLOCK(tobj);
+ if (lobj != obj)
+ VM_OBJECT_WUNLOCK(lobj);
+ lobj = tobj;
+ }
+ last_timestamp = map->timestamp;
+ vm_map_unlock_read(map);
+
+ freepath = NULL;
+ fullpath = "-";
+ if (lobj) {
+ switch (lobj->type) {
+ default:
+ case OBJT_DEFAULT:
+ type = "default";
+ vp = NULL;
+ break;
+ case OBJT_VNODE:
+ type = "vnode";
+ vp = lobj->handle;
+ vref(vp);
+ break;
+ case OBJT_SWAP:
+ type = "swap";
+ vp = NULL;
+ break;
+ case OBJT_SG:
+ case OBJT_DEVICE:
+ type = "device";
+ vp = NULL;
+ break;
+ }
+ if (lobj != obj)
+ VM_OBJECT_WUNLOCK(lobj);
+
+ flags = obj->flags;
+ ref_count = obj->ref_count;
+ shadow_count = obj->shadow_count;
+ VM_OBJECT_WUNLOCK(obj);
+ if (vp != NULL) {
+ vn_fullpath(td, vp, &fullpath, &freepath);
+ vrele(vp);
+ }
+ } else {
+ type = "none";
+ flags = 0;
+ ref_count = 0;
+ shadow_count = 0;
+ }
+
+ /*
+ * format:
+ * start, end, resident, private resident, cow, access, type,
+ * charged, charged uid.
+ */
+ error = sbuf_printf(sb,
+ "0x%lx 0x%lx %d %d %p %s%s%s %d %d 0x%x %s %s %s %s %s %d\n",
+ (u_long)e_start, (u_long)e_end,
+ resident, privateresident,
+#ifdef COMPAT_FREEBSD32
+ wrap32 ? NULL : obj, /* Hide 64 bit value */
+#else
+ obj,
+#endif
+ (e_prot & VM_PROT_READ)?"r":"-",
+ (e_prot & VM_PROT_WRITE)?"w":"-",
+ (e_prot & VM_PROT_EXECUTE)?"x":"-",
+ ref_count, shadow_count, flags,
+ (e_eflags & MAP_ENTRY_COW)?"COW":"NCOW",
+ (e_eflags & MAP_ENTRY_NEEDS_COPY)?"NC":"NNC",
+ type, fullpath,
+ cred ? "CH":"NCH", cred ? cred->cr_ruid : -1);
+
+ if (freepath != NULL)
+ free(freepath, M_TEMP);
+ vm_map_lock_read(map);
+ if (error == -1) {
+ error = 0;
+ break;
+ }
+ if (last_timestamp != map->timestamp) {
+ /*
+ * Look again for the entry because the map was
+ * modified while it was unlocked. Specifically,
+ * the entry may have been clipped, merged, or deleted.
+ */
+ vm_map_lookup_entry(map, e_end - 1, &tmp_entry);
+ entry = tmp_entry;
+ }
+ }
+ vm_map_unlock_read(map);
+ vmspace_free(vm);
+ return (error);
+}
diff --git a/sys/fs/procfs/procfs_mem.c b/sys/fs/procfs/procfs_mem.c
new file mode 100644
index 0000000..d4a7896
--- /dev/null
+++ b/sys/fs/procfs/procfs_mem.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 1993 Jan-Simon Pendry
+ * Copyright (c) 1993 Sean Eric Fagan
+ * 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 and Sean Eric Fagan.
+ *
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)procfs_mem.c 8.5 (Berkeley) 6/15/94
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+/*
+ * Copy data in and out of the target process.
+ * We do this by mapping the process's page into
+ * the kernel and then doing a uiomove direct
+ * from the kernel address space.
+ */
+int
+procfs_doprocmem(PFS_FILL_ARGS)
+{
+ int error;
+
+ if (uio->uio_resid == 0)
+ return (0);
+
+ PROC_LOCK(p);
+ error = p_candebug(td, p);
+ PROC_UNLOCK(p);
+ if (error == 0)
+ error = proc_rwmem(p, uio);
+
+ return (error);
+}
diff --git a/sys/fs/procfs/procfs_note.c b/sys/fs/procfs/procfs_note.c
new file mode 100644
index 0000000..16c917e
--- /dev/null
+++ b/sys/fs/procfs/procfs_note.c
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)procfs_note.c 8.2 (Berkeley) 1/21/94
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sbuf.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+int
+procfs_doprocnote(PFS_FILL_ARGS)
+{
+ sbuf_trim(sb);
+ sbuf_finish(sb);
+ /* send to process's notify function */
+ return (EOPNOTSUPP);
+}
diff --git a/sys/fs/procfs/procfs_osrel.c b/sys/fs/procfs/procfs_osrel.c
new file mode 100644
index 0000000..d32bd6d
--- /dev/null
+++ b/sys/fs/procfs/procfs_osrel.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2009 Konstantin Belousov
+ * All rights reserved.
+ *
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/sbuf.h>
+#include <sys/uio.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+int
+procfs_doosrel(PFS_FILL_ARGS)
+{
+ const char *pp;
+ int ov, osrel, i;
+
+ if (uio == NULL)
+ return (EOPNOTSUPP);
+ if (uio->uio_rw == UIO_READ) {
+ sbuf_printf(sb, "%d\n", p->p_osrel);
+ } else {
+ sbuf_trim(sb);
+ sbuf_finish(sb);
+ pp = sbuf_data(sb);
+ osrel = 0;
+ i = sbuf_len(sb);
+ while (i--) {
+ if (*pp < '0' || *pp > '9')
+ return (EINVAL);
+ ov = osrel * 10 + *pp++ - '0';
+ if (ov < osrel)
+ return (EINVAL);
+ osrel = ov;
+ }
+ p->p_osrel = osrel;
+ }
+ return (0);
+}
diff --git a/sys/fs/procfs/procfs_regs.c b/sys/fs/procfs/procfs_regs.c
new file mode 100644
index 0000000..3f78478
--- /dev/null
+++ b/sys/fs/procfs/procfs_regs.c
@@ -0,0 +1,132 @@
+/*-
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)procfs_regs.c 8.4 (Berkeley) 6/15/94
+ *
+ * From:
+ * $Id: procfs_regs.c,v 3.2 1993/12/15 09:40:17 jsp Exp $
+ * $FreeBSD$
+ */
+
+#include "opt_compat.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/sysent.h>
+#include <sys/uio.h>
+
+#include <machine/reg.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+#ifdef COMPAT_FREEBSD32
+#include <sys/procfs.h>
+#include <machine/fpu.h>
+
+/*
+ * PROC(write, regs, td2, &r) becomes
+ * proc_write_regs(td2, &r) or
+ * proc_write_regs32(td2, &r32)
+ *
+ * UIOMOVE_FROMBUF(r, uio) becomes
+ * uiomove_frombuf(&r, sizeof(r), uio) or
+ * uiomove_frombuf(&r32, sizeof(r32), uio)
+ */
+#define PROC(d, w, t, r) wrap32 ? \
+ proc_ ## d ## _ ## w ## 32(t, r ## 32) : \
+ proc_ ## d ## _ ## w(t, r)
+#define UIOMOVE_FROMBUF(k, u) wrap32 ? \
+ uiomove_frombuf(& k ## 32, sizeof(k ## 32), u) : \
+ uiomove_frombuf(& k, sizeof(k), u)
+#else
+#define PROC(d, w, t, r) proc_ ## d ## _ ## w(t, r)
+#define UIOMOVE_FROMBUF(k, u) uiomove_frombuf(& k, sizeof(k), u)
+#endif
+
+int
+procfs_doprocregs(PFS_FILL_ARGS)
+{
+ int error;
+ struct reg r;
+ struct thread *td2;
+#ifdef COMPAT_FREEBSD32
+ struct reg32 r32;
+ int wrap32 = 0;
+#endif
+
+ if (uio->uio_offset != 0)
+ return (0);
+
+ PROC_LOCK(p);
+ PROC_ASSERT_HELD(p);
+ if (p_candebug(td, p)) {
+ PROC_UNLOCK(p);
+ return (EPERM);
+ }
+ if (!P_SHOULDSTOP(p)) {
+ PROC_UNLOCK(p);
+ return (EBUSY);
+ }
+
+ /* XXXKSE: */
+ td2 = FIRST_THREAD_IN_PROC(p);
+#ifdef COMPAT_FREEBSD32
+ if (SV_CURPROC_FLAG(SV_ILP32)) {
+ if ((SV_PROC_FLAG(td2->td_proc, SV_ILP32)) == 0) {
+ PROC_UNLOCK(p);
+ return (EINVAL);
+ }
+ wrap32 = 1;
+ }
+#endif
+ error = PROC(read, regs, td2, &r);
+ if (error == 0) {
+ PROC_UNLOCK(p);
+ error = UIOMOVE_FROMBUF(r, uio);
+ PROC_LOCK(p);
+ }
+ if (error == 0 && uio->uio_rw == UIO_WRITE) {
+ if (!P_SHOULDSTOP(p))
+ error = EBUSY;
+ else
+ /* XXXKSE: */
+ error = PROC(write, regs, td2, &r);
+ }
+ PROC_UNLOCK(p);
+
+ return (error);
+}
diff --git a/sys/fs/procfs/procfs_rlimit.c b/sys/fs/procfs/procfs_rlimit.c
new file mode 100644
index 0000000..3885f56
--- /dev/null
+++ b/sys/fs/procfs/procfs_rlimit.c
@@ -0,0 +1,114 @@
+/*-
+ * Copyright (c) 1999 Adrian Chadd
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * To get resource.h to include our rlimit_ident[] array of rlimit identifiers
+ */
+
+#define _RLIMIT_IDENT
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/resourcevar.h>
+#include <sys/resource.h>
+#include <sys/sbuf.h>
+#include <sys/types.h>
+#include <sys/malloc.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+
+int
+procfs_doprocrlimit(PFS_FILL_ARGS)
+{
+ struct plimit *limp;
+ int i;
+
+ /*
+ * Obtain a private reference to resource limits
+ */
+
+ PROC_LOCK(p);
+ limp = lim_hold(p->p_limit);
+ PROC_UNLOCK(p);
+
+ for (i = 0; i < RLIM_NLIMITS; i++) {
+
+ /*
+ * Add the rlimit ident
+ */
+
+ sbuf_printf(sb, "%s ", rlimit_ident[i]);
+
+ /*
+ * Replace RLIM_INFINITY with -1 in the string
+ */
+
+ /*
+ * current limit
+ */
+
+ if (limp->pl_rlimit[i].rlim_cur == RLIM_INFINITY) {
+ sbuf_printf(sb, "-1 ");
+ } else {
+ sbuf_printf(sb, "%llu ",
+ (unsigned long long)limp->pl_rlimit[i].rlim_cur);
+ }
+
+ /*
+ * maximum limit
+ */
+
+ if (limp->pl_rlimit[i].rlim_max == RLIM_INFINITY) {
+ sbuf_printf(sb, "-1\n");
+ } else {
+ sbuf_printf(sb, "%llu\n",
+ (unsigned long long)limp->pl_rlimit[i].rlim_max);
+ }
+ }
+
+ lim_free(limp);
+ return (0);
+}
diff --git a/sys/fs/procfs/procfs_status.c b/sys/fs/procfs/procfs_status.c
new file mode 100644
index 0000000..a97e0a9
--- /dev/null
+++ b/sys/fs/procfs/procfs_status.c
@@ -0,0 +1,197 @@
+/*-
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
+ *
+ * From:
+ * $Id: procfs_status.c,v 3.1 1993/12/15 09:40:17 jsp Exp $
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/exec.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/jail.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
+#include <sys/proc.h>
+#include <sys/resourcevar.h>
+#include <sys/sbuf.h>
+#include <sys/sysent.h>
+#include <sys/tty.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_param.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+int
+procfs_doprocstatus(PFS_FILL_ARGS)
+{
+ struct session *sess;
+ struct thread *tdfirst;
+ struct tty *tp;
+ struct ucred *cr;
+ const char *wmesg;
+ char *pc;
+ char *sep;
+ int pid, ppid, pgid, sid;
+ int i;
+
+ pid = p->p_pid;
+ PROC_LOCK(p);
+ ppid = p->p_pptr ? p->p_pptr->p_pid : 0;
+ pgid = p->p_pgrp->pg_id;
+ sess = p->p_pgrp->pg_session;
+ SESS_LOCK(sess);
+ sid = sess->s_leader ? sess->s_leader->p_pid : 0;
+
+/* comm pid ppid pgid sid tty ctty,sldr start ut st wmsg
+ euid ruid rgid,egid,groups[1 .. ngroups]
+*/
+
+ pc = p->p_comm;
+ do {
+ if (*pc < 33 || *pc > 126 || *pc == '\\')
+ sbuf_printf(sb, "\\%03o", *pc);
+ else
+ sbuf_putc(sb, *pc);
+ } while (*++pc);
+ sbuf_printf(sb, " %d %d %d %d ", pid, ppid, pgid, sid);
+ if ((p->p_flag & P_CONTROLT) && (tp = sess->s_ttyp))
+ sbuf_printf(sb, "%s ", devtoname(tp->t_dev));
+ else
+ sbuf_printf(sb, "- ");
+
+ sep = "";
+ if (sess->s_ttyvp) {
+ sbuf_printf(sb, "%sctty", sep);
+ sep = ",";
+ }
+ if (SESS_LEADER(p)) {
+ sbuf_printf(sb, "%ssldr", sep);
+ sep = ",";
+ }
+ SESS_UNLOCK(sess);
+ if (*sep != ',') {
+ sbuf_printf(sb, "noflags");
+ }
+
+ tdfirst = FIRST_THREAD_IN_PROC(p);
+ thread_lock(tdfirst);
+ if (tdfirst->td_wchan != NULL) {
+ KASSERT(tdfirst->td_wmesg != NULL,
+ ("wchan %p has no wmesg", tdfirst->td_wchan));
+ wmesg = tdfirst->td_wmesg;
+ } else
+ wmesg = "nochan";
+ thread_unlock(tdfirst);
+
+ if (p->p_flag & P_INMEM) {
+ struct timeval start, ut, st;
+
+ PROC_SLOCK(p);
+ calcru(p, &ut, &st);
+ PROC_SUNLOCK(p);
+ start = p->p_stats->p_start;
+ timevaladd(&start, &boottime);
+ sbuf_printf(sb, " %jd,%ld %jd,%ld %jd,%ld",
+ (intmax_t)start.tv_sec, start.tv_usec,
+ (intmax_t)ut.tv_sec, ut.tv_usec,
+ (intmax_t)st.tv_sec, st.tv_usec);
+ } else
+ sbuf_printf(sb, " -1,-1 -1,-1 -1,-1");
+
+ sbuf_printf(sb, " %s", wmesg);
+
+ cr = p->p_ucred;
+
+ sbuf_printf(sb, " %lu %lu %lu",
+ (u_long)cr->cr_uid,
+ (u_long)cr->cr_ruid,
+ (u_long)cr->cr_rgid);
+
+ /* egid (cr->cr_svgid) is equal to cr_ngroups[0]
+ see also getegid(2) in /sys/kern/kern_prot.c */
+
+ for (i = 0; i < cr->cr_ngroups; i++) {
+ sbuf_printf(sb, ",%lu", (u_long)cr->cr_groups[i]);
+ }
+
+ if (jailed(cr)) {
+ mtx_lock(&cr->cr_prison->pr_mtx);
+ sbuf_printf(sb, " %s",
+ prison_name(td->td_ucred->cr_prison, cr->cr_prison));
+ mtx_unlock(&cr->cr_prison->pr_mtx);
+ } else {
+ sbuf_printf(sb, " -");
+ }
+ PROC_UNLOCK(p);
+ sbuf_printf(sb, "\n");
+
+ return (0);
+}
+
+int
+procfs_doproccmdline(PFS_FILL_ARGS)
+{
+
+ /*
+ * If we are using the ps/cmdline caching, use that. Otherwise
+ * read argv from the process space.
+ * Note that if the argv is no longer available, we deliberately
+ * don't fall back on p->p_comm or return an error: the authentic
+ * Linux behaviour is to return zero-length in this case.
+ */
+
+ PROC_LOCK(p);
+ if (p->p_args && p_cansee(td, p) == 0) {
+ sbuf_bcpy(sb, p->p_args->ar_args, p->p_args->ar_length);
+ PROC_UNLOCK(p);
+ return (0);
+ }
+
+ if ((p->p_flag & P_SYSTEM) != 0) {
+ PROC_UNLOCK(p);
+ return (0);
+ }
+
+ PROC_UNLOCK(p);
+
+ return (proc_getargv(td, p, sb));
+}
diff --git a/sys/fs/procfs/procfs_type.c b/sys/fs/procfs/procfs_type.c
new file mode 100644
index 0000000..80cecc5
--- /dev/null
+++ b/sys/fs/procfs/procfs_type.c
@@ -0,0 +1,56 @@
+/*-
+ * 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.
+ * 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 PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * 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, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/sbuf.h>
+#include <sys/sysent.h>
+
+#include <fs/pseudofs/pseudofs.h>
+#include <fs/procfs/procfs.h>
+
+int
+procfs_doproctype(PFS_FILL_ARGS)
+{
+ static const char *none = "Not Available";
+
+ if (p != NULL && p->p_sysent && p->p_sysent->sv_name)
+ sbuf_printf(sb, "%s", p->p_sysent->sv_name);
+ else
+ sbuf_printf(sb, "%s", none);
+ sbuf_putc(sb, '\n');
+ return (0);
+}
OpenPOWER on IntegriCloud