Cygwin: timerfd: move ioctl error handling into timerfd_tracker

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2019-01-21 12:41:00 +01:00
parent 528f4d4938
commit 289b7c09c8
3 changed files with 39 additions and 36 deletions

View File

@ -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

View File

@ -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

View File

@ -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); }