* Because of the fact that an I/O buffer is used
* to store the caller's arguments during exec,
* and more buffers are needed to read in the text file,
* deadly embraces waiting for free buffers are possible.
* Therefore the number of processes simultaneously
* running in exec has to be limited to NEXEC.
* and check various modes
if(access(ip
, IEXEC
) || (ip
->i_mode
&IFMT
)!=0)
while(ap
= fuword(u
.u_arg
[1])) {
* w0 = 407/410/411 (410 implies RO text) (411 implies sep ID)
u
.u_arg
[2] =+ u
.u_arg
[1];
if(u
.u_arg
[1]!=0 && (ip
->i_flag
&ITEXT
)==0 && ip
->i_count
!=1) {
* find text and data sizes
* try them out for possible
ts
= ((u
.u_arg
[1]+63)>>6) & 01777;
ds
= ((u
.u_arg
[2]+u
.u_arg
[3]+63)>>6) & 01777;
if(estabur(ts
, ds
, SSIZE
, sep
))
* allocate and clear core
* at this point, committed
clearseg(u
.u_procp
->p_addr
+c
);
u
.u_offset
[1] = 020+u
.u_arg
[1];
* initialize stack segment
estabur(u
.u_tsize
, u
.u_dsize
, u
.u_ssize
, u
.u_sep
);
* set SUID/SGID protections, if no tracing
if ((u
.u_procp
->p_flag
&STRC
)==0) {
u
.u_procp
->p_uid
= ip
->i_uid
;
* clear sigs, regs and return
for(ip
= &u
.u_signal
[0]; ip
< &u
.u_signal
[NSIG
]; ip
++)
for(cp
= ®loc
[0]; cp
< ®loc
[6];)
for(ip
= &u
.u_fsav
[0]; ip
< &u
.u_fsav
[25];)
u
.u_arg
[0] = u
.u_ar0
[R0
] << 8;
* Save u. area for parent to look at.
* Wake up parent and init processes,
* and dispose of children.
u
.u_procp
->p_flag
=& ~STRC
;
for(q
= &u
.u_signal
[0]; q
< &u
.u_signal
[NSIG
];)
for(q
= &u
.u_ofile
[0]; q
< &u
.u_ofile
[NOFILE
]; q
++)
bcopy(&u
, p
->b_addr
, 256);
mfree(coremap
, q
->p_size
, q
->p_addr
);
for(p
= &proc
[0]; p
< &proc
[NPROC
]; p
++)
if(q
->p_ppid
== p
->p_pid
) {
for(p
= &proc
[0]; p
< &proc
[NPROC
]; p
++)
if(q
->p_pid
== p
->p_ppid
) {
* Search for a terminated (zombie) child,
* finally lay it to rest, and collect its status.
* Look also for stopped (traced) children,
* and pass back status from them.
for(p
= &proc
[0]; p
< &proc
[NPROC
]; p
++)
if(p
->p_ppid
== u
.u_procp
->p_pid
) {
bp
= bread(swapdev
, f
=p
->p_addr
);
u
.u_cstime
[0] =+ p
->u_cstime
[0];
dpadd(u
.u_cstime
, p
->u_cstime
[1]);
dpadd(u
.u_cstime
, p
->u_stime
);
u
.u_cutime
[0] =+ p
->u_cutime
[0];
dpadd(u
.u_cutime
, p
->u_cutime
[1]);
dpadd(u
.u_cutime
, p
->u_utime
);
u
.u_ar0
[R1
] = p
->u_arg
[0];
if((p
->p_flag
&SWTED
) == 0) {
u
.u_ar0
[R1
] = (p
->p_sig
<<8) | 0177;
p
->p_flag
=& ~(STRC
|SWTED
);
register struct proc
*p1
, *p2
;
for(p2
= &proc
[0]; p2
< &proc
[NPROC
]; p2
++)
* -- bad planning: "break" is a dirty word in C.
* set n to new total size
n
= (((u
.u_arg
[0]+63)>>6) & 01777);
n
=- nseg(u
.u_tsize
) * 128;
if(estabur(u
.u_tsize
, u
.u_dsize
+d
, u
.u_ssize
, u
.u_sep
))
a
= u
.u_procp
->p_addr
+ n
- u
.u_ssize
;
a
= u
.u_procp
->p_addr
+ n
;