diff options
author | ru <ru@FreeBSD.org> | 2001-05-23 09:42:29 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2001-05-23 09:42:29 +0000 |
commit | 35437d86aa2e89b16dfeb84a5499976559847155 (patch) | |
tree | 2bade94e6086e67f8de015d8c16fd2c15e7f78c3 /sys/miscfs/procfs | |
parent | 627a25efaa565e765c3f4d9223bfeef7134724ef (diff) | |
download | FreeBSD-src-35437d86aa2e89b16dfeb84a5499976559847155.zip FreeBSD-src-35437d86aa2e89b16dfeb84a5499976559847155.tar.gz |
- FDESC, FIFO, NULL, PORTAL, PROC, UMAP and UNION file
systems were repo-copied from sys/miscfs to sys/fs.
- Renamed the following file systems and their modules:
fdesc -> fdescfs, portal -> portalfs, union -> unionfs.
- Renamed corresponding kernel options:
FDESC -> FDESCFS, PORTAL -> PORTALFS, UNION -> UNIONFS.
- Install header files for the above file systems.
- Removed bogus -I${.CURDIR}/../../sys CFLAGS from userland
Makefiles.
Diffstat (limited to 'sys/miscfs/procfs')
-rw-r--r-- | sys/miscfs/procfs/README | 113 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs.h | 162 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_ctl.c | 364 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_dbregs.c | 107 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_fpregs.c | 104 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_map.c | 186 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_mem.c | 328 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_note.c | 67 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_regs.c | 105 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_rlimit.c | 128 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_status.c | 265 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_subr.c | 416 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_type.c | 85 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_vfsops.c | 177 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_vnops.c | 1022 |
15 files changed, 0 insertions, 3629 deletions
diff --git a/sys/miscfs/procfs/README b/sys/miscfs/procfs/README deleted file mode 100644 index f816b32..0000000 --- a/sys/miscfs/procfs/README +++ /dev/null @@ -1,113 +0,0 @@ -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/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h deleted file mode 100644 index 1c8e5e1..0000000 --- a/sys/miscfs/procfs/procfs.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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$ - */ - -/* - * The different types of node in a procfs filesystem - */ -typedef enum { - Proot, /* the filesystem root */ - Pcurproc, /* symbolic link for curproc */ - Pproc, /* a process-specific sub-directory */ - Pfile, /* the executable file */ - Pmem, /* the process's memory image */ - Pregs, /* the process's register set */ - Pfpregs, /* the process's FP register set */ - Pdbregs, /* the process's debug register set */ - Pctl, /* process control */ - Pstatus, /* process status */ - Pnote, /* process notifier */ - Pnotepg, /* process group notifier */ - Pmap, /* memory map */ - Ptype, /* executable type */ - Pcmdline, /* command line */ - Prlimit /* resource limits */ -} pfstype; - -/* - * control data for the proc file system. - */ -struct pfsnode { - struct pfsnode *pfs_next; /* next on list */ - struct vnode *pfs_vnode; /* vnode associated with this pfsnode */ - pfstype pfs_type; /* type of procfs node */ - pid_t pfs_pid; /* associated process */ - u_short pfs_mode; /* mode bits for stat() */ - u_long pfs_flags; /* open flags */ - u_long pfs_fileno; /* unique file id */ - pid_t pfs_lockowner; /* pfs lock owner */ -}; - -#define PROCFS_NOTELEN 64 /* max length of a note (/proc/$pid/note) */ -#define PROCFS_CTLLEN 8 /* max length of a ctl msg (/proc/$pid/ctl */ -#define PROCFS_NAMELEN 8 /* max length of a filename component */ - -/* - * Kernel stuff follows - */ -#ifdef _KERNEL -#define CNEQ(cnp, s, len) \ - ((cnp)->cn_namelen == (len) && \ - (bcmp((s), (cnp)->cn_nameptr, (len)) == 0)) - -#define KMEM_GROUP 2 - -#define PROCFS_FILENO(pid, type) \ - (((type) < Pproc) ? \ - ((type) + 2) : \ - ((((pid)+1) << 4) + ((int) (type)))) - -/* - * Convert between pfsnode vnode - */ -#define VTOPFS(vp) ((struct pfsnode *)(vp)->v_data) -#define PFSTOV(pfs) ((pfs)->pfs_vnode) - -typedef struct vfs_namemap vfs_namemap_t; -struct vfs_namemap { - const char *nm_name; - int nm_val; -}; - -int vfs_getuserstr __P((struct uio *, char *, int *)); -vfs_namemap_t *vfs_findname __P((vfs_namemap_t *, char *, int)); - -/* <machine/reg.h> */ -struct reg; -struct fpreg; -struct dbreg; - -#define PFIND(pid) (pfind(pid)) - -void procfs_exit __P((struct proc *)); -int procfs_freevp __P((struct vnode *)); -int procfs_allocvp __P((struct mount *, struct vnode **, long, pfstype)); -struct vnode *procfs_findtextvp __P((struct proc *)); -int procfs_sstep __P((struct proc *)); -void procfs_fix_sstep __P((struct proc *)); -int procfs_read_regs __P((struct proc *, struct reg *)); -int procfs_write_regs __P((struct proc *, struct reg *)); -int procfs_read_fpregs __P((struct proc *, struct fpreg *)); -int procfs_write_fpregs __P((struct proc *, struct fpreg *)); -int procfs_read_dbregs __P((struct proc *, struct dbreg *)); -int procfs_write_dbregs __P((struct proc *, struct dbreg *)); -int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -int procfs_dofpregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -int procfs_dodbregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -int procfs_docmdline __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); -int procfs_dorlimit __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); - -/* Return 1 if process has special kernel digging privileges */ -int procfs_kmemaccess __P((struct proc *)); - -/* functions to check whether or not files should be displayed */ -int procfs_validfile __P((struct proc *)); -int procfs_validfpregs __P((struct proc *)); -int procfs_validregs __P((struct proc *)); -int procfs_validdbregs __P((struct proc *)); -int procfs_validmap __P((struct proc *)); -int procfs_validtype __P((struct proc *)); - -#define PROCFS_LOCKED 0x01 -#define PROCFS_WANT 0x02 - -extern vop_t **procfs_vnodeop_p; - -int procfs_root __P((struct mount *, struct vnode **)); -int procfs_rw __P((struct vop_read_args *)); -#endif /* _KERNEL */ diff --git a/sys/miscfs/procfs/procfs_ctl.c b/sys/miscfs/procfs/procfs_ctl.c deleted file mode 100644 index 5818758..0000000 --- a/sys/miscfs/procfs/procfs_ctl.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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 - * $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/signalvar.h> -#include <sys/sx.h> -#include <sys/vnode.h> - -#include <miscfs/procfs/procfs.h> - -#include <vm/vm.h> - -#ifndef FIX_SSTEP -#define FIX_SSTEP(p) -#endif - -/* - * True iff process (p) is in trace wait state - * relative to process (curp) - */ -#define TRACE_WAIT_P(curp, p) \ - ((p)->p_stat == SSTOP && \ - (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 - -static vfs_namemap_t 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 vfs_namemap_t 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 __P((struct proc *curp, struct proc *p, int op)); - -static int -procfs_control(curp, p, op) - struct proc *curp; - struct proc *p; - int op; -{ - int error = 0; - - /* - * 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. - */ - if (op != PROCFS_CTL_DETACH && - ((error = p_can(curp, p, P_CAN_DEBUG, NULL)))) - return (error); - - /* - * Attach - attaches the target process for debugging - * by the calling process. - */ - if (op == PROCFS_CTL_ATTACH) { - sx_xlock(&proctree_lock); - PROC_LOCK(p); - if (p->p_flag & P_TRACED) { - error = EBUSY; - goto out; - } - - /* Can't trace yourself! */ - if (p->p_pid == curp->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 != curp) { - p->p_oppid = p->p_pptr->p_pid; - proc_reparent(p, curp); - } - psignal(p, SIGSTOP); -out: - PROC_UNLOCK(p); - sx_xunlock(&proctree_lock); - return (error); - } - - /* - * Target process must be stopped, owned by (curp) 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: - PROC_LOCK(p); - mtx_lock_spin(&sched_lock); - if (!TRACE_WAIT_P(curp, p)) { - mtx_unlock_spin(&sched_lock); - PROC_UNLOCK(p); - return (EBUSY); - } - mtx_unlock_spin(&sched_lock); - PROC_UNLOCK(p); - } - - -#ifdef FIX_SSTEP - /* - * do single-step fixup if needed - */ - FIX_SSTEP(p); -#endif - - /* - * Don't deliver any signal by default. - * To continue with a signal, just send - * the signal name to the ctl file - */ - PROC_LOCK(p); - 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; - - /* remove pending SIGTRAP, else the process will die */ - SIGDELSET(p->p_siglist, SIGTRAP); - 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_reparent(p, pp); - } else - PROC_LOCK(p); - p->p_oppid = 0; - p->p_flag &= ~P_WAITED; /* XXX ? */ - PROC_UNLOCK(p); - sx_xunlock(&proctree_lock); - - wakeup((caddr_t) curp); /* XXX for CTL_WAIT below ? */ - - break; - - /* - * Step. Let the target process execute a single instruction. - */ - case PROCFS_CTL_STEP: - _PHOLD(p); - PROC_UNLOCK(p); - error = procfs_sstep(p); - PRELE(p); - if (error) - return (error); - break; - - /* - * Run. Let the target process continue running until a breakpoint - * or some other trap. - */ - case PROCFS_CTL_RUN: - PROC_UNLOCK(p); - 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) { - mtx_lock_spin(&sched_lock); - while (error == 0 && - (p->p_stat != SSTOP) && - (p->p_flag & P_TRACED) && - (p->p_pptr == curp)) { - mtx_unlock_spin(&sched_lock); - error = msleep((caddr_t) p, &p->p_mtx, - PWAIT|PCATCH, "procfsx", 0); - mtx_lock_spin(&sched_lock); - } - if (error == 0 && !TRACE_WAIT_P(curp, p)) - error = EBUSY; - mtx_unlock_spin(&sched_lock); - PROC_UNLOCK(p); - } else { - PROC_UNLOCK(p); - mtx_lock_spin(&sched_lock); - while (error == 0 && p->p_stat != SSTOP) { - mtx_unlock_spin(&sched_lock); - error = tsleep((caddr_t) p, - PWAIT|PCATCH, "procfs", 0); - mtx_lock_spin(&sched_lock); - } - mtx_unlock_spin(&sched_lock); - } - return (error); - - default: - panic("procfs_control"); - } - - mtx_lock_spin(&sched_lock); - if (p->p_stat == SSTOP) - setrunnable(p); - mtx_unlock_spin(&sched_lock); - return (0); -} - -int -procfs_doctl(curp, p, pfs, uio) - struct proc *curp; - struct pfsnode *pfs; - struct uio *uio; - struct proc *p; -{ - int xlen; - int error; - char msg[PROCFS_CTLLEN+1]; - vfs_namemap_t *nm; - - if (uio->uio_rw != UIO_WRITE) - return (EOPNOTSUPP); - - xlen = PROCFS_CTLLEN; - error = vfs_getuserstr(uio, msg, &xlen); - if (error) - return (error); - - /* - * 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; - - nm = vfs_findname(ctlnames, msg, xlen); - if (nm) { - error = procfs_control(curp, p, nm->nm_val); - } else { - nm = vfs_findname(signames, msg, xlen); - if (nm) { - PROC_LOCK(p); - mtx_lock_spin(&sched_lock); - if (TRACE_WAIT_P(curp, p)) { - p->p_xstat = nm->nm_val; -#ifdef FIX_SSTEP - FIX_SSTEP(p); -#endif - setrunnable(p); - mtx_unlock_spin(&sched_lock); - } else { - mtx_unlock_spin(&sched_lock); - psignal(p, nm->nm_val); - } - PROC_UNLOCK(p); - error = 0; - } - } - - return (error); -} diff --git a/sys/miscfs/procfs/procfs_dbregs.c b/sys/miscfs/procfs/procfs_dbregs.c deleted file mode 100644 index d80e28c..0000000 --- a/sys/miscfs/procfs/procfs_dbregs.c +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * 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. - * 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. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/vnode.h> - -#include <machine/reg.h> - -#include <miscfs/procfs/procfs.h> - -#include <vm/vm.h> - -int -procfs_dodbregs(curp, p, pfs, uio) - struct proc *curp; - struct proc *p; - struct pfsnode *pfs; - struct uio *uio; -{ - int error; - struct dbreg r; - char *kv; - int kl; - - if (p_can(curp, p, P_CAN_DEBUG, NULL)) - return (EPERM); - kl = sizeof(r); - kv = (char *) &r; - - kv += uio->uio_offset; - kl -= uio->uio_offset; - if (kl > uio->uio_resid) - kl = uio->uio_resid; - - PHOLD(p); - - if (kl < 0) - error = EINVAL; - else - error = procfs_read_dbregs(p, &r); - if (error == 0) - error = uiomove(kv, kl, uio); - if (error == 0 && uio->uio_rw == UIO_WRITE) { - if (p->p_stat != SSTOP) - error = EBUSY; - else - error = procfs_write_dbregs(p, &r); - } - PRELE(p); - - uio->uio_offset = 0; - return (error); -} - -int -procfs_validdbregs(p) - struct proc *p; -{ - - return ((p->p_flag & P_SYSTEM) == 0); -} diff --git a/sys/miscfs/procfs/procfs_fpregs.c b/sys/miscfs/procfs/procfs_fpregs.c deleted file mode 100644 index 7e2ff52..0000000 --- a/sys/miscfs/procfs/procfs_fpregs.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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: - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/vnode.h> - -#include <machine/reg.h> - -#include <miscfs/procfs/procfs.h> - -#include <vm/vm.h> - -int -procfs_dofpregs(curp, p, pfs, uio) - struct proc *curp; - struct proc *p; - struct pfsnode *pfs; - struct uio *uio; -{ - int error; - struct fpreg r; - char *kv; - int kl; - - if (p_can(curp, p, P_CAN_DEBUG, NULL)) - return EPERM; - kl = sizeof(r); - kv = (char *) &r; - - kv += uio->uio_offset; - kl -= uio->uio_offset; - if (kl > uio->uio_resid) - kl = uio->uio_resid; - - PHOLD(p); - - if (kl < 0) - error = EINVAL; - else - error = procfs_read_fpregs(p, &r); - if (error == 0) - error = uiomove(kv, kl, uio); - if (error == 0 && uio->uio_rw == UIO_WRITE) { - if (p->p_stat != SSTOP) - error = EBUSY; - else - error = procfs_write_fpregs(p, &r); - } - PRELE(p); - - uio->uio_offset = 0; - return (error); -} - -int -procfs_validfpregs(p) - struct proc *p; -{ - - return ((p->p_flag & P_SYSTEM) == 0); -} diff --git a/sys/miscfs/procfs/procfs_map.c b/sys/miscfs/procfs/procfs_map.c deleted file mode 100644 index 5c21993..0000000 --- a/sys/miscfs/procfs/procfs_map.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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 <sys/param.h> -#include <sys/systm.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/vnode.h> - -#include <miscfs/procfs/procfs.h> - -#include <vm/vm.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_domap(curp, p, pfs, uio) - struct proc *curp; - struct proc *p; - struct pfsnode *pfs; - struct uio *uio; -{ - int len; - int error; - vm_map_t map = &p->p_vmspace->vm_map; - pmap_t pmap = vmspace_pmap(p->p_vmspace); - vm_map_entry_t entry; - char mebuffer[MEBUFFERSIZE]; - - if (uio->uio_rw != UIO_READ) - return (EOPNOTSUPP); - - if (uio->uio_offset != 0) - return (0); - - error = 0; - if (map != &curproc->p_vmspace->vm_map) - vm_map_lock_read(map); - for (entry = map->header.next; - ((uio->uio_resid > 0) && (entry != &map->header)); - entry = entry->next) { - vm_object_t obj, tobj, lobj; - int ref_count, shadow_count, flags; - vm_offset_t addr; - int resident, privateresident; - char *type; - - if (entry->eflags & MAP_ENTRY_IS_SUB_MAP) - continue; - - obj = entry->object.vm_object; - if (obj && (obj->shadow_count == 1)) - privateresident = obj->resident_page_count; - else - privateresident = 0; - - resident = 0; - addr = entry->start; - while (addr < entry->end) { - if (pmap_extract( pmap, addr)) - resident++; - addr += PAGE_SIZE; - } - - for( lobj = tobj = obj; tobj; tobj = tobj->backing_object) - lobj = tobj; - - if (lobj) { - switch(lobj->type) { - -default: -case OBJT_DEFAULT: - type = "default"; - break; -case OBJT_VNODE: - type = "vnode"; - break; -case OBJT_SWAP: - type = "swap"; - break; -case OBJT_DEVICE: - type = "device"; - break; - } - - flags = obj->flags; - ref_count = obj->ref_count; - shadow_count = obj->shadow_count; - } else { - type = "none"; - flags = 0; - ref_count = 0; - shadow_count = 0; - } - - - /* - * format: - * start, end, resident, private resident, cow, access, type. - */ - snprintf(mebuffer, sizeof(mebuffer), - "0x%lx 0x%lx %d %d %p %s%s%s %d %d 0x%x %s %s %s\n", - (u_long)entry->start, (u_long)entry->end, - resident, privateresident, obj, - (entry->protection & VM_PROT_READ)?"r":"-", - (entry->protection & VM_PROT_WRITE)?"w":"-", - (entry->protection & VM_PROT_EXECUTE)?"x":"-", - ref_count, shadow_count, flags, - (entry->eflags & MAP_ENTRY_COW)?"COW":"NCOW", - (entry->eflags & MAP_ENTRY_NEEDS_COPY)?"NC":"NNC", - type); - - len = strlen(mebuffer); - if (len > uio->uio_resid) { - error = EFBIG; - break; - } - error = uiomove(mebuffer, len, uio); - if (error) - break; - } - if (map != &curproc->p_vmspace->vm_map) - vm_map_unlock_read(map); - return error; -} - -int -procfs_validmap(p) - struct proc *p; -{ - return ((p->p_flag & P_SYSTEM) == 0); -} diff --git a/sys/miscfs/procfs/procfs_mem.c b/sys/miscfs/procfs/procfs_mem.c deleted file mode 100644 index 1e28870..0000000 --- a/sys/miscfs/procfs/procfs_mem.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * 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. - * 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_mem.c 8.5 (Berkeley) 6/15/94 - * - * $FreeBSD$ - */ - -/* - * This is a lightly hacked and merged version - * of sef's pread/pwrite functions - */ - -#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/user.h> -#include <sys/vnode.h> - -#include <miscfs/procfs/procfs.h> - -#include <vm/vm.h> -#include <vm/vm_param.h> -#include <vm/pmap.h> -#include <vm/vm_extern.h> -#include <vm/vm_map.h> -#include <vm/vm_kern.h> -#include <vm/vm_object.h> -#include <vm/vm_page.h> - -static int procfs_rwmem __P((struct proc *curp, - struct proc *p, struct uio *uio)); - -static int -procfs_rwmem(curp, p, uio) - struct proc *curp; - struct proc *p; - struct uio *uio; -{ - int error; - int writing; - struct vmspace *vm; - vm_map_t map; - vm_object_t object = NULL; - vm_offset_t pageno = 0; /* page number */ - vm_prot_t reqprot; - vm_offset_t kva; - - /* - * if the vmspace is in the midst of being deallocated or the - * process is exiting, don't try to grab anything. The page table - * usage in that process can be messed up. - */ - vm = p->p_vmspace; - if ((p->p_flag & P_WEXIT)) - return EFAULT; - - mtx_lock(&vm_mtx); - if (vm->vm_refcnt < 1) { - mtx_unlock(&vm_mtx); - return EFAULT; - } - ++vm->vm_refcnt; - /* - * The map we want... - */ - map = &vm->vm_map; - - writing = uio->uio_rw == UIO_WRITE; - reqprot = writing ? (VM_PROT_WRITE | VM_PROT_OVERRIDE_WRITE) : VM_PROT_READ; - - kva = kmem_alloc_pageable(kernel_map, PAGE_SIZE); - - /* - * Only map in one page at a time. We don't have to, but it - * makes things easier. This way is trivial - right? - */ - do { - vm_map_t tmap; - vm_offset_t uva; - int page_offset; /* offset into page */ - vm_map_entry_t out_entry; - vm_prot_t out_prot; - boolean_t wired; - vm_pindex_t pindex; - u_int len; - vm_page_t m; - - object = NULL; - - uva = (vm_offset_t) uio->uio_offset; - - /* - * Get the page number of this segment. - */ - pageno = trunc_page(uva); - page_offset = uva - pageno; - - /* - * How many bytes to copy - */ - len = min(PAGE_SIZE - page_offset, uio->uio_resid); - - /* - * Fault the page on behalf of the process - */ - error = vm_fault(map, pageno, reqprot, VM_FAULT_NORMAL); - if (error) { - error = EFAULT; - break; - } - - /* - * Now we need to get the page. out_entry, out_prot, wired, - * and single_use aren't used. One would think the vm code - * would be a *bit* nicer... We use tmap because - * vm_map_lookup() can change the map argument. - */ - tmap = map; - error = vm_map_lookup(&tmap, pageno, reqprot, - &out_entry, &object, &pindex, &out_prot, - &wired); - - if (error) { - error = EFAULT; - - /* - * Make sure that there is no residue in 'object' from - * an error return on vm_map_lookup. - */ - object = NULL; - - break; - } - - m = vm_page_lookup(object, pindex); - - /* Allow fallback to backing objects if we are reading */ - - while (m == NULL && !writing && object->backing_object) { - - pindex += OFF_TO_IDX(object->backing_object_offset); - object = object->backing_object; - - m = vm_page_lookup(object, pindex); - } - - if (m == NULL) { - error = EFAULT; - - /* - * Make sure that there is no residue in 'object' from - * an error return on vm_map_lookup. - */ - object = NULL; - - vm_map_lookup_done(tmap, out_entry); - - break; - } - - /* - * Wire the page into memory - */ - vm_page_wire(m); - - /* - * We're done with tmap now. - * But reference the object first, so that we won't loose - * it. - */ - vm_object_reference(object); - vm_map_lookup_done(tmap, out_entry); - - pmap_kenter(kva, VM_PAGE_TO_PHYS(m)); - - /* - * Now do the i/o move. - */ - mtx_unlock(&vm_mtx); - error = uiomove((caddr_t)(kva + page_offset), len, uio); - mtx_lock(&vm_mtx); - - pmap_kremove(kva); - - /* - * release the page and the object - */ - vm_page_unwire(m, 1); - vm_object_deallocate(object); - - object = NULL; - - } while (error == 0 && uio->uio_resid > 0); - - if (object) - vm_object_deallocate(object); - - kmem_free(kernel_map, kva, PAGE_SIZE); - vmspace_free(vm); - mtx_unlock(&vm_mtx); - return (error); -} - -/* - * 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_domem(curp, p, pfs, uio) - struct proc *curp; - struct proc *p; - struct pfsnode *pfs; - struct uio *uio; -{ - - if (uio->uio_resid == 0) - return (0); - - /* - * XXX - * We need to check for KMEM_GROUP because ps is sgid kmem; - * not allowing it here causes ps to not work properly. Arguably, - * this is a bug with what ps does. We only need to do this - * for Pmem nodes, and only if it's reading. This is still not - * good, as it may still be possible to grab illicit data if - * a process somehow gets to be KMEM_GROUP. Note that this also - * means that KMEM_GROUP can't change without editing procfs.h! - * All in all, quite yucky. - */ - - if (p_can(curp, p, P_CAN_DEBUG, NULL) && - !(uio->uio_rw == UIO_READ && - procfs_kmemaccess(curp))) - return EPERM; - - return (procfs_rwmem(curp, p, uio)); -} - -/* - * Given process (p), find the vnode from which - * its text segment is being executed. - * - * It would be nice to grab this information from - * the VM system, however, there is no sure-fire - * way of doing that. Instead, fork(), exec() and - * wait() all maintain the p_textvp field in the - * process proc structure which contains a held - * reference to the exec'ed vnode. - * - * XXX - Currently, this is not not used, as the - * /proc/pid/file object exposes an information leak - * that shouldn't happen. Using a mount option would - * make it configurable on a per-system (or, at least, - * per-mount) basis; however, that's not really best. - * The best way to do it, I think, would be as an - * ioctl; this would restrict it to the uid running - * program, or root, which seems a reasonable compromise. - * However, the number of applications for this is - * minimal, if it can't be seen in the filesytem space, - * and doint it as an ioctl makes it somewhat less - * useful due to the, well, inelegance. - * - */ -struct vnode * -procfs_findtextvp(p) - struct proc *p; -{ - - return (p->p_textvp); -} - -int procfs_kmemaccess(curp) - struct proc *curp; -{ - int i; - struct ucred *cred; - - cred = curp->p_ucred; - if (suser(curp)) - return 1; - - /* XXX: Why isn't this done with file-perms ??? */ - for (i = 0; i < cred->cr_ngroups; i++) - if (cred->cr_groups[i] == KMEM_GROUP) - return 1; - - return 0; -} diff --git a/sys/miscfs/procfs/procfs_note.c b/sys/miscfs/procfs/procfs_note.c deleted file mode 100644 index 273010b..0000000 --- a/sys/miscfs/procfs/procfs_note.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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/vnode.h> -#include <miscfs/procfs/procfs.h> - -int -procfs_donote(curp, p, pfs, uio) - struct proc *curp; - struct proc *p; - struct pfsnode *pfs; - struct uio *uio; -{ - int xlen; - int error; - char note[PROCFS_NOTELEN+1]; - - if (uio->uio_rw != UIO_WRITE) - return (EINVAL); - - xlen = PROCFS_NOTELEN; - error = vfs_getuserstr(uio, note, &xlen); - if (error) - return (error); - - /* send to process's notify function */ - return (EOPNOTSUPP); -} diff --git a/sys/miscfs/procfs/procfs_regs.c b/sys/miscfs/procfs/procfs_regs.c deleted file mode 100644 index ba58517..0000000 --- a/sys/miscfs/procfs/procfs_regs.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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: - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/vnode.h> - -#include <machine/reg.h> - -#include <vm/vm.h> -#include <vm/vm_extern.h> - -#include <miscfs/procfs/procfs.h> - -int -procfs_doregs(curp, p, pfs, uio) - struct proc *curp; - struct proc *p; - struct pfsnode *pfs; - struct uio *uio; -{ - int error; - struct reg r; - char *kv; - int kl; - - if (p_can(curp, p, P_CAN_DEBUG, NULL)) - return EPERM; - kl = sizeof(r); - kv = (char *) &r; - - kv += uio->uio_offset; - kl -= uio->uio_offset; - if (kl > uio->uio_resid) - kl = uio->uio_resid; - - PHOLD(p); - - if (kl < 0) - error = EINVAL; - else - error = procfs_read_regs(p, &r); - if (error == 0) - error = uiomove(kv, kl, uio); - if (error == 0 && uio->uio_rw == UIO_WRITE) { - if (p->p_stat != SSTOP) - error = EBUSY; - else - error = procfs_write_regs(p, &r); - } - PRELE(p); - - uio->uio_offset = 0; - return (error); -} - -int -procfs_validregs(p) - struct proc *p; -{ - - return ((p->p_flag & P_SYSTEM) == 0); -} diff --git a/sys/miscfs/procfs/procfs_rlimit.c b/sys/miscfs/procfs/procfs_rlimit.c deleted file mode 100644 index 361f6f6..0000000 --- a/sys/miscfs/procfs/procfs_rlimit.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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/systm.h> -#include <sys/proc.h> -#include <sys/vnode.h> -#include <sys/resourcevar.h> -#include <sys/resource.h> -#include <sys/types.h> -#include <miscfs/procfs/procfs.h> - - -int -procfs_dorlimit(curp, p, pfs, uio) - struct proc *curp; - struct proc *p; - struct pfsnode *pfs; - struct uio *uio; -{ - char *ps; - int i; - int xlen; - int error; - char psbuf[512]; /* XXX - conservative */ - - if (uio->uio_rw != UIO_READ) - return (EOPNOTSUPP); - - - ps = psbuf; - - for (i = 0; i < RLIM_NLIMITS; i++) { - - /* - * Add the rlimit ident - */ - - ps += sprintf(ps, "%s ", rlimit_ident[i]); - - /* - * Replace RLIM_INFINITY with -1 in the string - */ - - /* - * current limit - */ - - if (p->p_rlimit[i].rlim_cur == RLIM_INFINITY) { - ps += sprintf(ps, "-1 "); - } else { - ps += sprintf(ps, "%llu ", - (unsigned long long)p->p_rlimit[i].rlim_cur); - } - - /* - * maximum limit - */ - - if (p->p_rlimit[i].rlim_max == RLIM_INFINITY) { - ps += sprintf(ps, "-1\n"); - } else { - ps += sprintf(ps, "%llu\n", - (unsigned long long)p->p_rlimit[i].rlim_max); - } - } - - /* - * This logic is rather tasty - but its from procfs_status.c, so - * I guess I'll use it here. - */ - - xlen = ps - psbuf; - xlen -= uio->uio_offset; - ps = psbuf + uio->uio_offset; - xlen = imin(xlen, uio->uio_resid); - if (xlen <= 0) - error = 0; - else - error = uiomove(ps, xlen, uio); - - return (error); -} - diff --git a/sys/miscfs/procfs/procfs_status.c b/sys/miscfs/procfs/procfs_status.c deleted file mode 100644 index b29b4a9..0000000 --- a/sys/miscfs/procfs/procfs_status.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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: - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/exec.h> -#include <sys/jail.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/resourcevar.h> -#include <sys/tty.h> -#include <sys/vnode.h> - -#include <vm/vm.h> -#include <vm/pmap.h> -#include <vm/vm_param.h> - -#include <miscfs/procfs/procfs.h> - -#define DOCHECK() do { if (ps >= psbuf+sizeof(psbuf)) goto bailout; } while (0) -int -procfs_dostatus(curp, p, pfs, uio) - struct proc *curp; - struct proc *p; - struct pfsnode *pfs; - struct uio *uio; -{ - struct session *sess; - struct tty *tp; - struct ucred *cr; - char *ps; - char *sep; - int pid, ppid, pgid, sid; - int i; - int xlen; - int error; - char psbuf[256]; /* XXX - conservative */ - - if (uio->uio_rw != UIO_READ) - return (EOPNOTSUPP); - - pid = p->p_pid; - PROC_LOCK(p); - ppid = p->p_pptr ? p->p_pptr->p_pid : 0; - PROC_UNLOCK(p); - pgid = p->p_pgrp->pg_id; - sess = p->p_pgrp->pg_session; - sid = sess->s_leader ? sess->s_leader->p_pid : 0; - -/* comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg - euid ruid rgid,egid,groups[1 .. NGROUPS] -*/ - KASSERT(sizeof(psbuf) > MAXCOMLEN, - ("Too short buffer for new MAXCOMLEN")); - - ps = psbuf; - bcopy(p->p_comm, ps, MAXCOMLEN); - ps[MAXCOMLEN] = '\0'; - ps += strlen(ps); - DOCHECK(); - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, - " %d %d %d %d ", pid, ppid, pgid, sid); - DOCHECK(); - if ((p->p_flag&P_CONTROLT) && (tp = sess->s_ttyp)) - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, - "%d,%d ", major(tp->t_dev), minor(tp->t_dev)); - else - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, - "%d,%d ", -1, -1); - DOCHECK(); - - sep = ""; - if (sess->s_ttyvp) { - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "%sctty", sep); - sep = ","; - DOCHECK(); - } - if (SESS_LEADER(p)) { - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "%ssldr", sep); - sep = ","; - DOCHECK(); - } - if (*sep != ',') { - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "noflags"); - DOCHECK(); - } - - mtx_lock_spin(&sched_lock); - if (p->p_sflag & PS_INMEM) { - struct timeval ut, st; - - calcru(p, &ut, &st, (struct timeval *) NULL); - mtx_unlock_spin(&sched_lock); - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, - " %ld,%ld %ld,%ld %ld,%ld", - p->p_stats->p_start.tv_sec, - p->p_stats->p_start.tv_usec, - ut.tv_sec, ut.tv_usec, - st.tv_sec, st.tv_usec); - } else { - mtx_unlock_spin(&sched_lock); - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, - " -1,-1 -1,-1 -1,-1"); - } - DOCHECK(); - - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %s", - (p->p_wchan && p->p_wmesg) ? p->p_wmesg : "nochan"); - DOCHECK(); - - cr = p->p_ucred; - - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %lu %lu %lu", - (u_long)cr->cr_uid, - (u_long)p->p_cred->p_ruid, - (u_long)p->p_cred->p_rgid); - DOCHECK(); - - /* egid (p->p_cred->p_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++) { - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, - ",%lu", (u_long)cr->cr_groups[i]); - DOCHECK(); - } - - if (jailed(p->p_ucred)) - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, - " %s", p->p_ucred->cr_prison->pr_host); - else - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " -"); - DOCHECK(); - ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "\n"); - DOCHECK(); - - xlen = ps - psbuf; - xlen -= uio->uio_offset; - ps = psbuf + uio->uio_offset; - xlen = imin(xlen, uio->uio_resid); - if (xlen <= 0) - error = 0; - else - error = uiomove(ps, xlen, uio); - - return (error); - -bailout: - return (ENOMEM); -} - -int -procfs_docmdline(curp, p, pfs, uio) - struct proc *curp; - struct proc *p; - struct pfsnode *pfs; - struct uio *uio; -{ - char *ps; - int xlen; - int error; - char *buf, *bp; - int buflen; - struct ps_strings pstr; - int i; - size_t bytes_left, done; - - if (uio->uio_rw != UIO_READ) - return (EOPNOTSUPP); - - /* - * If we are using the ps/cmdline caching, use that. Otherwise - * revert back to the old way which only implements full cmdline - * for the currept process and just p->p_comm for all other - * processes. - * 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. - */ - - if (p->p_args && (ps_argsopen || !p_can(curp, p, P_CAN_SEE, NULL))) { - bp = p->p_args->ar_args; - buflen = p->p_args->ar_length; - buf = 0; - } else if (p != curp) { - bp = p->p_comm; - buflen = MAXCOMLEN; - buf = 0; - } else { - buflen = 256; - MALLOC(buf, char *, buflen + 1, M_TEMP, M_WAITOK); - bp = buf; - ps = buf; - error = copyin((void*)PS_STRINGS, &pstr, sizeof(pstr)); - if (error) { - FREE(buf, M_TEMP); - return (error); - } - bytes_left = buflen; - for (i = 0; bytes_left && (i < pstr.ps_nargvstr); i++) { - error = copyinstr(pstr.ps_argvstr[i], ps, - bytes_left, &done); - /* If too long or malformed, just truncate */ - if (error) { - error = 0; - break; - } - ps += done; - bytes_left -= done; - } - buflen = ps - buf; - } - - buflen -= uio->uio_offset; - ps = bp + uio->uio_offset; - xlen = min(buflen, uio->uio_resid); - if (xlen <= 0) - error = 0; - else - error = uiomove(ps, xlen, uio); - if (buf) - FREE(buf, M_TEMP); - return (error); -} diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c deleted file mode 100644 index 64adecb..0000000 --- a/sys/miscfs/procfs/procfs_subr.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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_subr.c 8.6 (Berkeley) 5/14/95 - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/mount.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/socket.h> -#include <sys/sysctl.h> -#include <sys/vnode.h> - -#include <miscfs/procfs/procfs.h> - -static struct pfsnode *pfshead; -static int pfsvplock; - -/* - * allocate a pfsnode/vnode pair. the vnode is - * referenced, but not locked. - * - * the pid, pfs_type, and mount point uniquely - * identify a pfsnode. the mount point is needed - * because someone might mount this filesystem - * twice. - * - * all pfsnodes are maintained on a singly-linked - * list. new nodes are only allocated when they cannot - * be found on this list. entries on the list are - * removed when the vfs reclaim entry is called. - * - * a single lock is kept for the entire list. this is - * needed because the getnewvnode() function can block - * waiting for a vnode to become free, in which case there - * may be more than one process trying to get the same - * vnode. this lock is only taken if we are going to - * call getnewvnode, since the kernel itself is single-threaded. - * - * if an entry is found on the list, then call vget() to - * take a reference. this is done because there may be - * zero references to it and so it needs to removed from - * the vnode free list. - */ -int -procfs_allocvp(mp, vpp, pid, pfs_type) - struct mount *mp; - struct vnode **vpp; - long pid; - pfstype pfs_type; -{ - struct proc *p = curproc; /* XXX */ - struct pfsnode *pfs; - struct vnode *vp; - struct pfsnode **pp; - int error; - -loop: - for (pfs = pfshead; pfs != 0; pfs = pfs->pfs_next) { - vp = PFSTOV(pfs); - if (pfs->pfs_pid == pid && - pfs->pfs_type == pfs_type && - vp->v_mount == mp) { - if (vget(vp, 0, p)) - goto loop; - *vpp = vp; - return (0); - } - } - - /* - * otherwise lock the vp list while we call getnewvnode - * since that can block. - */ - if (pfsvplock & PROCFS_LOCKED) { - pfsvplock |= PROCFS_WANT; - (void) tsleep((caddr_t) &pfsvplock, PINOD, "pfsavp", 0); - goto loop; - } - pfsvplock |= PROCFS_LOCKED; - - /* - * Do the MALLOC before the getnewvnode since doing so afterward - * might cause a bogus v_data pointer to get dereferenced - * elsewhere if MALLOC should block. - */ - MALLOC(pfs, struct pfsnode *, sizeof(struct pfsnode), M_TEMP, M_WAITOK); - - if ((error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp)) != 0) { - FREE(pfs, M_TEMP); - goto out; - } - vp = *vpp; - - vp->v_data = pfs; - - pfs->pfs_next = 0; - pfs->pfs_pid = (pid_t) pid; - pfs->pfs_type = pfs_type; - pfs->pfs_vnode = vp; - pfs->pfs_flags = 0; - pfs->pfs_lockowner = 0; - pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type); - - switch (pfs_type) { - case Proot: /* /proc = dr-xr-xr-x */ - pfs->pfs_mode = (VREAD|VEXEC) | - (VREAD|VEXEC) >> 3 | - (VREAD|VEXEC) >> 6; - vp->v_type = VDIR; - vp->v_flag = VROOT; - break; - - case Pcurproc: /* /proc/curproc = lr--r--r-- */ - pfs->pfs_mode = (VREAD) | - (VREAD >> 3) | - (VREAD >> 6); - vp->v_type = VLNK; - break; - - case Pproc: - pfs->pfs_mode = (VREAD|VEXEC) | - (VREAD|VEXEC) >> 3 | - (VREAD|VEXEC) >> 6; - vp->v_type = VDIR; - break; - - case Pfile: - pfs->pfs_mode = (VREAD|VEXEC) | - (VREAD|VEXEC) >> 3 | - (VREAD|VEXEC) >> 6; - vp->v_type = VLNK; - break; - - case Pmem: - pfs->pfs_mode = (VREAD|VWRITE) | - (VREAD) >> 3;; - vp->v_type = VREG; - break; - - case Pregs: - case Pfpregs: - case Pdbregs: - pfs->pfs_mode = (VREAD|VWRITE); - vp->v_type = VREG; - break; - - case Pctl: - case Pnote: - case Pnotepg: - pfs->pfs_mode = (VWRITE); - vp->v_type = VREG; - break; - - case Ptype: - case Pmap: - case Pstatus: - case Pcmdline: - case Prlimit: - pfs->pfs_mode = (VREAD) | - (VREAD >> 3) | - (VREAD >> 6); - vp->v_type = VREG; - break; - - default: - panic("procfs_allocvp"); - } - - /* add to procfs vnode list */ - for (pp = &pfshead; *pp; pp = &(*pp)->pfs_next) - continue; - *pp = pfs; - -out: - pfsvplock &= ~PROCFS_LOCKED; - - if (pfsvplock & PROCFS_WANT) { - pfsvplock &= ~PROCFS_WANT; - wakeup((caddr_t) &pfsvplock); - } - - return (error); -} - -int -procfs_freevp(vp) - struct vnode *vp; -{ - struct pfsnode **pfspp; - struct pfsnode *pfs = VTOPFS(vp); - - for (pfspp = &pfshead; *pfspp != 0; pfspp = &(*pfspp)->pfs_next) { - if (*pfspp == pfs) { - *pfspp = pfs->pfs_next; - break; - } - } - - FREE(vp->v_data, M_TEMP); - vp->v_data = 0; - return (0); -} - -int -procfs_rw(ap) - struct vop_read_args *ap; -{ - struct vnode *vp = ap->a_vp; - struct uio *uio = ap->a_uio; - struct proc *curp = uio->uio_procp; - struct pfsnode *pfs = VTOPFS(vp); - struct proc *p; - int rtval; - - p = PFIND(pfs->pfs_pid); - if (p == NULL) - return (EINVAL); - PROC_UNLOCK(p); - if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE) - return (EACCES); - - mp_fixme("pfs_lockowner needs a lock"); - while (pfs->pfs_lockowner) { - tsleep(&pfs->pfs_lockowner, PRIBIO, "pfslck", 0); - } - pfs->pfs_lockowner = curproc->p_pid; - - switch (pfs->pfs_type) { - case Pnote: - case Pnotepg: - rtval = procfs_donote(curp, p, pfs, uio); - break; - - case Pregs: - rtval = procfs_doregs(curp, p, pfs, uio); - break; - - case Pfpregs: - rtval = procfs_dofpregs(curp, p, pfs, uio); - break; - - case Pdbregs: - rtval = procfs_dodbregs(curp, p, pfs, uio); - break; - - case Pctl: - rtval = procfs_doctl(curp, p, pfs, uio); - break; - - case Pstatus: - rtval = procfs_dostatus(curp, p, pfs, uio); - break; - - case Pmap: - rtval = procfs_domap(curp, p, pfs, uio); - break; - - case Pmem: - rtval = procfs_domem(curp, p, pfs, uio); - break; - - case Ptype: - rtval = procfs_dotype(curp, p, pfs, uio); - break; - - case Pcmdline: - rtval = procfs_docmdline(curp, p, pfs, uio); - break; - - case Prlimit: - rtval = procfs_dorlimit(curp, p, pfs, uio); - break; - - default: - rtval = EOPNOTSUPP; - break; - } - pfs->pfs_lockowner = 0; - wakeup(&pfs->pfs_lockowner); - return rtval; -} - -/* - * Get a string from userland into (buf). Strip a trailing - * nl character (to allow easy access from the shell). - * The buffer should be *buflenp + 1 chars long. vfs_getuserstr - * will automatically add a nul char at the end. - * - * Returns 0 on success or the following errors - * - * EINVAL: file offset is non-zero. - * EMSGSIZE: message is longer than kernel buffer - * EFAULT: user i/o buffer is not addressable - */ -int -vfs_getuserstr(uio, buf, buflenp) - struct uio *uio; - char *buf; - int *buflenp; -{ - int xlen; - int error; - - if (uio->uio_offset != 0) - return (EINVAL); - - xlen = *buflenp; - - /* must be able to read the whole string in one go */ - if (xlen < uio->uio_resid) - return (EMSGSIZE); - xlen = uio->uio_resid; - - if ((error = uiomove(buf, xlen, uio)) != 0) - return (error); - - /* allow multiple writes without seeks */ - uio->uio_offset = 0; - - /* cleanup string and remove trailing newline */ - buf[xlen] = '\0'; - xlen = strlen(buf); - if (xlen > 0 && buf[xlen-1] == '\n') - buf[--xlen] = '\0'; - *buflenp = xlen; - - return (0); -} - -vfs_namemap_t * -vfs_findname(nm, buf, buflen) - vfs_namemap_t *nm; - char *buf; - int buflen; -{ - - for (; nm->nm_name; nm++) - if (bcmp(buf, nm->nm_name, buflen+1) == 0) - return (nm); - - return (0); -} - -void -procfs_exit(struct proc *p) -{ - struct pfsnode *pfs; - pid_t pid = p->p_pid; - - /* - * The reason for this loop is not obvious -- basicly, - * procfs_freevp(), which is called via vgone() (eventually), - * removes the specified procfs node from the pfshead list. - * It does this by *pfsp = pfs->pfs_next, meaning that it - * overwrites the node. So when we do pfs = pfs->next, we - * end up skipping the node that replaces the one that was - * vgone'd. Since it may have been the last one on the list, - * it may also have been set to null -- but *our* pfs pointer, - * here, doesn't see this. So the loop starts from the beginning - * again. - * - * This is not a for() loop because the final event - * would be "pfs = pfs->pfs_next"; in the case where - * pfs is set to pfshead again, that would mean that - * pfshead is skipped over. - * - */ - pfs = pfshead; - while (pfs) { - if (pfs->pfs_pid == pid) { - vgone(PFSTOV(pfs)); - pfs = pfshead; - } else - pfs = pfs->pfs_next; - } -} diff --git a/sys/miscfs/procfs/procfs_type.c b/sys/miscfs/procfs/procfs_type.c deleted file mode 100644 index cb2a45f..0000000 --- a/sys/miscfs/procfs/procfs_type.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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/sysent.h> -#include <sys/vnode.h> -#include <miscfs/procfs/procfs.h> - -int -procfs_dotype(curp, p, pfs, uio) - struct proc *curp; - struct proc *p; - struct pfsnode *pfs; - struct uio *uio; -{ - int len; - int error; - /* - * buffer for emulation type - */ - char mebuffer[256]; - char *none = "Not Available"; - - if (uio->uio_rw != UIO_READ) - return (EOPNOTSUPP); - - if (uio->uio_offset != 0) - return (0); - - if (p && p->p_sysent && p->p_sysent->sv_name) { - len = strlen(p->p_sysent->sv_name); - bcopy(p->p_sysent->sv_name, mebuffer, len); - } else { - len = strlen(none); - bcopy(none, mebuffer, len); - } - mebuffer[len++] = '\n'; - error = uiomove(mebuffer, len, uio); - return error; -} - -int -procfs_validtype(p) - struct proc *p; -{ - return ((p->p_flag & P_SYSTEM) == 0); -} diff --git a/sys/miscfs/procfs/procfs_vfsops.c b/sys/miscfs/procfs/procfs_vfsops.c deleted file mode 100644 index 91daf9d..0000000 --- a/sys/miscfs/procfs/procfs_vfsops.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) 1993 Jan-Simon Pendry - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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$ - */ - -/* - * procfs VFS interface - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/proc.h> -#include <sys/mount.h> -#include <sys/vnode.h> -#include <miscfs/procfs/procfs.h> - -static int procfs_mount __P((struct mount *mp, char *path, caddr_t data, - struct nameidata *ndp, struct proc *p)); -static int procfs_statfs __P((struct mount *mp, struct statfs *sbp, - struct proc *p)); -static int procfs_unmount __P((struct mount *mp, int mntflags, - struct proc *p)); - -/* - * VFS Operations. - * - * mount system call - */ -/* ARGSUSED */ -static int -procfs_mount(mp, path, data, ndp, p) - struct mount *mp; - char *path; - caddr_t data; - struct nameidata *ndp; - struct proc *p; -{ - size_t size; - int error; - - if (mp->mnt_flag & MNT_UPDATE) - return (EOPNOTSUPP); - - if (mp->mnt_vfc->vfc_refcount == 1 && (error = at_exit(procfs_exit))) { - printf("procfs: cannot register procfs_exit with at_exit\n"); - return(error); - } - - mp->mnt_flag |= MNT_LOCAL; - mp->mnt_data = 0; - vfs_getnewfsid(mp); - - size = sizeof("procfs") - 1; - bcopy("procfs", mp->mnt_stat.f_mntfromname, size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void)procfs_statfs(mp, &mp->mnt_stat, p); - - return (0); -} - -/* - * unmount system call - */ -static int -procfs_unmount(mp, mntflags, p) - struct mount *mp; - int mntflags; - struct proc *p; -{ - int error; - int flags = 0; - - if (mntflags & MNT_FORCE) - flags |= FORCECLOSE; - - error = vflush(mp, 0, flags); - if (error) - return (error); - - if (mp->mnt_vfc->vfc_refcount == 1) - rm_at_exit(procfs_exit); - - return (0); -} - -int -procfs_root(mp, vpp) - struct mount *mp; - struct vnode **vpp; -{ - - return (procfs_allocvp(mp, vpp, 0, Proot)); -} - -/* - * Get file system statistics. - */ -static int -procfs_statfs(mp, sbp, p) - struct mount *mp; - struct statfs *sbp; - struct proc *p; -{ - sbp->f_bsize = PAGE_SIZE; - sbp->f_iosize = PAGE_SIZE; - sbp->f_blocks = 1; /* avoid divide by zero in some df's */ - sbp->f_bfree = 0; - sbp->f_bavail = 0; - sbp->f_files = maxproc; /* approx */ - sbp->f_ffree = maxproc - nprocs; /* approx */ - - if (sbp != &mp->mnt_stat) { - sbp->f_type = mp->mnt_vfc->vfc_typenum; - bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid)); - bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); - bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); - } - - return (0); -} - -static struct vfsops procfs_vfsops = { - procfs_mount, - vfs_stdstart, - procfs_unmount, - procfs_root, - vfs_stdquotactl, - procfs_statfs, - vfs_stdsync, - vfs_stdvget, - vfs_stdfhtovp, - vfs_stdcheckexp, - vfs_stdvptofh, - vfs_stdinit, - vfs_stduninit, - vfs_stdextattrctl, -}; - -VFS_SET(procfs_vfsops, procfs, VFCF_SYNTHETIC); -MODULE_VERSION(procfs, 1); diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c deleted file mode 100644 index dbdafc8..0000000 --- a/sys/miscfs/procfs/procfs_vnops.c +++ /dev/null @@ -1,1022 +0,0 @@ -/* - * Copyright (c) 1993, 1995 Jan-Simon Pendry - * Copyright (c) 1993, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Jan-Simon Pendry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 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_vnops.c 8.18 (Berkeley) 5/21/95 - * - * $FreeBSD$ - */ - -/* - * procfs vnode interface - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/dirent.h> -#include <sys/fcntl.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/mount.h> -#include <sys/mutex.h> -#include <sys/namei.h> -#include <sys/pioctl.h> -#include <sys/proc.h> -#include <sys/signalvar.h> -#include <sys/socket.h> -#include <sys/sx.h> -#include <sys/time.h> -#include <sys/uio.h> -#include <sys/vnode.h> - -#include <machine/reg.h> - -#include <vm/vm_zone.h> - -#include <miscfs/procfs/procfs.h> - -static int procfs_access __P((struct vop_access_args *)); -static int procfs_badop __P((void)); -static int procfs_close __P((struct vop_close_args *)); -static int procfs_getattr __P((struct vop_getattr_args *)); -static int procfs_ioctl __P((struct vop_ioctl_args *)); -static int procfs_lookup __P((struct vop_lookup_args *)); -static int procfs_open __P((struct vop_open_args *)); -static int procfs_print __P((struct vop_print_args *)); -static int procfs_readdir __P((struct vop_readdir_args *)); -static int procfs_readlink __P((struct vop_readlink_args *)); -static int procfs_reclaim __P((struct vop_reclaim_args *)); -static int procfs_setattr __P((struct vop_setattr_args *)); - -/* - * This is a list of the valid names in the - * process-specific sub-directories. It is - * used in procfs_lookup and procfs_readdir - */ -static struct proc_target { - u_char pt_type; - u_char pt_namlen; - char *pt_name; - pfstype pt_pfstype; - int (*pt_valid) __P((struct proc *p)); -} proc_targets[] = { -#define N(s) sizeof(s)-1, s - /* name type validp */ - { DT_DIR, N("."), Pproc, NULL }, - { DT_DIR, N(".."), Proot, NULL }, - { DT_REG, N("mem"), Pmem, NULL }, - { DT_REG, N("regs"), Pregs, procfs_validregs }, - { DT_REG, N("fpregs"), Pfpregs, procfs_validfpregs }, - { DT_REG, N("dbregs"), Pdbregs, procfs_validdbregs }, - { DT_REG, N("ctl"), Pctl, NULL }, - { DT_REG, N("status"), Pstatus, NULL }, - { DT_REG, N("note"), Pnote, NULL }, - { DT_REG, N("notepg"), Pnotepg, NULL }, - { DT_REG, N("map"), Pmap, procfs_validmap }, - { DT_REG, N("etype"), Ptype, procfs_validtype }, - { DT_REG, N("cmdline"), Pcmdline, NULL }, - { DT_REG, N("rlimit"), Prlimit, NULL }, - { DT_LNK, N("file"), Pfile, NULL }, -#undef N -}; -static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]); - -static pid_t atopid __P((const char *, u_int)); - -/* - * set things up for doing i/o on - * the pfsnode (vp). (vp) is locked - * on entry, and should be left locked - * on exit. - * - * for procfs we don't need to do anything - * in particular for i/o. all that is done - * is to support exclusive open on process - * memory images. - */ -static int -procfs_open(ap) - struct vop_open_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ - struct pfsnode *pfs = VTOPFS(ap->a_vp); - struct proc *p1, *p2; - int error = 0; - - p2 = PFIND(pfs->pfs_pid); - if (p2 == NULL) - return (ENOENT); - if (pfs->pfs_pid && p_can(ap->a_p, p2, P_CAN_SEE, NULL)) { - error = ENOENT; - goto out; - } - - switch (pfs->pfs_type) { - case Pmem: - if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) || - ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) { - error = EBUSY; - goto out; - } - - p1 = ap->a_p; - if (p_can(p1, p2, P_CAN_DEBUG, NULL) && - !procfs_kmemaccess(p1)) { - error = EPERM; - } - - if (ap->a_mode & FWRITE) - pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); - - default: - break; - } -out: - PROC_UNLOCK(p2); - return (error); -} - -/* - * close the pfsnode (vp) after doing i/o. - * (vp) is not locked on entry or exit. - * - * nothing to do for procfs other than undo - * any exclusive open flag (see _open above). - */ -static int -procfs_close(ap) - struct vop_close_args /* { - struct vnode *a_vp; - int a_fflag; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ - struct pfsnode *pfs = VTOPFS(ap->a_vp); - struct proc *p; - - switch (pfs->pfs_type) { - case Pmem: - if ((ap->a_fflag & FWRITE) && (pfs->pfs_flags & O_EXCL)) - pfs->pfs_flags &= ~(FWRITE|O_EXCL); - /* - * If this is the last close, then it checks to see if - * the target process has PF_LINGER set in p_pfsflags, - * if this is *not* the case, then the process' stop flags - * are cleared, and the process is woken up. This is - * to help prevent the case where a process has been - * told to stop on an event, but then the requesting process - * has gone away or forgotten about it. - */ - if ((ap->a_vp->v_usecount < 2) && (p = pfind(pfs->pfs_pid))) { - if (!(p->p_pfsflags & PF_LINGER)) { - p->p_stops = 0; - p->p_step = 0; - wakeup(&p->p_step); - } - PROC_UNLOCK(p); - } - break; - default: - break; - } - - return (0); -} - -/* - * do an ioctl operation on a pfsnode (vp). - * (vp) is not locked on entry or exit. - */ -static int -procfs_ioctl(ap) - struct vop_ioctl_args *ap; -{ - struct pfsnode *pfs = VTOPFS(ap->a_vp); - struct proc *procp, *p; - int error; - int signo; - struct procfs_status *psp; - unsigned char flags; - - p = ap->a_p; - procp = pfind(pfs->pfs_pid); - if (procp == NULL) { - return ENOTTY; - } - - if ((error = p_can(p, procp, P_CAN_DEBUG, NULL))) { - PROC_UNLOCK(procp); - return (error == ESRCH ? ENOENT : error); - } - - switch (ap->a_command) { - case PIOCBIS: - procp->p_stops |= *(unsigned int*)ap->a_data; - break; - case PIOCBIC: - procp->p_stops &= ~*(unsigned int*)ap->a_data; - break; - case PIOCSFL: - /* - * NFLAGS is "non-suser_xxx flags" -- currently, only - * PFS_ISUGID ("ignore set u/g id"); - */ -#define NFLAGS (PF_ISUGID) - flags = (unsigned char)*(unsigned int*)ap->a_data; - if (flags & NFLAGS && (error = suser(p))) { - PROC_UNLOCK(procp); - return error; - } - procp->p_pfsflags = flags; - break; - case PIOCGFL: - *(unsigned int*)ap->a_data = (unsigned int)procp->p_pfsflags; - /* FALLTHROUGH */ - case PIOCSTATUS: - psp = (struct procfs_status *)ap->a_data; - psp->state = (procp->p_step == 0); - psp->flags = procp->p_pfsflags; - psp->events = procp->p_stops; - if (procp->p_step) { - psp->why = procp->p_stype; - psp->val = procp->p_xstat; - } else { - psp->why = psp->val = 0; /* Not defined values */ - } - break; - case PIOCWAIT: - psp = (struct procfs_status *)ap->a_data; - if (procp->p_step == 0) { - error = msleep(&procp->p_stype, &procp->p_mtx, PWAIT | PCATCH, - "piocwait", 0); - if (error) { - PROC_UNLOCK(procp); - return error; - } - } - psp->state = 1; /* It stopped */ - psp->flags = procp->p_pfsflags; - psp->events = procp->p_stops; - psp->why = procp->p_stype; /* why it stopped */ - psp->val = procp->p_xstat; /* any extra info */ - break; - case PIOCCONT: /* Restart a proc */ - if (procp->p_step == 0) { - PROC_UNLOCK(procp); - return EINVAL; /* Can only start a stopped process */ - } - if ((signo = *(int*)ap->a_data) != 0) { - if (signo >= NSIG || signo <= 0) { - PROC_UNLOCK(procp); - return EINVAL; - } - psignal(procp, signo); - } - procp->p_step = 0; - wakeup(&procp->p_step); - break; - default: - PROC_UNLOCK(procp); - return (ENOTTY); - } - PROC_UNLOCK(procp); - return 0; -} - -/* - * _reclaim is called when getnewvnode() - * wants to make use of an entry on the vnode - * free list. at this time the filesystem needs - * to free any private data and remove the node - * from any private lists. - */ -static int -procfs_reclaim(ap) - struct vop_reclaim_args /* { - struct vnode *a_vp; - } */ *ap; -{ - - return (procfs_freevp(ap->a_vp)); -} - -/* - * _print is used for debugging. - * just print a readable description - * of (vp). - */ -static int -procfs_print(ap) - struct vop_print_args /* { - struct vnode *a_vp; - } */ *ap; -{ - struct pfsnode *pfs = VTOPFS(ap->a_vp); - - printf("tag VT_PROCFS, type %d, pid %ld, mode %x, flags %lx\n", - pfs->pfs_type, (long)pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags); - return (0); -} - -/* - * generic entry point for unsupported operations - */ -static int -procfs_badop() -{ - - return (EIO); -} - -/* - * Invent attributes for pfsnode (vp) and store - * them in (vap). - * Directories lengths are returned as zero since - * any real length would require the genuine size - * to be computed, and nothing cares anyway. - * - * this is relatively minimal for procfs. - */ -static int -procfs_getattr(ap) - struct vop_getattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ - struct pfsnode *pfs = VTOPFS(ap->a_vp); - struct vattr *vap = ap->a_vap; - struct proc *procp; - int error; - - /* - * First make sure that the process and its credentials - * still exist. - */ - switch (pfs->pfs_type) { - case Proot: - case Pcurproc: - procp = NULL; - break; - - default: - procp = PFIND(pfs->pfs_pid); - if (procp == NULL) - return (ENOENT); - if (procp->p_cred == NULL || procp->p_ucred == NULL) { - PROC_UNLOCK(procp); - return (ENOENT); - } - - if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) { - PROC_UNLOCK(procp); - return (ENOENT); - } - PROC_UNLOCK(procp); - } - - error = 0; - - /* start by zeroing out the attributes */ - VATTR_NULL(vap); - - /* next do all the common fields */ - vap->va_type = ap->a_vp->v_type; - vap->va_mode = pfs->pfs_mode; - vap->va_fileid = pfs->pfs_fileno; - vap->va_flags = 0; - vap->va_blocksize = PAGE_SIZE; - vap->va_bytes = vap->va_size = 0; - vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; - - /* - * Make all times be current TOD. - * It would be possible to get the process start - * time from the p_stat structure, but there's - * no "file creation" time stamp anyway, and the - * p_stat structure is not addressible if u. gets - * swapped out for that process. - */ - nanotime(&vap->va_ctime); - vap->va_atime = vap->va_mtime = vap->va_ctime; - - /* - * If the process has exercised some setuid or setgid - * privilege, then rip away read/write permission so - * that only root can gain access. - */ - switch (pfs->pfs_type) { - case Pctl: - case Pregs: - case Pfpregs: - case Pdbregs: - if (procp->p_flag & P_SUGID) - vap->va_mode &= ~((VREAD|VWRITE)| - ((VREAD|VWRITE)>>3)| - ((VREAD|VWRITE)>>6)); - break; - case Pmem: - /* Retain group kmem readablity. */ - PROC_LOCK(procp); - if (procp->p_flag & P_SUGID) - vap->va_mode &= ~(VREAD|VWRITE); - PROC_UNLOCK(procp); - break; - default: - break; - } - - /* - * now do the object specific fields - * - * The size could be set from struct reg, but it's hardly - * worth the trouble, and it puts some (potentially) machine - * dependent data into this machine-independent code. If it - * becomes important then this function should break out into - * a per-file stat function in the corresponding .c file. - */ - - vap->va_nlink = 1; - if (procp) { - PROC_LOCK(procp); - vap->va_uid = procp->p_ucred->cr_uid; - vap->va_gid = procp->p_ucred->cr_gid; - PROC_UNLOCK(procp); - } - - switch (pfs->pfs_type) { - case Proot: - /* - * Set nlink to 1 to tell fts(3) we don't actually know. - */ - vap->va_nlink = 1; - vap->va_uid = 0; - vap->va_gid = 0; - vap->va_size = vap->va_bytes = DEV_BSIZE; - break; - - case Pcurproc: { - char buf[16]; /* should be enough */ - vap->va_uid = 0; - vap->va_gid = 0; - vap->va_size = vap->va_bytes = - snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid); - break; - } - - case Pproc: - vap->va_nlink = nproc_targets; - vap->va_size = vap->va_bytes = DEV_BSIZE; - break; - - case Pfile: { - char *fullpath, *freepath; - error = textvp_fullpath(procp, &fullpath, &freepath); - if (error == 0) { - vap->va_size = strlen(fullpath); - free(freepath, M_TEMP); - } else { - vap->va_size = sizeof("unknown") - 1; - error = 0; - } - vap->va_bytes = vap->va_size; - break; - } - - case Pmem: - /* - * If we denied owner access earlier, then we have to - * change the owner to root - otherwise 'ps' and friends - * will break even though they are setgid kmem. *SIGH* - */ - PROC_LOCK(procp); - if (procp->p_flag & P_SUGID) - vap->va_uid = 0; - else - vap->va_uid = procp->p_ucred->cr_uid; - PROC_UNLOCK(procp); - vap->va_gid = KMEM_GROUP; - break; - - case Pregs: - vap->va_bytes = vap->va_size = sizeof(struct reg); - break; - - case Pfpregs: - vap->va_bytes = vap->va_size = sizeof(struct fpreg); - break; - - case Pdbregs: - vap->va_bytes = vap->va_size = sizeof(struct dbreg); - break; - - case Ptype: - case Pmap: - case Pctl: - case Pstatus: - case Pnote: - case Pnotepg: - case Pcmdline: - case Prlimit: - break; - - default: - panic("procfs_getattr"); - } - - return (error); -} - -static int -procfs_setattr(ap) - struct vop_setattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ - - if (ap->a_vap->va_flags != VNOVAL) - return (EOPNOTSUPP); - - /* - * just fake out attribute setting - * it's not good to generate an error - * return, otherwise things like creat() - * will fail when they try to set the - * file length to 0. worse, this means - * that echo $note > /proc/$pid/note will fail. - */ - - return (0); -} - -/* - * implement access checking. - * - * actually, the check for super-user is slightly - * broken since it will allow read access to write-only - * objects. this doesn't cause any particular trouble - * but does mean that the i/o entry points need to check - * that the operation really does make sense. - */ -static int -procfs_access(ap) - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct proc *a_p; - } */ *ap; -{ - struct pfsnode *pfs = VTOPFS(ap->a_vp); - struct vnode *vp = ap->a_vp; - struct proc *procp; - struct vattr *vap; - struct vattr vattr; - int error; - - switch (pfs->pfs_type) { - case Proot: - case Pcurproc: - break; - default: - procp = PFIND(pfs->pfs_pid); - if (procp == NULL) - return (ENOENT); - if (p_can(ap->a_p, procp, P_CAN_SEE, NULL)) { - PROC_UNLOCK(procp); - return (ENOENT); - } - PROC_UNLOCK(procp); - } - - vap = &vattr; - error = VOP_GETATTR(vp, vap, ap->a_cred, ap->a_p); - if (error) - return (error); - - return (vaccess(vp->v_type, vap->va_mode, vap->va_uid, vap->va_gid, - ap->a_mode, ap->a_cred, NULL)); -} - -/* - * lookup. this is incredibly complicated in the - * general case, however for most pseudo-filesystems - * very little needs to be done. - * - * unless you want to get a migraine, just make sure your - * filesystem doesn't do any locking of its own. otherwise - * read and inwardly digest ufs_lookup(). - */ -static int -procfs_lookup(ap) - struct vop_lookup_args /* { - struct vnode * a_dvp; - struct vnode ** a_vpp; - struct componentname * a_cnp; - } */ *ap; -{ - struct componentname *cnp = ap->a_cnp; - struct vnode **vpp = ap->a_vpp; - struct vnode *dvp = ap->a_dvp; - char *pname = cnp->cn_nameptr; - struct proc *curp = cnp->cn_proc; - struct proc_target *pt; - pid_t pid; - struct pfsnode *pfs; - struct proc *p; - int i; - - *vpp = NULL; - - if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME || - cnp->cn_nameiop == CREATE) - return (EROFS); - - if (cnp->cn_namelen == 1 && *pname == '.') { - *vpp = dvp; - VREF(dvp); - /* vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, curp); */ - return (0); - } - - pfs = VTOPFS(dvp); - switch (pfs->pfs_type) { - case Proot: - if (cnp->cn_flags & ISDOTDOT) - return (EIO); - - if (CNEQ(cnp, "curproc", 7)) - return (procfs_allocvp(dvp->v_mount, vpp, 0, Pcurproc)); - - pid = atopid(pname, cnp->cn_namelen); - if (pid == NO_PID) - break; - - p = PFIND(pid); - if (p == NULL) - break; - - if (p_can(curp, p, P_CAN_SEE, NULL)) { - PROC_UNLOCK(p); - break; - } - PROC_UNLOCK(p); - - return (procfs_allocvp(dvp->v_mount, vpp, pid, Pproc)); - - case Pproc: - if (cnp->cn_flags & ISDOTDOT) - return (procfs_root(dvp->v_mount, vpp)); - - p = PFIND(pfs->pfs_pid); - if (p == NULL) - break; - - for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) { - if (cnp->cn_namelen == pt->pt_namlen && - bcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 && - (pt->pt_valid == NULL || (*pt->pt_valid)(p))) - goto found; - } - PROC_UNLOCK(p); - break; - found: - PROC_UNLOCK(p); - return (procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, - pt->pt_pfstype)); - - default: - return (ENOTDIR); - } - - return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS); -} - -/* - * Does this process have a text file? - */ -int -procfs_validfile(p) - struct proc *p; -{ - - return (procfs_findtextvp(p) != NULLVP); -} - -/* - * readdir() returns directory entries from pfsnode (vp). - * - * We generate just one directory entry at a time, as it would probably - * not pay off to buffer several entries locally to save uiomove calls. - */ -static int -procfs_readdir(ap) - struct vop_readdir_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - int *a_eofflag; - int *a_ncookies; - u_long **a_cookies; - } */ *ap; -{ - struct uio *uio = ap->a_uio; - struct dirent d; - struct dirent *dp = &d; - struct pfsnode *pfs; - int count, error, i, off; - static u_int delen; - - if (!delen) { - - d.d_namlen = PROCFS_NAMELEN; - delen = GENERIC_DIRSIZ(&d); - } - - pfs = VTOPFS(ap->a_vp); - - off = (int)uio->uio_offset; - if (off != uio->uio_offset || off < 0 || - off % delen != 0 || uio->uio_resid < delen) - return (EINVAL); - - error = 0; - count = 0; - i = off / delen; - - switch (pfs->pfs_type) { - /* - * this is for the process-specific sub-directories. - * all that is needed to is copy out all the entries - * from the procent[] table (top of this file). - */ - case Pproc: { - struct proc *p; - struct proc_target *pt; - - p = PFIND(pfs->pfs_pid); - if (p == NULL) - break; - if (p_can(curproc, p, P_CAN_SEE, NULL)) { - PROC_UNLOCK(p); - break; - } - - for (pt = &proc_targets[i]; - uio->uio_resid >= delen && i < nproc_targets; pt++, i++) { - if (pt->pt_valid && (*pt->pt_valid)(p) == 0) - continue; - - dp->d_reclen = delen; - dp->d_fileno = PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype); - dp->d_namlen = pt->pt_namlen; - bcopy(pt->pt_name, dp->d_name, pt->pt_namlen + 1); - dp->d_type = pt->pt_type; - - if ((error = uiomove((caddr_t)dp, delen, uio)) != 0) - break; - } - PROC_UNLOCK(p); - - break; - } - - /* - * this is for the root of the procfs filesystem - * what is needed is a special entry for "curproc" - * followed by an entry for each process on allproc -#ifdef PROCFS_ZOMBIE - * and zombproc. -#endif - */ - - case Proot: { -#ifdef PROCFS_ZOMBIE - int doingzomb = 0; -#endif - int pcnt = 0; - struct proc *p; - - sx_slock(&allproc_lock); - p = LIST_FIRST(&allproc); - for (; p && uio->uio_resid >= delen; i++, pcnt++) { - bzero((char *) dp, delen); - dp->d_reclen = delen; - - switch (i) { - case 0: /* `.' */ - case 1: /* `..' */ - dp->d_fileno = PROCFS_FILENO(0, Proot); - dp->d_namlen = i + 1; - bcopy("..", dp->d_name, dp->d_namlen); - dp->d_name[i + 1] = '\0'; - dp->d_type = DT_DIR; - break; - - case 2: - dp->d_fileno = PROCFS_FILENO(0, Pcurproc); - dp->d_namlen = 7; - bcopy("curproc", dp->d_name, 8); - dp->d_type = DT_LNK; - break; - - default: - while (pcnt < i) { - p = LIST_NEXT(p, p_list); - if (p == NULL) - goto done; - if (p_can(curproc, p, P_CAN_SEE, NULL)) - continue; - pcnt++; - } - while (p_can(curproc, p, P_CAN_SEE, NULL)) { - p = LIST_NEXT(p, p_list); - if (p == NULL) - goto done; - } - dp->d_fileno = PROCFS_FILENO(p->p_pid, Pproc); - dp->d_namlen = sprintf(dp->d_name, "%ld", - (long)p->p_pid); - dp->d_type = DT_DIR; - p = LIST_NEXT(p, p_list); - break; - } - - if ((error = uiomove((caddr_t)dp, delen, uio)) != 0) - break; - } - done: - -#ifdef PROCFS_ZOMBIE - if (p == NULL && doingzomb == 0) { - doingzomb = 1; - p = LIST_FIRST(&zombproc); - goto again; - } -#endif - - sx_sunlock(&allproc_lock); - break; - - } - - default: - error = ENOTDIR; - break; - } - - uio->uio_offset = i * delen; - - return (error); -} - -/* - * readlink reads the link of `curproc' or `file' - */ -static int -procfs_readlink(ap) - struct vop_readlink_args *ap; -{ - char buf[16]; /* should be enough */ - struct proc *procp; - struct vnode *vp = ap->a_vp; - struct pfsnode *pfs = VTOPFS(vp); - char *fullpath, *freepath; - int error, len; - - switch (pfs->pfs_type) { - case Pcurproc: - if (pfs->pfs_fileno != PROCFS_FILENO(0, Pcurproc)) - return (EINVAL); - - len = snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid); - - return (uiomove(buf, len, ap->a_uio)); - /* - * There _should_ be no way for an entire process to disappear - * from under us... - */ - case Pfile: - procp = PFIND(pfs->pfs_pid); - if (procp == NULL || procp->p_cred == NULL || - procp->p_ucred == NULL) { - if (procp != NULL) - PROC_UNLOCK(procp); - printf("procfs_readlink: pid %d disappeared\n", - pfs->pfs_pid); - return (uiomove("unknown", sizeof("unknown") - 1, - ap->a_uio)); - } - PROC_UNLOCK(procp); - error = textvp_fullpath(procp, &fullpath, &freepath); - if (error != 0) - return (uiomove("unknown", sizeof("unknown") - 1, - ap->a_uio)); - error = uiomove(fullpath, strlen(fullpath), ap->a_uio); - free(freepath, M_TEMP); - return (error); - default: - return (EINVAL); - } -} - -/* - * convert decimal ascii to pid_t - */ -static pid_t -atopid(b, len) - const char *b; - u_int len; -{ - pid_t p = 0; - - while (len--) { - char c = *b++; - if (c < '0' || c > '9') - return (NO_PID); - p = 10 * p + (c - '0'); - if (p > PID_MAX) - return (NO_PID); - } - - return (p); -} - -/* - * procfs vnode operations. - */ -vop_t **procfs_vnodeop_p; -static struct vnodeopv_entry_desc procfs_vnodeop_entries[] = { - { &vop_default_desc, (vop_t *) vop_defaultop }, - { &vop_access_desc, (vop_t *) procfs_access }, - { &vop_advlock_desc, (vop_t *) procfs_badop }, - { &vop_close_desc, (vop_t *) procfs_close }, - { &vop_create_desc, (vop_t *) procfs_badop }, - { &vop_getattr_desc, (vop_t *) procfs_getattr }, - { &vop_link_desc, (vop_t *) procfs_badop }, - { &vop_lookup_desc, (vop_t *) procfs_lookup }, - { &vop_mkdir_desc, (vop_t *) procfs_badop }, - { &vop_mknod_desc, (vop_t *) procfs_badop }, - { &vop_open_desc, (vop_t *) procfs_open }, - { &vop_pathconf_desc, (vop_t *) vop_stdpathconf }, - { &vop_print_desc, (vop_t *) procfs_print }, - { &vop_read_desc, (vop_t *) procfs_rw }, - { &vop_readdir_desc, (vop_t *) procfs_readdir }, - { &vop_readlink_desc, (vop_t *) procfs_readlink }, - { &vop_reclaim_desc, (vop_t *) procfs_reclaim }, - { &vop_remove_desc, (vop_t *) procfs_badop }, - { &vop_rename_desc, (vop_t *) procfs_badop }, - { &vop_rmdir_desc, (vop_t *) procfs_badop }, - { &vop_setattr_desc, (vop_t *) procfs_setattr }, - { &vop_symlink_desc, (vop_t *) procfs_badop }, - { &vop_write_desc, (vop_t *) procfs_rw }, - { &vop_ioctl_desc, (vop_t *) procfs_ioctl }, - { NULL, NULL } -}; -static struct vnodeopv_desc procfs_vnodeop_opv_desc = - { &procfs_vnodeop_p, procfs_vnodeop_entries }; - -VNODEOP_SET(procfs_vnodeop_opv_desc); |