summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/bsd
diff options
context:
space:
mode:
authorspew <devnull@localhost>2018-07-01 18:48:12 -0400
committerspew <devnull@localhost>2018-07-01 18:48:12 -0400
commit91d03436276fd2239670fdea902c761f31ea7a72 (patch)
tree6f5b8f0d3826d2897e541bbb7bbf3d6b03c03a88 /sys/src/ape/lib/bsd
parent9dc907361c8398c714fed81a65cd447803ae1a8d (diff)
ape: an implemenation of getitimer setitimer
Diffstat (limited to 'sys/src/ape/lib/bsd')
-rw-r--r--sys/src/ape/lib/bsd/getitimer.c86
-rw-r--r--sys/src/ape/lib/bsd/mkfile1
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\