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 91140 2002-02-23 11:12:57Z tanimura $
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
58MALLOC_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 struct proc *dopfind __P((register pid_t));
64
65static void doenterpgrp __P((struct proc *, struct pgrp *));
66
67static void pgdelete __P((struct pgrp *));
68
69static void orphanpg __P((struct pgrp *pg));
70
71/*
72 * Other process lists
73 */
74struct pidhashhead *pidhashtbl;
75u_long pidhash;
76struct pgrphashhead *pgrphashtbl;
77u_long pgrphash;
78struct proclist allproc;
79struct proclist zombproc;
80struct sx allproc_lock;
81struct sx proctree_lock;
82struct sx pgrpsess_lock;
83vm_zone_t proc_zone;
84vm_zone_t ithread_zone;
85
86/*
87 * Initialize global process hashing structures.
88 */
89void
90procinit()
91{
92 int i, j;
93
94 sx_init(&allproc_lock, "allproc");
95 sx_init(&proctree_lock, "proctree");
96 sx_init(&pgrpsess_lock, "pgrpsess");
97 LIST_INIT(&allproc);
98 LIST_INIT(&zombproc);
99 pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
100 pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
101 proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5);
102 uihashinit();
103 /*
104 * This should really be a compile time warning, but I do
--- 161 unchanged lines hidden (view full) ---
266 */
267struct proc *
268pfind(pid)
269 register pid_t pid;
270{
271 register struct proc *p;
272
273 sx_slock(&allproc_lock);
274 p = dopfind(pid);
275 sx_sunlock(&allproc_lock);
276 return (p);
277}
278
279static struct proc *
280dopfind(pid)
281 register pid_t pid;
282{
283 register struct proc *p;
284
285 sx_assert(&allproc_lock, SX_LOCKED);
286
287 LIST_FOREACH(p, PIDHASH(pid), p_hash)
288 if (p->p_pid == pid) {
289 PROC_LOCK(p);
290 break;
291 }
292 return (p);
293}
294
295/*
296 * Locate a process group by number.
297 * The caller must hold pgrpsess_lock.
298 */
299struct pgrp *
300pgfind(pgid)
301 register pid_t pgid;
302{
303 register struct pgrp *pgrp;
304
305 PGRPSESS_LOCK_ASSERT(SX_LOCKED);
306
307 LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash) {
308 if (pgrp->pg_id == pgid) {
309 PGRP_LOCK(pgrp);
310 return (pgrp);
311 }
312 }
313 return (NULL);
314}
315
316/*
317 * Create a new process group.
318 * pgid must be equal to the pid of p.
319 * Begin a new session if required.
320 */
321int
322enterpgrp(p, pgid, pgrp, sess)
323 register struct proc *p;
324 pid_t pgid;
325 struct pgrp *pgrp;
326 struct session *sess;
327{
328 struct pgrp *pgrp2;
329
330 PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
331
332 KASSERT(pgrp != NULL, ("enterpgrp: pgrp == NULL"));
333 KASSERT(p->p_pid == pgid,
334 ("enterpgrp: new pgrp and pid != pgid"));
335
336 pgrp2 = pgfind(pgid);
337
338 KASSERT(pgrp2 == NULL,
339 ("enterpgrp: pgrp with pgid exists"));
340 KASSERT(!SESS_LEADER(p),
341 ("enterpgrp: session leader attempted setpgrp"));
342
343 mtx_init(&pgrp->pg_mtx, "process group", MTX_DEF);
344
345 if (sess != NULL) {
346 /*
347 * new session
348 */
349 mtx_init(&sess->s_mtx, "session", MTX_DEF);
350 PROC_LOCK(p);
351 p->p_flag &= ~P_CONTROLT;
352 PROC_UNLOCK(p);
353 PGRP_LOCK(pgrp);
354 sess->s_leader = p;
355 sess->s_sid = p->p_pid;
356 sess->s_count = 1;
357 sess->s_ttyvp = NULL;
358 sess->s_ttyp = NULL;
359 bcopy(p->p_session->s_login, sess->s_login,
360 sizeof(sess->s_login));
361 pgrp->pg_session = sess;
362 KASSERT(p == curproc,
363 ("enterpgrp: mksession and p != curproc"));
364 } else {
365 pgrp->pg_session = p->p_session;
366 SESS_LOCK(pgrp->pg_session);
367 pgrp->pg_session->s_count++;
368 SESS_UNLOCK(pgrp->pg_session);
369 PGRP_LOCK(pgrp);
370 }
371 pgrp->pg_id = pgid;
372 LIST_INIT(&pgrp->pg_members);
373
374 /*
375 * As we have an exclusive lock of pgrpsess_lock,
376 * this should not deadlock.
377 */
378 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
379 pgrp->pg_jobc = 0;
380 SLIST_INIT(&pgrp->pg_sigiolst);
381 PGRP_UNLOCK(pgrp);
382
383 doenterpgrp(p, pgrp);
384
385 return (0);
386}
387
388/*
389 * Move p to an existing process group
390 */
391int
392enterthispgrp(p, pgrp)
393 register struct proc *p;
394 struct pgrp *pgrp;
395{
396 PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
397 PROC_LOCK_ASSERT(p, MA_NOTOWNED);
398 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
399 PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED);
400 SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED);
401 KASSERT(pgrp->pg_session == p->p_session,
402 ("%s: pgrp's session %p, p->p_session %p.\n",
403 __func__,
404 pgrp->pg_session,
405 p->p_session));
406 KASSERT(pgrp != p->p_pgrp,
407 ("%s: p belongs to pgrp.", __func__));
408
409 doenterpgrp(p, pgrp);
410
411 return (0);
412}
413
414/*
415 * Move p to a process group
416 */
417static void
418doenterpgrp(p, pgrp)
419 struct proc *p;
420 struct pgrp *pgrp;
421{
422 struct pgrp *savepgrp;
423
424 PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
425 PROC_LOCK_ASSERT(p, MA_NOTOWNED);
426 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
427 PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED);
428 SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED);
429
430 savepgrp = p->p_pgrp;
431
432 /*
433 * Adjust eligibility of affected pgrps to participate in job control.
434 * Increment eligibility counts before decrementing, otherwise we
435 * could reach 0 spuriously during the first call.
436 */
437 fixjobc(p, pgrp, 1);
438 fixjobc(p, p->p_pgrp, 0);
439
440 PGRP_LOCK(pgrp);
441 PGRP_LOCK(savepgrp);
442 PROC_LOCK(p);
443 LIST_REMOVE(p, p_pglist);
444 p->p_pgrp = pgrp;
445 PROC_UNLOCK(p);
446 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
447 PGRP_UNLOCK(savepgrp);
448 PGRP_UNLOCK(pgrp);
449 if (LIST_EMPTY(&savepgrp->pg_members))
450 pgdelete(savepgrp);
451}
452
453/*
454 * remove process from process group
455 */
456int
457leavepgrp(p)
458 register struct proc *p;
459{
460 struct pgrp *savepgrp;
461
462 PGRPSESS_XLOCK();
463 savepgrp = p->p_pgrp;
464 PGRP_LOCK(savepgrp);
465 PROC_LOCK(p);
466 LIST_REMOVE(p, p_pglist);
467 p->p_pgrp = NULL;
468 PROC_UNLOCK(p);
469 PGRP_UNLOCK(savepgrp);
470 if (LIST_EMPTY(&savepgrp->pg_members))
471 pgdelete(savepgrp);
472 PGRPSESS_XUNLOCK();
473 return (0);
474}
475
476/*
477 * delete a process group
478 */
479static void
480pgdelete(pgrp)
481 register struct pgrp *pgrp;
482{
483 struct session *savesess;
484
485 PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
486 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
487 SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED);
488
489 PGRP_LOCK(pgrp);
490
491 /*
492 * Reset any sigio structures pointing to us as a result of
493 * F_SETOWN with our pgid.
494 */
495 funsetownlst(&pgrp->pg_sigiolst);
496
497 if (pgrp->pg_session->s_ttyp != NULL &&
498 pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
499 pgrp->pg_session->s_ttyp->t_pgrp = NULL;
500 LIST_REMOVE(pgrp, pg_hash);
501 savesess = pgrp->pg_session;
502 SESS_LOCK(savesess);
503 savesess->s_count--;
504 SESS_UNLOCK(savesess);
505 PGRP_UNLOCK(pgrp);
506 if (savesess->s_count == 0) {
507 mtx_destroy(&savesess->s_mtx);
508 FREE(pgrp->pg_session, M_SESSION);
509 }
510 mtx_destroy(&pgrp->pg_mtx);
511 FREE(pgrp, M_PGRP);
512}
513
514/*
515 * Adjust pgrp jobc counters when specified process changes process group.
516 * We count the number of processes in each process group that "qualify"
517 * the group for terminal job control (those with a parent in a different
518 * process group of the same session). If that count reaches zero, the
--- 4 unchanged lines hidden (view full) ---
523 */
524void
525fixjobc(p, pgrp, entering)
526 register struct proc *p;
527 register struct pgrp *pgrp;
528 int entering;
529{
530 register struct pgrp *hispgrp;
531 register struct session *mysession;
532
533 PGRPSESS_LOCK_ASSERT(SX_LOCKED);
534 PROC_LOCK_ASSERT(p, MA_NOTOWNED);
535 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
536 SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED);
537
538 /*
539 * Check p's parent to see whether p qualifies its own process
540 * group; if so, adjust count for p's process group.
541 */
542 mysession = pgrp->pg_session;
543 sx_slock(&proctree_lock);
544 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
545 hispgrp->pg_session == mysession) {
546 PGRP_LOCK(pgrp);
547 if (entering)
548 pgrp->pg_jobc++;
549 else {
550 --pgrp->pg_jobc;
551 if (pgrp->pg_jobc == 0)
552 orphanpg(pgrp);
553 }
554 PGRP_UNLOCK(pgrp);
555 }
556
557 /*
558 * Check this process' children to see whether they qualify
559 * their process groups; if so, adjust counts for children's
560 * process groups.
561 */
562 LIST_FOREACH(p, &p->p_children, p_sibling) {
563 if ((hispgrp = p->p_pgrp) != pgrp &&
564 hispgrp->pg_session == mysession &&
565 p->p_stat != SZOMB) {
566 PGRP_LOCK(hispgrp);
567 if (entering)
568 hispgrp->pg_jobc++;
569 else {
570 --hispgrp->pg_jobc;
571 if (hispgrp->pg_jobc == 0)
572 orphanpg(hispgrp);
573 }
574 PGRP_UNLOCK(hispgrp);
575 }
576 }
577 sx_sunlock(&proctree_lock);
578}
579
580/*
581 * A process group has become orphaned;
582 * if there are any stopped processes in the group,
583 * hang-up all process in that group.
584 */
585static void
586orphanpg(pg)
587 struct pgrp *pg;
588{
589 register struct proc *p;
590
591 PGRP_LOCK_ASSERT(pg, MA_OWNED);
592
593 mtx_lock_spin(&sched_lock);
594 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
595 if (p->p_stat == SSTOP) {
596 mtx_unlock_spin(&sched_lock);
597 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
598 PROC_LOCK(p);
599 psignal(p, SIGHUP);
600 psignal(p, SIGCONT);
--- 127 unchanged lines hidden (view full) ---
728 kp->ki_oncpu = p->p_kse.ke_oncpu;
729 kp->ki_lastcpu = td->td_lastcpu;
730 kp->ki_tdflags = td->td_flags;
731 kp->ki_pcb = td->td_pcb;
732 kp->ki_kstack = (void *)td->td_kstack;
733 /* ^^^ XXXKSE */
734 mtx_unlock_spin(&sched_lock);
735 sp = NULL;
736 tp = NULL;
737 if (p->p_pgrp) {
738 kp->ki_pgid = p->p_pgrp->pg_id;
739 kp->ki_jobc = p->p_pgrp->pg_jobc;
740 sp = p->p_pgrp->pg_session;
741
742 if (sp != NULL) {
743 kp->ki_sid = sp->s_sid;
744 SESS_LOCK(sp);
745 strncpy(kp->ki_login, sp->s_login,
746 sizeof(kp->ki_login) - 1);
747 if (sp->s_ttyvp)
748 kp->ki_kiflag |= KI_CTTY;
749 if (SESS_LEADER(p))
750 kp->ki_kiflag |= KI_SLEADER;
751 tp = sp->s_ttyp;
752 SESS_UNLOCK(sp);
753 }
754 }
755 if ((p->p_flag & P_CONTROLT) && tp != NULL) {
756 kp->ki_tdev = dev2udev(tp->t_dev);
757 kp->ki_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
758 if (tp->t_session)
759 kp->ki_tsid = tp->t_session->s_sid;
760 } else
761 kp->ki_tdev = NOUDEV;
762 if (p->p_comm[0] != '\0') {
763 strncpy(kp->ki_comm, p->p_comm, sizeof(kp->ki_comm) - 1);
--- 117 unchanged lines hidden (view full) ---
881 /*
882 * TODO - make more efficient (see notes below).
883 * do by session.
884 */
885 switch (oidp->oid_number) {
886
887 case KERN_PROC_PGRP:
888 /* could do this by traversing pgrp */
889 PROC_LOCK(p);
890 if (p->p_pgrp == NULL ||
891 p->p_pgrp->pg_id != (pid_t)name[0]) {
892 PROC_UNLOCK(p);
893 continue;
894 }
895 PROC_UNLOCK(p);
896 break;
897
898 case KERN_PROC_TTY:
899 PROC_LOCK(p);
900 if ((p->p_flag & P_CONTROLT) == 0 ||
901 p->p_session == NULL) {
902 PROC_UNLOCK(p);
903 continue;
904 }
905 SESS_LOCK(p->p_session);
906 if (p->p_session->s_ttyp == NULL ||
907 dev2udev(p->p_session->s_ttyp->t_dev) !=
908 (udev_t)name[0]) {
909 SESS_UNLOCK(p->p_session);
910 PROC_UNLOCK(p);
911 continue;
912 }
913 SESS_UNLOCK(p->p_session);
914 PROC_UNLOCK(p);
915 break;
916
917 case KERN_PROC_UID:
918 if (p->p_ucred == NULL ||
919 p->p_ucred->cr_uid != (uid_t)name[0])
920 continue;
921 break;
922
--- 103 unchanged lines hidden ---
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 91140 2002-02-23 11:12:57Z tanimura $
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
58MALLOC_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 struct proc *dopfind __P((register pid_t));
64
65static void doenterpgrp __P((struct proc *, struct pgrp *));
66
67static void pgdelete __P((struct pgrp *));
68
69static void orphanpg __P((struct pgrp *pg));
70
71/*
72 * Other process lists
73 */
74struct pidhashhead *pidhashtbl;
75u_long pidhash;
76struct pgrphashhead *pgrphashtbl;
77u_long pgrphash;
78struct proclist allproc;
79struct proclist zombproc;
80struct sx allproc_lock;
81struct sx proctree_lock;
82struct sx pgrpsess_lock;
83vm_zone_t proc_zone;
84vm_zone_t ithread_zone;
85
86/*
87 * Initialize global process hashing structures.
88 */
89void
90procinit()
91{
92 int i, j;
93
94 sx_init(&allproc_lock, "allproc");
95 sx_init(&proctree_lock, "proctree");
96 sx_init(&pgrpsess_lock, "pgrpsess");
97 LIST_INIT(&allproc);
98 LIST_INIT(&zombproc);
99 pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
100 pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
101 proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5);
102 uihashinit();
103 /*
104 * This should really be a compile time warning, but I do
--- 161 unchanged lines hidden (view full) ---
266 */
267struct proc *
268pfind(pid)
269 register pid_t pid;
270{
271 register struct proc *p;
272
273 sx_slock(&allproc_lock);
274 p = dopfind(pid);
275 sx_sunlock(&allproc_lock);
276 return (p);
277}
278
279static struct proc *
280dopfind(pid)
281 register pid_t pid;
282{
283 register struct proc *p;
284
285 sx_assert(&allproc_lock, SX_LOCKED);
286
287 LIST_FOREACH(p, PIDHASH(pid), p_hash)
288 if (p->p_pid == pid) {
289 PROC_LOCK(p);
290 break;
291 }
292 return (p);
293}
294
295/*
296 * Locate a process group by number.
297 * The caller must hold pgrpsess_lock.
298 */
299struct pgrp *
300pgfind(pgid)
301 register pid_t pgid;
302{
303 register struct pgrp *pgrp;
304
305 PGRPSESS_LOCK_ASSERT(SX_LOCKED);
306
307 LIST_FOREACH(pgrp, PGRPHASH(pgid), pg_hash) {
308 if (pgrp->pg_id == pgid) {
309 PGRP_LOCK(pgrp);
310 return (pgrp);
311 }
312 }
313 return (NULL);
314}
315
316/*
317 * Create a new process group.
318 * pgid must be equal to the pid of p.
319 * Begin a new session if required.
320 */
321int
322enterpgrp(p, pgid, pgrp, sess)
323 register struct proc *p;
324 pid_t pgid;
325 struct pgrp *pgrp;
326 struct session *sess;
327{
328 struct pgrp *pgrp2;
329
330 PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
331
332 KASSERT(pgrp != NULL, ("enterpgrp: pgrp == NULL"));
333 KASSERT(p->p_pid == pgid,
334 ("enterpgrp: new pgrp and pid != pgid"));
335
336 pgrp2 = pgfind(pgid);
337
338 KASSERT(pgrp2 == NULL,
339 ("enterpgrp: pgrp with pgid exists"));
340 KASSERT(!SESS_LEADER(p),
341 ("enterpgrp: session leader attempted setpgrp"));
342
343 mtx_init(&pgrp->pg_mtx, "process group", MTX_DEF);
344
345 if (sess != NULL) {
346 /*
347 * new session
348 */
349 mtx_init(&sess->s_mtx, "session", MTX_DEF);
350 PROC_LOCK(p);
351 p->p_flag &= ~P_CONTROLT;
352 PROC_UNLOCK(p);
353 PGRP_LOCK(pgrp);
354 sess->s_leader = p;
355 sess->s_sid = p->p_pid;
356 sess->s_count = 1;
357 sess->s_ttyvp = NULL;
358 sess->s_ttyp = NULL;
359 bcopy(p->p_session->s_login, sess->s_login,
360 sizeof(sess->s_login));
361 pgrp->pg_session = sess;
362 KASSERT(p == curproc,
363 ("enterpgrp: mksession and p != curproc"));
364 } else {
365 pgrp->pg_session = p->p_session;
366 SESS_LOCK(pgrp->pg_session);
367 pgrp->pg_session->s_count++;
368 SESS_UNLOCK(pgrp->pg_session);
369 PGRP_LOCK(pgrp);
370 }
371 pgrp->pg_id = pgid;
372 LIST_INIT(&pgrp->pg_members);
373
374 /*
375 * As we have an exclusive lock of pgrpsess_lock,
376 * this should not deadlock.
377 */
378 LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
379 pgrp->pg_jobc = 0;
380 SLIST_INIT(&pgrp->pg_sigiolst);
381 PGRP_UNLOCK(pgrp);
382
383 doenterpgrp(p, pgrp);
384
385 return (0);
386}
387
388/*
389 * Move p to an existing process group
390 */
391int
392enterthispgrp(p, pgrp)
393 register struct proc *p;
394 struct pgrp *pgrp;
395{
396 PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
397 PROC_LOCK_ASSERT(p, MA_NOTOWNED);
398 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
399 PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED);
400 SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED);
401 KASSERT(pgrp->pg_session == p->p_session,
402 ("%s: pgrp's session %p, p->p_session %p.\n",
403 __func__,
404 pgrp->pg_session,
405 p->p_session));
406 KASSERT(pgrp != p->p_pgrp,
407 ("%s: p belongs to pgrp.", __func__));
408
409 doenterpgrp(p, pgrp);
410
411 return (0);
412}
413
414/*
415 * Move p to a process group
416 */
417static void
418doenterpgrp(p, pgrp)
419 struct proc *p;
420 struct pgrp *pgrp;
421{
422 struct pgrp *savepgrp;
423
424 PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
425 PROC_LOCK_ASSERT(p, MA_NOTOWNED);
426 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
427 PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED);
428 SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED);
429
430 savepgrp = p->p_pgrp;
431
432 /*
433 * Adjust eligibility of affected pgrps to participate in job control.
434 * Increment eligibility counts before decrementing, otherwise we
435 * could reach 0 spuriously during the first call.
436 */
437 fixjobc(p, pgrp, 1);
438 fixjobc(p, p->p_pgrp, 0);
439
440 PGRP_LOCK(pgrp);
441 PGRP_LOCK(savepgrp);
442 PROC_LOCK(p);
443 LIST_REMOVE(p, p_pglist);
444 p->p_pgrp = pgrp;
445 PROC_UNLOCK(p);
446 LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist);
447 PGRP_UNLOCK(savepgrp);
448 PGRP_UNLOCK(pgrp);
449 if (LIST_EMPTY(&savepgrp->pg_members))
450 pgdelete(savepgrp);
451}
452
453/*
454 * remove process from process group
455 */
456int
457leavepgrp(p)
458 register struct proc *p;
459{
460 struct pgrp *savepgrp;
461
462 PGRPSESS_XLOCK();
463 savepgrp = p->p_pgrp;
464 PGRP_LOCK(savepgrp);
465 PROC_LOCK(p);
466 LIST_REMOVE(p, p_pglist);
467 p->p_pgrp = NULL;
468 PROC_UNLOCK(p);
469 PGRP_UNLOCK(savepgrp);
470 if (LIST_EMPTY(&savepgrp->pg_members))
471 pgdelete(savepgrp);
472 PGRPSESS_XUNLOCK();
473 return (0);
474}
475
476/*
477 * delete a process group
478 */
479static void
480pgdelete(pgrp)
481 register struct pgrp *pgrp;
482{
483 struct session *savesess;
484
485 PGRPSESS_LOCK_ASSERT(SX_XLOCKED);
486 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
487 SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED);
488
489 PGRP_LOCK(pgrp);
490
491 /*
492 * Reset any sigio structures pointing to us as a result of
493 * F_SETOWN with our pgid.
494 */
495 funsetownlst(&pgrp->pg_sigiolst);
496
497 if (pgrp->pg_session->s_ttyp != NULL &&
498 pgrp->pg_session->s_ttyp->t_pgrp == pgrp)
499 pgrp->pg_session->s_ttyp->t_pgrp = NULL;
500 LIST_REMOVE(pgrp, pg_hash);
501 savesess = pgrp->pg_session;
502 SESS_LOCK(savesess);
503 savesess->s_count--;
504 SESS_UNLOCK(savesess);
505 PGRP_UNLOCK(pgrp);
506 if (savesess->s_count == 0) {
507 mtx_destroy(&savesess->s_mtx);
508 FREE(pgrp->pg_session, M_SESSION);
509 }
510 mtx_destroy(&pgrp->pg_mtx);
511 FREE(pgrp, M_PGRP);
512}
513
514/*
515 * Adjust pgrp jobc counters when specified process changes process group.
516 * We count the number of processes in each process group that "qualify"
517 * the group for terminal job control (those with a parent in a different
518 * process group of the same session). If that count reaches zero, the
--- 4 unchanged lines hidden (view full) ---
523 */
524void
525fixjobc(p, pgrp, entering)
526 register struct proc *p;
527 register struct pgrp *pgrp;
528 int entering;
529{
530 register struct pgrp *hispgrp;
531 register struct session *mysession;
532
533 PGRPSESS_LOCK_ASSERT(SX_LOCKED);
534 PROC_LOCK_ASSERT(p, MA_NOTOWNED);
535 PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED);
536 SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED);
537
538 /*
539 * Check p's parent to see whether p qualifies its own process
540 * group; if so, adjust count for p's process group.
541 */
542 mysession = pgrp->pg_session;
543 sx_slock(&proctree_lock);
544 if ((hispgrp = p->p_pptr->p_pgrp) != pgrp &&
545 hispgrp->pg_session == mysession) {
546 PGRP_LOCK(pgrp);
547 if (entering)
548 pgrp->pg_jobc++;
549 else {
550 --pgrp->pg_jobc;
551 if (pgrp->pg_jobc == 0)
552 orphanpg(pgrp);
553 }
554 PGRP_UNLOCK(pgrp);
555 }
556
557 /*
558 * Check this process' children to see whether they qualify
559 * their process groups; if so, adjust counts for children's
560 * process groups.
561 */
562 LIST_FOREACH(p, &p->p_children, p_sibling) {
563 if ((hispgrp = p->p_pgrp) != pgrp &&
564 hispgrp->pg_session == mysession &&
565 p->p_stat != SZOMB) {
566 PGRP_LOCK(hispgrp);
567 if (entering)
568 hispgrp->pg_jobc++;
569 else {
570 --hispgrp->pg_jobc;
571 if (hispgrp->pg_jobc == 0)
572 orphanpg(hispgrp);
573 }
574 PGRP_UNLOCK(hispgrp);
575 }
576 }
577 sx_sunlock(&proctree_lock);
578}
579
580/*
581 * A process group has become orphaned;
582 * if there are any stopped processes in the group,
583 * hang-up all process in that group.
584 */
585static void
586orphanpg(pg)
587 struct pgrp *pg;
588{
589 register struct proc *p;
590
591 PGRP_LOCK_ASSERT(pg, MA_OWNED);
592
593 mtx_lock_spin(&sched_lock);
594 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
595 if (p->p_stat == SSTOP) {
596 mtx_unlock_spin(&sched_lock);
597 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
598 PROC_LOCK(p);
599 psignal(p, SIGHUP);
600 psignal(p, SIGCONT);
--- 127 unchanged lines hidden (view full) ---
728 kp->ki_oncpu = p->p_kse.ke_oncpu;
729 kp->ki_lastcpu = td->td_lastcpu;
730 kp->ki_tdflags = td->td_flags;
731 kp->ki_pcb = td->td_pcb;
732 kp->ki_kstack = (void *)td->td_kstack;
733 /* ^^^ XXXKSE */
734 mtx_unlock_spin(&sched_lock);
735 sp = NULL;
736 tp = NULL;
737 if (p->p_pgrp) {
738 kp->ki_pgid = p->p_pgrp->pg_id;
739 kp->ki_jobc = p->p_pgrp->pg_jobc;
740 sp = p->p_pgrp->pg_session;
741
742 if (sp != NULL) {
743 kp->ki_sid = sp->s_sid;
744 SESS_LOCK(sp);
745 strncpy(kp->ki_login, sp->s_login,
746 sizeof(kp->ki_login) - 1);
747 if (sp->s_ttyvp)
748 kp->ki_kiflag |= KI_CTTY;
749 if (SESS_LEADER(p))
750 kp->ki_kiflag |= KI_SLEADER;
751 tp = sp->s_ttyp;
752 SESS_UNLOCK(sp);
753 }
754 }
755 if ((p->p_flag & P_CONTROLT) && tp != NULL) {
756 kp->ki_tdev = dev2udev(tp->t_dev);
757 kp->ki_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
758 if (tp->t_session)
759 kp->ki_tsid = tp->t_session->s_sid;
760 } else
761 kp->ki_tdev = NOUDEV;
762 if (p->p_comm[0] != '\0') {
763 strncpy(kp->ki_comm, p->p_comm, sizeof(kp->ki_comm) - 1);
--- 117 unchanged lines hidden (view full) ---
881 /*
882 * TODO - make more efficient (see notes below).
883 * do by session.
884 */
885 switch (oidp->oid_number) {
886
887 case KERN_PROC_PGRP:
888 /* could do this by traversing pgrp */
889 PROC_LOCK(p);
890 if (p->p_pgrp == NULL ||
891 p->p_pgrp->pg_id != (pid_t)name[0]) {
892 PROC_UNLOCK(p);
893 continue;
894 }
895 PROC_UNLOCK(p);
896 break;
897
898 case KERN_PROC_TTY:
899 PROC_LOCK(p);
900 if ((p->p_flag & P_CONTROLT) == 0 ||
901 p->p_session == NULL) {
902 PROC_UNLOCK(p);
903 continue;
904 }
905 SESS_LOCK(p->p_session);
906 if (p->p_session->s_ttyp == NULL ||
907 dev2udev(p->p_session->s_ttyp->t_dev) !=
908 (udev_t)name[0]) {
909 SESS_UNLOCK(p->p_session);
910 PROC_UNLOCK(p);
911 continue;
912 }
913 SESS_UNLOCK(p->p_session);
914 PROC_UNLOCK(p);
915 break;
916
917 case KERN_PROC_UID:
918 if (p->p_ucred == NULL ||
919 p->p_ucred->cr_uid != (uid_t)name[0])
920 continue;
921 break;
922
--- 103 unchanged lines hidden ---