| 805 | } |
| 806 | |
| 807 | static int |
| 808 | kern_sem_wait(struct thread *td, semid_t id, int tryflag, |
| 809 | struct timespec *abstime) |
| 810 | { |
| 811 | struct timespec ts1, ts2; |
| 812 | struct timeval tv; |
| 813 | cap_rights_t rights; |
| 814 | struct file *fp; |
| 815 | struct ksem *ks; |
| 816 | int error; |
| 817 | |
| 818 | DP((">>> kern_sem_wait entered! pid=%d\n", (int)td->td_proc->p_pid)); |
| 819 | AUDIT_ARG_FD(id); |
| 820 | error = ksem_get(td, id, cap_rights_init_one(&rights, CAP_SEM_WAIT), |
| 821 | &fp); |
| 822 | if (error) |
| 823 | return (error); |
| 824 | ks = fp->f_data; |
| 825 | mtx_lock(&sem_lock); |
| 826 | DP((">>> kern_sem_wait critical section entered! pid=%d\n", |
| 827 | (int)td->td_proc->p_pid)); |
| 828 | #ifdef MAC |
| 829 | error = mac_posixsem_check_wait(td->td_ucred, fp->f_cred, ks); |
| 830 | if (error) { |
| 831 | DP(("kern_sem_wait mac failed\n")); |
| 832 | goto err; |
| 833 | } |
| 834 | #endif |
| 835 | DP(("kern_sem_wait value = %d, tryflag %d\n", ks->ks_value, tryflag)); |
| 836 | vfs_timestamp(&ks->ks_atime); |
| 837 | while (ks->ks_value == 0) { |
| 838 | ks->ks_waiters++; |
| 839 | if (tryflag != 0) |
| 840 | error = EAGAIN; |
| 841 | else if (abstime == NULL) |
| 842 | error = cv_wait_sig(&ks->ks_cv, &sem_lock); |
| 843 | else { |
| 844 | for (;;) { |
| 845 | ts1 = *abstime; |
| 846 | getnanotime(&ts2); |
| 847 | timespecsub(&ts1, &ts2, &ts1); |
| 848 | TIMESPEC_TO_TIMEVAL(&tv, &ts1); |
| 849 | if (tv.tv_sec < 0) { |
| 850 | error = ETIMEDOUT; |
| 851 | break; |
| 852 | } |
| 853 | error = cv_timedwait_sig(&ks->ks_cv, |
| 854 | &sem_lock, tvtohz(&tv)); |
| 855 | if (error != EWOULDBLOCK) |
| 856 | break; |
| 857 | } |
| 858 | } |
| 859 | ks->ks_waiters--; |
| 860 | if (error) |
| 861 | goto err; |
| 862 | } |
| 863 | ks->ks_value--; |
| 864 | DP(("kern_sem_wait value post-decrement = %d\n", ks->ks_value)); |
no test coverage detected