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:
parent
8e1f0c6b2f
commit
699e3be9e9
114
sys/miscfs/procfs/README
Normal file
114
sys/miscfs/procfs/README
Normal 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
282
sys/miscfs/procfs/procfs.h
Normal 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 */
|
302
sys/miscfs/procfs/procfs_ctl.c
Normal file
302
sys/miscfs/procfs/procfs_ctl.c
Normal 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);
|
||||
}
|
300
sys/miscfs/procfs/procfs_mem.c
Normal file
300
sys/miscfs/procfs/procfs_mem.c
Normal 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 */
|
75
sys/miscfs/procfs/procfs_note.c
Normal file
75
sys/miscfs/procfs/procfs_note.c
Normal 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);
|
||||
}
|
86
sys/miscfs/procfs/procfs_regs.c
Normal file
86
sys/miscfs/procfs/procfs_regs.c
Normal 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);
|
||||
}
|
139
sys/miscfs/procfs/procfs_status.c
Normal file
139
sys/miscfs/procfs/procfs_status.c
Normal 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);
|
||||
}
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user