1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright (c) 2015, Joyent, Inc. All rights reserved. 14 */ 15 16 #include <sys/timerfd.h> 17 #include <sys/stat.h> 18 #include <unistd.h> 19 #include <errno.h> 20 #include <fcntl.h> 21 22 int 23 timerfd_create(int clockid, int flags) 24 { 25 int oflags = O_RDWR; 26 int fd; 27 28 if (flags & ~(TFD_NONBLOCK | TFD_CLOEXEC)) { 29 errno = EINVAL; 30 return (-1); 31 } 32 33 if (flags & TFD_NONBLOCK) 34 oflags |= O_NONBLOCK; 35 36 if (flags & TFD_CLOEXEC) 37 oflags |= O_CLOEXEC; 38 39 if ((fd = open("/dev/timerfd", oflags)) < 0) 40 return (-1); 41 42 if (ioctl(fd, TIMERFDIOC_CREATE, clockid) != 0) { 43 (void) close(fd); 44 return (-1); 45 } 46 47 return (fd); 48 } 49 50 int 51 timerfd_settime(int fd, int flags, const struct itimerspec *new_value, 52 struct itimerspec *old_value) 53 { 54 timerfd_settime_t st; 55 int rval; 56 57 if (flags & ~(TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET)) { 58 errno = EINVAL; 59 return (-1); 60 } 61 62 st.tfd_settime_flags = flags; 63 st.tfd_settime_value = (uint64_t)(uintptr_t)new_value; 64 st.tfd_settime_ovalue = (uint64_t)(uintptr_t)old_value; 65 66 rval = ioctl(fd, TIMERFDIOC_SETTIME, &st); 67 68 if (rval == -1 && errno == ENOTTY) { 69 /* 70 * Linux has us return EINVAL when the file descriptor is valid 71 * but is not a timerfd file descriptor -- and LTP explicitly 72 * checks this case. 73 */ 74 errno = EINVAL; 75 } 76 77 return (rval); 78 } 79 80 int 81 timerfd_gettime(int fd, struct itimerspec *curr_value) 82 { 83 int rval = ioctl(fd, TIMERFDIOC_GETTIME, curr_value); 84 85 if (rval == -1 && errno == ENOTTY) { 86 /* 87 * See comment in timerfd_settime(), above. 88 */ 89 errno = EINVAL; 90 } 91 92 return (rval); 93 } 94