/* kern_proc.c 3.3 %H% */
* exec system call, with and without environments.
((struct execa
*)u
.u_ap
)->envp
= NULL
;
register struct execa
*uap
;
if ((ip
= namei(uchar
, 0)) == NULL
)
if((ip
->i_mode
& IFMT
) != IFREG
||
(ip
->i_mode
& (IEXEC
|(IEXEC
>>3)|(IEXEC
>>6))) == 0) {
* Collect arguments on "file" in swap space.
uap
= (struct execa
*)u
.u_ap
;
if ((bno
= malloc(swapmap
, ctod(clrnd((int) btoc(NCARGS
))))) == 0) {
swkill(u
.u_procp
, "exece");
if (uap
->argp
) for (;;) {
ap
= fuword((caddr_t
)uap
->argp
);
if (ap
==NULL
&& uap
->envp
) {
if ((ap
= fuword((caddr_t
)uap
->envp
)) == NULL
)
if ((c
= fubyte((caddr_t
)ap
++)) < 0)
bp
= getblk(swapdev
, (daddr_t
)(dbtofsb(swplo
+bno
)+(nc
>>BSHIFT
)));
nc
= (nc
+ NBPW
-1) & ~(NBPW
-1);
if (getxfile(ip
, nc
) || u
.u_error
) {
for (c
= 0; c
< nc
; c
+= BSIZE
)
if (bp
= baddr(swapdev
, dbtofsb(swplo
+bno
)+(c
>>BSHIFT
))) {
bp
->b_flags
|= B_AGE
; /* throw away */
bp
->b_flags
&= ~B_DELWRI
; /* cancel io */
ucp
= USRSTACK
- nc
- NBPW
;
ap
= ucp
- na
*NBPW
- 3*NBPW
;
(void) suword((caddr_t
)ap
, na
-ne
);
(void) suword((caddr_t
)ap
, 0);
(void) suword((caddr_t
)ap
, ucp
);
bp
= bread(swapdev
, (daddr_t
)(dbtofsb(swplo
+bno
)+(nc
>>BSHIFT
)));
bp
->b_flags
|= B_AGE
; /* throw away */
bp
->b_flags
&= ~B_DELWRI
; /* cancel io */
(void) subyte((caddr_t
)ucp
++, (c
= *cp
++));
(void) suword((caddr_t
)ap
, 0);
(void) suword((caddr_t
)ucp
, 0);
mfree(swapmap
, ctod(clrnd((int) btoc(NCARGS
))), bno
);
* Read in and set up memory for executed file.
* non-zero means only the text is being replaced
register struct inode
*ip
;
register size_t ts
, ds
, ss
;
* read in first few bytes
* ux_mag = 407/410/411/405
* 407 is plain executable
* 412 is demand paged plain executable (NOT IMPLEMENTED)
* 413 is demand paged RO text
u
.u_base
= (caddr_t
)&u
.u_exdata
;
u
.u_count
= sizeof(u
.u_exdata
);
switch (u
.u_exdata
.ux_mag
) {
u
.u_exdata
.ux_dsize
+= u
.u_exdata
.ux_tsize
;
if (u
.u_exdata
.ux_tsize
== 0) {
if(u
.u_exdata
.ux_tsize
!=0 && (ip
->i_flag
&ITEXT
)==0 && ip
->i_count
!=1) {
* find text and data sizes
* try them out for possible
ts
= clrnd(btoc(u
.u_exdata
.ux_tsize
));
ds
= clrnd(btoc((u
.u_exdata
.ux_dsize
+u
.u_exdata
.ux_bsize
)));
ss
= clrnd(SSIZE
+ btoc(nargc
));
if ((u
.u_procp
->p_flag
& SPAGI
) || u
.u_sep
==0 && ctos(ts
) != ctos(u
.u_tsize
) || nargc
) {
u
.u_ar0
[PC
] = u
.u_exdata
.ux_entloc
+ 2; /* skip over entry mask */
if (swpexpand(ds
, ss
, &u
.u_cdmap
, &u
.u_csmap
) == NULL
)
* At this point, committed to the new image!
* Release virtual memory resources of old process, and
* initialize the virtual memory of the new process.
* If we resulted from vfork(), instead wakeup our
* parent who will set SVFDONE when he has taken back
if ((u
.u_procp
->p_flag
& SVFORK
) == 0)
u
.u_procp
->p_flag
&= ~SVFORK
;
u
.u_procp
->p_flag
|= SKEEP
;
wakeup((caddr_t
)u
.u_procp
);
while ((u
.u_procp
->p_flag
& SVFDONE
) == 0)
sleep((caddr_t
)u
.u_procp
, PZERO
- 1);
u
.u_procp
->p_flag
&= ~(SVFDONE
|SKEEP
);
u
.u_procp
->p_flag
&= ~(SPAGI
|SANOM
|SUANOM
);
u
.u_procp
->p_flag
|= pagi
;
u
.u_base
= (char *)ctob(ts
);
u
.u_offset
= sizeof(u
.u_exdata
)+u
.u_exdata
.ux_tsize
;
u
.u_count
= u
.u_exdata
.ux_dsize
;
if (pagi
&& u
.u_procp
->p_textp
)
vinifod((struct fpte
*)dptopte(u
.u_procp
, 0),
PG_FTEXT
, u
.u_procp
->p_textp
->x_iptr
,
1 + ts
/CLSIZE
, (int)btoc(u
.u_exdata
.ux_dsize
));
/* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
* set SUID/SGID protections, if no tracing
if ((u
.u_procp
->p_flag
&STRC
)==0) {
u
.u_procp
->p_uid
= ip
->i_uid
;
psignal(u
.u_procp
, SIGTRC
);
* Clear registers on exec
for(rp
= &u
.u_signal
[0]; rp
< &u
.u_signal
[NSIG
]; rp
++)
for(rp = &u.u_ar0[0]; rp < &u.u_ar0[16];)
u
.u_ar0
[PC
] = u
.u_exdata
.ux_entloc
+ 2; /* skip over entry mask */
for(i
=0; i
<NOFILE
; i
++) {
if (u
.u_pofile
[i
]&EXCLOSE
) {
u
.u_pofile
[i
] &= ~EXCLOSE
;
* Remember file name for accounting.
bcopy((caddr_t
)u
.u_dbuf
, (caddr_t
)u
.u_comm
, DIRSIZ
);
uap
= (struct a
*)u
.u_ap
;
exit((uap
->rval
& 0377) << 8);
* Save u. area for parent to look at.
* Wake up parent and init processes,
* and dispose of children.
register struct proc
*p
, *q
;
p
->p_flag
&= ~(STRC
|SULOCK
);
rate
.v_pgin
-= p
->p_aveflt
;
* Release virtual memory. If we resulted from
* a vfork(), instead give the resources back to
if ((p
->p_flag
& SVFORK
) == 0)
while ((p
->p_flag
& SVFDONE
) == 0)
sleep((caddr_t
)p
, PZERO
- 1);
for(i
=0; i
<NOFILE
; i
++) {
spl7(); /* clock will get mad because of overlaying */
pidhash
[i
] = p
->p_idhash
;
for (i
= pidhash
[i
]; i
!= 0; i
= proc
[i
].p_idhash
)
if (proc
[i
].p_idhash
== x
) {
proc
[i
].p_idhash
= p
->p_idhash
;
((struct xproc
*)p
)->xp_xstat
= rv
; /* overlay */
((struct xproc
*)p
)->xp_vm
= u
.u_vm
; /* overlay */
vmsadd(&((struct xproc
*)p
)->xp_vm
, &u
.u_cvm
);
for(q
= &proc
[0]; q
< &proc
[NPROC
]; q
++)
if(q
->p_ppid
== p
->p_pid
) {
wakeup((caddr_t
)&proc
[1]);
wait1((struct vtimes
*)0);
* 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
) {
u
.u_r
.r_val2
= ((struct xproc
*)p
)->xp_xstat
;
((struct xproc
*)p
)->xp_xstat
= 0;
*vp
= ((struct xproc
*)p
)->xp_vm
;
vmsadd(&u
.u_cvm
, &((struct xproc
*)p
)->xp_vm
);
((struct xproc
*)p
)->xp_vm
= zvms
;
if((p
->p_flag
&SWTED
) == 0) {
u
.u_r
.r_val2
= (fsig(p
)<<8) | 0177;
sleep((caddr_t
)u
.u_procp
, PWAIT
);
if (swpexpand(u
.u_dsize
, u
.u_ssize
, &u
.u_cdmap
, &u
.u_csmap
) == 0) {
register struct proc
*p1
, *p2
;
for(p1
= &proc
[0]; p1
< &proc
[NPROC
]; p1
++) {
if (p1
->p_stat
==NULL
&& p2
==NULL
)
if (p1
->p_uid
==u
.u_uid
&& p1
->p_stat
!=NULL
)
* not su and too many procs owned; or
* not su and would take last slot.
if (p2
==NULL
|| (u
.u_uid
!=0 && (p2
==&proc
[NPROC
-1] || a
>MAXUPRC
))) {
(void) vsexpand(0, &u
.u_cdmap
, 1);
(void) vsexpand(0, &u
.u_csmap
, 1);
u
.u_r
.r_val1
= p1
->p_pid
;
u
.u_r
.r_val2
= 1; /* child */
u
.u_r
.r_val1
= p2
->p_pid
;
* -- bad planning: "break" is a dirty word in C.
n
= btoc(((struct a
*)u
.u_ap
)->nsiz
);
n
-= ctos(u
.u_tsize
) * stoc(1);
d
= clrnd(n
- u
.u_dsize
);
if (chksize(u
.u_tsize
, u
.u_dsize
+d
, u
.u_ssize
))
if (swpexpand(u
.u_dsize
+d
, u
.u_ssize
, &u
.u_dmap
, &u
.u_smap
)==0)