kern_exit.c (a5bdcb2a2fc53a8690da41f5b580422fdb880f27) kern_exit.c (b7e23e826c650173f9175c42f1b03cd80fdb0a93)
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

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

80#include <vm/vm_map.h>
81#include <vm/vm_page.h>
82#include <vm/uma.h>
83#include <sys/user.h>
84
85/* Required to be non-static for SysVR4 emulator */
86MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status");
87
1/*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

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

80#include <vm/vm_map.h>
81#include <vm/vm_page.h>
82#include <vm/uma.h>
83#include <sys/user.h>
84
85/* Required to be non-static for SysVR4 emulator */
86MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status");
87
88static int wait1(struct thread *, struct wait_args *, int);
89
90/*
91 * exit --
92 * Death of process.
93 *
94 * MPSAFE
95 */
96void
97sys_exit(struct thread *td, struct sys_exit_args *uap)

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

546 * This will also release this thread's reference to the ucred.
547 * Other thread parts to release include pcb bits and such.
548 */
549 thread_exit();
550}
551
552#ifdef COMPAT_43
553/*
88/*
89 * exit --
90 * Death of process.
91 *
92 * MPSAFE
93 */
94void
95sys_exit(struct thread *td, struct sys_exit_args *uap)

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

544 * This will also release this thread's reference to the ucred.
545 * Other thread parts to release include pcb bits and such.
546 */
547 thread_exit();
548}
549
550#ifdef COMPAT_43
551/*
554 * MPSAFE. The dirty work is handled by wait1().
552 * MPSAFE. The dirty work is handled by kern_wait().
555 */
556int
557owait(struct thread *td, struct owait_args *uap __unused)
558{
553 */
554int
555owait(struct thread *td, struct owait_args *uap __unused)
556{
559 struct wait_args w;
557 int error, status;
560
558
561 w.options = 0;
562 w.rusage = NULL;
563 w.pid = WAIT_ANY;
564 w.status = NULL;
565 return (wait1(td, &w, 1));
559 error = kern_wait(td, WAIT_ANY, &status, 0, NULL);
560 if (error == 0)
561 td->td_retval[1] = status;
562 return (error);
566}
567#endif /* COMPAT_43 */
568
569/*
563}
564#endif /* COMPAT_43 */
565
566/*
570 * MPSAFE. The dirty work is handled by wait1().
567 * MPSAFE. The dirty work is handled by kern_wait().
571 */
572int
573wait4(struct thread *td, struct wait_args *uap)
574{
568 */
569int
570wait4(struct thread *td, struct wait_args *uap)
571{
572 struct rusage ru;
573 int error, status;
575
574
576 return (wait1(td, uap, 0));
575 error = kern_wait(td, uap->pid, &status, uap->options, &ru);
576 if (uap->status != NULL && error == 0)
577 error = copyout(&status, uap->status, sizeof(status));
578 if (uap->rusage != NULL && error == 0)
579 error = copyout(&ru, uap->rusage, sizeof(struct rusage));
580 return (error);
577}
578
581}
582
579/*
580 * MPSAFE
581 */
582static int
583wait1(struct thread *td, struct wait_args *uap, int compat)
583int
584kern_wait(struct thread *td, pid_t pid, int *status, int options, struct rusage *rusage)
584{
585{
585 struct rusage ru;
586 int nfound;
587 struct proc *p, *q, *t;
586 int nfound;
587 struct proc *p, *q, *t;
588 int status, error;
588 int error;
589
590 q = td->td_proc;
589
590 q = td->td_proc;
591 if (uap->pid == 0) {
591 if (pid == 0) {
592 PROC_LOCK(q);
592 PROC_LOCK(q);
593 uap->pid = -q->p_pgid;
593 pid = -q->p_pgid;
594 PROC_UNLOCK(q);
595 }
594 PROC_UNLOCK(q);
595 }
596 if (uap->options &~ (WUNTRACED|WNOHANG|WCONTINUED|WLINUXCLONE))
596 if (options &~ (WUNTRACED|WNOHANG|WCONTINUED|WLINUXCLONE))
597 return (EINVAL);
598loop:
599 nfound = 0;
600 sx_xlock(&proctree_lock);
601 LIST_FOREACH(p, &q->p_children, p_sibling) {
602 PROC_LOCK(p);
597 return (EINVAL);
598loop:
599 nfound = 0;
600 sx_xlock(&proctree_lock);
601 LIST_FOREACH(p, &q->p_children, p_sibling) {
602 PROC_LOCK(p);
603 if (uap->pid != WAIT_ANY &&
604 p->p_pid != uap->pid && p->p_pgid != -uap->pid) {
603 if (pid != WAIT_ANY &&
604 p->p_pid != pid && p->p_pgid != -pid) {
605 PROC_UNLOCK(p);
606 continue;
607 }
608
609 /*
610 * This special case handles a kthread spawned by linux_clone
611 * (see linux_misc.c). The linux_wait4 and linux_waitpid
612 * functions need to be able to distinguish between waiting
613 * on a process and waiting on a thread. It is a thread if
614 * p_sigparent is not SIGCHLD, and the WLINUXCLONE option
615 * signifies we want to wait for threads and not processes.
616 */
617 if ((p->p_sigparent != SIGCHLD) ^
605 PROC_UNLOCK(p);
606 continue;
607 }
608
609 /*
610 * This special case handles a kthread spawned by linux_clone
611 * (see linux_misc.c). The linux_wait4 and linux_waitpid
612 * functions need to be able to distinguish between waiting
613 * on a process and waiting on a thread. It is a thread if
614 * p_sigparent is not SIGCHLD, and the WLINUXCLONE option
615 * signifies we want to wait for threads and not processes.
616 */
617 if ((p->p_sigparent != SIGCHLD) ^
618 ((uap->options & WLINUXCLONE) != 0)) {
618 ((options & WLINUXCLONE) != 0)) {
619 PROC_UNLOCK(p);
620 continue;
621 }
622
623 nfound++;
624 if (p->p_state == PRS_ZOMBIE) {
625 td->td_retval[0] = p->p_pid;
619 PROC_UNLOCK(p);
620 continue;
621 }
622
623 nfound++;
624 if (p->p_state == PRS_ZOMBIE) {
625 td->td_retval[0] = p->p_pid;
626#ifdef COMPAT_43
627 if (compat)
628 td->td_retval[1] = p->p_xstat;
629 else
630#endif
631 if (uap->status) {
632 status = p->p_xstat; /* convert to int */
633 PROC_UNLOCK(p);
634 if ((error = copyout(&status,
635 uap->status, sizeof(status)))) {
636 sx_xunlock(&proctree_lock);
637 mtx_unlock(&Giant);
638 return (error);
639 }
640 PROC_LOCK(p);
641 }
642 if (uap->rusage) {
643 bcopy(p->p_ru, &ru, sizeof(ru));
644 PROC_UNLOCK(p);
645 if ((error = copyout(&ru,
646 uap->rusage, sizeof (struct rusage)))) {
647 sx_xunlock(&proctree_lock);
648 mtx_unlock(&Giant);
649 return (error);
650 }
651 } else
652 PROC_UNLOCK(p);
626 if (status)
627 *status = p->p_xstat; /* convert to int */
628 if (rusage)
629 bcopy(p->p_ru, rusage, sizeof(struct rusage));
630
653 /*
654 * If we got the child via a ptrace 'attach',
655 * we need to give it back to the old parent.
656 */
631 /*
632 * If we got the child via a ptrace 'attach',
633 * we need to give it back to the old parent.
634 */
635 PROC_UNLOCK(p);
657 if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) {
658 PROC_LOCK(p);
659 p->p_oppid = 0;
660 proc_reparent(p, t);
661 PROC_UNLOCK(p);
662 psignal(t, SIGCHLD);
663 wakeup(t);
664 PROC_UNLOCK(t);

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

720 */
721 mtx_lock(&Giant);
722 vm_waitproc(p);
723 mtx_unlock(&Giant);
724#ifdef MAC
725 mac_destroy_proc(p);
726#endif
727 KASSERT(FIRST_THREAD_IN_PROC(p),
636 if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) {
637 PROC_LOCK(p);
638 p->p_oppid = 0;
639 proc_reparent(p, t);
640 PROC_UNLOCK(p);
641 psignal(t, SIGCHLD);
642 wakeup(t);
643 PROC_UNLOCK(t);

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

699 */
700 mtx_lock(&Giant);
701 vm_waitproc(p);
702 mtx_unlock(&Giant);
703#ifdef MAC
704 mac_destroy_proc(p);
705#endif
706 KASSERT(FIRST_THREAD_IN_PROC(p),
728 ("wait1: no residual thread!"));
707 ("kern_wait: no residual thread!"));
729 uma_zfree(proc_zone, p);
730 sx_xlock(&allproc_lock);
731 nprocs--;
732 sx_xunlock(&allproc_lock);
733 return (0);
734 }
735 mtx_lock_spin(&sched_lock);
736 if (P_SHOULDSTOP(p) && (p->p_suspcount == p->p_numthreads) &&
737 ((p->p_flag & P_WAITED) == 0) &&
708 uma_zfree(proc_zone, p);
709 sx_xlock(&allproc_lock);
710 nprocs--;
711 sx_xunlock(&allproc_lock);
712 return (0);
713 }
714 mtx_lock_spin(&sched_lock);
715 if (P_SHOULDSTOP(p) && (p->p_suspcount == p->p_numthreads) &&
716 ((p->p_flag & P_WAITED) == 0) &&
738 (p->p_flag & P_TRACED || uap->options & WUNTRACED)) {
717 (p->p_flag & P_TRACED || options & WUNTRACED)) {
739 mtx_unlock_spin(&sched_lock);
740 p->p_flag |= P_WAITED;
741 sx_xunlock(&proctree_lock);
742 td->td_retval[0] = p->p_pid;
718 mtx_unlock_spin(&sched_lock);
719 p->p_flag |= P_WAITED;
720 sx_xunlock(&proctree_lock);
721 td->td_retval[0] = p->p_pid;
743#ifdef COMPAT_43
744 if (compat) {
745 td->td_retval[1] = W_STOPCODE(p->p_xstat);
746 PROC_UNLOCK(p);
747 error = 0;
748 } else
749#endif
750 if (uap->status) {
751 status = W_STOPCODE(p->p_xstat);
752 PROC_UNLOCK(p);
753 error = copyout(&status,
754 uap->status, sizeof(status));
755 } else {
756 PROC_UNLOCK(p);
757 error = 0;
758 }
759 return (error);
722 if (status)
723 *status = W_STOPCODE(p->p_xstat);
724 PROC_UNLOCK(p);
725 return (0);
760 }
761 mtx_unlock_spin(&sched_lock);
726 }
727 mtx_unlock_spin(&sched_lock);
762 if (uap->options & WCONTINUED && (p->p_flag & P_CONTINUED)) {
728 if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) {
763 sx_xunlock(&proctree_lock);
764 td->td_retval[0] = p->p_pid;
765 p->p_flag &= ~P_CONTINUED;
766 PROC_UNLOCK(p);
767
729 sx_xunlock(&proctree_lock);
730 td->td_retval[0] = p->p_pid;
731 p->p_flag &= ~P_CONTINUED;
732 PROC_UNLOCK(p);
733
768 if (uap->status) {
769 status = SIGCONT;
770 error = copyout(&status,
771 uap->status, sizeof(status));
772 } else
773 error = 0;
774
775 return (error);
734 if (status)
735 *status = SIGCONT;
736 return (0);
776 }
777 PROC_UNLOCK(p);
778 }
779 if (nfound == 0) {
780 sx_xunlock(&proctree_lock);
781 return (ECHILD);
782 }
737 }
738 PROC_UNLOCK(p);
739 }
740 if (nfound == 0) {
741 sx_xunlock(&proctree_lock);
742 return (ECHILD);
743 }
783 if (uap->options & WNOHANG) {
744 if (options & WNOHANG) {
784 sx_xunlock(&proctree_lock);
785 td->td_retval[0] = 0;
786 return (0);
787 }
788 PROC_LOCK(q);
789 sx_xunlock(&proctree_lock);
790 error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "wait", 0);
791 PROC_UNLOCK(q);

--- 22 unchanged lines hidden ---
745 sx_xunlock(&proctree_lock);
746 td->td_retval[0] = 0;
747 return (0);
748 }
749 PROC_LOCK(q);
750 sx_xunlock(&proctree_lock);
751 error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "wait", 0);
752 PROC_UNLOCK(q);

--- 22 unchanged lines hidden ---