diff --git a/sys/include/ape/signal.h b/sys/include/ape/signal.h index 81884bddf..7d4e322bb 100644 --- a/sys/include/ape/signal.h +++ b/sys/include/ape/signal.h @@ -37,9 +37,11 @@ typedef int sig_atomic_t; #define SIGTSTP 18 /* interactive stop */ #define SIGTTIN 19 /* read from ctl tty by member of background */ #define SIGTTOU 20 /* write to ctl tty by member of background */ +#define SIGVTALRM 21 /* virtual alarm clock */ +#define SIGPROF 22 /* profiling alarm clock */ #ifdef _BSD_EXTENSION -#define NSIG 21 +#define NSIG 23 #endif #ifdef __cplusplus diff --git a/sys/include/ape/sys/time.h b/sys/include/ape/sys/time.h index 484fe9acb..a15aa3646 100644 --- a/sys/include/ape/sys/time.h +++ b/sys/include/ape/sys/time.h @@ -9,6 +9,11 @@ struct timeval { long tv_usec; }; +struct itimerval { + struct timeval it_interval; + struct timeval it_value; +}; + #ifdef _BSD_EXTENSION struct timezone { int tz_minuteswest; @@ -17,6 +22,12 @@ struct timezone { #endif #endif /* __TIMEVAL__ */ +#define ITIMER_REAL 0 +#define ITIMER_VIRTUAL 1 +#define ITIMER_PROF 3 + extern int gettimeofday(struct timeval *, struct timezone *); +int getitimer(int, struct itimerval *); +int setitimer(int, const struct itimerval *, struct itimerval *); #endif /* __SYSTIME_H */ diff --git a/sys/src/ape/lib/ap/plan9/signal.c b/sys/src/ape/lib/ap/plan9/signal.c index a662ee0c1..b9bfbb715 100644 --- a/sys/src/ape/lib/ap/plan9/signal.c +++ b/sys/src/ape/lib/ap/plan9/signal.c @@ -28,10 +28,11 @@ static struct { {"sys: trap: address error", SIGSEGV}, {"sys: trap: TLB", SIGSEGV}, {"sys: write on closed pipe", SIGPIPE}, - {"alarm", SIGALRM}, {"term", SIGTERM}, {"usr1", SIGUSR1}, {"usr2", SIGUSR2}, + {"virtual alarm", SIGVTALRM}, + {"profiling alarm", SIGPROF}, }; #define NSIGTAB ((sizeof sigtab)/(sizeof (sigtab[0]))) 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 +#include +#include +#include +#include +#include +#include +#include +#include + +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\