[newlib-cygwin] Cygwin: timerfd: move ioctl error handling into timerfd_tracker
Corinna Vinschen
corinna@sourceware.org
Mon Jan 21 11:41:00 GMT 2019
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=289b7c09c8bca6c84edfddf77c11b530bda95016
commit 289b7c09c8bca6c84edfddf77c11b530bda95016
Author: Corinna Vinschen <corinna@vinschen.de>
Date: Mon Jan 21 12:41:00 2019 +0100
Cygwin: timerfd: move ioctl error handling into timerfd_tracker
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diff:
---
winsup/cygwin/fhandler_timerfd.cc | 62 ++++++++++++++++++---------------------
winsup/cygwin/timerfd.cc | 11 +++++--
winsup/cygwin/timerfd.h | 2 +-
3 files changed, 39 insertions(+), 36 deletions(-)
diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc
index 8a6c4b5..2a05217 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 08fff31..a03749a 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 1f9f762..66bf784 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); }
More information about the Cygwin-cvs
mailing list