* Used to pass trace command from
* parent to child being traced.
* This data base cannot be
* Send the specified signal to
* all processes with 'pgrp' as
* Called by tty.c for quits and
for(p
= &proc
[0]; p
< &proc
[NPROC
]; p
++)
* Send the specified signal to
if((unsigned)sig
>= NSIG
)
if(p
->p_stat
== SSLEEP
&& p
->p_pri
> PZERO
)
* Returns true if the current
* process has a signal to process.
* This is asked at least once
* each time a process enters the
* A signal does not do anything
* directly to a process; it sets
* a flag that asks the process to
* do something to itself.
if((u
.u_signal
[n
]&1) == 0 || (p
->p_flag
&STRC
))
* Enter the tracing STOP state.
* In this state, the parent is
* informed and the process is able to
* receive commands from the parent.
register struct proc
*pp
, *cp
;
for (pp
= &proc
[0]; pp
< &proc
[NPROC
]; pp
++)
if (pp
->p_pid
== cp
->p_ppid
) {
if ((cp
->p_flag
&STRC
)==0 || procxmt())
* Perform the action specified by
register struct proc
*rp
;
rp
->p_sig
&= ~(1<<(n
-1));
if((p
=u
.u_signal
[n
]) != 0) {
if(n
!= SIGINS
&& n
!= SIGTRC
)
* find the signal in bit-position
* representation in p_sig.
* Create a core image on the file "core"
* If you are looking for protection glitches,
* there are probably a wealth of them here
* when this occurs to a suid command.
* It writes USIZE block of the
* user.h area followed by the entire
register struct inode
*ip
;
if(!access(ip
, IWRITE
) &&
(ip
->i_mode
&IFMT
) == IFREG
&&
s
= u
.u_procp
->p_size
- USIZE
;
estabur((unsigned)0, s
, (unsigned)0, 0, RO
);
* grow the stack to include the SP
* true return if successful.
if(sp
>= USRSTACK
-ctob(u
.u_ssize
))
si
= btoc((USRSTACK
-sp
)) - u
.u_ssize
+ SINCR
;
if(estabur(u
.u_tsize
, u
.u_dsize
, u
.u_ssize
+si
, u
.u_sep
, RO
))
a
= p
->p_addr
+ p
->p_size
;
for(i
=u
.u_ssize
; i
; i
--) {
uap
= (struct a
*)u
.u_ap
;
u
.u_procp
->p_flag
|= STRC
;
for (p
=proc
; p
< &proc
[NPROC
]; p
++)
&& p
->p_ppid
==u
.u_procp
->p_pid
)
sleep((caddr_t
)&ipc
, IPCPRI
);
sleep((caddr_t
)&ipc
, IPCPRI
);
u
.u_r
.r_val1
= ipc
.ip_data
;
int ipcreg
[] = {R0
, R1
, R2
, R3
, R4
, R5
, R6
, R7
, R8
, R9
, R10
, R11
, AP
, FP
, SP
, PC
};
* Code that the child process
* executes to implement the command
* of the parent process in tracing.
register struct text
*xp
;
if (ipc
.ip_lock
!= u
.u_procp
->p_pid
)
if ( !useracc((caddr_t
)ipc
.ip_addr
, 4, 1))
ipc
.ip_data
= fuiword((caddr_t
)ipc
.ip_addr
);
if ( !useracc((caddr_t
)ipc
.ip_addr
, 4, 1))
ipc
.ip_data
= fuword((caddr_t
)ipc
.ip_addr
);
if (i
<0 || i
>= ctob(USIZE
))
ipc
.ip_data
= ((physadr
)&u
)->r
[i
>>2];
/* Must set up to allow writing */
* If text, must assure exclusive use
if (xp
= u
.u_procp
->p_textp
) {
if (xp
->x_count
!=1 || xp
->x_iptr
->i_mode
&ISVTX
)
xp
->x_iptr
->i_flag
&= ~ITEXT
;
estabur(u
.u_tsize
, u
.u_dsize
, u
.u_ssize
, u
.u_sep
, RW
);
i
= suiword((caddr_t
)ipc
.ip_addr
, 0);
suiword((caddr_t
)ipc
.ip_addr
, ipc
.ip_data
);
estabur(u
.u_tsize
, u
.u_dsize
, u
.u_ssize
, u
.u_sep
, RO
);
if (suword((caddr_t
)ipc
.ip_addr
, 0) < 0)
suword((caddr_t
)ipc
.ip_addr
, ipc
.ip_data
);
p
= (int *)&((physadr
)&u
)->r
[i
>>2];
if (p
== &u
.u_ar0
[ipcreg
[i
]])
ipc
.ip_data
|= 0x3c00000; /* modes == user */
ipc
.ip_data
&= ~0x3c20ff00; /* IS, FPD, ... */
/* set signal and continue */
/* one version causes a trace-trap */
if ((int)ipc
.ip_addr
!= 1)
u
.u_ar0
[PC
] = (int)ipc
.ip_addr
;
psignal(u
.u_procp
, ipc
.ip_data
);