+
+ uth = (struct uthread *)get_bsdthread_info(target_act);
+
+ /* if the thread is in vfork do not cancel */
+ if ((uth->uu_flag & (P_VFORK | UT_CANCEL | UT_CANCELED )) == 0) {
+ uth->uu_flag |= (UT_CANCEL | UT_NO_SIGMASK);
+ if (((uth->uu_flag & UT_NOTCANCELPT) == 0)
+ && ((uth->uu_flag & UT_CANCELDISABLE) == 0))
+ thread_abort_safely(target_act);
+ }
+
+ thread_deallocate(target_act);
+ return (error);
+}
+
+/* if action =0 ; return the cancellation state ,
+ * if marked for cancellation, make the thread canceled
+ * if action = 1 ; Enable the cancel handling
+ * if action = 2; Disable the cancel handling
+ */
+int
+__pthread_canceled(p, uap, retval)
+ struct proc *p;
+ register struct __pthread_canceled_args *uap;
+ register_t *retval;
+{
+ thread_act_t thr_act;
+ struct uthread *uth;
+ int action = uap->action;
+
+ thr_act = current_act();
+ uth = (struct uthread *)get_bsdthread_info(thr_act);
+
+ switch (action) {
+ case 1:
+ uth->uu_flag &= ~UT_CANCELDISABLE;
+ return(0);
+ case 2:
+ uth->uu_flag |= UT_CANCELDISABLE;
+ return(0);
+ case 0:
+ default:
+ /* if the thread is in vfork do not cancel */
+ if((uth->uu_flag & ( UT_CANCELDISABLE | UT_CANCEL | UT_CANCELED)) == UT_CANCEL) {
+ uth->uu_flag &= ~UT_CANCEL;
+ uth->uu_flag |= (UT_CANCELED | UT_NO_SIGMASK);
+ return(0);
+ }
+ return(EINVAL);
+ }
+ return(EINVAL);
+}
+
+void
+__posix_sem_syscall_return(kern_return_t kern_result)
+{
+ int error = 0;
+
+ if (kern_result == KERN_SUCCESS)
+ error = 0;
+ else if (kern_result == KERN_ABORTED)
+ error = EINTR;
+ else if (kern_result == KERN_OPERATION_TIMED_OUT)
+ error = ETIMEDOUT;
+ else
+ error = EINVAL;
+ unix_syscall_return(error);
+ /* does not return */
+}
+
+
+int
+__semwait_signal(p, uap, retval)
+ struct proc *p;
+ register struct __semwait_signal_args *uap;
+ register_t *retval;
+{
+
+ kern_return_t kern_result;
+ mach_timespec_t then;
+ struct timespec now;
+
+ if(uap->timeout) {
+
+ if (uap->relative) {
+ then.tv_sec = uap->tv_sec;
+ then.tv_nsec = uap->tv_nsec;
+ } else {
+ nanotime(&now);
+ then.tv_sec = uap->tv_sec - now.tv_sec;
+ then.tv_nsec = uap->tv_nsec - now.tv_nsec;
+ if (then.tv_nsec < 0) {
+ then.tv_nsec += NSEC_PER_SEC;
+ then.tv_sec--;
+ }
+ }
+
+ if (uap->mutex_sem == (void *)NULL)
+ kern_result = semaphore_timedwait_trap_internal(uap->cond_sem, then.tv_sec, then.tv_nsec, __posix_sem_syscall_return);
+ else
+ kern_result = semaphore_timedwait_signal_trap_internal(uap->cond_sem, uap->mutex_sem, then.tv_sec, then.tv_nsec, __posix_sem_syscall_return);
+
+ } else {
+
+ if (uap->mutex_sem == (void *)NULL)
+ kern_result = semaphore_wait_trap_internal(uap->cond_sem, __posix_sem_syscall_return);
+ else
+
+ kern_result = semaphore_wait_signal_trap_internal(uap->cond_sem, uap->mutex_sem, __posix_sem_syscall_return);
+ }
+
+out:
+ if (kern_result == KERN_SUCCESS)
+ return(0);
+ else if (kern_result == KERN_ABORTED)
+ return(EINTR);
+ else if (kern_result == KERN_OPERATION_TIMED_OUT)
+ return(ETIMEDOUT);
+ else
+ return(EINVAL);
+}
+
+
+int
+__pthread_kill(__unused struct proc *p,
+ register struct __pthread_kill_args *uap,
+ __unused register_t *retval)
+{
+ thread_t target_act;
+ int error = 0;
+ int signum = uap->sig;
+ struct uthread *uth;
+
+ target_act = (thread_t)port_name_to_thread(uap->thread_port);
+
+ if (target_act == THREAD_NULL)
+ return (ESRCH);