Deleted Added
sdiff udiff text old ( 91066 ) new ( 91140 )
full compact
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
34 * $FreeBSD: head/sys/kern/kern_proc.c 91066 2002-02-22 13:32:01Z phk $
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>
40#include <sys/lock.h>
41#include <sys/malloc.h>
42#include <sys/mutex.h>

--- 7 unchanged lines hidden (view full) ---

50#include <sys/user.h>
51#include <sys/jail.h>
52
53#include <vm/vm.h>
54#include <vm/pmap.h>
55#include <vm/vm_map.h>
56#include <vm/vm_zone.h>
57
58static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header");
59MALLOC_DEFINE(M_SESSION, "session", "session header");
60static MALLOC_DEFINE(M_PROC, "proc", "Proc structures");
61MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures");
62
63static void pgdelete __P((struct pgrp *));
64
65static void orphanpg __P((struct pgrp *pg));
66
67/*
68 * Other process lists
69 */
70struct pidhashhead *pidhashtbl;
71u_long pidhash;
72struct pgrphashhead *pgrphashtbl;
73u_long pgrphash;
74struct proclist allproc;
75struct proclist zombproc;
76struct sx allproc_lock;
77struct sx proctree_lock;
78vm_zone_t proc_zone;
79vm_zone_t ithread_zone;
80
81/*
82 * Initialize global process hashing structures.
83 */
84void
85procinit()
86{
87 int i, j;
88
89 sx_init(&allproc_lock, "allproc");
90 sx_init(&proctree_lock, "proctree");
91 LIST_INIT(&allproc);
92 LIST_INIT(&zombproc);
93 pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
94 pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
95 proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5);
96 uihashinit();
97 /*
98 * This should really be a compile time warning, but I do

--- 161 unchanged lines hidden (view full) ---

260 */
261struct proc *
262pfind(pid)
263 register pid_t pid;
264{
265 register struct proc *p;
266
267 sx_slock(&allproc_lock);
268 LIST_FOREACH(p, PIDHASH(pid), p_hash)
269 if (p->p_pid == pid) {
270 PROC_LOCK(p);
271 break;
272 }
273 sx_sunlock(&allproc_lock);
274 return (p);
275}
276
277/*
278 * Locate a process group by number
279 */
280struct pgrp *
281pgfind(pgid)
282 register pid_t pgid;
283{
284 register struct pgrp *pgrp;
285
286 LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash)
287 if (pgrp->pg_id == pgid)
288 return (pgrp);
289 return (NULL);
290}
291
292/*
293 * Move p to a new or existing process group (and session)
294 */
295int
296enterpgrp(p, pgid, mksess)
297 register struct proc *p;
298 pid_t pgid;
299 int mksess;
300{
301 register struct pgrp *pgrp = pgfind(pgid);
302 struct pgrp *savegrp;
303
304 KASSERT(pgrp == NULL || !mksess,
305 ("enterpgrp: setsid into non-empty pgrp"));
306 KASSERT(!SESS_LEADER(p),
307 ("enterpgrp: session leader attempted setpgrp"));
308
309 if (pgrp == NULL) {
310 pid_t savepid = p->p_pid;
311 struct proc *np;
312 /*
313 * new process group
314 */
315 KASSERT(p->p_pid == pgid,
316 ("enterpgrp: new pgrp and pid != pgid"));
317 if ((np = pfind(savepid)) == NULL || np != p) {
318 if (np != NULL)
319 PROC_UNLOCK(np);
320 return (ESRCH);
321 }
322 PROC_UNLOCK(np);
323 MALLOC(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
324 M_WAITOK);
325 if (mksess) {
326 register struct session *sess;
327
328 /*
329 * new session
330 */
331 MALLOC(sess, struct session *, sizeof(struct session),
332 M_SESSION, M_WAITOK);
333 sess->s_leader = p;
334 sess->s_sid = p->p_pid;
335 sess->s_count = 1;
336 sess->s_ttyvp = NULL;
337 sess->s_ttyp = NULL;
338 bcopy(p->p_session->s_login, sess->s_login,
339 sizeof(sess->s_login));
340 PROC_LOCK(p);
341 p->p_flag &= ~P_CONTROLT;
342 PROC_UNLOCK(p);
343 pgrp->pg_session = sess;
344 KASSERT(p == curproc,
345 ("enterpgrp: mksession and p != curproc"));
346 } else {
347 pgrp->pg_session = p->p_session;
348 pgrp->pg_session->s_count++;
349 }
350 pgrp->pg_id = pgid;
351 LIST_INIT(&pgrp->pg_members);
352 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
353 pgrp->pg_jobc = 0;
354 SLIST_INIT(&pgrp->pg_sigiolst);
355 } else if (pgrp == p->p_pgrp)
356 return (0);
357
358 /*
359 * Adjust eligibility of affected pgrps to participate in job control.
360 * Increment eligibility counts before decrementing, otherwise we
361 * could reach 0 spuriously during the first call.
362 */
363 fixjobc(p, pgrp, 1);
364 fixjobc(p, p->p_pgrp, 0);
365
366 PROC_LOCK(p);
367 LIST_REMOVE(p, p_pglist);
368 savegrp = p->p_pgrp;
369 p->p_pgrp = pgrp;
370 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
371 PROC_UNLOCK(p);
372 if (LIST_EMPTY(&savegrp->pg_members))
373 pgdelete(savegrp);
374 return (0);
375}
376
377/*
378 * remove process from process group
379 */
380int
381leavepgrp(p)
382 register struct proc *p;
383{
384 struct pgrp *savegrp;
385
386 PROC_LOCK(p);
387 LIST_REMOVE(p, p_pglist);
388 savegrp = p->p_pgrp;
389 p->p_pgrp = NULL;
390 PROC_UNLOCK(p);
391 if (LIST_EMPTY(&savegrp->pg_members))
392 pgdelete(savegrp);
393 return (0);
394}
395
396/*
397 * delete a process group
398 */
399static void
400pgdelete(pgrp)
401 register struct pgrp *pgrp;
402{
403
404 /*
405 * Reset any sigio structures pointing to us as a result of
406 * F_SETOWN with our pgid.
407 */
408 funsetownlst(&pgrp->pg_sigiolst);
409
410 if (pgrp->pg_session->s_ttyp != NULL &&
411 pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
412 pgrp->pg_session->s_ttyp->t_pgrp = NULL;
413 LIST_REMOVE(pgrp, pg_hash);
414 if (--pgrp->pg_session->s_count == 0)
415 FREE(pgrp->pg_session, M_SESSION);
416 FREE(pgrp, M_PGRP);
417}
418
419/*
420 * Adjust pgrp jobc counters when specified process changes process group.
421 * We count the number of processes in each process group that "qualify"
422 * the group for terminal job control (those with a parent in a different
423 * process group of the same session). If that count reaches zero, the

--- 4 unchanged lines hidden (view full) ---

428 */
429void
430fixjobc(p, pgrp, entering)
431 register struct proc *p;
432 register struct pgrp *pgrp;
433 int entering;
434{
435 register struct pgrp *hispgrp;
436 register struct session *mysession = pgrp->pg_session;
437
438 /*
439 * Check p's parent to see whether p qualifies its own process
440 * group; if so, adjust count for p's process group.
441 */
442 sx_slock(&proctree_lock);
443 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
444 hispgrp->pg_session == mysession) {
445 if (entering)
446 pgrp->pg_jobc++;
447 else if (--pgrp->pg_jobc == 0)
448 orphanpg(pgrp);
449 }
450
451 /*
452 * Check this process' children to see whether they qualify
453 * their process groups; if so, adjust counts for children's
454 * process groups.
455 */
456 LIST_FOREACH(p, &p->p_children, p_sibling)
457 if ((hispgrp = p->p_pgrp) != pgrp &&
458 hispgrp->pg_session == mysession &&
459 p->p_stat != SZOMB) {
460 if (entering)
461 hispgrp->pg_jobc++;
462 else if (--hispgrp->pg_jobc == 0)
463 orphanpg(hispgrp);
464 }
465 sx_sunlock(&proctree_lock);
466}
467
468/*
469 * A process group has become orphaned;
470 * if there are any stopped processes in the group,
471 * hang-up all process in that group.
472 */
473static void
474orphanpg(pg)
475 struct pgrp *pg;
476{
477 register struct proc *p;
478
479 mtx_lock_spin(&sched_lock);
480 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
481 if (p->p_stat == SSTOP) {
482 mtx_unlock_spin(&sched_lock);
483 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
484 PROC_LOCK(p);
485 psignal(p, SIGHUP);
486 psignal(p, SIGCONT);

--- 127 unchanged lines hidden (view full) ---

614 kp->ki_oncpu = p->p_kse.ke_oncpu;
615 kp->ki_lastcpu = td->td_lastcpu;
616 kp->ki_tdflags = td->td_flags;
617 kp->ki_pcb = td->td_pcb;
618 kp->ki_kstack = (void *)td->td_kstack;
619 /* ^^^ XXXKSE */
620 mtx_unlock_spin(&sched_lock);
621 sp = NULL;
622 if (p->p_pgrp) {
623 kp->ki_pgid = p->p_pgrp->pg_id;
624 kp->ki_jobc = p->p_pgrp->pg_jobc;
625 sp = p->p_pgrp->pg_session;
626
627 if (sp != NULL) {
628 kp->ki_sid = sp->s_sid;
629 strncpy(kp->ki_login, sp->s_login,
630 sizeof(kp->ki_login) - 1);
631 if (sp->s_ttyvp)
632 kp->ki_kiflag |= KI_CTTY;
633 if (SESS_LEADER(p))
634 kp->ki_kiflag |= KI_SLEADER;
635 }
636 }
637 if ((p->p_flag & P_CONTROLT) && sp && ((tp = sp->s_ttyp) != NULL)) {
638 kp->ki_tdev = dev2udev(tp->t_dev);
639 kp->ki_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
640 if (tp->t_session)
641 kp->ki_tsid = tp->t_session->s_sid;
642 } else
643 kp->ki_tdev = NOUDEV;
644 if (p->p_comm[0] != '\0') {
645 strncpy(kp->ki_comm, p->p_comm, sizeof(kp->ki_comm) - 1);

--- 117 unchanged lines hidden (view full) ---

763 /*
764 * TODO - make more efficient (see notes below).
765 * do by session.
766 */
767 switch (oidp->oid_number) {
768
769 case KERN_PROC_PGRP:
770 /* could do this by traversing pgrp */
771 if (p->p_pgrp == NULL ||
772 p->p_pgrp->pg_id != (pid_t)name[0])
773 continue;
774 break;
775
776 case KERN_PROC_TTY:
777 if ((p->p_flag & P_CONTROLT) == 0 ||
778 p->p_session == NULL ||
779 p->p_session->s_ttyp == NULL ||
780 dev2udev(p->p_session->s_ttyp->t_dev) !=
781 (udev_t)name[0])
782 continue;
783 break;
784
785 case KERN_PROC_UID:
786 if (p->p_ucred == NULL ||
787 p->p_ucred->cr_uid != (uid_t)name[0])
788 continue;
789 break;
790

--- 103 unchanged lines hidden ---