Make procfs really work for debugging.
Implement not & notepg files in procfs.
This commit is contained in:
parent
16b1f2baeb
commit
2cee3e073f
@ -1 +1 @@
|
||||
revision 1.13 intentionally removed
|
||||
revision 1.14 intentionally removed
|
||||
|
@ -1 +1 @@
|
||||
revision 1.11 intentionally removed
|
||||
revision 1.12 intentionally removed
|
||||
|
@ -1 +1 @@
|
||||
revision 1.21 intentionally removed
|
||||
revision 1.22 intentionally removed
|
||||
|
@ -14,13 +14,12 @@ are:
|
||||
|
||||
status - r/o. returns process status.
|
||||
|
||||
ctl - w/o. sends a control message to the process.
|
||||
ctl - r/w. 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.
|
||||
a debugged process' signal may be read
|
||||
from here.
|
||||
see below for more details.
|
||||
|
||||
mem - r/w. virtual memory image of the process.
|
||||
@ -30,13 +29,17 @@ are:
|
||||
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. ]
|
||||
note - r/w. writing a string here sends the
|
||||
equivalent note to the process or process group.
|
||||
for example:
|
||||
echo hup > /proc/curproc/note
|
||||
will send a SIGHUP to the shell.
|
||||
reading will return the lowest numbered signal
|
||||
pending for process and inhibit its delivery to
|
||||
process.
|
||||
|
||||
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.
|
||||
@ -71,44 +74,44 @@ total 0
|
||||
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
|
||||
3 lr-xr-xr-x 2 root wheel 0 Sep 21 15:06 curproc
|
||||
% ls -li /proc/curproc
|
||||
total 408
|
||||
3341 --w------- 1 jsp staff 0 Sep 21 15:06 ctl
|
||||
3341 -rw------- 1 jsp staff 8 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
|
||||
3343 -rw------- 1 jsp staff 8 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
|
||||
3340 -rw------- 1 jsp staff 56 Sep 21 15:06 regs
|
||||
3342 -r--r--r-- 1 jsp staff 256 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
|
||||
cat 446 439 400 81 12,0 ctty 748620684 270000 0 0 0 20000 nochan 11 20 20 0 21 117
|
||||
|
||||
|
||||
|
||||
the basic sequence of commands written to "ctl" would be
|
||||
the basic sequence of commands written to "ctl"/data read from "ctl" would be
|
||||
|
||||
attach - this stops the target process and
|
||||
write 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,
|
||||
to become the debug control process.
|
||||
read <signame> - read signal that caused the stop.
|
||||
write step - single step, with no signal delivery.
|
||||
read <signame> - see above
|
||||
write 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
|
||||
write <signame> - set signal to be delivered on next step or run.
|
||||
write 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
|
||||
(with a self-inflicted SIGSTOP). the parent should do 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 $
|
||||
$Id: README,v 1.2 1994/01/20 21:23:03 ws Exp $
|
||||
|
@ -37,7 +37,7 @@
|
||||
* From:
|
||||
* Id: procfs.h,v 4.1 1993/12/17 10:47:45 jsp Rel
|
||||
*
|
||||
* $Id: procfs.h,v 1.4 1994/01/11 18:02:06 ws Exp $
|
||||
* $Id: procfs.h,v 1.5 1994/01/20 21:23:04 ws Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -68,7 +68,7 @@ struct pfsnode {
|
||||
u_long pfs_fileno; /* unique file id */
|
||||
};
|
||||
|
||||
#define PROCFS_NOTELEN 64 /* max length of a note (/proc/$pid/note) */
|
||||
#define PROCFS_NOTELEN 8 /* max length of a note (/proc/$pid/note) */
|
||||
#define PROCFS_CTLLEN 8 /* max length of a ctl msg (/proc/$pid/ctl */
|
||||
|
||||
/*
|
||||
@ -103,14 +103,14 @@ struct pfsdent {
|
||||
#define VTOPFS(vp) ((struct pfsnode *)(vp)->v_data)
|
||||
#define PFSTOV(pfs) ((pfs)->pfs_vnode)
|
||||
|
||||
typedef struct vfs_namemap vfs_namemap_t;
|
||||
struct vfs_namemap {
|
||||
typedef struct procfs_namemap procfs_namemap_t;
|
||||
struct procfs_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));
|
||||
extern int procfs_getuserstr __P((struct uio *, char *, int *));
|
||||
extern procfs_namemap_t *procfs_findname __P((procfs_namemap_t *, char *, int));
|
||||
|
||||
struct reg;
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
* From:
|
||||
* Id: procfs_ctl.c,v 4.1 1993/12/17 10:47:45 jsp Rel
|
||||
*
|
||||
* $Id: procfs_ctl.c,v 1.6 1994/01/09 23:57:56 cgd Exp $
|
||||
* $Id: procfs_ctl.c,v 1.7 1994/01/20 21:23:05 ws Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -55,12 +55,9 @@
|
||||
|
||||
/*
|
||||
* True iff process (p) is in trace wait state
|
||||
* relative to process (curp)
|
||||
*/
|
||||
#define TRACE_WAIT_P(curp, p) \
|
||||
#define TRACE_WAIT_P(p) \
|
||||
((p)->p_stat == SSTOP && \
|
||||
((p)->p_flag & SWTED) && \
|
||||
(p)->p_pptr == (curp) && \
|
||||
((p)->p_flag & STRC))
|
||||
|
||||
#define PROCFS_CTL_ATTACH 1
|
||||
@ -69,36 +66,16 @@
|
||||
#define PROCFS_CTL_RUN 4
|
||||
#define PROCFS_CTL_WAIT 5
|
||||
|
||||
static vfs_namemap_t ctlnames[] = {
|
||||
static procfs_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 },
|
||||
};
|
||||
extern procfs_namemap_t procfs_signames[];
|
||||
|
||||
static int
|
||||
procfs_control(curp, p, op)
|
||||
@ -109,48 +86,18 @@ procfs_control(curp, p, 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;
|
||||
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).
|
||||
* Target process must be stopped and
|
||||
* be set up for tracing (SFSTRC flag set).
|
||||
* Of course ATTACH is allowed any time.
|
||||
* Allow DETACH to take place at any time for sanity.
|
||||
* Allow WAIT any time, of course.
|
||||
*/
|
||||
switch (op) {
|
||||
case PROCFS_CTL_ATTACH:
|
||||
case PROCFS_CTL_DETACH:
|
||||
case PROCFS_CTL_WAIT:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!TRACE_WAIT_P(curp, p))
|
||||
if (!TRACE_WAIT_P(p))
|
||||
return (EBUSY);
|
||||
}
|
||||
|
||||
@ -159,87 +106,81 @@ procfs_control(curp, p, op)
|
||||
*/
|
||||
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) {
|
||||
case PROCFS_CTL_ATTACH:
|
||||
/*
|
||||
* Attach - attaches the target process for debugging
|
||||
* by the calling process.
|
||||
*/
|
||||
/* check whether already being traced */
|
||||
if (p->p_flag & STRC)
|
||||
return (EBUSY);
|
||||
|
||||
/* can't trace yourself! */
|
||||
/* DO WE REALLY NEED THIS RESTRICTION??? */
|
||||
if (curp && 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|SFSTRC;
|
||||
psignal(p, SIGSTOP);
|
||||
break;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
if ((p->p_flag & SFSTRC) == 0)
|
||||
return (0);
|
||||
|
||||
if (error = process_sstep(p, 0))
|
||||
return error;
|
||||
|
||||
/* 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_flag &= ~SWTED; /* XXX ? */
|
||||
p->p_oppid = 0;
|
||||
|
||||
break;
|
||||
|
||||
p->p_flag &= ~(STRC|SFSTRC);
|
||||
setrun(p);
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Step. Let the target process execute a single instruction.
|
||||
*/
|
||||
case PROCFS_CTL_STEP:
|
||||
if (error = process_sstep(p))
|
||||
return error;
|
||||
break;
|
||||
|
||||
/* Fall through */
|
||||
/*
|
||||
* Run. Let the target process continue running until a breakpoint
|
||||
* or some other trap.
|
||||
*/
|
||||
case PROCFS_CTL_RUN:
|
||||
if (error = process_sstep(p, op == PROCFS_CTL_STEP))
|
||||
return error;
|
||||
setrun(p);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Wait for the target process to stop.
|
||||
* If the target is not being traced then just wait
|
||||
* to enter
|
||||
*/
|
||||
case PROCFS_CTL_WAIT:
|
||||
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);
|
||||
/*
|
||||
* Wait for the target process to stop.
|
||||
*/
|
||||
while ((p->p_stat != SSTOP) &&
|
||||
(p->p_flag & SFSTRC)) {
|
||||
if (error = tsleep((caddr_t) p,
|
||||
PWAIT|PCATCH, "procfs", 0))
|
||||
return error;
|
||||
}
|
||||
if (!TRACE_WAIT_P(p))
|
||||
return EBUSY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pfs_doctl(curp, p, pfs, uio)
|
||||
@ -251,46 +192,48 @@ pfs_doctl(curp, p, pfs, uio)
|
||||
int len = uio->uio_resid;
|
||||
int xlen;
|
||||
int error;
|
||||
struct sigmap *sm;
|
||||
char msg[PROCFS_CTLLEN+1];
|
||||
char *cp = msg;
|
||||
vfs_namemap_t *nm;
|
||||
|
||||
procfs_namemap_t *nm;
|
||||
|
||||
/*
|
||||
* If we are debugging, you might read the stop signal.
|
||||
*/
|
||||
if (uio->uio_rw == UIO_READ && TRACE_WAIT_P(p)) {
|
||||
if (p->p_xstat) {
|
||||
if (error = pfs_readnote(p->p_xstat, uio))
|
||||
return error;
|
||||
|
||||
p->p_xstat = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (uio->uio_rw != UIO_WRITE)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
xlen = PROCFS_CTLLEN;
|
||||
error = vfs_getuserstr(uio, msg, &xlen);
|
||||
error = procfs_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.
|
||||
* Map debug control. Unknown commands return EOPNOTSUPP.
|
||||
*/
|
||||
error = EOPNOTSUPP;
|
||||
|
||||
nm = vfs_findname(ctlnames, msg, xlen);
|
||||
nm = procfs_findname(ctlnames, msg, xlen);
|
||||
if (nm) {
|
||||
error = procfs_control(curp, p, nm->nm_val);
|
||||
} else {
|
||||
nm = vfs_findname(signames, msg, xlen);
|
||||
} else if (TRACE_WAIT_P(p)) {
|
||||
/*
|
||||
* If we are debugging, it might be a signal.
|
||||
*/
|
||||
nm = procfs_findname(procfs_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);
|
||||
}
|
||||
p->p_xstat = nm->nm_val;
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
* 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 $
|
||||
* $Id: procfs_note.c,v 1.2 1994/01/20 21:23:06 ws Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -47,8 +47,55 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <miscfs/procfs/procfs.h>
|
||||
|
||||
procfs_namemap_t procfs_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 },
|
||||
};
|
||||
|
||||
pfs_readnote(sig, uio)
|
||||
int sig;
|
||||
struct uio *uio;
|
||||
{
|
||||
int xlen;
|
||||
int error;
|
||||
procfs_namemap_t *nm;
|
||||
|
||||
/* could do indexing by sig */
|
||||
for (nm = procfs_signames; nm->nm_name; nm++)
|
||||
if (nm->nm_val == sig)
|
||||
break;
|
||||
if (!nm->nm_name)
|
||||
panic("pfs_readnote");
|
||||
|
||||
xlen = strlen(nm->nm_name);
|
||||
if (uio->uio_resid < xlen)
|
||||
return EMSGSIZE;
|
||||
|
||||
if (error = uiomove(nm->nm_name, xlen, uio))
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pfs_donote(curp, p, pfs, uio)
|
||||
struct proc *curp;
|
||||
struct proc *p;
|
||||
@ -58,18 +105,49 @@ pfs_donote(curp, p, pfs, uio)
|
||||
int len = uio->uio_resid;
|
||||
int xlen;
|
||||
int error;
|
||||
struct sigmap *sm;
|
||||
char note[PROCFS_NOTELEN+1];
|
||||
char *cp = note;
|
||||
|
||||
procfs_namemap_t *nm;
|
||||
int sig, mask;
|
||||
|
||||
if (pfs->pfs_type == Pnote && uio->uio_rw == UIO_READ) {
|
||||
|
||||
mask = p->p_sig & ~p->p_sigmask;
|
||||
|
||||
if (p->p_flag&SPPWAIT)
|
||||
mask &= ~stopsigmask;
|
||||
if (mask == 0)
|
||||
return 0;
|
||||
sig = ffs((long)mask);
|
||||
|
||||
if (error = pfs_readnote(sig, pfs, uio))
|
||||
return error;
|
||||
|
||||
p->p_sig &= ~mask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (uio->uio_rw != UIO_WRITE)
|
||||
return (EINVAL);
|
||||
|
||||
xlen = PROCFS_NOTELEN;
|
||||
error = vfs_getuserstr(uio, note, &xlen);
|
||||
error = procfs_getuserstr(uio, note, &xlen);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
/* send to process's notify function */
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
/*
|
||||
* Map signal names into signal generation
|
||||
* Unknown signals return EOPNOTSUPP.
|
||||
*/
|
||||
error = EOPNOTSUPP;
|
||||
|
||||
nm = procfs_findname(procfs_signames, note, xlen);
|
||||
if (nm) {
|
||||
if (pfs->pfs_type == Pnote)
|
||||
psignal(p, nm->nm_val);
|
||||
else
|
||||
gsignal(p->p_pgid, nm->nm_val);
|
||||
|
||||
error = 0;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
* From:
|
||||
* Id: procfs_subr.c,v 4.1 1993/12/17 10:47:45 jsp Rel
|
||||
*
|
||||
* $Id: procfs_subr.c,v 1.7 1994/01/10 04:58:14 mycroft Exp $
|
||||
* $Id: procfs_subr.c,v 1.8 1994/01/20 21:23:07 ws Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -165,7 +165,7 @@ loop:
|
||||
break;
|
||||
|
||||
case Pctl:
|
||||
pfs->pfs_mode = (VWRITE);
|
||||
pfs->pfs_mode = (VREAD|VWRITE);
|
||||
vp->v_type = VREG;
|
||||
break;
|
||||
|
||||
@ -177,7 +177,7 @@ loop:
|
||||
break;
|
||||
|
||||
case Pnote:
|
||||
pfs->pfs_mode = (VWRITE);
|
||||
pfs->pfs_mode = (VREAD|VWRITE);
|
||||
vp->v_type = VREG;
|
||||
break;
|
||||
|
||||
@ -263,7 +263,7 @@ procfs_rw(vp, uio, ioflag, cred)
|
||||
/*
|
||||
* 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
|
||||
* The buffer should be *buflenp + 1 chars long. procfs_getuserstr
|
||||
* will automatically add a nul char at the end.
|
||||
*
|
||||
* Returns 0 on success or the following errors
|
||||
@ -272,7 +272,7 @@ procfs_rw(vp, uio, ioflag, cred)
|
||||
* EMSGSIZE: message is longer than kernel buffer
|
||||
* EFAULT: user i/o buffer is not addressable
|
||||
*/
|
||||
vfs_getuserstr(uio, buf, buflenp)
|
||||
procfs_getuserstr(uio, buf, buflenp)
|
||||
struct uio *uio;
|
||||
char *buf;
|
||||
int *buflenp;
|
||||
@ -280,9 +280,6 @@ vfs_getuserstr(uio, buf, 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 */
|
||||
@ -294,9 +291,6 @@ vfs_getuserstr(uio, buf, buflenp)
|
||||
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);
|
||||
@ -307,9 +301,9 @@ vfs_getuserstr(uio, buf, buflenp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
vfs_namemap_t *
|
||||
vfs_findname(nm, buf, buflen)
|
||||
vfs_namemap_t *nm;
|
||||
procfs_namemap_t *
|
||||
procfs_findname(nm, buf, buflen)
|
||||
procfs_namemap_t *nm;
|
||||
char *buf;
|
||||
int buflen;
|
||||
{
|
||||
|
@ -37,7 +37,7 @@
|
||||
* From:
|
||||
* Id: procfs_vfsops.c,v 4.1 1993/12/17 10:47:45 jsp Rel
|
||||
*
|
||||
* $Id: procfs_vfsops.c,v 1.10 1994/01/09 19:44:08 ws Exp $
|
||||
* $Id: procfs_vfsops.c,v 1.11 1994/01/20 21:23:08 ws Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -203,57 +203,29 @@ procfs_sync(mp, waitfor)
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct pfs_handle {
|
||||
u_short h_len;
|
||||
u_short h_align;
|
||||
pfstype h_pfstype;
|
||||
pid_t h_pid;
|
||||
struct timeval h_start;
|
||||
};
|
||||
|
||||
procfs_fhtovp(mp, fhp, vpp)
|
||||
struct mount *mp;
|
||||
struct fid *fhp;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
struct pfs_handle *php;
|
||||
struct proc *p;
|
||||
|
||||
php = (struct pfs_handle *)fhp;
|
||||
|
||||
if (php->h_pfstype != Proot) {
|
||||
|
||||
if (!(p = PFIND(php->h_pid)))
|
||||
return ESTALE;
|
||||
|
||||
if (bcmp(&p->p_stats->p_start,&php->h_start,sizeof(struct timeval)))
|
||||
return ESTALE;
|
||||
}
|
||||
|
||||
return procfs_allocvp(mp,vpp,php->h_pid,php->h_pfstype);
|
||||
/*
|
||||
* NFS mounting of procfs doesn't work correctly.
|
||||
* The files in procfs are more similar to devices
|
||||
* than to regular files.
|
||||
*/
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
procfs_vptofh(vp, fhp)
|
||||
struct vnode *vp;
|
||||
struct fid *fhp;
|
||||
{
|
||||
struct pfs_handle *php;
|
||||
struct proc *p;
|
||||
struct pfsnode *pfs = VTOPFS(vp);
|
||||
|
||||
php = (struct pfs_handle *)fhp;
|
||||
php->h_len = sizeof(*php);
|
||||
|
||||
php->h_pfstype = pfs->pfs_type;
|
||||
php->h_pid = pfs->pfs_pid;
|
||||
|
||||
if (pfs->pfs_type != Proot) {
|
||||
if (!(p = PFIND(pfs->pfs_pid)))
|
||||
return ENOENT;
|
||||
php->h_start = p->p_stats->p_start;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/*
|
||||
* NFS mounting of procfs doesn't work correctly.
|
||||
* The files in procfs are more similar to devices
|
||||
* than to regular files.
|
||||
*/
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
procfs_init()
|
||||
|
@ -37,7 +37,7 @@
|
||||
* From:
|
||||
* Id: procfs_vnops.c,v 4.2 1994/01/02 15:28:44 jsp Exp
|
||||
*
|
||||
* $Id: procfs_vnops.c,v 1.12 1994/01/09 19:44:10 ws Exp $
|
||||
* $Id: procfs_vnops.c,v 1.13 1994/01/20 21:23:10 ws Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -387,9 +387,13 @@ procfs_getattr(vp, vap, cred, p)
|
||||
break;
|
||||
|
||||
case Pctl:
|
||||
vap->va_bytes = vap->va_size = PROCFS_CTLLEN;
|
||||
break;
|
||||
|
||||
case Pnote:
|
||||
vap->va_bytes = vap->va_size = PROCFS_NOTELEN;
|
||||
break;
|
||||
|
||||
case Pnotepg:
|
||||
break;
|
||||
|
||||
@ -622,6 +626,15 @@ procfs_readdir(vp, uio, cred, eofflagp, cookies, ncookies)
|
||||
int count;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* NFS mounting of procfs doesn't work correctly.
|
||||
* The files in procfs are more similar to devices
|
||||
* than to regular files.
|
||||
* See also procfs_vptofh & procfs_fhtovp in procfs_vfsops.c
|
||||
*/
|
||||
if (cookies)
|
||||
panic("procfs_readdir");
|
||||
|
||||
pfs = VTOPFS(vp);
|
||||
|
||||
if (uio->uio_resid < UIO_MX)
|
||||
|
@ -1 +1 @@
|
||||
revision 1.16 intentionally removed
|
||||
revision 1.17 intentionally removed
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)ptrace.h 7.4 (Berkeley) 2/22/91
|
||||
* $Id: ptrace.h,v 1.9 1994/01/09 23:58:45 cgd Exp $
|
||||
* $Id: ptrace.h,v 1.10 1994/01/20 21:23:18 ws Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_PTRACE_H_
|
||||
@ -63,7 +63,7 @@ int process_read_regs __P((struct proc *p, struct reg *regs));
|
||||
#ifdef PT_SETREGS
|
||||
int process_write_regs __P((struct proc *p, struct reg *regs));
|
||||
#endif
|
||||
int process_sstep __P((struct proc *p));
|
||||
int process_sstep __P((struct proc *p, int sstep));
|
||||
int process_fix_sstep __P((struct proc *p));
|
||||
int process_set_pc __P((struct proc *p, u_int addr));
|
||||
|
||||
@ -71,9 +71,9 @@ int process_set_pc __P((struct proc *p, u_int addr));
|
||||
|
||||
/* do a single-stepping fixup, if needed */
|
||||
#define FIX_SSTEP(p) { \
|
||||
if ((p)->p_stat & SSSTEP) { \
|
||||
if ((p)->p_flag & SSSTEP) { \
|
||||
process_fix_sstep(p); \
|
||||
(p)->p_stat &= ~SSSTEP; \
|
||||
(p)->p_flag &= ~SSSTEP; \
|
||||
} \
|
||||
}
|
||||
#else /* KERNEL */
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)signalvar.h 7.1 (Berkeley) 5/9/91
|
||||
* $Id: signalvar.h,v 1.5 1993/10/14 22:35:26 cgd Exp $
|
||||
* $Id: signalvar.h,v 1.6 1994/01/20 21:23:19 ws Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SIGNALVAR_H_
|
||||
@ -137,13 +137,12 @@ int sigprop[NSIG + 1] = {
|
||||
SA_KILL, /* SIGUSR1 */
|
||||
SA_KILL, /* SIGUSR2 */
|
||||
};
|
||||
#endif /* SIGPROP */
|
||||
|
||||
#define stopsigmask (sigmask(SIGSTOP)|sigmask(SIGTSTP)|\
|
||||
sigmask(SIGTTIN)|sigmask(SIGTTOU))
|
||||
#define contsigmask (sigmask(SIGCONT))
|
||||
|
||||
#endif /* SIGPROP */
|
||||
|
||||
#define sigcantmask (sigmask(SIGKILL)|sigmask(SIGSTOP))
|
||||
|
||||
#ifdef KERNEL
|
||||
|
Loading…
Reference in New Issue
Block a user