00001
00012 #include "sigsafe_internal.h"
00013 #include <mach/mach.h>
00014 #include <mach/clock.h>
00015 #include <sys/types.h>
00016 #include <sys/wait.h>
00017 #include <sys/resource.h>
00018 #include <errno.h>
00019 #include <assert.h>
00020
00021 extern mach_port_t clock_port;
00022
00023 PRIVATE_DEF(kern_return_t sigsafe_clock_sleep_trap(
00024 mach_port_name_t clock_name,
00025 sleep_type_t sleep_type,
00026 int sleep_sec,
00027 int sleep_nsec,
00028 mach_timespec_t *abs_time_after));
00029
00030
00031 int sigsafe_nanosleep(const struct timespec *req, struct timespec *rem) {
00032 kern_return_t ret;
00033 mach_timespec_t abs_time_after;
00034 mach_timespec_t abs_time_before;
00035
00036
00037 if ((req == NULL) || (req->tv_sec < 0) || (req->tv_nsec > NSEC_PER_SEC)) {
00038 return -EINVAL;
00039 }
00040
00041 if (rem != NULL) {
00042 ret = clock_get_time(clock_port, &abs_time_before);
00043 assert(ret == KERN_SUCCESS);
00044 }
00045
00046 ret = sigsafe_clock_sleep_trap(clock_port, TIME_RELATIVE,
00047 req->tv_sec, req->tv_nsec, NULL);
00048
00049 if (ret == KERN_ABORTED) {
00050 if (rem != NULL) {
00051 ret = clock_get_time(clock_port, &abs_time_after);
00052 assert(ret == KERN_SUCCESS);
00053
00054
00055 ADD_MACH_TIMESPEC(&abs_time_before, req);
00056 SUB_MACH_TIMESPEC(&abs_time_before, &abs_time_after);
00057 rem->tv_sec = abs_time_before.tv_sec;
00058 rem->tv_nsec = abs_time_before.tv_nsec;
00059 }
00060 return -EINTR;
00061 }
00062
00063 return (ret == KERN_SUCCESS) ? 0 : -EINVAL;
00064 }
00065
00066 PRIVATE_DEF(int sigsafe_sigsuspend_(const sigset_t mask));
00067
00068 int sigsafe_sigsuspend(const sigset_t *mask_p) {
00069 sigset_t mask;
00070
00071 if (mask_p)
00072 mask = *mask_p;
00073 else
00074 sigemptyset(&mask);
00075
00076 return sigsafe_sigsuspend_(mask);
00077 }
00078
00079 int sigsafe_pause(void) {
00080 sigset_t mask;
00081 sigemptyset(&mask);
00082 return sigsafe_sigsuspend_(mask);
00083 }
00084
00085 pid_t sigsafe_wait(int *status) {
00086 return sigsafe_wait4(WAIT_ANY, status, 0, NULL);
00087 }
00088
00089 pid_t sigsafe_wait3(int *status, int options, struct rusage *rusage) {
00090 return sigsafe_wait4(WAIT_ANY, status, options, rusage);
00091 }