diff options
Diffstat (limited to 'sys/fs/procfs')
-rw-r--r-- | sys/fs/procfs/README | 113 | ||||
-rw-r--r-- | sys/fs/procfs/procfs.c | 212 | ||||
-rw-r--r-- | sys/fs/procfs/procfs.h | 65 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_ctl.c | 358 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_dbregs.c | 133 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_fpregs.c | 132 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_ioctl.c | 220 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_map.c | 244 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_mem.c | 71 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_note.c | 53 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_osrel.c | 68 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_regs.c | 132 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_rlimit.c | 114 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_status.c | 197 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_type.c | 56 |
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); +} |