add new procfs code, from Jan-Simon Pendry, jsp@sequent.com.

This is pretty-much "virgin", so that diffs can be done later.
This commit is contained in:
cgd 1994-01-05 07:51:08 +00:00
parent 8e1f0c6b2f
commit 699e3be9e9
10 changed files with 2234 additions and 983 deletions

114
sys/miscfs/procfs/README Normal file
View File

@ -0,0 +1,114 @@
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
at 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.
writing is only allowed to a stopped process.
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.
From: Id: README,v 4.1 1993/12/17 10:47:45 jsp Rel
$Id: README,v 1.1 1994/01/05 07:51:08 cgd Exp $

282
sys/miscfs/procfs/procfs.h Normal file
View File

@ -0,0 +1,282 @@
/*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Jan-Simon Pendry
* 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.
*
* From:
* Id: procfs.h,v 4.1 1993/12/17 10:47:45 jsp Rel
*
* $Id: procfs.h,v 1.1 1994/01/05 07:51:12 cgd Exp $
*/
/*
* The different types of node in a procfs filesystem
*/
typedef enum {
Proot, /* the filesystem root */
Pproc, /* a process-specific sub-directory */
Pfile, /* the executable file */
Pmem, /* the process's memory image */
Pregs, /* the process's register set */
Pctl, /* process control */
Pstatus, /* process status */
Pnote, /* process notifier */
Pnotepg /* process group notifier */
} 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 */
};
#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 */
/*
* Kernel stuff follows
*/
#ifdef KERNEL
#ifndef VT_PROCFS
#define VT_PROCFS VT_UFS
#endif
#define NDEQ(ndp, s, len) \
((ndp)->ni_namelen == (len) && \
(bcmp((s), (ndp)->ni_ptr, (len)) == 0))
/*
* Format of a directory entry in /proc, ...
* This must map onto struct dirent (see <dirent.h>)
*/
#define PROCFS_NAMELEN 8
struct pfsdent {
u_long d_fileno;
u_short d_reclen;
u_short d_namlen;
char d_name[PROCFS_NAMELEN];
};
#define UIO_MX sizeof(struct pfsdent)
#define PROCFS_FILENO(pid, type) \
(((type) == Proot) ? \
2 : \
((((pid)+1) << 3) + ((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;
};
extern int vfs_getuserstr __P((struct uio *, char *, int *));
extern vfs_namemap_t *vfs_findname __P((vfs_namemap_t *, char *, int));
struct reg;
#define PFIND(pid) ((pid) ? pfind(pid) : &proc0)
extern int procfs_freevp __P((struct vnode *));
extern int procfs_allocvp __P((struct mount *, struct vnode **, long, pfstype));
extern struct vnode *procfs_findtextvp __P((struct proc *));
extern int procfs_sstep __P((struct proc *));
extern int procfs_read_regs __P((struct proc *, struct reg *));
extern int procfs_write_regs __P((struct proc *, struct reg *));
extern int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_rw __P((struct vnode *, struct uio *, int, struct ucred *));
#define PROCFS_LOCKED 0x01
#define PROCFS_WANT 0x02
extern struct vnodeops procfs_vnodeops;
extern struct vfsops procfs_vfsops;
/*
* Prototypes for procfs vnode ops
*/
int procfs_badop(); /* varargs */
int procfs_rw __P((
struct vnode *vp,
struct uio *uio,
int ioflag,
struct ucred *cred));
int procfs_lookup __P((
struct vnode *vp,
struct nameidata *ndp,
struct proc *p));
#define procfs_create ((int (*) __P(( \
struct nameidata *ndp, \
struct vattr *vap, \
struct proc *p))) procfs_badop)
#define procfs_mknod ((int (*) __P(( \
struct nameidata *ndp, \
struct vattr *vap, \
struct ucred *cred, \
struct proc *p))) procfs_badop)
int procfs_open __P((
struct vnode *vp,
int mode,
struct ucred *cred,
struct proc *p));
int procfs_close __P((
struct vnode *vp,
int fflag,
struct ucred *cred,
struct proc *p));
int procfs_access __P((
struct vnode *vp,
int mode,
struct ucred *cred,
struct proc *p));
int procfs_getattr __P((
struct vnode *vp,
struct vattr *vap,
struct ucred *cred,
struct proc *p));
int procfs_setattr __P((
struct vnode *vp,
struct vattr *vap,
struct ucred *cred,
struct proc *p));
#define procfs_read procfs_rw
#define procfs_write procfs_rw
int procfs_ioctl __P((
struct vnode *vp,
int command,
caddr_t data,
int fflag,
struct ucred *cred,
struct proc *p));
#define procfs_select ((int (*) __P(( \
struct vnode *vp, \
int which, \
int fflags, \
struct ucred *cred, \
struct proc *p))) procfs_badop)
#define procfs_mmap ((int (*) __P(( \
struct vnode *vp, \
int fflags, \
struct ucred *cred, \
struct proc *p))) procfs_badop)
#define procfs_fsync ((int (*) __P(( \
struct vnode *vp, \
int fflags, \
struct ucred *cred, \
int waitfor, \
struct proc *p))) procfs_badop)
#define procfs_seek ((int (*) __P(( \
struct vnode *vp, \
off_t oldoff, \
off_t newoff, \
struct ucred *cred))) procfs_badop)
#define procfs_remove ((int (*) __P(( \
struct nameidata *ndp, \
struct proc *p))) procfs_badop)
#define procfs_link ((int (*) __P(( \
struct vnode *vp, \
struct nameidata *ndp, \
struct proc *p))) procfs_badop)
#define procfs_rename ((int (*) __P(( \
struct nameidata *fndp, \
struct nameidata *tdnp, \
struct proc *p))) procfs_badop)
#define procfs_mkdir ((int (*) __P(( \
struct nameidata *ndp, \
struct vattr *vap, \
struct proc *p))) procfs_badop)
#define procfs_rmdir ((int (*) __P(( \
struct nameidata *ndp, \
struct proc *p))) procfs_badop)
#define procfs_symlink ((int (*) __P(( \
struct nameidata *ndp, \
struct vattr *vap, \
char *target, \
struct proc *p))) procfs_badop)
int procfs_readdir __P((
struct vnode *vp,
struct uio *uio,
struct ucred *cred,
int *eofflagp,
u_int *cookies,
int ncookies));
#define procfs_readlink ((int (*) __P(( \
struct vnode *vp, \
struct uio *uio, \
struct ucred *cred))) procfs_badop)
int procfs_abortop __P((
struct nameidata *ndp));
int procfs_inactive __P((
struct vnode *vp,
struct proc *p));
int procfs_reclaim __P((
struct vnode *vp));
#define procfs_lock ((int (*) __P(( \
struct vnode *vp))) nullop)
#define procfs_unlock ((int (*) __P(( \
struct vnode *vp))) nullop)
int procfs_bmap __P((
struct vnode *vp,
daddr_t bn,
struct vnode **vpp,
daddr_t *bnp));
#define procfs_strategy ((int (*) __P(( \
struct buf *bp))) procfs_badop)
int procfs_print __P((
struct vnode *vp));
#define procfs_islocked ((int (*) __P(( \
struct vnode *vp))) nullop)
#define procfs_advlock ((int (*) __P(( \
struct vnode *vp, \
caddr_t id, \
int op, \
struct flock *fl, \
int flags))) procfs_badop)
#endif /* KERNEL */

View File

@ -0,0 +1,302 @@
/*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Jan-Simon Pendry
* 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.
*
* From:
* Id: procfs_ctl.c,v 4.1 1993/12/17 10:47:45 jsp Rel
*
* $Id: procfs_ctl.c,v 1.1 1994/01/05 07:51:15 cgd Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/ioctl.h>
#include <sys/tty.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
#include <miscfs/procfs/procfs.h>
/*
* 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 & STRC))
#define FIX_SSTEP(p) { \
if ((p)->p_stat & SSSTEP) { \
procfs_fix_sstep(p); \
(p)->p_stat &= ~SSSTEP; \
} \
}
#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(curp, p, op)
struct proc *curp;
struct proc *p;
int op;
{
int error;
/*
* Attach - attaches the target process for debugging
* by the calling process.
*/
if (op == PROCFS_CTL_ATTACH) {
/* check whether already being traced */
if (p->p_flag & STRC)
return (EBUSY);
/* can't trace yourself! */
if (p->p_pid == curp->p_pid)
return (EINVAL);
/*
* 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 |= STRC;
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);
return (0);
}
/*
* Target process must be stopped, owned by (curp) and
* be set up for tracing (STRC flag set).
* Allow DETACH to take place at any time for sanity.
* Allow WAIT any time, of course.
*/
switch (op) {
case PROCFS_CTL_DETACH:
case PROCFS_CTL_WAIT:
break;
default:
if (!TRACE_WAIT_P(curp, p))
return (EBUSY);
}
/*
* do single-step fixup if needed
*/
FIX_SSTEP(p);
/*
* Don't deliver any signal by default.
* To continue with a signal, just send
* the signal name to the ctl file
*/
p->p_xstat = 0;
switch (op) {
/*
* Detach. Cleans up the target process, reparent it if possible
* and set it running once more.
*/
case PROCFS_CTL_DETACH:
/* if not being traced, then this is a painless no-op */
if ((p->p_flag & STRC) == 0)
return (0);
/* not being traced any more */
p->p_flag &= ~STRC;
/* give process back to original parent */
if (p->p_oppid != p->p_pptr->p_pid) {
struct proc *pp;
pp = pfind(p->p_oppid);
if (pp)
proc_reparent(p, pp);
}
p->p_oppid = 0;
p->p_flag &= ~SWTED; /* XXX ? */
wakeup((caddr_t) curp); /* XXX for CTL_WAIT below ? */
break;
/*
* Step. Let the target process execute a single instruction.
*/
case PROCFS_CTL_STEP:
procfs_sstep(p);
break;
/*
* Run. Let the target process continue running until a breakpoint
* or some other trap.
*/
case PROCFS_CTL_RUN:
break;
/*
* Wait for the target process to stop.
* If the target is not being traced then just wait
* to enter
*/
case PROCFS_CTL_WAIT:
error = 0;
if (p->p_flag & STRC) {
while (error == 0 &&
(p->p_stat != SSTOP) &&
(p->p_flag & STRC) &&
(p->p_pptr == curp)) {
error = tsleep((caddr_t) p,
PWAIT|PCATCH, "procfsx", 0);
}
if (error == 0 && !TRACE_WAIT_P(curp, p))
error = EBUSY;
} else {
while (error == 0 && p->p_stat != SSTOP) {
error = tsleep((caddr_t) p,
PWAIT|PCATCH, "procfs", 0);
}
}
return (error);
default:
panic("procfs_control");
}
if (p->p_stat == SSTOP)
setrun(p);
return (0);
}
pfs_doctl(curp, p, pfs, uio)
struct proc *curp;
struct pfsnode *pfs;
struct uio *uio;
struct proc *p;
{
int len = uio->uio_resid;
int xlen;
int error;
struct sigmap *sm;
char msg[PROCFS_CTLLEN+1];
char *cp = msg;
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) {
if (TRACE_WAIT_P(curp, p)) {
p->p_xstat = nm->nm_val;
FIX_SSTEP(p);
setrun(p);
} else {
psignal(p, nm->nm_val);
}
error = 0;
}
}
return (error);
}

View File

@ -0,0 +1,300 @@
/*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Jan-Simon Pendry
* 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.
*
* From:
* Id: procfs_mem.c,v 4.1 1993/12/17 10:47:45 jsp Rel
*
* $Id: procfs_mem.c,v 1.1 1994/01/05 07:51:18 cgd Exp $
*/
/*
* This is a lightly hacked and merged version
* of sef's pread/pwrite functions
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <miscfs/procfs/procfs.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
static int
pfs_rwmem(p, uio)
struct proc *p;
struct uio *uio;
{
int error;
int writing;
writing = uio->uio_rw == UIO_WRITE;
/*
* 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 map, tmap;
vm_object_t object;
vm_offset_t kva;
vm_offset_t uva;
int page_offset; /* offset into page */
vm_offset_t pageno; /* page number */
vm_map_entry_t out_entry;
vm_prot_t out_prot;
vm_page_t m;
boolean_t wired, single_use;
vm_offset_t off;
u_int len;
int fix_prot;
uva = (vm_offset_t) uio->uio_offset;
if (uva > VM_MAXUSER_ADDRESS) {
error = 0;
break;
}
/*
* 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);
/*
* The map we want...
*/
map = &p->p_vmspace->vm_map;
/*
* Check the permissions for the area we're interested
* in.
*/
fix_prot = 0;
if (writing)
fix_prot = !vm_map_check_protection(map, pageno,
pageno + PAGE_SIZE, VM_PROT_WRITE);
if (fix_prot) {
/*
* If the page is not writable, we make it so.
* XXX It is possible that a page may *not* be
* read/executable, if a process changes that!
* We will assume, for now, that a page is either
* VM_PROT_ALL, or VM_PROT_READ|VM_PROT_EXECUTE.
*/
error = vm_map_protect(map, pageno,
pageno + PAGE_SIZE, VM_PROT_ALL, 0);
if (error)
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,
writing ? VM_PROT_WRITE : VM_PROT_READ,
&out_entry, &object, &off, &out_prot,
&wired, &single_use);
/*
* We're done with tmap now.
*/
if (!error)
vm_map_lookup_done(tmap, out_entry);
/*
* Fault the page in...
*/
if (!error && writing && object->shadow) {
m = vm_page_lookup(object, off);
if (m == 0 || m->copy_on_write)
error = vm_fault(map, pageno,
VM_PROT_WRITE, FALSE);
}
/* Find space in kernel_map for the page we're interested in */
if (!error)
error = vm_map_find(kernel_map, object, off, &kva,
PAGE_SIZE, 1);
if (!error) {
/*
* Neither vm_map_lookup() nor vm_map_find() appear
* to add a reference count to the object, so we do
* that here and now.
*/
vm_object_reference(object);
/*
* Mark the page we just found as pageable.
*/
error = vm_map_pageable(kernel_map, kva,
kva + PAGE_SIZE, 0);
/*
* Now do the i/o move.
*/
if (!error)
error = uiomove(kva + page_offset, len, uio);
vm_map_remove(kernel_map, kva, kva + PAGE_SIZE);
}
if (fix_prot)
vm_map_protect(map, pageno, pageno + PAGE_SIZE,
VM_PROT_READ|VM_PROT_EXECUTE, 0);
} while (error == 0 && uio->uio_resid > 0);
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.
*/
pfs_domem(curp, p, pfs, uio)
struct proc *curp;
struct proc *p;
struct pfsnode *pfs;
struct uio *uio;
{
int error;
if (uio->uio_resid == 0)
return (0);
error = pfs_rwmem(p, uio);
return (error);
}
/*
* Given process (p), find the vnode from which
* it's 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.
*/
struct vnode *
procfs_findtextvp(p)
struct proc *p;
{
return (p->p_textvp);
}
#ifdef probably_never
/*
* Given process (p), find the vnode from which
* it's text segment is being mapped.
*
* (This is here, rather than in procfs_subr in order
* to keep all the VM related code in one place.)
*/
struct vnode *
procfs_findtextvp(p)
struct proc *p;
{
int error;
vm_object_t object;
vm_offset_t pageno; /* page number */
/* find a vnode pager for the user address space */
for (pageno = VM_MIN_ADDRESS;
pageno < VM_MAXUSER_ADDRESS;
pageno += PAGE_SIZE) {
vm_map_t map;
vm_map_entry_t out_entry;
vm_prot_t out_prot;
boolean_t wired, single_use;
vm_offset_t off;
map = &p->p_vmspace->vm_map;
error = vm_map_lookup(&map, pageno,
VM_PROT_READ,
&out_entry, &object, &off, &out_prot,
&wired, &single_use);
if (!error) {
vm_pager_t pager;
printf("procfs: found object\n");
vm_map_lookup_done(map, out_entry);
printf("procfs: object = %x\n", object);
/*
* At this point, assuming no errors, object
* is the VM object mapping UVA (pageno).
* Ensure it has a vnode pager, then grab
* the vnode from that pager's handle.
*/
pager = object->pager;
printf("procfs: pager = %x\n", pager);
if (pager)
printf("procfs: found pager, type = %d\n", pager->pg_type);
if (pager && pager->pg_type == PG_VNODE) {
struct vnode *vp;
vp = (struct vnode *) pager->pg_handle;
printf("procfs: vp = 0x%x\n", vp);
return (vp);
}
}
}
printf("procfs: not found\n");
return (0);
}
#endif /* notyet */

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Jan-Simon Pendry
* 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.
*
* From:
* Id: procfs_note.c,v 4.1 1993/12/17 10:47:45 jsp Rel
*
* $Id: procfs_note.c,v 1.1 1994/01/05 07:51:22 cgd Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/signal.h>
#include <miscfs/procfs/procfs.h>
pfs_donote(curp, p, pfs, uio)
struct proc *curp;
struct proc *p;
struct pfsnode *pfs;
struct uio *uio;
{
int len = uio->uio_resid;
int xlen;
int error;
struct sigmap *sm;
char note[PROCFS_NOTELEN+1];
char *cp = note;
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);
}

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Jan-Simon Pendry
* 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.
*
* From:
* Id: procfs_regs.c,v 4.1 1993/12/17 10:47:45 jsp Rel
*
* $Id: procfs_regs.c,v 1.1 1994/01/05 07:51:24 cgd Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <machine/reg.h>
#include <miscfs/procfs/procfs.h>
pfs_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;
kl = sizeof(r);
kv = (char *) &r;
kv += uio->uio_offset;
kl -= uio->uio_offset;
if (kl > uio->uio_resid)
kl = uio->uio_resid;
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_flag & SSTOP) == 0)
error = EBUSY;
else
error = procfs_write_regs(p, &r);
}
uio->uio_offset = 0;
return (error);
}

View File

@ -0,0 +1,139 @@
/*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Jan-Simon Pendry
* 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.
*
* From:
* Id: procfs_status.c,v 4.1 1993/12/17 10:47:45 jsp Rel
*
* $Id: procfs_status.c,v 1.1 1994/01/05 07:51:27 cgd Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/ioctl.h>
#include <sys/tty.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
#include <miscfs/procfs/procfs.h>
pfs_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;
ppid = p->p_pptr ? p->p_pptr->p_pid : 0,
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 uid groups ... */
ps = psbuf;
bcopy(p->p_comm, ps, MAXCOMLEN);
ps[MAXCOMLEN] = '\0';
ps += strlen(ps);
ps += sprintf(ps, " %d %d %d %d ", pid, ppid, pgid, sid);
if ((p->p_flag&SCTTY) && (tp = sess->s_ttyp))
ps += sprintf(ps, "%d,%d ", major(tp->t_dev), minor(tp->t_dev));
else
ps += sprintf(ps, "%d,%d ", -1, -1);
sep = "";
if (sess->s_ttyvp) {
ps += sprintf(ps, "%sctty", sep);
sep = ",";
}
if (SESS_LEADER(p)) {
ps += sprintf(ps, "%ssldr", sep);
sep = ",";
}
if (*sep != ',')
ps += sprintf(ps, "noflags");
if (p->p_stat & SLOAD)
ps += sprintf(ps, " %d %d",
p->p_stats->p_start.tv_sec,
p->p_stats->p_start.tv_usec);
else
ps += sprintf(ps, " -1 -1");
ps += sprintf(ps, " %d %d %d %d",
p->p_utime.tv_sec,
p->p_utime.tv_usec,
p->p_stime.tv_sec,
p->p_stime.tv_usec);
ps += sprintf(ps, " %s",
(p->p_wchan && p->p_wmesg) ? p->p_wmesg : "nochan");
cr = p->p_ucred;
ps += sprintf(ps, " %d %d", cr->cr_uid, cr->cr_gid);
for (i = 0; i < cr->cr_ngroups; i++)
ps += sprintf(ps, " %d", cr->cr_groups[i]);
ps += sprintf(ps, "\n");
xlen = ps - psbuf;
xlen -= uio->uio_offset;
ps = psbuf + uio->uio_offset;
xlen = min(xlen, uio->uio_resid);
if (xlen <= 0)
error = 0;
else
error = uiomove(ps, xlen, uio);
return (error);
}

View File

@ -1,7 +1,11 @@
/*
* Copyright (c) 1993 Paul Kranenburg
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Jan-Simon Pendry
* 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:
@ -12,369 +16,289 @@
* 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 Paul Kranenburg.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
* 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.
*
* $Id: procfs_subr.c,v 1.4 1993/12/18 03:58:08 mycroft Exp $
* From:
* Id: procfs_subr.c,v 4.1 1993/12/17 10:47:45 jsp Rel
*
* $Id: procfs_subr.c,v 1.5 1994/01/05 07:51:29 cgd Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/ioctl.h>
#include <sys/proc.h>
#include <sys/buf.h>
#include <sys/vnode.h>
#include <sys/file.h>
#include <sys/resourcevar.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_kern.h>
#include <sys/kinfo.h>
#include <sys/kinfo_proc.h>
#include <miscfs/procfs/procfs.h>
#include <sys/procfs.h>
#include <miscfs/procfs/pfsnode.h>
#include <machine/vmparam.h>
static struct pfsnode *pfshead;
static int pfsvplock;
/*
* Get process address map (PIOCGMAP)
* 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
pfs_vmmap(procp, pfsp, pmapp)
struct proc *procp;
struct nfsnode *pfsp;
struct procmap *pmapp;
procfs_allocvp(mp, vpp, pid, pfs_type)
struct mount *mp;
struct vnode **vpp;
long pid;
pfstype pfs_type;
{
int error = 0;
vm_map_t map;
vm_map_entry_t entry;
struct procmap prmap;
int error;
struct pfsnode *pfs;
struct pfsnode **pp;
struct vnode *vp;
map = &procp->p_vmspace->vm_map;
vm_map_lock(map);
entry = map->header.next;
while (entry != &map->header) {
if (entry->is_a_map) {
vm_map_t submap = entry->object.share_map;
vm_map_entry_t subentry;
vm_map_lock(submap);
subentry = submap->header.next;
while (subentry != &submap->header) {
prmap.vaddr = subentry->start;
prmap.size = subentry->end - subentry->start;
prmap.offset = subentry->offset;
prmap.prot = subentry->protection;
error = copyout(&prmap, pmapp, sizeof(prmap));
if (error)
break;
pmapp++;
subentry = subentry->next;
}
vm_map_unlock(submap);
if (error)
break;
loop:
for (pfs = pfshead; pfs != 0; pfs = pfs->pfs_next) {
if (pfs->pfs_pid == pid &&
pfs->pfs_type == pfs_type &&
PFSTOV(pfs)->v_mount == mp) {
if (vget(pfs->pfs_vnode))
goto loop;
VOP_UNLOCK(pfs->pfs_vnode);
*vpp = pfs->pfs_vnode;
return (0);
}
prmap.vaddr = entry->start;
prmap.size = entry->end - entry->start;
prmap.offset = entry->offset;
prmap.prot = entry->protection;
error = copyout(&prmap, pmapp, sizeof(prmap));
if (error)
break;
pmapp++;
entry = entry->next;
}
vm_map_unlock(map);
return error;
}
/*
* Count number of VM entries of process (PIOCNMAP)
*/
int
pfs_vm_nentries(procp, pfsp)
struct proc *procp;
struct nfsnode *pfsp;
{
int count = 0;
vm_map_t map;
vm_map_entry_t entry;
map = &procp->p_vmspace->vm_map;
vm_map_lock(map);
entry = map->header.next;
while (entry != &map->header) {
if (entry->is_a_map)
count += entry->object.share_map->nentries;
else
count++;
entry = entry->next;
/*
* otherwise lock the vp list while we call getnewvnode
* since that can block.
*/
if (pfsvplock & PROCFS_LOCKED) {
pfsvplock |= PROCFS_WANT;
sleep((caddr_t) &pfsvplock, PINOD);
goto loop;
}
pfsvplock |= PROCFS_LOCKED;
vm_map_unlock(map);
return count;
}
/*
* Map process mapped file to file descriptor (PIOCGMAPFD)
*/
int
pfs_vmfd(procp, pfsp, vmfdp, p)
struct proc *procp;
struct pfsnode *pfsp;
struct vmfd *vmfdp;
struct proc *p;
{
int rv;
vm_map_t map;
vm_offset_t addr;
vm_size_t size;
vm_prot_t prot, maxprot;
vm_inherit_t inherit;
boolean_t shared;
vm_object_t object;
vm_offset_t objoff;
struct vnode *vp;
struct file *fp;
extern struct fileops vnops;
map = &procp->p_vmspace->vm_map;
addr = vmfdp->vaddr;
rv = vm_region(map, &addr, &size, &prot, &maxprot,
&inherit, &shared, &object, &objoff);
if (rv != KERN_SUCCESS)
return EINVAL;
while (object != NULL && object->pager == NULL)
object = object->shadow;
if (object == NULL || object->pager == NULL
/* Nobody seems to care || !object->pager_ready */ )
return ENOENT;
if (object->pager->pg_type != PG_VNODE)
return ENOENT;
/* We have a vnode pager, allocate file descriptor */
vp = (struct vnode *)object->pager->pg_handle;
if (VOP_ACCESS(vp, VREAD, p->p_ucred, p)) {
rv = EACCES;
goto out;
}
rv = falloc(p, &fp, &vmfdp->fd);
if (rv)
error = getnewvnode(VT_PROCFS, mp, &procfs_vnodeops, vpp);
if (error)
goto out;
VREF(vp);
fp->f_type = DTYPE_VNODE;
fp->f_ops = &vnops;
fp->f_data = (caddr_t)vp;
fp->f_flag = FREAD;
/* 4.4: at this point, need to allocate a pfsnode */
pfs = VTOPFS(*vpp);
pfs->pfs_next = 0;
pfs->pfs_pid = (pid_t) pid;
pfs->pfs_type = pfs_type;
pfs->pfs_vnode = *vpp;
pfs->pfs_flags = 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;
break;
case Pproc:
pfs->pfs_mode = (VREAD|VEXEC) |
(VREAD|VEXEC) >> 3 |
(VREAD|VEXEC) >> 6;
break;
case Pfile:
pfs->pfs_mode = (VREAD|VWRITE);
break;
case Pmem:
pfs->pfs_mode = (VREAD|VWRITE);
break;
case Pregs:
pfs->pfs_mode = (VREAD|VWRITE);
break;
case Pctl:
pfs->pfs_mode = (VWRITE);
break;
case Pstatus:
pfs->pfs_mode = (VREAD) |
(VREAD >> 3) |
(VREAD >> 6);
break;
case Pnote:
pfs->pfs_mode = (VWRITE);
break;
case Pnotepg:
pfs->pfs_mode = (VWRITE);
break;
default:
panic("procfs_allocvp");
}
/* add to procfs vnode list */
for (pp = &pfshead; *pp; pp = &(*pp)->pfs_next)
continue;
*pp = pfs;
out:
vm_object_unlock(object);
return rv;
}
pfsvplock &= ~PROCFS_LOCKED;
/*
* Vnode op for reading/writing.
*/
/* ARGSUSED */
pfs_doio(vp, uio, ioflag, cred)
struct vnode *vp;
register struct uio *uio;
int ioflag;
struct ucred *cred;
{
struct pfsnode *pfsp = VTOPFS(vp);
struct proc *procp;
int error = 0;
long n, on;
#ifdef DEBUG
if (pfs_debug)
printf("pfs_doio(%s): vp 0x%x, proc %x\n",
uio->uio_rw==UIO_READ?"R":"W", vp, uio->uio_procp);
#endif
#ifdef DIAGNOSTIC
if (vp->v_type != VPROC)
panic("pfs_doio vtype");
#endif
procp = pfsp->pfs_pid?pfind(pfsp->pfs_pid):&proc0;
if (!procp)
return ESRCH;
if (procp->p_flag & SSYS)
return EACCES;
if (uio->uio_resid == 0)
return (0);
if (uio->uio_offset < 0)
return (EINVAL);
do { /* One page at a time */
int rv;
vm_map_t map;
vm_offset_t offset;
vm_size_t size;
vm_prot_t oldprot = 0, prot, maxprot;
vm_inherit_t inherit;
boolean_t shared;
vm_object_t object;
vm_offset_t objoff;
vm_page_t m;
vm_offset_t kva;
on = uio->uio_offset - trunc_page(uio->uio_offset);
n = MIN(PAGE_SIZE-on, uio->uio_resid);
/* Map page into kernel space */
map = &procp->p_vmspace->vm_map;
#if 0
vm_map_print(map, 1);
#endif
offset = trunc_page(uio->uio_offset);
rv = vm_region(map, &offset, &size, &prot, &maxprot,
&inherit, &shared, &object, &objoff);
if (rv != KERN_SUCCESS)
return EINVAL;
vm_object_unlock(object);
if (uio->uio_rw == UIO_WRITE && (prot & VM_PROT_WRITE) == 0) {
oldprot = prot;
prot |= VM_PROT_WRITE;
rv = vm_protect(map, offset, PAGE_SIZE, FALSE, prot);
if (rv != KERN_SUCCESS)
return EPERM;
}
/* Just fault the page */
rv = vm_fault(map, offset, prot, FALSE);
if (rv != KERN_SUCCESS)
return EFAULT;
/* Look up again as vm_fault() may have inserted a shadow object */
rv = vm_region(map, &offset, &size, &prot, &maxprot,
&inherit, &shared, &object, &objoff);
if (rv != KERN_SUCCESS)
return EINVAL;
/* Now find the page */
/* XXX hope it's still there, should we have wired it? */
m = vm_page_lookup(object, objoff);
if (m == NULL)
return ESRCH;
kva = kmem_alloc_wait(kernel_map, PAGE_SIZE);
pmap_enter(vm_map_pmap(kernel_map), kva, VM_PAGE_TO_PHYS(m),
VM_PROT_DEFAULT, TRUE);
error = uiomove(kva + on, (int)n, uio);
pmap_remove(vm_map_pmap(kernel_map), kva, kva + PAGE_SIZE);
kmem_free_wakeup(kernel_map, kva, PAGE_SIZE);
if (oldprot) {
rv = vm_protect(map, offset, PAGE_SIZE, FALSE, oldprot);
if (rv != KERN_SUCCESS)
return EPERM;
}
} while (error == 0 && uio->uio_resid > 0);
if (pfsvplock & PROCFS_WANT) {
pfsvplock &= ~PROCFS_WANT;
wakeup((caddr_t) &pfsvplock);
}
return (error);
}
#if 00
int
pfs_map(procp, kva, rw, offset)
struct proc *procp;
int rw;
vm_offset_t *kva, offset;
procfs_freevp(vp)
struct vnode *vp;
{
int rv;
vm_map_t map;
vm_size_t size;
vm_prot_t prot, maxprot;
vm_inherit_t inherit;
boolean_t shared;
vm_object_t object;
vm_offset_t objoff;
vm_page_t m;
struct pfsnode **pfspp;
struct pfsnode *pfs = VTOPFS(vp);
map = &procp->p_vmspace->vm_map;
#if 0
vm_map_print(map, 1);
#endif
/* 4.4: at this point, need to deallocate the pfsnode */
offset = trunc_page(offset);
rv = vm_region(map, &offset, &size, &prot, &maxprot,
&inherit, &shared, &object, &objoff);
if (rv != KERN_SUCCESS)
return EINVAL;
vm_object_unlock(object);
if (rw == UIO_WRITE && (prot & VM_PROT_WRITE) == 0) {
prot |= VM_PROT_WRITE;
rv = vm_protect(map, offset, PAGE_SIZE, FALSE, prot);
if (rv != KERN_SUCCESS)
return EPERM;
for (pfspp = &pfshead; *pfspp != 0; pfspp = &(*pfspp)->pfs_next) {
if (*pfspp == pfs) {
*pfspp = pfs->pfs_next;
break;
}
}
/* Just fault page */
rv = vm_fault(map, offset, prot, FALSE);
if (rv != KERN_SUCCESS)
return EFAULT;
/* Look up again as vm_fault() may have inserted a shadow object */
rv = vm_region(map, &offset, &size, &prot, &maxprot,
&inherit, &shared, &object, &objoff);
if (rv != KERN_SUCCESS)
return EINVAL;
m = vm_page_lookup(object, objoff);
if (m == NULL)
return ESRCH;
*kva = kmem_alloc_wait(kernel_map, PAGE_SIZE);
pmap_enter(vm_map_pmap(kernel_map), *kva, VM_PAGE_TO_PHYS(m),
VM_PROT_DEFAULT, TRUE);
return 0;
return (0);
}
int
pfs_unmap(procp, kva)
struct proc *procp;
vm_offset_t kva;
procfs_rw(vp, uio, ioflag, cred)
struct vnode *vp;
struct uio *uio;
int ioflag;
struct ucred *cred;
{
pmap_remove(vm_map_pmap(kernel_map), kva, kva + PAGE_SIZE);
kmem_free_wakeup(kernel_map, kva, PAGE_SIZE);
struct proc *curp = uio->uio_procp;
struct pfsnode *pfs = VTOPFS(vp);
struct proc *p;
p = PFIND(pfs->pfs_pid);
if (p == 0)
return (EINVAL);
switch (pfs->pfs_type) {
case Pnote:
case Pnotepg:
return (pfs_donote(curp, p, pfs, uio));
case Pregs:
return (pfs_doregs(curp, p, pfs, uio));
case Pctl:
return (pfs_doctl(curp, p, pfs, uio));
case Pstatus:
return (pfs_dostatus(curp, p, pfs, uio));
case Pmem:
return (pfs_domem(curp, p, pfs, uio));
default:
return (EOPNOTSUPP);
}
}
/*
* 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
*/
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;
error = uiomove(buf, xlen, uio);
if (error)
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, (char *) nm->nm_name, buflen+1) == 0)
return (nm);
return (0);
}
#endif

View File

@ -1,7 +1,11 @@
/*
* Copyright (c) 1993 Paul Kranenburg
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Jan-Simon Pendry
* 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:
@ -12,26 +16,32 @@
* 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 Paul Kranenburg.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
* 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.
*
* $Id: procfs_vfsops.c,v 1.8 1993/12/18 03:58:11 mycroft Exp $
* From:
* Id: procfs_vfsops.c,v 4.1 1993/12/17 10:47:45 jsp Rel
*
* $Id: procfs_vfsops.c,v 1.9 1994/01/05 07:51:31 cgd Exp $
*/
/*
* PROCFS VFS interface routines
* procfs VFS interface
*/
#include <sys/param.h>
@ -39,40 +49,12 @@
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/buf.h>
#include <sys/syslog.h>
#include <sys/mount.h>
#include <sys/signalvar.h>
#include <sys/vnode.h>
#include <miscfs/procfs/pfsnode.h>
extern struct vnodeops pfs_vnodeops;
/*
* mfs vfs operations.
*/
int pfs_mount();
int pfs_start();
int pfs_unmount();
int pfs_root();
int pfs_quotactl();
int pfs_statfs();
int pfs_sync();
int pfs_fhtovp();
int pfs_vptofh();
int pfs_init();
struct vfsops procfs_vfsops = {
pfs_mount,
pfs_start,
pfs_unmount,
pfs_root,
pfs_quotactl,
pfs_statfs,
pfs_sync,
pfs_fhtovp,
pfs_vptofh,
pfs_init,
};
#include <miscfs/procfs/procfs.h>
#include <vm/vm.h> /* for page_size */
/*
* VFS Operations.
@ -80,28 +62,28 @@ struct vfsops procfs_vfsops = {
* mount system call
*/
/* ARGSUSED */
pfs_mount(mp, path, data, ndp, p)
register struct mount *mp;
procfs_mount(mp, path, data, ndp, p)
struct mount *mp;
char *path;
caddr_t data;
struct nameidata *ndp;
struct proc *p;
{
#if 0
struct pfs_args args;
#endif
struct vnode *pvp;
u_int size;
int error;
if (mp->mnt_flag & MNT_UPDATE) {
return (0);
if (UIO_MX & (UIO_MX-1)) {
log(LOG_ERR, "procfs: invalid directory entry size");
return (EINVAL);
}
#if 0
if (error = copyin(data, (caddr_t)&args, sizeof (struct pfs_args)))
return (error);
#endif
if (mp->mnt_flag & MNT_UPDATE)
return (EOPNOTSUPP);
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_data = 0;
getnewfsid(mp, MOUNT_PROCFS);
(void) copyinstr(path, (caddr_t)mp->mnt_stat.f_mntonname, MNAMELEN, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
@ -109,128 +91,154 @@ pfs_mount(mp, path, data, ndp, p)
bcopy("proc", mp->mnt_stat.f_mntfromname, size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
(void) pfs_statfs(mp, &mp->mnt_stat, p);
return (0);
}
/*
* unmount system call
*/
pfs_unmount(mp, mntflags, p)
procfs_unmount(mp, mntflags, p)
struct mount *mp;
int mntflags;
struct proc *p;
{
int error;
extern int doforce;
int flags = 0;
if (mntflags & MNT_FORCE) {
/* procfs can never be rootfs so don't check for it */
if (!doforce)
return (EINVAL);
flags |= FORCECLOSE;
}
/*
* Clear out buffer cache. I don't think we
* ever get anything cached at this level at the
* moment, but who knows...
*/
mntflushbuf(mp, 0);
if (mntinvalbuf(mp, 1))
return (EBUSY);
if (error = vflush(mp, 0, flags))
return (error);
return (0);
}
pfs_root(mp, vpp)
procfs_root(mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
struct pfsnode *pfs;
struct vnode *vp;
struct pfsnode *pfsp, **pp;
int error;
/* Look in "cache" first */
for (pfsp = pfshead; pfsp != NULL; pfsp = pfsp->pfs_next) {
if (pfsp->pfs_vnode->v_flag & VROOT) {
*vpp = pfsp->pfs_vnode;
vref(*vpp);
return 0;
}
}
/* Not on list, allocate new vnode */
error = getnewvnode(VT_PROCFS, mp, &pfs_vnodeops, &vp);
error = procfs_allocvp(mp, &vp, (pid_t) 0, Proot);
if (error)
return error;
return (error);
vp->v_type = VDIR;
vp->v_flag = VROOT;
pfsp = VTOPFS(vp);
pfsp->pfs_next = NULL;
pfsp->pfs_pid = 0;
pfsp->pfs_vnode = vp;
pfsp->pfs_flags = 0;
pfsp->pfs_vflags = 0;
pfsp->pfs_uid = 0;
pfsp->pfs_gid = 0;
pfsp->pfs_mode = 0755; /* /proc = drwxr-xr-x */
/* Append to pfs node list */
for (pp = &pfshead; *pp; pp = &(*pp)->pfs_next);
*pp = pfsp;
pfs = VTOPFS(vp);
*vpp = vp;
return 0;
return (0);
}
/*
*/
/* ARGSUSED */
pfs_start(mp, flags, p)
procfs_start(mp, flags, p)
struct mount *mp;
int flags;
struct proc *p;
{
return 0;
return (0);
}
/*
* Get file system statistics.
*/
pfs_statfs(mp, sbp, p)
procfs_statfs(mp, sbp, p)
struct mount *mp;
struct statfs *sbp;
struct proc *p;
{
sbp->f_type = MOUNT_PROCFS;
sbp->f_fsize = 0;
sbp->f_bsize = 0;
sbp->f_blocks = 0;
sbp->f_fsize = page_size >> 2;
sbp->f_bsize = 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 + 3;
sbp->f_ffree = maxproc - nprocs;
sbp->f_files = maxproc; /* approx */
sbp->f_ffree = maxproc - nprocs; /* approx */
return 0;
if (sbp != &mp->mnt_stat) {
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);
}
pfs_quotactl(mp, cmds, uid, arg, p)
procfs_quotactl(mp, cmds, uid, arg, p)
struct mount *mp;
int cmds;
uid_t uid;
caddr_t arg;
struct proc *p;
{
return EOPNOTSUPP;
return (EOPNOTSUPP);
}
pfs_sync(mp, waitfor)
procfs_sync(mp, waitfor)
struct mount *mp;
int waitfor;
{
return 0;
return (0);
}
pfs_fhtovp(mp, fhp, vpp)
register struct mount *mp;
procfs_fhtovp(mp, fhp, vpp)
struct mount *mp;
struct fid *fhp;
struct vnode **vpp;
{
return EINVAL;
return (EINVAL);
}
pfs_vptofh(vp, fhp)
procfs_vptofh(vp, fhp)
struct vnode *vp;
struct fid *fhp;
{
return EINVAL;
}
pfs_init()
procfs_init()
{
return 0;
return (0);
}
struct vfsops procfs_vfsops = {
procfs_mount,
procfs_start,
procfs_unmount,
procfs_root,
procfs_quotactl,
procfs_statfs,
procfs_sync,
procfs_fhtovp,
procfs_vptofh,
procfs_init,
};

File diff suppressed because it is too large Load Diff