summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/fhandler_timerfd.cc62
-rw-r--r--winsup/cygwin/timerfd.cc11
-rw-r--r--winsup/cygwin/timerfd.h2
3 files changed, 39 insertions, 36 deletions
diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc
index 8a6c4b559..2a0521708 100644
--- a/winsup/cygwin/fhandler_timerfd.cc
+++ b/winsup/cygwin/fhandler_timerfd.cc
@@ -187,6 +187,35 @@ fhandler_timerfd::dup (fhandler_base *child, int flags)
return ret;
}
+int
+fhandler_timerfd::ioctl (unsigned int cmd, void *p)
+{
+ int ret = -1;
+ uint64_t exp_cnt;
+
+ switch (cmd)
+ {
+ case TFD_IOC_SET_TICKS:
+ __try
+ {
+ timerfd_tracker *tfd = (timerfd_tracker *) timerid;
+
+ exp_cnt = *(uint64_t *) p;
+ ret = tfd->ioctl_set_ticks (exp_cnt);
+ if (ret < 0)
+ set_errno (-ret);
+ }
+ __except (EFAULT) {}
+ __endtry
+ break;
+ default:
+ ret = fhandler_base::ioctl (cmd, p);
+ break;
+ }
+ syscall_printf ("%d = ioctl_timerfd(%x, %p)", ret, cmd, p);
+ return ret;
+}
+
void
fhandler_timerfd::fixup_after_fork (HANDLE)
{
@@ -214,39 +243,6 @@ fhandler_timerfd::fixup_after_exec ()
__endtry
}
-int
-fhandler_timerfd::ioctl (unsigned int cmd, void *p)
-{
- int ret = -1;
- uint64_t exp_cnt;
-
- switch (cmd)
- {
- case TFD_IOC_SET_TICKS:
- __try
- {
- timerfd_tracker *tfd = (timerfd_tracker *) timerid;
-
- exp_cnt = *(uint64_t *) p;
- if (!exp_cnt)
- {
- set_errno (EINVAL);
- break;
- }
- tfd->ioctl_set_ticks (exp_cnt);
- ret = 0;
- }
- __except (EFAULT) {}
- __endtry
- break;
- default:
- ret = fhandler_base::ioctl (cmd, p);
- break;
- }
- syscall_printf ("%d = ioctl_timerfd(%x, %p)", ret, cmd, p);
- return ret;
-}
-
fhandler_timerfd::~fhandler_timerfd ()
{
__try
diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc
index 08fff312c..a03749a60 100644
--- a/winsup/cygwin/timerfd.cc
+++ b/winsup/cygwin/timerfd.cc
@@ -394,11 +394,18 @@ timerfd_tracker::close ()
InterlockedDecrement (&tfd_shared->instance_count);
}
-void
-timerfd_tracker::ioctl_set_ticks (uint64_t exp_cnt)
+int
+timerfd_tracker::ioctl_set_ticks (uint64_t new_exp_cnt)
{
+ LONG64 exp_cnt = (LONG64) new_exp_cnt;
+ if (exp_cnt == 0 || exp_cnt == -1LL)
+ return -EINVAL;
+ if (!enter_critical_section ())
+ return -EBADF;
set_expiration_count (exp_cnt);
timer_expired ();
+ leave_critical_section ();
+ return 0;
}
void
diff --git a/winsup/cygwin/timerfd.h b/winsup/cygwin/timerfd.h
index 1f9f76268..66bf78424 100644
--- a/winsup/cygwin/timerfd.h
+++ b/winsup/cygwin/timerfd.h
@@ -148,7 +148,7 @@ class timerfd_tracker /* cygheap! */
int settime (int, const struct itimerspec *, struct itimerspec *);
static void dtor (timerfd_tracker *);
void close ();
- void ioctl_set_ticks (uint64_t);
+ int ioctl_set_ticks (uint64_t);
void fixup_after_fork_exec (bool);
void fixup_after_fork () { fixup_after_fork_exec (false); }
void fixup_after_exec () { fixup_after_fork_exec (true); }