#include <errno.h>
#include <sys/time.h>
#include <mach/message.h>
#include <mach/mach_error.h>
#include <mach/mach_syscalls.h>
#include <mach/clock.h>
#include <mach/clock_types.h>
#include <stdio.h>
extern mach_port_t clock_port;
int
nanosleep(const struct timespec *requested_time, struct timespec *remaining_time) {
kern_return_t ret;
mach_timespec_t remain;
mach_timespec_t current;
if ((requested_time == NULL) || (requested_time->tv_sec < 0) || (requested_time->tv_nsec > NSEC_PER_SEC)) {
errno = EINVAL;
return -1;
}
ret = clock_get_time(clock_port, ¤t);
if (ret != KERN_SUCCESS) {
fprintf(stderr, "clock_get_time() failed: %s\n", mach_error_string(ret));
return -1;
}
ret = clock_sleep_trap(clock_port, TIME_RELATIVE, requested_time->tv_sec, requested_time->tv_nsec, &remain);
if (ret != KERN_SUCCESS) {
if (ret == KERN_ABORTED) {
errno = EINTR;
if (remaining_time != NULL) {
ret = clock_get_time(clock_port, &remain);
if (ret != KERN_SUCCESS) {
fprintf(stderr, "clock_get_time() failed: %s\n", mach_error_string(ret));
return -1;
}
ADD_MACH_TIMESPEC(¤t, requested_time);
SUB_MACH_TIMESPEC(¤t, &remain);
remaining_time->tv_sec = current.tv_sec;
remaining_time->tv_nsec = current.tv_nsec;
}
} else {
errno = EINVAL;
}
return -1;
}
return 0;
}