diff options
author | spew <devnull@localhost> | 2018-07-01 18:48:12 -0400 |
---|---|---|
committer | spew <devnull@localhost> | 2018-07-01 18:48:12 -0400 |
commit | 91d03436276fd2239670fdea902c761f31ea7a72 (patch) | |
tree | 6f5b8f0d3826d2897e541bbb7bbf3d6b03c03a88 /sys/src/ape/lib/bsd | |
parent | 9dc907361c8398c714fed81a65cd447803ae1a8d (diff) |
ape: an implemenation of getitimer setitimer
Diffstat (limited to 'sys/src/ape/lib/bsd')
-rw-r--r-- | sys/src/ape/lib/bsd/getitimer.c | 86 | ||||
-rw-r--r-- | sys/src/ape/lib/bsd/mkfile | 1 |
2 files changed, 87 insertions, 0 deletions
diff --git a/sys/src/ape/lib/bsd/getitimer.c b/sys/src/ape/lib/bsd/getitimer.c new file mode 100644 index 000000000..167a04eeb --- /dev/null +++ b/sys/src/ape/lib/bsd/getitimer.c @@ -0,0 +1,86 @@ +#include <sys/types.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <signal.h> +#include <errno.h> +#include <time.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> + +typedef struct Timer Timer; +struct Timer { + int pid, signal; + struct itimerval itimer; +}; + +Timer timers[3] = { + {0, SIGALRM}, + {0, SIGVTALRM}, + {0, SIGPROF}, +}; + +void +timerloop(Timer *timer, const struct timeval tval) +{ + pid_t ppid; + struct timespec t, s; + + ppid = getppid(); + t.tv_sec = tval.tv_sec; + t.tv_nsec = tval.tv_usec*1000; + for(;;){ + nanosleep(&t, &s); + kill(ppid, timer->signal); + } +} + +int +setitimer(int which, const struct itimerval *new, struct itimerval *curr) +{ + pid_t pid; + int status; + Timer *timer; + + if(which < 0 || which >= 3){ + errno = EINVAL; + return -1; + } + + timer = timers+which; + if(timer->pid != 0){ + kill(timer->pid, SIGKILL); + waitpid(timer->pid, &status, 0); + } + + switch(pid = fork()){ + default: + timer->pid = pid; + if(curr != NULL) + *curr = timer->itimer; + timer->itimer = *new; + break; + case -1: + errno = EFAULT; + return -1; + case 0: + timerloop(timer, new->it_interval); + exit(0); + } + return 0; +} + +int +getitimer(int which, struct itimerval *curr) +{ + Timer *timer; + + if(which < 0 || which >= 3){ + errno = EINVAL; + return -1; + } + + timer = timers+which; + *curr = timer->itimer; + return 0; +} diff --git a/sys/src/ape/lib/bsd/mkfile b/sys/src/ape/lib/bsd/mkfile index 90fefd36b..c121f8a0e 100644 --- a/sys/src/ape/lib/bsd/mkfile +++ b/sys/src/ape/lib/bsd/mkfile @@ -15,6 +15,7 @@ OFILES=\ gethostbyaddr.$O\ gethostbyname.$O\ gethostname.$O\ + getitimer.$O\ getnameinfo.$O\ getopt.$O\ getpeername.$O\ |