procfs_ctl.c (85297) | procfs_ctl.c (87321) |
---|---|
1/* 2 * Copyright (c) 1993 Jan-Simon Pendry 3 * Copyright (c) 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Jan-Simon Pendry. 8 * --- 21 unchanged lines hidden (view full) --- 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)procfs_ctl.c 8.4 (Berkeley) 6/15/94 | 1/* 2 * Copyright (c) 1993 Jan-Simon Pendry 3 * Copyright (c) 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Jan-Simon Pendry. 8 * --- 21 unchanged lines hidden (view full) --- 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)procfs_ctl.c 8.4 (Berkeley) 6/15/94 |
38 * $FreeBSD: head/sys/fs/procfs/procfs_ctl.c 85297 2001-10-21 23:57:24Z des $ | 38 * $FreeBSD: head/sys/fs/procfs/procfs_ctl.c 87321 2001-12-04 01:35:06Z des $ |
39 */ 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/lock.h> 44#include <sys/mutex.h> 45#include <sys/proc.h> 46#include <sys/ptrace.h> | 39 */ 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/lock.h> 44#include <sys/mutex.h> 45#include <sys/proc.h> 46#include <sys/ptrace.h> |
47#include <sys/sbuf.h> |
|
47#include <sys/signalvar.h> 48#include <sys/sx.h> | 48#include <sys/signalvar.h> 49#include <sys/sx.h> |
49#include <sys/vnode.h> | 50#include <sys/uio.h> |
50 | 51 |
52#include <fs/pseudofs/pseudofs.h> |
|
51#include <fs/procfs/procfs.h> 52 53#include <vm/vm.h> 54 55/* 56 * True iff process (p) is in trace wait state 57 * relative to process (curp) 58 */ 59#define TRACE_WAIT_P(curp, p) \ 60 ((p)->p_stat == SSTOP && \ 61 (p)->p_pptr == (curp) && \ 62 ((p)->p_flag & P_TRACED)) 63 64#define PROCFS_CTL_ATTACH 1 65#define PROCFS_CTL_DETACH 2 66#define PROCFS_CTL_STEP 3 67#define PROCFS_CTL_RUN 4 68#define PROCFS_CTL_WAIT 5 69 | 53#include <fs/procfs/procfs.h> 54 55#include <vm/vm.h> 56 57/* 58 * True iff process (p) is in trace wait state 59 * relative to process (curp) 60 */ 61#define TRACE_WAIT_P(curp, p) \ 62 ((p)->p_stat == SSTOP && \ 63 (p)->p_pptr == (curp) && \ 64 ((p)->p_flag & P_TRACED)) 65 66#define PROCFS_CTL_ATTACH 1 67#define PROCFS_CTL_DETACH 2 68#define PROCFS_CTL_STEP 3 69#define PROCFS_CTL_RUN 4 70#define PROCFS_CTL_WAIT 5 71 |
70static vfs_namemap_t ctlnames[] = { | 72struct namemap { 73 const char *nm_name; 74 int nm_val; 75}; 76 77static struct namemap ctlnames[] = { |
71 /* special /proc commands */ 72 { "attach", PROCFS_CTL_ATTACH }, 73 { "detach", PROCFS_CTL_DETACH }, 74 { "step", PROCFS_CTL_STEP }, 75 { "run", PROCFS_CTL_RUN }, 76 { "wait", PROCFS_CTL_WAIT }, 77 { 0 }, 78}; 79 | 78 /* special /proc commands */ 79 { "attach", PROCFS_CTL_ATTACH }, 80 { "detach", PROCFS_CTL_DETACH }, 81 { "step", PROCFS_CTL_STEP }, 82 { "run", PROCFS_CTL_RUN }, 83 { "wait", PROCFS_CTL_WAIT }, 84 { 0 }, 85}; 86 |
80static vfs_namemap_t signames[] = { | 87static struct namemap signames[] = { |
81 /* regular signal names */ 82 { "hup", SIGHUP }, { "int", SIGINT }, 83 { "quit", SIGQUIT }, { "ill", SIGILL }, 84 { "trap", SIGTRAP }, { "abrt", SIGABRT }, 85 { "iot", SIGIOT }, { "emt", SIGEMT }, 86 { "fpe", SIGFPE }, { "kill", SIGKILL }, 87 { "bus", SIGBUS }, { "segv", SIGSEGV }, 88 { "sys", SIGSYS }, { "pipe", SIGPIPE }, --- 7 unchanged lines hidden (view full) --- 96 { "winch", SIGWINCH }, { "info", SIGINFO }, 97 { "usr1", SIGUSR1 }, { "usr2", SIGUSR2 }, 98 { 0 }, 99}; 100 101static int procfs_control __P((struct proc *curp, struct proc *p, int op)); 102 103static int | 88 /* regular signal names */ 89 { "hup", SIGHUP }, { "int", SIGINT }, 90 { "quit", SIGQUIT }, { "ill", SIGILL }, 91 { "trap", SIGTRAP }, { "abrt", SIGABRT }, 92 { "iot", SIGIOT }, { "emt", SIGEMT }, 93 { "fpe", SIGFPE }, { "kill", SIGKILL }, 94 { "bus", SIGBUS }, { "segv", SIGSEGV }, 95 { "sys", SIGSYS }, { "pipe", SIGPIPE }, --- 7 unchanged lines hidden (view full) --- 103 { "winch", SIGWINCH }, { "info", SIGINFO }, 104 { "usr1", SIGUSR1 }, { "usr2", SIGUSR2 }, 105 { 0 }, 106}; 107 108static int procfs_control __P((struct proc *curp, struct proc *p, int op)); 109 110static int |
104procfs_control(curp, p, op) 105 struct proc *curp; 106 struct proc *p; 107 int op; | 111procfs_control(struct proc *curp, struct proc *p, int op) |
108{ 109 int error = 0; 110 111 /* 112 * Authorization check: rely on normal debugging protection, except 113 * allow processes to disengage debugging on a process onto which 114 * they have previously attached, but no longer have permission to 115 * debug. --- 119 unchanged lines hidden (view full) --- 235 wakeup((caddr_t) curp); /* XXX for CTL_WAIT below ? */ 236 237 break; 238 239 /* 240 * Step. Let the target process execute a single instruction. 241 */ 242 case PROCFS_CTL_STEP: | 112{ 113 int error = 0; 114 115 /* 116 * Authorization check: rely on normal debugging protection, except 117 * allow processes to disengage debugging on a process onto which 118 * they have previously attached, but no longer have permission to 119 * debug. --- 119 unchanged lines hidden (view full) --- 239 wakeup((caddr_t) curp); /* XXX for CTL_WAIT below ? */ 240 241 break; 242 243 /* 244 * Step. Let the target process execute a single instruction. 245 */ 246 case PROCFS_CTL_STEP: |
243 _PHOLD(p); | |
244 PROC_UNLOCK(p); 245 error = proc_sstep(&p->p_thread); /* XXXKSE */ 246 PRELE(p); 247 if (error) 248 return (error); 249 break; 250 251 /* --- 44 unchanged lines hidden (view full) --- 296 297 mtx_lock_spin(&sched_lock); 298 if (p->p_stat == SSTOP) 299 setrunnable(&p->p_thread); /* XXXKSE */ 300 mtx_unlock_spin(&sched_lock); 301 return (0); 302} 303 | 247 PROC_UNLOCK(p); 248 error = proc_sstep(&p->p_thread); /* XXXKSE */ 249 PRELE(p); 250 if (error) 251 return (error); 252 break; 253 254 /* --- 44 unchanged lines hidden (view full) --- 299 300 mtx_lock_spin(&sched_lock); 301 if (p->p_stat == SSTOP) 302 setrunnable(&p->p_thread); /* XXXKSE */ 303 mtx_unlock_spin(&sched_lock); 304 return (0); 305} 306 |
307static struct namemap * 308findname(struct namemap *nm, char *buf, int buflen) 309{ 310 311 for (; nm->nm_name; nm++) 312 if (bcmp(buf, nm->nm_name, buflen+1) == 0) 313 return (nm); 314 315 return (0); 316} 317 |
|
304int | 318int |
305procfs_doctl(curp, p, pfs, uio) 306 struct proc *curp; 307 struct pfsnode *pfs; 308 struct uio *uio; 309 struct proc *p; | 319procfs_doprocctl(PFS_FILL_ARGS) |
310{ | 320{ |
311 int xlen; | |
312 int error; | 321 int error; |
313 char msg[PROCFS_CTLLEN+1]; 314 vfs_namemap_t *nm; | 322 struct namemap *nm; |
315 | 323 |
316 if (uio->uio_rw != UIO_WRITE) | 324 if (uio == NULL || uio->uio_rw != UIO_WRITE) |
317 return (EOPNOTSUPP); 318 | 325 return (EOPNOTSUPP); 326 |
319 xlen = PROCFS_CTLLEN; 320 error = vfs_getuserstr(uio, msg, &xlen); 321 if (error) 322 return (error); 323 | |
324 /* 325 * Map signal names into signal generation 326 * or debug control. Unknown commands and/or signals 327 * return EOPNOTSUPP. 328 * 329 * Sending a signal while the process is being debugged 330 * also has the side effect of letting the target continue 331 * to run. There is no way to single-step a signal delivery. 332 */ 333 error = EOPNOTSUPP; 334 | 327 /* 328 * Map signal names into signal generation 329 * or debug control. Unknown commands and/or signals 330 * return EOPNOTSUPP. 331 * 332 * Sending a signal while the process is being debugged 333 * also has the side effect of letting the target continue 334 * to run. There is no way to single-step a signal delivery. 335 */ 336 error = EOPNOTSUPP; 337 |
335 nm = vfs_findname(ctlnames, msg, xlen); | 338 sbuf_trim(sb); 339 sbuf_finish(sb); 340 nm = findname(ctlnames, sbuf_data(sb), sbuf_len(sb)); |
336 if (nm) { | 341 if (nm) { |
337 error = procfs_control(curp, p, nm->nm_val); | 342 printf("procfs: got a %s command\n", sbuf_data(sb)); 343 error = procfs_control(td->td_proc, p, nm->nm_val); |
338 } else { | 344 } else { |
339 nm = vfs_findname(signames, msg, xlen); | 345 nm = findname(signames, sbuf_data(sb), sbuf_len(sb)); |
340 if (nm) { | 346 if (nm) { |
347 printf("procfs: got a sig%s\n", sbuf_data(sb)); |
|
341 PROC_LOCK(p); 342 mtx_lock_spin(&sched_lock); | 348 PROC_LOCK(p); 349 mtx_lock_spin(&sched_lock); |
343 if (TRACE_WAIT_P(curp, p)) { | 350 if (TRACE_WAIT_P(td->td_proc, p)) { |
344 p->p_xstat = nm->nm_val; 345#ifdef FIX_SSTEP 346 FIX_SSTEP(&p->p_thread); /* XXXKSE */ 347#endif 348 setrunnable(&p->p_thread); /* XXXKSE */ 349 mtx_unlock_spin(&sched_lock); 350 } else { 351 mtx_unlock_spin(&sched_lock); 352 psignal(p, nm->nm_val); 353 } 354 PROC_UNLOCK(p); 355 error = 0; 356 } 357 } 358 359 return (error); 360} | 351 p->p_xstat = nm->nm_val; 352#ifdef FIX_SSTEP 353 FIX_SSTEP(&p->p_thread); /* XXXKSE */ 354#endif 355 setrunnable(&p->p_thread); /* XXXKSE */ 356 mtx_unlock_spin(&sched_lock); 357 } else { 358 mtx_unlock_spin(&sched_lock); 359 psignal(p, nm->nm_val); 360 } 361 PROC_UNLOCK(p); 362 error = 0; 363 } 364 } 365 366 return (error); 367} |