diff options
author | sef <sef@FreeBSD.org> | 1997-12-06 04:11:14 +0000 |
---|---|---|
committer | sef <sef@FreeBSD.org> | 1997-12-06 04:11:14 +0000 |
commit | c7d273eccbdbad69eed3ca880a3956ca804a83c8 (patch) | |
tree | 213faf73090825488ed9bc01587c6f942d45f53e | |
parent | 9821c0958535e623d28d6d4fc1d1ac205a20ec36 (diff) | |
download | FreeBSD-src-c7d273eccbdbad69eed3ca880a3956ca804a83c8.zip FreeBSD-src-c7d273eccbdbad69eed3ca880a3956ca804a83c8.tar.gz |
Changes to allow event-based process monitoring and control.
-rw-r--r-- | sys/amd64/amd64/trap.c | 13 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_subr.c | 13 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_vnops.c | 78 | ||||
-rw-r--r-- | sys/i386/i386/trap.c | 13 | ||||
-rw-r--r-- | sys/kern/init_main.c | 8 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 12 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 27 | ||||
-rw-r--r-- | sys/kern/subr_trap.c | 13 | ||||
-rw-r--r-- | sys/kern/sys_process.c | 21 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 5 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_subr.c | 13 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_vnops.c | 78 | ||||
-rw-r--r-- | sys/sys/pioctl.h | 36 | ||||
-rw-r--r-- | sys/sys/proc.h | 11 |
15 files changed, 326 insertions, 20 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 8c45d1f..f936fd6 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.117 1997/12/04 14:35:40 jkh Exp $ + * $Id: trap.c,v 1.118 1997/12/04 21:21:26 jmg Exp $ */ /* @@ -50,6 +50,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> +#include <sys/pioctl.h> #include <sys/kernel.h> #include <sys/resourcevar.h> #include <sys/signalvar.h> @@ -987,6 +988,8 @@ syscall(frame) p->p_retval[0] = 0; p->p_retval[1] = frame.tf_edx; + STOPEVENT(p, S_SCE, callp->sy_narg); + error = (*callp->sy_call)(p, args); switch (error) { @@ -1037,6 +1040,14 @@ bad: if (KTRPOINT(p, KTR_SYSRET)) ktrsysret(p->p_tracep, code, error, p->p_retval[0]); #endif + + /* + * This works because errno is findable through the + * register set. If we ever support an emulation where this + * is not the case, this code will need to be revisited. + */ + STOPEVENT(p, S_SCX, code); + } /* diff --git a/sys/fs/procfs/procfs_subr.c b/sys/fs/procfs/procfs_subr.c index 42e9bf4..b77489b 100644 --- a/sys/fs/procfs/procfs_subr.c +++ b/sys/fs/procfs/procfs_subr.c @@ -36,7 +36,7 @@ * * @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95 * - * $Id: procfs_subr.c,v 1.16 1997/06/26 16:12:53 alex Exp $ + * $Id: procfs_subr.c,v 1.17 1997/08/02 14:32:18 bde Exp $ */ #include <sys/param.h> @@ -351,3 +351,14 @@ vfs_findname(nm, buf, buflen) return (0); } + +void +procfs_exit(pid_t pid) +{ + struct pfsnode *pfs; + + for (pfs = pfshead; pfs ; pfs = pfs->pfs_next) { + if (pfs->pfs_pid == pid) + vgone(PFSTOV(pfs)); + } +} diff --git a/sys/fs/procfs/procfs_vnops.c b/sys/fs/procfs/procfs_vnops.c index 284242f..a1789da 100644 --- a/sys/fs/procfs/procfs_vnops.c +++ b/sys/fs/procfs/procfs_vnops.c @@ -36,7 +36,7 @@ * * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 * - * $Id: procfs_vnops.c,v 1.42 1997/11/07 08:53:15 phk Exp $ + * $Id: procfs_vnops.c,v 1.43 1997/12/05 19:55:47 bde Exp $ */ /* @@ -56,6 +56,7 @@ #include <sys/dirent.h> #include <machine/reg.h> #include <miscfs/procfs/procfs.h> +#include <sys/pioctl.h> static int procfs_abortop __P((struct vop_abortop_args *)); static int procfs_access __P((struct vop_access_args *)); @@ -64,6 +65,7 @@ static int procfs_bmap __P((struct vop_bmap_args *)); static int procfs_close __P((struct vop_close_args *)); static int procfs_getattr __P((struct vop_getattr_args *)); static int procfs_inactive __P((struct vop_inactive_args *)); +static int procfs_ioctl __P((struct vop_ioctl_args *)); static int procfs_lookup __P((struct vop_lookup_args *)); static int procfs_open __P((struct vop_open_args *)); static int procfs_print __P((struct vop_print_args *)); @@ -185,6 +187,79 @@ procfs_close(ap) } /* + * do an ioctl operation on a pfsnode (vp). + * (vp) is not locked on entry or exit. + */ +static int +procfs_ioctl(ap) + struct vop_ioctl_args *ap; +{ + struct pfsnode *pfs = VTOPFS(ap->a_vp); + struct proc *procp; + int error; + int signo; + struct procfs_status *psp; + + procp = pfind(pfs->pfs_pid); + if (procp == NULL) { + return ENOTTY; + } + + switch (ap->a_command) { + case PIOCBIS: + procp->p_stops |= *(unsigned int*)ap->a_data; + break; + case PIOCBIC: + procp->p_stops &= ~*(unsigned int*)ap->a_data; + break; + case PIOCSFL: + procp->p_pfsflags = (unsigned char)*(unsigned int*)ap->a_data; + *(unsigned int*)ap->a_data = procp->p_stops; + break; + case PIOCSTATUS: + psp = (struct procfs_status *)ap->a_data; + psp->state = (procp->p_step == 0); + psp->flags = procp->p_pfsflags; + psp->events = procp->p_stops; + if (procp->p_step) { + psp->why = procp->p_stype; + psp->val = procp->p_xstat; + } else { + psp->why = psp->val = 0; /* Not defined values */ + } + break; + case PIOCWAIT: + psp = (struct procfs_status *)ap->a_data; + if (procp->p_step == 0) { + error = tsleep(&procp->p_stype, PWAIT | PCATCH, "piocwait", 0); + if (error) + return error; + } + psp->state = 1; /* It stopped */ + psp->flags = procp->p_pfsflags; + psp->events = procp->p_stops; + psp->why = procp->p_stype; /* why it stopped */ + psp->val = procp->p_xstat; /* any extra info */ + break; + case PIOCCONT: /* Restart a proc */ + if (procp->p_step == 0) + return EINVAL; /* Can only start a stopped process */ + if (ap->a_data && (signo = *(int*)ap->a_data)) { + if (signo >= NSIG || signo <= 0) + return EINVAL; + if (error = psignal(procp, signo)) + return error; + } + procp->p_step = 0; + wakeup(&procp->p_step); + break; + default: + return (ENOTTY); + } + return 0; +} + +/* * do block mapping for pfsnode (vp). * since we don't use the buffer cache * for procfs this function should never @@ -909,6 +984,7 @@ static struct vnodeopv_entry_desc procfs_vnodeop_entries[] = { { &vop_setattr_desc, (vop_t *) procfs_setattr }, { &vop_symlink_desc, (vop_t *) procfs_badop }, { &vop_write_desc, (vop_t *) procfs_rw }, + { &vop_ioctl_desc, (vop_t *) procfs_ioctl }, { NULL, NULL } }; static struct vnodeopv_desc procfs_vnodeop_opv_desc = diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 8c45d1f..f936fd6 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.117 1997/12/04 14:35:40 jkh Exp $ + * $Id: trap.c,v 1.118 1997/12/04 21:21:26 jmg Exp $ */ /* @@ -50,6 +50,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> +#include <sys/pioctl.h> #include <sys/kernel.h> #include <sys/resourcevar.h> #include <sys/signalvar.h> @@ -987,6 +988,8 @@ syscall(frame) p->p_retval[0] = 0; p->p_retval[1] = frame.tf_edx; + STOPEVENT(p, S_SCE, callp->sy_narg); + error = (*callp->sy_call)(p, args); switch (error) { @@ -1037,6 +1040,14 @@ bad: if (KTRPOINT(p, KTR_SYSRET)) ktrsysret(p->p_tracep, code, error, p->p_retval[0]); #endif + + /* + * This works because errno is findable through the + * register set. If we ever support an emulation where this + * is not the case, this code will need to be revisited. + */ + STOPEVENT(p, S_SCX, code); + } /* diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index fa381e2..e56531e 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -39,7 +39,7 @@ * SUCH DAMAGE. * * @(#)init_main.c 8.9 (Berkeley) 1/21/94 - * $Id: init_main.c,v 1.75 1997/11/24 18:35:04 bde Exp $ + * $Id: init_main.c,v 1.76 1997/11/25 07:07:41 julian Exp $ */ #include "opt_devfs.h" @@ -415,6 +415,12 @@ proc0_init(dummy) * Charge root for one process. */ (void)chgproccnt(0, 1); + + /* + * Initialize the procfs flags (to 0, of course) + */ + p->p_stops = p->p_stype = p->p_step = 0; + } SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL) diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index bdad7d9..4d4f05a 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: kern_exec.c,v 1.67 1997/10/15 18:28:34 guido Exp $ + * $Id: kern_exec.c,v 1.68 1997/11/06 19:29:08 phk Exp $ */ #include <sys/param.h> @@ -40,6 +40,7 @@ #include <sys/imgact_elf.h> #include <sys/wait.h> #include <sys/proc.h> +#include <sys/pioctl.h> #include <sys/malloc.h> #include <sys/namei.h> #include <sys/sysent.h> @@ -338,6 +339,8 @@ interpret: * If tracing the process, trap to debugger so breakpoints * can be set before the program executes. */ + STOPEVENT(p, S_EXEC, 0); + if (p->p_flag & P_TRACED) psignal(p, SIGTRAP); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index dd1a54e..d282d22 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 - * $Id: kern_exit.c,v 1.59 1997/11/06 19:29:08 phk Exp $ + * $Id: kern_exit.c,v 1.60 1997/11/20 19:09:43 bde Exp $ */ #include "opt_ktrace.h" @@ -46,6 +46,7 @@ #include <sys/sysproto.h> #include <sys/malloc.h> #include <sys/proc.h> +#include <sys/pioctl.h> #include <sys/tty.h> #include <sys/wait.h> #include <sys/vnode.h> @@ -113,6 +114,7 @@ exit1(p, rv) register struct proc *q, *nq; register struct vmspace *vm; ele_p ep = exit_list; + extern void procfs_exit(pid_t); if (p->p_pid == 1) { printf("init died (signal %d, exit %d)\n", @@ -155,6 +157,14 @@ exit1(p, rv) #ifdef PGINPROF vmsizmon(); #endif + STOPEVENT(p, S_EXIT, rv); + + /* + * Now that we're back from stopevent(), force a close + * of all open procfs files for this process. + */ + procfs_exit(p->p_pid); + /* * Check if any LKMs need anything done at process exit. * e.g. SYSV IPC stuff diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 8a378a1..3200080 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94 - * $Id: kern_sig.c,v 1.34 1997/09/13 19:42:12 joerg Exp $ + * $Id: kern_sig.c,v 1.35 1997/11/06 19:29:14 phk Exp $ */ #include "opt_ktrace.h" @@ -49,6 +49,7 @@ #include <sys/namei.h> #include <sys/vnode.h> #include <sys/proc.h> +#include <sys/pioctl.h> #include <sys/systm.h> #include <sys/acct.h> #include <sys/fcntl.h> @@ -743,15 +744,19 @@ psignal(p, signum) register sig_t action; int mask; - if ((u_int)signum >= NSIG || signum == 0) + if ((u_int)signum >= NSIG || signum == 0) { + printf("psignal: signum %d\n", signum); panic("psignal signal number"); + } mask = sigmask(signum); prop = sigprop[signum]; /* - * If proc is traced, always give parent a chance. + * If proc is traced, always give parent a chance; + * if signal event is tracked by procfs, give *that* + * a chance, as well. */ - if (p->p_flag & P_TRACED) + if ((p->p_flag & P_TRACED) || (p->p_stops & S_SIG)) action = SIG_DFL; else { /* @@ -948,6 +953,8 @@ issignal(p) register int signum, mask, prop; for (;;) { + int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG); + mask = p->p_siglist & ~p->p_sigmask; if (p->p_flag & P_PPWAIT) mask &= ~stopsigmask; @@ -956,11 +963,14 @@ issignal(p) signum = ffs((long)mask); mask = sigmask(signum); prop = sigprop[signum]; + + STOPEVENT(p, S_SIG, signum); + /* * We should see pending but ignored signals * only if P_TRACED was on when they were posted. */ - if (mask & p->p_sigignore && (p->p_flag & P_TRACED) == 0) { + if ((mask & p->p_sigignore) && (traced == 0)) { p->p_siglist &= ~mask; continue; } @@ -974,7 +984,8 @@ issignal(p) do { stop(p); mi_switch(); - } while (!trace_req(p) && p->p_flag & P_TRACED); + } while (!trace_req(p) + && p->p_flag & P_TRACED); /* * If the traced bit got turned off, go back up @@ -1118,6 +1129,8 @@ postsig(signum) signum, action, ps->ps_flags & SAS_OLDMASK ? ps->ps_oldmask : p->p_sigmask, 0); #endif + STOPEVENT(p, S_SIG, signum); + if (action == SIG_DFL) { /* * Default action, where the default is to kill @@ -1236,6 +1249,8 @@ coredump(p) int error, error1; char name[MAXCOMLEN+6]; /* progname.core */ + STOPEVENT(p, S_CORE, 0); + if (p->p_flag & P_SUGID) return (EFAULT); if (ctob(UPAGES + vm->vm_dsize + vm->vm_ssize) >= diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 8c45d1f..f936fd6 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.117 1997/12/04 14:35:40 jkh Exp $ + * $Id: trap.c,v 1.118 1997/12/04 21:21:26 jmg Exp $ */ /* @@ -50,6 +50,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> +#include <sys/pioctl.h> #include <sys/kernel.h> #include <sys/resourcevar.h> #include <sys/signalvar.h> @@ -987,6 +988,8 @@ syscall(frame) p->p_retval[0] = 0; p->p_retval[1] = frame.tf_edx; + STOPEVENT(p, S_SCE, callp->sy_narg); + error = (*callp->sy_call)(p, args); switch (error) { @@ -1037,6 +1040,14 @@ bad: if (KTRPOINT(p, KTR_SYSRET)) ktrsysret(p->p_tracep, code, error, p->p_retval[0]); #endif + + /* + * This works because errno is findable through the + * register set. If we ever support an emulation where this + * is not the case, this code will need to be revisited. + */ + STOPEVENT(p, S_SCX, code); + } /* diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 28007f72..c289115 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: sys_process.c,v 1.31 1997/11/06 19:29:22 phk Exp $ + * $Id: sys_process.c,v 1.32 1997/11/12 12:28:12 tegge Exp $ */ #include <sys/param.h> @@ -503,3 +503,22 @@ trace_req(p) { return 1; } + +/* + * stopevent() + * Stop a process because of a procfs event; + * stay stopped until p->p_step is cleared + * (cleared by PIOCCONT in procfs). + */ + +void +stopevent(struct proc *p, unsigned int event, unsigned int val) { + p->p_step = 1; + + do { + p->p_xstat = val; + p->p_stype = event; /* Which event caused the stop? */ + wakeup(&p->p_stype); /* Wake up any PIOCWAIT'ing procs */ + tsleep(&p->p_step, PWAIT, "stopevent", 0); + } while (p->p_step); +} diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index dd12e9f..58dfad5 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94 - * $Id: vfs_vnops.c,v 1.41 1997/11/07 08:53:11 phk Exp $ + * $Id: vfs_vnops.c,v 1.42 1997/11/29 01:33:10 dyson Exp $ */ #include <sys/param.h> @@ -454,8 +454,9 @@ vn_ioctl(fp, com, data, p) /* fall into ... */ default: +#if 0 return (ENOTTY); - +#endif case VFIFO: case VCHR: case VBLK: diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c index 42e9bf4..b77489b 100644 --- a/sys/miscfs/procfs/procfs_subr.c +++ b/sys/miscfs/procfs/procfs_subr.c @@ -36,7 +36,7 @@ * * @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95 * - * $Id: procfs_subr.c,v 1.16 1997/06/26 16:12:53 alex Exp $ + * $Id: procfs_subr.c,v 1.17 1997/08/02 14:32:18 bde Exp $ */ #include <sys/param.h> @@ -351,3 +351,14 @@ vfs_findname(nm, buf, buflen) return (0); } + +void +procfs_exit(pid_t pid) +{ + struct pfsnode *pfs; + + for (pfs = pfshead; pfs ; pfs = pfs->pfs_next) { + if (pfs->pfs_pid == pid) + vgone(PFSTOV(pfs)); + } +} diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c index 284242f..a1789da 100644 --- a/sys/miscfs/procfs/procfs_vnops.c +++ b/sys/miscfs/procfs/procfs_vnops.c @@ -36,7 +36,7 @@ * * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 * - * $Id: procfs_vnops.c,v 1.42 1997/11/07 08:53:15 phk Exp $ + * $Id: procfs_vnops.c,v 1.43 1997/12/05 19:55:47 bde Exp $ */ /* @@ -56,6 +56,7 @@ #include <sys/dirent.h> #include <machine/reg.h> #include <miscfs/procfs/procfs.h> +#include <sys/pioctl.h> static int procfs_abortop __P((struct vop_abortop_args *)); static int procfs_access __P((struct vop_access_args *)); @@ -64,6 +65,7 @@ static int procfs_bmap __P((struct vop_bmap_args *)); static int procfs_close __P((struct vop_close_args *)); static int procfs_getattr __P((struct vop_getattr_args *)); static int procfs_inactive __P((struct vop_inactive_args *)); +static int procfs_ioctl __P((struct vop_ioctl_args *)); static int procfs_lookup __P((struct vop_lookup_args *)); static int procfs_open __P((struct vop_open_args *)); static int procfs_print __P((struct vop_print_args *)); @@ -185,6 +187,79 @@ procfs_close(ap) } /* + * do an ioctl operation on a pfsnode (vp). + * (vp) is not locked on entry or exit. + */ +static int +procfs_ioctl(ap) + struct vop_ioctl_args *ap; +{ + struct pfsnode *pfs = VTOPFS(ap->a_vp); + struct proc *procp; + int error; + int signo; + struct procfs_status *psp; + + procp = pfind(pfs->pfs_pid); + if (procp == NULL) { + return ENOTTY; + } + + switch (ap->a_command) { + case PIOCBIS: + procp->p_stops |= *(unsigned int*)ap->a_data; + break; + case PIOCBIC: + procp->p_stops &= ~*(unsigned int*)ap->a_data; + break; + case PIOCSFL: + procp->p_pfsflags = (unsigned char)*(unsigned int*)ap->a_data; + *(unsigned int*)ap->a_data = procp->p_stops; + break; + case PIOCSTATUS: + psp = (struct procfs_status *)ap->a_data; + psp->state = (procp->p_step == 0); + psp->flags = procp->p_pfsflags; + psp->events = procp->p_stops; + if (procp->p_step) { + psp->why = procp->p_stype; + psp->val = procp->p_xstat; + } else { + psp->why = psp->val = 0; /* Not defined values */ + } + break; + case PIOCWAIT: + psp = (struct procfs_status *)ap->a_data; + if (procp->p_step == 0) { + error = tsleep(&procp->p_stype, PWAIT | PCATCH, "piocwait", 0); + if (error) + return error; + } + psp->state = 1; /* It stopped */ + psp->flags = procp->p_pfsflags; + psp->events = procp->p_stops; + psp->why = procp->p_stype; /* why it stopped */ + psp->val = procp->p_xstat; /* any extra info */ + break; + case PIOCCONT: /* Restart a proc */ + if (procp->p_step == 0) + return EINVAL; /* Can only start a stopped process */ + if (ap->a_data && (signo = *(int*)ap->a_data)) { + if (signo >= NSIG || signo <= 0) + return EINVAL; + if (error = psignal(procp, signo)) + return error; + } + procp->p_step = 0; + wakeup(&procp->p_step); + break; + default: + return (ENOTTY); + } + return 0; +} + +/* * do block mapping for pfsnode (vp). * since we don't use the buffer cache * for procfs this function should never @@ -909,6 +984,7 @@ static struct vnodeopv_entry_desc procfs_vnodeop_entries[] = { { &vop_setattr_desc, (vop_t *) procfs_setattr }, { &vop_symlink_desc, (vop_t *) procfs_badop }, { &vop_write_desc, (vop_t *) procfs_rw }, + { &vop_ioctl_desc, (vop_t *) procfs_ioctl }, { NULL, NULL } }; static struct vnodeopv_desc procfs_vnodeop_opv_desc = diff --git a/sys/sys/pioctl.h b/sys/sys/pioctl.h new file mode 100644 index 0000000..bc264e9 --- /dev/null +++ b/sys/sys/pioctl.h @@ -0,0 +1,36 @@ +/* + * procfs ioctl definitions. + * + * $Id$ + */ + +#ifndef _SYS_PIOCTL_H +# define _SYS_PIOCTL_H + +# include <sys/ioccom.h> + +struct procfs_status { + int state; /* Running, stopped, something else? */ + int flags; /* Any flags */ + unsigned long events; /* Events to stop on */ + int why; /* What event, if any, proc stopped on */ + unsigned long val; /* Any extra data */ +}; + +# define PIOCBIS _IOW('p', 1, unsigned int) /* Set event flag */ +# define PIOCBIC _IOW('p', 2, unsigned int) /* Clear event flag */ +# define PIOCSFL _IOR('p', 3, unsigned int) /* Set flags */ + /* wait for proc to stop */ +# define PIOCWAIT _IOR('p', 4, struct procfs_status) +# define PIOCCONT _IOW('p', 5, int) /* Continue a process */ + /* Get proc status */ +# define PIOCSTATUS _IOW('p', 6, struct procfs_status) + +# define S_EXEC 0x00000001 /* stop-on-exec */ +# define S_SIG 0x00000002 /* stop-on-signal */ +# define S_SCE 0x00000004 /* stop on syscall entry */ +# define S_SCX 0x00000008 /* stop on syscall exit */ +# define S_CORE 0x00000010 /* stop on coredump */ +# define S_EXIT 0x00000020 /* stop on exit */ + +#endif diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 201cb3d..2dc5c30 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)proc.h 8.15 (Berkeley) 5/19/95 - * $Id: proc.h,v 1.48 1997/11/24 15:15:20 bde Exp $ + * $Id: proc.h,v 1.49 1997/11/25 07:07:48 julian Exp $ */ #ifndef _SYS_PROC_H_ @@ -151,6 +151,11 @@ struct proc { short p_locks; /* DEBUG: lockmgr count of held locks */ short p_simple_locks; /* DEBUG: count of held simple locks */ + unsigned int p_stops; /* procfs event bitmask */ + unsigned int p_stype; /* procfs stop event type */ + char p_step; /* procfs stop *once* flag */ + unsigned char p_pfsflags; /* procfs flags */ + char p_pad3[2]; /* padding for alignment */ register_t p_retval[2]; /* syscall aux returns */ /* End area that is zeroed on creation. */ @@ -270,6 +275,10 @@ MALLOC_DECLARE(M_SUBPROC); FREE(s, M_SESSION); \ } +extern void stopevent(struct proc*, unsigned int, unsigned int); +#define STOPEVENT(p,e,v) do { \ + if ((p)->p_stops & (e)) stopevent(p,e,v); } while (0) + /* hold process U-area in memory, normally for ptrace/procfs work */ #define PHOLD(p) { \ if ((p)->p_lock++ == 0 && ((p)->p_flag & P_INMEM) == 0) \ |