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 --- |