1 /* fhandler_timerfd.cc: fhandler for timerfd, public timerfd API
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
16 #include <sys/timerfd.h>
17 #include <cygwin/signal.h>
19 fhandler_timerfd::fhandler_timerfd () :
25 fhandler_timerfd::get_proc_fd_name (char *buf
)
27 return strcpy (buf
, "anon_inode:[timerfd]");
30 /* The timers connected to a descriptor are stored on the cygheap
31 together with their fhandler. */
34 fhandler_timerfd::timerfd (clockid_t clock_id
, int flags
)
36 timerfd_tracker
*tfd
= (timerfd_tracker
*)
37 ccalloc (HEAP_FHANDLER
, 1, sizeof (timerfd_tracker
));
43 new (tfd
) timerfd_tracker ();
44 int ret
= tfd
->create (clock_id
);
51 if (flags
& TFD_NONBLOCK
)
52 set_nonblocking (true);
53 if (flags
& TFD_CLOEXEC
)
54 set_close_on_exec (true);
57 set_ino (get_unique_id ());
58 set_flags (O_RDWR
| O_BINARY
);
59 timerid
= (timer_t
) tfd
;
64 fhandler_timerfd::settime (int flags
, const struct itimerspec
*new_value
,
65 struct itimerspec
*old_value
)
71 timerfd_tracker
*tfd
= (timerfd_tracker
*) timerid
;
72 ret
= tfd
->settime (flags
, new_value
, old_value
);
85 fhandler_timerfd::gettime (struct itimerspec
*ovalue
)
91 timerfd_tracker
*tfd
= (timerfd_tracker
*) timerid
;
92 ret
= tfd
->gettime (ovalue
);
105 fhandler_timerfd::fstat (struct stat
*buf
)
107 int ret
= fhandler_base::fstat (buf
);
110 buf
->st_mode
= S_IRUSR
| S_IWUSR
;
111 buf
->st_dev
= FH_TIMERFD
;
112 buf
->st_ino
= get_unique_id ();
118 fhandler_timerfd::read (void *ptr
, size_t& len
)
120 if (len
< sizeof (LONG64
))
129 timerfd_tracker
*tfd
= (timerfd_tracker
*) timerid
;
130 LONG64 ret
= tfd
->wait (is_nonblocking ());
136 *(PLONG64
) ptr
= ret
;
137 len
= sizeof (LONG64
);
147 fhandler_timerfd::write (const void *, size_t)
154 fhandler_timerfd::get_timerfd_handle ()
158 timerfd_tracker
*tfd
= (timerfd_tracker
*) timerid
;
159 return tfd
->get_timerfd_handle ();
167 fhandler_timerfd::dup (fhandler_base
*child
, int flags
)
169 int ret
= fhandler_base::dup (child
, flags
);
173 fhandler_timerfd
*fhc
= (fhandler_timerfd
*) child
;
176 timerfd_tracker
*tfd
= (timerfd_tracker
*) fhc
->timerid
;
187 fhandler_timerfd::ioctl (unsigned int cmd
, void *p
)
194 case TFD_IOC_SET_TICKS
:
197 timerfd_tracker
*tfd
= (timerfd_tracker
*) timerid
;
199 exp_cnt
= *(uint64_t *) p
;
200 ret
= tfd
->ioctl_set_ticks (exp_cnt
);
208 ret
= fhandler_base::ioctl (cmd
, p
);
211 syscall_printf ("%d = ioctl_timerfd(%x, %p)", ret
, cmd
, p
);
216 fhandler_timerfd::fixup_after_fork (HANDLE
)
220 timerfd_tracker
*tfd
= (timerfd_tracker
*) timerid
;
221 tfd
->fixup_after_fork ();
228 fhandler_timerfd::fixup_after_exec ()
232 timerfd_tracker
*tfd
= (timerfd_tracker
*) timerid
;
233 tfd
->init_fixup_after_fork_exec ();
234 if (close_on_exec ())
235 timerfd_tracker::dtor (tfd
);
237 tfd
->fixup_after_exec ();
244 fhandler_timerfd::close ()
250 timerfd_tracker
*tfd
= (timerfd_tracker
*) timerid
;
251 timerfd_tracker::dtor (tfd
);
260 timerfd_create (clockid_t clock_id
, int flags
)
263 fhandler_timerfd
*fh
;
265 debug_printf ("timerfd_create (%lu, %y)", clock_id
, flags
);
267 if (clock_id
!= CLOCK_REALTIME
268 && clock_id
!= CLOCK_MONOTONIC
269 && clock_id
!= CLOCK_BOOTTIME
)
274 if ((flags
& ~(TFD_NONBLOCK
| TFD_CLOEXEC
)) != 0)
281 /* Create new timerfd descriptor. */
286 fh
= (fhandler_timerfd
*) build_fh_dev (*timerfd_dev
);
287 if (fh
&& fh
->timerfd (clock_id
, flags
) == 0)
299 syscall_printf ("%R = timerfd_create (%lu, %y)", ret
, clock_id
, flags
);
304 timerfd_settime (int fd_in
, int flags
, const struct itimerspec
*value
,
305 struct itimerspec
*ovalue
)
307 if ((flags
& ~(TFD_TIMER_ABSTIME
| TFD_TIMER_CANCEL_ON_SET
)) != 0)
313 cygheap_fdget
fd (fd_in
);
316 fhandler_timerfd
*fh
= fd
->is_timerfd ();
322 return fh
->settime (flags
, value
, ovalue
);
326 timerfd_gettime (int fd_in
, struct itimerspec
*ovalue
)
328 cygheap_fdget
fd (fd_in
);
331 fhandler_timerfd
*fh
= fd
->is_timerfd ();
337 return fh
->gettime (ovalue
);