Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

emulated_syscalls.c

Go to the documentation of this file.
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; /* see Libc/mach/mach_init_ports.c */
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 /* Derived from Libc/gen/nanosleep.c */
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     /* Validate arguments */
00037     if ((req == NULL) || (req->tv_sec < 0) || (req->tv_nsec > NSEC_PER_SEC)) {
00038         return -EINVAL;
00039     }
00040 
00041     if (rem != NULL) { /* we might have to calculate rem; get current time */
00042         ret = clock_get_time(clock_port, &abs_time_before);
00043         assert(ret == KERN_SUCCESS); /* should never fail */
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) { /* this is Mach's equivalent of EINTR */
00050         if (rem != NULL) { /* update remaining time */
00051             ret = clock_get_time(clock_port, &abs_time_after);
00052             assert(ret == KERN_SUCCESS);
00053 
00054             /* rem = abs_time_before + req - abs_time_after */
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 }

Generated on Fri Feb 4 11:13:32 2005 for sigsafe by doxygen 1.3.5