* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* @(#)kern_proc.c 7.6 (Berkeley) %G%
#include "../ufs/quota.h"
* Clear any pending stops for top and all descendents.
~(sigmask(SIGTSTP
)|sigmask(SIGTTIN
)|sigmask(SIGTTOU
));
* If this process has children, descend to them next,
* otherwise do any siblings, and if done with this level,
* follow back up the tree (but not past top).
* Is p an inferior of the current process?
for (; p
!= u
.u_procp
; p
= p
->p_pptr
)
for (p
= &proc
[pidhash
[PIDHASH(pid
)]] ;
p
!= &proc
[0]; p
= &proc
[p
->p_idhash
])
return ((struct proc
*)0);
* Locate a process group by number
register struct pgrp
*pgrp
= pgrphash
[PIDHASH(pgid
)];
for (; pgrp
; pgrp
= pgrp
->pg_hforw
)
return ((struct pgrp
*)0);
* Move p to a new or existing process group (and session)
register struct pgrp
*pgrp
= pgfind(pgid
);
register struct proc
**pp
= &p
->p_pgrp
->pg_mem
;
register struct proc
*cp
;
if (pgrp
&& mksess
) /* firewalls */
panic("pgmv: setsid into non-empty pgrp");
panic("pgmv: session leader attempted setpgrp");
panic("pgmv: new pgrp and pid != pgid");
MALLOC(pgrp
, struct pgrp
*, sizeof(struct pgrp
), M_PGRP
,
register struct session
*sess
;
MALLOC(sess
, struct session
*, sizeof(struct session
),
panic("pgmv: mksession and p != u.u_procp");
pgrp
->pg_session
= p
->p_session
;
pgrp
->pg_session
->s_count
++;
pgrp
->pg_hforw
= pgrphash
[n
=PIDHASH(pgid
)];
* adjust eligibility of affected pgrps to participate in job control
for (cp
= p
->p_cptr
; cp
; cp
= cp
->p_osptr
)
* unlink p from old process group
for (; *pp
; pp
= &(*pp
)->p_pgrpnxt
)
panic("pgmv: can't find p on old pgrp");
p
->p_pgrpnxt
= pgrp
->pg_mem
;
* adjust eligibility of affected pgrps to participate in job control
for (cp
= p
->p_cptr
; cp
; cp
= cp
->p_osptr
)
* remove process from process group
register struct proc
**pp
= &p
->p_pgrp
->pg_mem
;
for (; *pp
; pp
= &(*pp
)->p_pgrpnxt
)
panic("pgrm: can't find p in pgrp");
register struct pgrp
*pgrp
;
register struct pgrp
**pgp
= &pgrphash
[PIDHASH(pgrp
->pg_id
)];
for (; *pgp
; pgp
= &(*pgp
)->pg_hforw
)
panic("pgdelete: can't find pgrp on hash chain");
if (--pgrp
->pg_session
->s_count
== 0)
FREE(pgrp
->pg_session
, M_SESSION
);
* init the process queues
* most procs are initially on freequeue
* nb: we place them there in their "natural" order.
for (p
= procNPROC
; --p
> proc
; freeproc
= p
)
* but proc[0] is special ...
register struct pgrp
*pgrp
;
for (i
=0; i
<PIDHSZ
; i
++) {
printf("\tindx %d\n", i
);
for (pgrp
=pgrphash
[i
]; pgrp
; pgrp
=pgrp
->pg_hforw
) {
printf("\tpgrp %x, pgid %d, sess %x, sesscnt %d, mem %x\n",
pgrp
, pgrp
->pg_id
, pgrp
->pg_session
,
pgrp
->pg_session
->s_count
, pgrp
->pg_mem
);
for (p
=pgrp
->pg_mem
; p
; p
=p
->p_pgrpnxt
) {
printf("\t\tpid %d addr %x pgrp %x\n",