allow nil pointers for option values
[unix-history] / usr / src / sys / kern / sys_process.c
CommitLineData
961945a8
SL
1/* sys_process.c 5.8 82/12/17 */
2
3#include "../machine/reg.h"
4#include "../machine/psl.h"
5#include "../machine/pte.h"
9ce4de2d
BJ
6
7#include "../h/param.h"
8#include "../h/systm.h"
9#include "../h/dir.h"
10#include "../h/user.h"
11#include "../h/proc.h"
12#include "../h/inode.h"
9ce4de2d
BJ
13#include "../h/text.h"
14#include "../h/seg.h"
9ce4de2d
BJ
15#include "../h/vm.h"
16#include "../h/buf.h"
9ce4de2d
BJ
17#include "../h/acct.h"
18
4147b3f6
BJ
19/*
20 * Priority for tracing
21 */
22#define IPCPRI PZERO
23
24/*
25 * Tracing variables.
26 * Used to pass trace command from
27 * parent to child being traced.
28 * This data base cannot be
29 * shared and is locked
30 * per user.
31 */
32struct {
33 int ip_lock;
34 int ip_req;
35 int *ip_addr;
36 int ip_data;
37} ipc;
38
39/*
40 * sys-trace system call.
41 */
42ptrace()
43{
44 register struct proc *p;
45 register struct a {
46 int req;
47 int pid;
48 int *addr;
49 int data;
50 } *uap;
51
52 uap = (struct a *)u.u_ap;
53 if (uap->req <= 0) {
54 u.u_procp->p_flag |= STRC;
55 return;
56 }
57 p = pfind(uap->pid);
58 if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid) {
59 u.u_error = ESRCH;
60 return;
61 }
62 while (ipc.ip_lock)
63 sleep((caddr_t)&ipc, IPCPRI);
64 ipc.ip_lock = p->p_pid;
65 ipc.ip_data = uap->data;
66 ipc.ip_addr = uap->addr;
67 ipc.ip_req = uap->req;
68 p->p_flag &= ~SWTED;
69 while (ipc.ip_req > 0) {
70 if (p->p_stat==SSTOP)
71 setrun(p);
72 sleep((caddr_t)&ipc, IPCPRI);
73 }
74 u.u_r.r_val1 = ipc.ip_data;
75 if (ipc.ip_req < 0)
76 u.u_error = EIO;
77 ipc.ip_lock = 0;
78 wakeup((caddr_t)&ipc);
79}
80
b4e32d36 81#ifdef vax
883d0f83
BJ
82#define NIPCREG 16
83#endif
b4e32d36 84#ifdef sun
883d0f83
BJ
85#define NIPCREG 17
86#endif
87int ipcreg[NIPCREG] =
b4e32d36 88#ifdef vax
883d0f83
BJ
89 {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC};
90#endif
b4e32d36 91#ifdef sun
883d0f83
BJ
92 {R0,R1,R2,R3,R4,R5,R6,R7,AR0,AR1,AR2,AR3,AR4,AR5,AR6,AR7,PC};
93#endif
94
fc0890b1 95#define PHYSOFF(p, o) \
883d0f83
BJ
96 ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0])))
97
4147b3f6
BJ
98/*
99 * Code that the child process
100 * executes to implement the command
101 * of the parent process in tracing.
102 */
103procxmt()
104{
105 register int i;
106 register *p;
107 register struct text *xp;
108
109 if (ipc.ip_lock != u.u_procp->p_pid)
110 return (0);
111 u.u_procp->p_slptime = 0;
112 i = ipc.ip_req;
113 ipc.ip_req = 0;
114 switch (i) {
115
116 /* read user I */
117 case 1:
118 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
119 goto error;
120 ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
121 break;
122
123 /* read user D */
124 case 2:
125 if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
126 goto error;
127 ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
128 break;
129
130 /* read u */
131 case 3:
132 i = (int)ipc.ip_addr;
133 if (i<0 || i >= ctob(UPAGES))
134 goto error;
883d0f83 135 ipc.ip_data = *(int *)PHYSOFF(&u, i);
4147b3f6
BJ
136 break;
137
138 /* write user I */
139 /* Must set up to allow writing */
140 case 4:
141 /*
142 * If text, must assure exclusive use
143 */
144 if (xp = u.u_procp->p_textp) {
145 if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
146 goto error;
147 xp->x_iptr->i_flag &= ~ITEXT;
148 }
149 i = -1;
883d0f83
BJ
150 if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
151 if (chgprot((caddr_t)ipc.ip_addr, RW) &&
152 chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW))
153 i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
154 (void) chgprot((caddr_t)ipc.ip_addr, RO);
155 (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO);
156 }
4147b3f6
BJ
157 if (i < 0)
158 goto error;
159 if (xp)
160 xp->x_flag |= XWRIT;
161 break;
162
163 /* write user D */
164 case 5:
165 if (suword((caddr_t)ipc.ip_addr, 0) < 0)
166 goto error;
167 (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
168 break;
169
170 /* write u */
171 case 6:
172 i = (int)ipc.ip_addr;
883d0f83
BJ
173 p = (int *)PHYSOFF(&u, i);
174 for (i=0; i<NIPCREG; i++)
4147b3f6
BJ
175 if (p == &u.u_ar0[ipcreg[i]])
176 goto ok;
177 if (p == &u.u_ar0[PS]) {
883d0f83 178 ipc.ip_data |= PSL_USERSET;
4147b3f6 179 ipc.ip_data &= ~PSL_USERCLR;
961945a8
SL
180#ifdef sun
181 if (ipc.ip_data & PSL_T)
182 traceon();
183 else
184 traceoff();
185#endif
4147b3f6
BJ
186 goto ok;
187 }
188 goto error;
189
190 ok:
191 *p = ipc.ip_data;
192 break;
193
194 /* set signal and continue */
195 /* one version causes a trace-trap */
196 case 9:
197 case 7:
198 if ((int)ipc.ip_addr != 1)
199 u.u_ar0[PC] = (int)ipc.ip_addr;
200 if ((unsigned)ipc.ip_data > NSIG)
201 goto error;
202 u.u_procp->p_cursig = ipc.ip_data; /* see issig */
961945a8
SL
203 if (i == 9)
204#ifdef sun
205 traceon();
206#else
4147b3f6 207 u.u_ar0[PS] |= PSL_T;
961945a8 208#endif
4147b3f6
BJ
209 wakeup((caddr_t)&ipc);
210 return (1);
211
212 /* force exit */
213 case 8:
214 wakeup((caddr_t)&ipc);
215 exit(u.u_procp->p_cursig);
216
217 default:
218 error:
219 ipc.ip_req = -1;
220 }
221 wakeup((caddr_t)&ipc);
222 return (0);
223}