Implement timerfd_settime

Bug #104
This commit is contained in:
Theodore Dubois 2019-09-30 22:33:28 -07:00
parent 0c5c4c952b
commit 6daf24b336
4 changed files with 47 additions and 1 deletions

View File

@ -185,6 +185,7 @@ syscall_t syscall_table[] = {
[322] = (syscall_t) sys_timerfd_create,
[323] = (syscall_t) sys_eventfd,
[324] = (syscall_t) sys_fallocate,
[325] = (syscall_t) sys_timerfd_settime,
[328] = (syscall_t) sys_eventfd2,
[329] = (syscall_t) sys_epoll_create,
[330] = (syscall_t) sys_dup3,

View File

@ -10,6 +10,7 @@
#endif
#include <limits.h>
#include <string.h>
#include "kernel/calls.h"
static bool resource_valid(int resource) {

View File

@ -240,6 +240,44 @@ fd_t sys_timerfd_create(int_t clockid, int_t flags) {
return f_install(fd, flags);
}
int_t sys_timerfd_settime(fd_t f, int_t flags, addr_t new_value_addr, addr_t old_value_addr) {
STRACE("timerfd_settime(%d, %d, %#x, %#x)", f, flags, new_value_addr, old_value_addr);
struct fd *fd = f_get(f);
if (fd == NULL)
return _EBADF;
if (fd->ops != &timerfd_ops)
return _EINVAL;
struct itimerspec_ value;
if (user_get(new_value_addr, value))
return _EFAULT;
struct timer_spec spec = {
.value.tv_sec = value.value.sec,
.value.tv_nsec = value.value.nsec,
.interval.tv_sec = value.interval.sec,
.interval.tv_nsec = value.interval.nsec,
};
struct timer_spec old_spec;
lock(&fd->lock);
int err = timer_set(fd->timerfd.timer, spec, &old_spec);
unlock(&fd->lock);
if (err < 0)
return err;
if (old_value_addr) {
struct itimerspec_ old_value = {
.value.sec = old_spec.value.tv_sec,
.value.nsec = old_spec.value.tv_nsec,
.interval.sec = old_spec.interval.tv_sec,
.interval.nsec = old_spec.interval.tv_nsec,
};
if (user_put(old_value_addr, old_value))
return _EFAULT;
}
return 0;
}
static ssize_t timerfd_read(struct fd *fd, void *buf, size_t bufsize) {
if (bufsize < sizeof(uint64_t))
return _EINVAL;
@ -260,7 +298,7 @@ static ssize_t timerfd_read(struct fd *fd, void *buf, size_t bufsize) {
static int timerfd_poll(struct fd *fd) {
int res = 0;
lock(&fd->lock);
if (fd->timerfd.expirations == 0)
if (fd->timerfd.expirations != 0)
res |= POLL_READ;
unlock(&fd->lock);
return res;

View File

@ -36,6 +36,11 @@ struct itimerval_ {
struct timeval_ value;
};
struct itimerspec_ {
struct timespec_ interval;
struct timespec_ value;
};
struct tms_ {
clock_t_ tms_utime; /* user time */
clock_t_ tms_stime; /* system time */
@ -51,5 +56,6 @@ dword_t sys_gettimeofday(addr_t tv, addr_t tz);
dword_t sys_settimeofday(addr_t tv, addr_t tz);
fd_t sys_timerfd_create(int_t clockid, int_t flags);
int_t sys_timerfd_settime(fd_t f, int_t flags, addr_t new_value_addr, addr_t old_value_addr);
#endif