duplicate TIOCGPGRP for controller - minus the check for controlling terminal
[unix-history] / usr / src / sys / kern / sys_process.c
CommitLineData
da7c5cc6 1/*
c4ec2128 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
19dec745 6 * @(#)sys_process.c 7.11 (Berkeley) %G%
da7c5cc6 7 */
961945a8 8
ff32eb64 9#define IPCREG
94368568 10#include "param.h"
8c7d0e2a 11#include "syscontext.h"
94368568 12#include "proc.h"
c4ec2128 13#include "vnode.h"
94368568
JB
14#include "text.h"
15#include "seg.h"
94368568 16#include "buf.h"
01b0e233 17#include "ptrace.h"
9ce4de2d 18
d301d150
KM
19#include "machine/reg.h"
20#include "machine/psl.h"
21#include "machine/pte.h"
22
4147b3f6
BJ
23/*
24 * Priority for tracing
25 */
26#define IPCPRI PZERO
27
28/*
29 * Tracing variables.
30 * Used to pass trace command from
31 * parent to child being traced.
32 * This data base cannot be
33 * shared and is locked
34 * per user.
35 */
36struct {
37 int ip_lock;
38 int ip_req;
39 int *ip_addr;
40 int ip_data;
41} ipc;
42
43/*
44 * sys-trace system call.
45 */
8c7d0e2a
KM
46ptrace(curp, uap, retval)
47 struct proc *curp;
48 register struct args {
4147b3f6
BJ
49 int req;
50 int pid;
51 int *addr;
52 int data;
53 } *uap;
8c7d0e2a
KM
54 int *retval;
55{
56 register struct proc *p;
4147b3f6 57
4147b3f6 58 if (uap->req <= 0) {
8c7d0e2a
KM
59 curp->p_flag |= STRC;
60 RETURN (0);
4147b3f6
BJ
61 }
62 p = pfind(uap->pid);
8c7d0e2a
KM
63 if (p == 0 || p->p_stat != SSTOP || p->p_ppid != curp->p_pid ||
64 !(p->p_flag & STRC))
65 RETURN (ESRCH);
4147b3f6
BJ
66 while (ipc.ip_lock)
67 sleep((caddr_t)&ipc, IPCPRI);
68 ipc.ip_lock = p->p_pid;
69 ipc.ip_data = uap->data;
70 ipc.ip_addr = uap->addr;
71 ipc.ip_req = uap->req;
72 p->p_flag &= ~SWTED;
73 while (ipc.ip_req > 0) {
74 if (p->p_stat==SSTOP)
75 setrun(p);
76 sleep((caddr_t)&ipc, IPCPRI);
77 }
8c7d0e2a 78 *retval = ipc.ip_data;
4147b3f6
BJ
79 ipc.ip_lock = 0;
80 wakeup((caddr_t)&ipc);
8c7d0e2a
KM
81 if (ipc.ip_req < 0)
82 RETURN (EIO);
83 RETURN (0);
4147b3f6
BJ
84}
85
fc0890b1 86#define PHYSOFF(p, o) \
883d0f83
BJ
87 ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0])))
88
4147b3f6
BJ
89/*
90 * Code that the child process
91 * executes to implement the command
92 * of the parent process in tracing.
93 */
82655668
KM
94procxmt(p)
95 register struct proc *p;
4147b3f6 96{
82655668 97 register int i, *poff;
4147b3f6 98 register struct text *xp;
c4ec2128
KM
99 struct vattr vattr;
100 struct vnode *vp;
4147b3f6 101
82655668 102 if (ipc.ip_lock != p->p_pid)
4147b3f6 103 return (0);
82655668 104 p->p_slptime = 0;
4147b3f6
BJ
105 i = ipc.ip_req;
106 ipc.ip_req = 0;
107 switch (i) {
108
01b0e233 109 case PT_READ_I: /* read the child's text space */
4147b3f6
BJ
110 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
111 goto error;
112 ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
113 break;
114
01b0e233 115 case PT_READ_D: /* read the child's data space */
4147b3f6
BJ
116 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
117 goto error;
118 ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
119 break;
120
01b0e233 121 case PT_READ_U: /* read the child's u. */
dc57440c
KM
122#ifdef HPUXCOMPAT
123 if (u.u_pcb.pcb_flags & PCB_HPUXTRACE)
124 i = hpuxtobsduoff(ipc.ip_addr);
125 else
126#endif
4147b3f6 127 i = (int)ipc.ip_addr;
dc57440c 128 if (i<0 || i > ctob(UPAGES)-sizeof(int))
4147b3f6 129 goto error;
883d0f83 130 ipc.ip_data = *(int *)PHYSOFF(&u, i);
4147b3f6
BJ
131 break;
132
01b0e233 133 case PT_WRITE_I: /* write the child's text space */
4147b3f6
BJ
134 /*
135 * If text, must assure exclusive use
136 */
82655668 137 if (xp = p->p_textp) {
c4ec2128
KM
138 vp = xp->x_vptr;
139 VOP_GETATTR(vp, &vattr, u.u_cred);
140 if (xp->x_count!=1 || (vattr.va_mode & VSVTX))
4147b3f6 141 goto error;
cdb14d96 142 xp->x_flag |= XTRC;
4147b3f6
BJ
143 }
144 i = -1;
883d0f83 145 if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
eeec7d1d
KM
146 if (!chgprot((caddr_t)ipc.ip_addr, RW) &&
147 !chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW))
883d0f83
BJ
148 i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
149 (void) chgprot((caddr_t)ipc.ip_addr, RO);
150 (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO);
151 }
4147b3f6
BJ
152 if (i < 0)
153 goto error;
fb1db32c
MK
154#if defined(tahoe)
155 /* make sure the old value is not in cache */
82655668
KM
156 ckeyrelease(p->p_ckey);
157 p->p_ckey = getcodekey();
fb1db32c
MK
158#endif
159 if (xp) {
4147b3f6 160 xp->x_flag |= XWRIT;
fb1db32c 161#if defined(tahoe)
82655668 162 xp->x_ckey = p->p_ckey;
fb1db32c
MK
163#endif
164 }
4147b3f6
BJ
165 break;
166
01b0e233 167 case PT_WRITE_D: /* write the child's data space */
4147b3f6
BJ
168 if (suword((caddr_t)ipc.ip_addr, 0) < 0)
169 goto error;
170 (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
171 break;
172
01b0e233 173 case PT_WRITE_U: /* write the child's u. */
dc57440c
KM
174#ifdef HPUXCOMPAT
175 if (u.u_pcb.pcb_flags & PCB_HPUXTRACE)
176 i = hpuxtobsduoff(ipc.ip_addr);
177 else
178#endif
4147b3f6 179 i = (int)ipc.ip_addr;
82655668 180 poff = (int *)PHYSOFF(&u, i);
883d0f83 181 for (i=0; i<NIPCREG; i++)
82655668 182 if (poff == &u.u_ar0[ipcreg[i]])
4147b3f6 183 goto ok;
82655668 184 if (poff == &u.u_ar0[PS]) {
883d0f83 185 ipc.ip_data |= PSL_USERSET;
dc57440c 186 ipc.ip_data &= ~PSL_USERCLR;
bf47fbca
MK
187#ifdef PSL_CM_CLR
188 if (ipc.ip_data & PSL_CM)
189 ipc.ip_data &= ~PSL_CM_CLR;
190#endif
4147b3f6
BJ
191 goto ok;
192 }
dc57440c
KM
193#if defined(hp300)
194#ifdef FPCOPROC
82655668
KM
195 if (poff >= (int *)u.u_pcb.pcb_fpregs.fpf_regs &&
196 poff <= (int *)&u.u_pcb.pcb_fpregs.fpf_fpiar)
dc57440c
KM
197 goto ok;
198#endif
199#endif
4147b3f6
BJ
200 goto error;
201
202 ok:
82655668 203 *poff = ipc.ip_data;
4147b3f6
BJ
204 break;
205
01b0e233
MK
206 case PT_STEP: /* single step the child */
207 case PT_CONTINUE: /* continue the child */
4147b3f6
BJ
208 if ((int)ipc.ip_addr != 1)
209 u.u_ar0[PC] = (int)ipc.ip_addr;
210 if ((unsigned)ipc.ip_data > NSIG)
211 goto error;
19dec745 212 p->p_xstat = ipc.ip_data; /* see issig */
01b0e233 213 if (i == PT_STEP)
4147b3f6
BJ
214 u.u_ar0[PS] |= PSL_T;
215 wakeup((caddr_t)&ipc);
216 return (1);
217
01b0e233 218 case PT_KILL: /* kill the child process */
4147b3f6 219 wakeup((caddr_t)&ipc);
19dec745 220 exit(p, p->p_xstat);
4147b3f6
BJ
221
222 default:
223 error:
224 ipc.ip_req = -1;
225 }
226 wakeup((caddr_t)&ipc);
227 return (0);
228}