1 1.40 thorpej /* $NetBSD: linux32_time.c,v 1.40 2021/09/19 23:51:37 thorpej Exp $ */ 2 1.1 manu 3 1.1 manu /*- 4 1.1 manu * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. 5 1.1 manu * 6 1.1 manu * Redistribution and use in source and binary forms, with or without 7 1.1 manu * modification, are permitted provided that the following conditions 8 1.1 manu * are met: 9 1.1 manu * 1. Redistributions of source code must retain the above copyright 10 1.1 manu * notice, this list of conditions and the following disclaimer. 11 1.1 manu * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 manu * notice, this list of conditions and the following disclaimer in the 13 1.1 manu * documentation and/or other materials provided with the distribution. 14 1.1 manu * 3. All advertising materials mentioning features or use of this software 15 1.1 manu * must display the following acknowledgement: 16 1.1 manu * This product includes software developed by Emmanuel Dreyfus 17 1.1 manu * 4. The name of the author may not be used to endorse or promote 18 1.1 manu * products derived from this software without specific prior written 19 1.1 manu * permission. 20 1.1 manu * 21 1.1 manu * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' 22 1.1 manu * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 1.1 manu * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 1.1 manu * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 25 1.1 manu * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 1.1 manu * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 1.1 manu * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 manu * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 1.1 manu * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 1.1 manu * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 1.1 manu * POSSIBILITY OF SUCH DAMAGE. 32 1.1 manu */ 33 1.1 manu 34 1.1 manu #include <sys/cdefs.h> 35 1.1 manu 36 1.40 thorpej __KERNEL_RCSID(0, "$NetBSD: linux32_time.c,v 1.40 2021/09/19 23:51:37 thorpej Exp $"); 37 1.1 manu 38 1.1 manu #include <sys/types.h> 39 1.1 manu #include <sys/param.h> 40 1.1 manu #include <sys/fstypes.h> 41 1.1 manu #include <sys/signal.h> 42 1.1 manu #include <sys/dirent.h> 43 1.4 skd #include <sys/kauth.h> 44 1.1 manu #include <sys/kernel.h> 45 1.1 manu #include <sys/fcntl.h> 46 1.12 dsl #include <sys/namei.h> 47 1.1 manu #include <sys/select.h> 48 1.40 thorpej #include <sys/timerfd.h> 49 1.1 manu #include <sys/proc.h> 50 1.13 dsl #include <sys/resourcevar.h> 51 1.1 manu #include <sys/ucred.h> 52 1.1 manu #include <sys/swap.h> 53 1.12 dsl #include <sys/vfs_syscalls.h> 54 1.1 manu 55 1.1 manu #include <machine/types.h> 56 1.1 manu 57 1.1 manu #include <sys/syscallargs.h> 58 1.1 manu 59 1.1 manu #include <compat/netbsd32/netbsd32.h> 60 1.1 manu #include <compat/netbsd32/netbsd32_conv.h> 61 1.1 manu #include <compat/netbsd32/netbsd32_syscallargs.h> 62 1.1 manu 63 1.1 manu #include <compat/linux/common/linux_types.h> 64 1.1 manu #include <compat/linux/common/linux_signal.h> 65 1.1 manu #include <compat/linux/common/linux_machdep.h> 66 1.1 manu #include <compat/linux/common/linux_misc.h> 67 1.1 manu #include <compat/linux/common/linux_oldolduname.h> 68 1.18 njoly #include <compat/linux/common/linux_sched.h> 69 1.23 ad #include <compat/linux/common/linux_ipc.h> 70 1.23 ad #include <compat/linux/common/linux_sem.h> 71 1.1 manu #include <compat/linux/linux_syscallargs.h> 72 1.1 manu 73 1.1 manu #include <compat/linux32/common/linux32_types.h> 74 1.1 manu #include <compat/linux32/common/linux32_signal.h> 75 1.1 manu #include <compat/linux32/common/linux32_machdep.h> 76 1.1 manu #include <compat/linux32/common/linux32_sysctl.h> 77 1.1 manu #include <compat/linux32/common/linux32_socketcall.h> 78 1.36 christos #include <compat/linux32/common/linux32_sched.h> 79 1.1 manu #include <compat/linux32/linux32_syscallargs.h> 80 1.1 manu 81 1.39 thorpej CTASSERT(LINUX_TIMER_ABSTIME == TIMER_ABSTIME); 82 1.39 thorpej 83 1.1 manu extern struct timezone linux_sys_tz; 84 1.18 njoly 85 1.1 manu int 86 1.16 dsl linux32_sys_gettimeofday(struct lwp *l, const struct linux32_sys_gettimeofday_args *uap, register_t *retval) 87 1.1 manu { 88 1.16 dsl /* { 89 1.28 njoly syscallarg(netbsd32_timeval50p_t) tp; 90 1.1 manu syscallarg(netbsd32_timezonep_t) tzp; 91 1.16 dsl } */ 92 1.1 manu struct timeval tv; 93 1.28 njoly struct netbsd32_timeval50 tv32; 94 1.1 manu int error; 95 1.1 manu 96 1.10 dsl if (SCARG_P32(uap, tp) != NULL) { 97 1.1 manu microtime(&tv); 98 1.28 njoly netbsd32_from_timeval50(&tv, &tv32); 99 1.10 dsl if ((error = copyout(&tv32, SCARG_P32(uap, tp), 100 1.1 manu sizeof(tv32))) != 0) 101 1.1 manu return error; 102 1.1 manu } 103 1.1 manu 104 1.1 manu /* timezone size does not change */ 105 1.10 dsl if (SCARG_P32(uap, tzp) != NULL) { 106 1.10 dsl if ((error = copyout(&linux_sys_tz, SCARG_P32(uap, tzp), 107 1.1 manu sizeof(linux_sys_tz))) != 0) 108 1.1 manu return error; 109 1.1 manu } 110 1.1 manu 111 1.1 manu return 0; 112 1.1 manu } 113 1.1 manu 114 1.1 manu int 115 1.16 dsl linux32_sys_settimeofday(struct lwp *l, const struct linux32_sys_settimeofday_args *uap, register_t *retval) 116 1.1 manu { 117 1.16 dsl /* { 118 1.28 njoly syscallarg(netbsd32_timeval50p_t) tp; 119 1.1 manu syscallarg(netbsd32_timezonep_t) tzp; 120 1.16 dsl } */ 121 1.1 manu struct linux_sys_settimeofday_args ua; 122 1.1 manu 123 1.28 njoly NETBSD32TOP_UAP(tp, struct timeval50); 124 1.1 manu NETBSD32TOP_UAP(tzp, struct timezone); 125 1.1 manu 126 1.1 manu return linux_sys_settimeofday(l, &ua, retval); 127 1.1 manu } 128 1.1 manu 129 1.1 manu int 130 1.16 dsl linux32_sys_time(struct lwp *l, const struct linux32_sys_time_args *uap, register_t *retval) 131 1.1 manu { 132 1.16 dsl /* { 133 1.26 njoly syscallarg(linux32_timep_t) t; 134 1.16 dsl } */ 135 1.2 manu struct timeval atv; 136 1.2 manu linux32_time_t tt; 137 1.2 manu int error; 138 1.2 manu 139 1.2 manu microtime(&atv); 140 1.2 manu 141 1.2 manu tt = (linux32_time_t)atv.tv_sec; 142 1.2 manu 143 1.10 dsl if (SCARG_P32(uap, t) && (error = copyout(&tt, 144 1.10 dsl SCARG_P32(uap, t), sizeof(tt)))) 145 1.2 manu return error; 146 1.1 manu 147 1.2 manu retval[0] = tt; 148 1.1 manu 149 1.2 manu return 0; 150 1.1 manu } 151 1.1 manu 152 1.1 manu 153 1.20 christos #define CONVTCK(r) (r.tv_sec * hz + r.tv_usec / (1000000 / hz)) 154 1.20 christos 155 1.1 manu int 156 1.16 dsl linux32_sys_times(struct lwp *l, const struct linux32_sys_times_args *uap, register_t *retval) 157 1.1 manu { 158 1.16 dsl /* { 159 1.1 manu syscallarg(linux32_tmsp_t) tms; 160 1.16 dsl } */ 161 1.20 christos struct proc *p = l->l_proc; 162 1.20 christos struct timeval t; 163 1.20 christos int error; 164 1.1 manu 165 1.20 christos if (SCARG_P32(uap, tms)) { 166 1.20 christos struct linux32_tms ltms32; 167 1.20 christos struct rusage ru; 168 1.20 christos 169 1.38 riastrad memset(<ms32, 0, sizeof(ltms32)); 170 1.38 riastrad 171 1.20 christos mutex_enter(p->p_lock); 172 1.20 christos calcru(p, &ru.ru_utime, &ru.ru_stime, NULL, NULL); 173 1.20 christos ltms32.ltms32_utime = CONVTCK(ru.ru_utime); 174 1.20 christos ltms32.ltms32_stime = CONVTCK(ru.ru_stime); 175 1.20 christos ltms32.ltms32_cutime = CONVTCK(p->p_stats->p_cru.ru_utime); 176 1.20 christos ltms32.ltms32_cstime = CONVTCK(p->p_stats->p_cru.ru_stime); 177 1.20 christos mutex_exit(p->p_lock); 178 1.13 dsl 179 1.21 christos error = copyout(<ms32, SCARG_P32(uap, tms), sizeof(ltms32)); 180 1.21 christos if (error) 181 1.20 christos return error; 182 1.20 christos } 183 1.13 dsl 184 1.20 christos getmicrouptime(&t); 185 1.13 dsl 186 1.20 christos retval[0] = ((linux32_clock_t)(CONVTCK(t))); 187 1.20 christos return 0; 188 1.20 christos } 189 1.1 manu 190 1.20 christos #undef CONVTCK 191 1.1 manu 192 1.1 manu int 193 1.16 dsl linux32_sys_stime(struct lwp *l, const struct linux32_sys_stime_args *uap, register_t *retval) 194 1.1 manu { 195 1.16 dsl /* { 196 1.1 manu syscallarg(linux32_timep_t) t; 197 1.16 dsl } */ 198 1.1 manu struct timespec ts; 199 1.1 manu linux32_time_t tt32; 200 1.1 manu int error; 201 1.1 manu 202 1.27 njoly if ((error = copyin(SCARG_P32(uap, t), &tt32, sizeof tt32)) != 0) 203 1.10 dsl return error; 204 1.1 manu 205 1.1 manu ts.tv_sec = (long)tt32; 206 1.1 manu ts.tv_nsec = 0; 207 1.1 manu 208 1.5 ad return settime(l->l_proc, &ts); 209 1.1 manu } 210 1.1 manu 211 1.1 manu int 212 1.16 dsl linux32_sys_utime(struct lwp *l, const struct linux32_sys_utime_args *uap, register_t *retval) 213 1.1 manu { 214 1.16 dsl /* { 215 1.1 manu syscallarg(const netbsd32_charp) path; 216 1.1 manu syscallarg(linux32_utimbufp_t) times; 217 1.16 dsl } */ 218 1.1 manu struct timeval tv[2], *tvp; 219 1.1 manu struct linux32_utimbuf lut; 220 1.1 manu int error; 221 1.1 manu 222 1.10 dsl if (SCARG_P32(uap, times) != NULL) { 223 1.10 dsl if ((error = copyin(SCARG_P32(uap, times), &lut, sizeof lut))) 224 1.1 manu return error; 225 1.1 manu 226 1.1 manu tv[0].tv_sec = (long)lut.l_actime; 227 1.1 manu tv[0].tv_usec = 0; 228 1.1 manu tv[1].tv_sec = (long)lut.l_modtime; 229 1.1 manu tv[1].tv_usec = 0; 230 1.12 dsl tvp = tv; 231 1.1 manu } else { 232 1.12 dsl tvp = NULL; 233 1.1 manu } 234 1.1 manu 235 1.12 dsl return do_sys_utimes(l, NULL, SCARG_P32(uap, path), FOLLOW, 236 1.12 dsl tvp, UIO_SYSSPACE); 237 1.18 njoly } 238 1.18 njoly 239 1.34 chs void 240 1.39 thorpej native_to_linux32_timespec(struct linux32_timespec *ltp, 241 1.39 thorpej const struct timespec *ntp) 242 1.18 njoly { 243 1.38 riastrad 244 1.38 riastrad memset(ltp, 0, sizeof(*ltp)); 245 1.18 njoly ltp->tv_sec = ntp->tv_sec; 246 1.18 njoly ltp->tv_nsec = ntp->tv_nsec; 247 1.18 njoly } 248 1.18 njoly 249 1.34 chs void 250 1.39 thorpej linux32_to_native_timespec(struct timespec *ntp, 251 1.39 thorpej const struct linux32_timespec *ltp) 252 1.18 njoly { 253 1.38 riastrad 254 1.38 riastrad memset(ntp, 0, sizeof(*ntp)); 255 1.18 njoly ntp->tv_sec = ltp->tv_sec; 256 1.18 njoly ntp->tv_nsec = ltp->tv_nsec; 257 1.18 njoly } 258 1.18 njoly 259 1.39 thorpej void 260 1.39 thorpej native_to_linux32_itimerspec(struct linux32_itimerspec *litp, 261 1.39 thorpej const struct itimerspec *nitp) 262 1.39 thorpej { 263 1.39 thorpej memset(litp, 0, sizeof(*litp)); 264 1.39 thorpej native_to_linux32_timespec(&litp->it_interval, &nitp->it_interval); 265 1.39 thorpej native_to_linux32_timespec(&litp->it_value, &nitp->it_value); 266 1.39 thorpej } 267 1.39 thorpej 268 1.39 thorpej void 269 1.39 thorpej linux32_to_native_itimerspec(struct itimerspec *nitp, 270 1.39 thorpej const struct linux32_itimerspec *litp) 271 1.39 thorpej { 272 1.39 thorpej memset(nitp, 0, sizeof(*nitp)); 273 1.39 thorpej linux32_to_native_timespec(&nitp->it_interval, &litp->it_interval); 274 1.39 thorpej linux32_to_native_timespec(&nitp->it_value, &litp->it_value); 275 1.39 thorpej } 276 1.39 thorpej 277 1.18 njoly int 278 1.22 njoly linux32_sys_nanosleep(struct lwp *l, 279 1.22 njoly const struct linux32_sys_nanosleep_args *uap, register_t *retval) 280 1.22 njoly { 281 1.22 njoly /* { 282 1.22 njoly syscallarg(linux32_timespecp_t) rqtp; 283 1.22 njoly syscallarg(linux32_timespecp_t) rmtp; 284 1.22 njoly } */ 285 1.22 njoly struct timespec rqts, rmts; 286 1.22 njoly struct linux32_timespec lrqts, lrmts; 287 1.22 njoly int error, error1; 288 1.22 njoly 289 1.22 njoly error = copyin(SCARG_P32(uap, rqtp), &lrqts, sizeof(lrqts)); 290 1.22 njoly if (error != 0) 291 1.22 njoly return error; 292 1.22 njoly linux32_to_native_timespec(&rqts, &lrqts); 293 1.22 njoly 294 1.37 christos error = nanosleep1(l, CLOCK_MONOTONIC, 0, &rqts, 295 1.37 christos SCARG_P32(uap, rmtp) ? &rmts : NULL); 296 1.22 njoly if (SCARG_P32(uap, rmtp) == NULL || (error != 0 && error != EINTR)) 297 1.22 njoly return error; 298 1.22 njoly 299 1.22 njoly native_to_linux32_timespec(&lrmts, &rmts); 300 1.22 njoly error1 = copyout(&lrmts, SCARG_P32(uap, rmtp), sizeof(lrmts)); 301 1.22 njoly return error1 ? error1 : error; 302 1.22 njoly } 303 1.22 njoly 304 1.22 njoly int 305 1.18 njoly linux32_sys_clock_settime(struct lwp *l, 306 1.18 njoly const struct linux32_sys_clock_settime_args *uap, register_t *retval) 307 1.18 njoly { 308 1.18 njoly /* { 309 1.18 njoly syscallarg(clockid_t) which; 310 1.18 njoly syscallarg(linux32_timespecp_t) tp; 311 1.18 njoly } */ 312 1.18 njoly int error; 313 1.18 njoly struct timespec ts; 314 1.18 njoly struct linux32_timespec lts; 315 1.30 njoly clockid_t id; 316 1.18 njoly 317 1.30 njoly error = linux_to_native_clockid(&id, SCARG(uap, which)); 318 1.30 njoly if (error != 0) 319 1.30 njoly return error; 320 1.18 njoly 321 1.18 njoly if ((error = copyin(SCARG_P32(uap, tp), <s, sizeof lts))) 322 1.18 njoly return error; 323 1.18 njoly 324 1.18 njoly linux32_to_native_timespec(&ts, <s); 325 1.30 njoly return clock_settime1(l->l_proc, id, &ts, true); 326 1.18 njoly } 327 1.18 njoly 328 1.18 njoly int 329 1.18 njoly linux32_sys_clock_gettime(struct lwp *l, 330 1.18 njoly const struct linux32_sys_clock_gettime_args *uap, register_t *retval) 331 1.18 njoly { 332 1.18 njoly /* { 333 1.18 njoly syscallarg(clockid_t) which; 334 1.18 njoly syscallarg(linux32_timespecp_t) tp; 335 1.18 njoly } */ 336 1.32 njoly int error; 337 1.32 njoly clockid_t id; 338 1.18 njoly struct timespec ts; 339 1.18 njoly struct linux32_timespec lts; 340 1.18 njoly 341 1.32 njoly error = linux_to_native_clockid(&id, SCARG(uap, which)); 342 1.32 njoly if (error != 0) 343 1.32 njoly return error; 344 1.32 njoly 345 1.32 njoly error = clock_gettime1(id, &ts); 346 1.32 njoly if (error != 0) 347 1.32 njoly return error; 348 1.18 njoly 349 1.18 njoly native_to_linux32_timespec(<s, &ts); 350 1.18 njoly return copyout(<s, SCARG_P32(uap, tp), sizeof lts); 351 1.18 njoly } 352 1.18 njoly 353 1.18 njoly int 354 1.18 njoly linux32_sys_clock_getres(struct lwp *l, 355 1.18 njoly const struct linux32_sys_clock_getres_args *uap, register_t *retval) 356 1.18 njoly { 357 1.18 njoly /* { 358 1.18 njoly syscallarg(clockid_t) which; 359 1.18 njoly syscallarg(linux32_timespecp_t) tp; 360 1.18 njoly } */ 361 1.18 njoly int error; 362 1.18 njoly clockid_t id; 363 1.18 njoly struct timespec ts; 364 1.18 njoly struct linux32_timespec lts; 365 1.18 njoly 366 1.18 njoly error = linux_to_native_clockid(&id, SCARG(uap, which)); 367 1.18 njoly if (error != 0 || SCARG_P32(uap, tp) == NULL) 368 1.18 njoly return error; 369 1.18 njoly 370 1.31 njoly error = clock_getres1(id, &ts); 371 1.31 njoly if (error != 0) 372 1.31 njoly return error; 373 1.31 njoly 374 1.18 njoly native_to_linux32_timespec(<s, &ts); 375 1.18 njoly return copyout(<s, SCARG_P32(uap, tp), sizeof lts); 376 1.18 njoly } 377 1.25 njoly 378 1.25 njoly int 379 1.25 njoly linux32_sys_clock_nanosleep(struct lwp *l, 380 1.25 njoly const struct linux32_sys_clock_nanosleep_args *uap, register_t *retval) 381 1.25 njoly { 382 1.25 njoly /* { 383 1.25 njoly syscallarg(clockid_t) which; 384 1.25 njoly syscallarg(int) flags; 385 1.25 njoly syscallarg(linux32_timespecp_t) rqtp; 386 1.25 njoly syscallarg(linux32_timespecp_t) rmtp; 387 1.25 njoly } */ 388 1.25 njoly struct linux32_timespec lrqts, lrmts; 389 1.25 njoly struct timespec rqts, rmts; 390 1.37 christos int error, error1, flags; 391 1.35 njoly clockid_t id; 392 1.25 njoly 393 1.37 christos flags = SCARG(uap, flags) != 0 ? TIMER_ABSTIME : 0; 394 1.35 njoly 395 1.35 njoly error = linux_to_native_clockid(&id, SCARG(uap, which)); 396 1.35 njoly if (error != 0) 397 1.35 njoly return error; 398 1.25 njoly 399 1.25 njoly error = copyin(SCARG_P32(uap, rqtp), &lrqts, sizeof lrqts); 400 1.25 njoly if (error != 0) 401 1.25 njoly return error; 402 1.25 njoly linux32_to_native_timespec(&rqts, &lrqts); 403 1.25 njoly 404 1.37 christos error = nanosleep1(l, id, flags, &rqts, 405 1.37 christos SCARG_P32(uap, rmtp) ? &rmts : NULL); 406 1.25 njoly if (SCARG_P32(uap, rmtp) == NULL || (error != 0 && error != EINTR)) 407 1.25 njoly return error; 408 1.25 njoly 409 1.25 njoly native_to_linux32_timespec(&lrmts, &rmts); 410 1.25 njoly error1 = copyout(&lrmts, SCARG_P32(uap, rmtp), sizeof lrmts); 411 1.25 njoly return error1 ? error1 : error; 412 1.25 njoly } 413 1.39 thorpej 414 1.39 thorpej int 415 1.39 thorpej linux32_sys_timer_create(struct lwp *l, 416 1.39 thorpej const struct linux32_sys_timer_create_args *uap, register_t *retval) 417 1.39 thorpej { 418 1.39 thorpej /* { 419 1.39 thorpej syscallarg(clockid_t) clockid; 420 1.39 thorpej syscallarg(struct linux32_sigevent *) evp; 421 1.39 thorpej syscallarg(timer_t *) timerid; 422 1.39 thorpej } */ 423 1.39 thorpej clockid_t id; 424 1.39 thorpej int error; 425 1.39 thorpej 426 1.39 thorpej error = linux_to_native_timer_create_clockid(&id, SCARG(uap, clockid)); 427 1.39 thorpej if (error == 0) { 428 1.39 thorpej error = timer_create1(SCARG(uap, timerid), id, 429 1.39 thorpej (void *)SCARG(uap, evp), linux32_sigevent_copyin, l); 430 1.39 thorpej } 431 1.39 thorpej 432 1.39 thorpej return error; 433 1.39 thorpej } 434 1.39 thorpej 435 1.39 thorpej int 436 1.39 thorpej linux32_sys_timer_settime(struct lwp *l, 437 1.39 thorpej const struct linux32_sys_timer_settime_args *uap, register_t *retval) 438 1.39 thorpej { 439 1.39 thorpej /* { 440 1.39 thorpej syscallarg(timer_t) timerid; 441 1.39 thorpej syscallarg(int) flags; 442 1.39 thorpej syscallarg(const struct linux32_itimerspec *) tim; 443 1.39 thorpej syscallarg(struct linux32_itimerspec *) otim; 444 1.39 thorpej } */ 445 1.39 thorpej struct itimerspec value, ovalue, *ovp = NULL; 446 1.39 thorpej struct linux32_itimerspec tim, otim; 447 1.39 thorpej int error; 448 1.39 thorpej 449 1.39 thorpej error = copyin(SCARG(uap, tim), &tim, sizeof(tim)); 450 1.39 thorpej if (error) { 451 1.39 thorpej return error; 452 1.39 thorpej } 453 1.39 thorpej linux32_to_native_itimerspec(&value, &tim); 454 1.39 thorpej 455 1.39 thorpej if (SCARG(uap, otim)) { 456 1.39 thorpej ovp = &ovalue; 457 1.39 thorpej } 458 1.39 thorpej 459 1.39 thorpej if (SCARG(uap, flags) & ~TIMER_ABSTIME) { 460 1.39 thorpej return EINVAL; 461 1.39 thorpej } 462 1.39 thorpej 463 1.39 thorpej error = dotimer_settime(SCARG(uap, timerid), &value, ovp, 464 1.39 thorpej SCARG(uap, flags), l->l_proc); 465 1.39 thorpej if (error) { 466 1.39 thorpej return error; 467 1.39 thorpej } 468 1.39 thorpej 469 1.39 thorpej if (ovp) { 470 1.39 thorpej native_to_linux32_itimerspec(&otim, ovp); 471 1.39 thorpej error = copyout(&otim, SCARG(uap, otim), sizeof(otim)); 472 1.39 thorpej } 473 1.39 thorpej 474 1.39 thorpej return error; 475 1.39 thorpej } 476 1.39 thorpej 477 1.39 thorpej int 478 1.39 thorpej linux32_sys_timer_gettime(struct lwp *l, 479 1.39 thorpej const struct linux32_sys_timer_gettime_args *uap, register_t *retval) 480 1.39 thorpej { 481 1.39 thorpej /* { 482 1.39 thorpej syscallarg(timer_t) timerid; 483 1.39 thorpej syscallarg(struct linux32_itimerspec *) tim; 484 1.39 thorpej } */ 485 1.39 thorpej struct itimerspec its; 486 1.39 thorpej struct linux32_itimerspec lits; 487 1.39 thorpej int error; 488 1.39 thorpej 489 1.39 thorpej error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, &its); 490 1.39 thorpej if (error == 0) { 491 1.39 thorpej native_to_linux32_itimerspec(&lits, &its); 492 1.39 thorpej error = copyout(&lits, SCARG(uap, tim), sizeof(lits)); 493 1.39 thorpej } 494 1.39 thorpej 495 1.39 thorpej return error; 496 1.39 thorpej } 497 1.39 thorpej 498 1.39 thorpej /* 499 1.39 thorpej * timer_gettoverrun(2) and timer_delete(2) are handled directly 500 1.39 thorpej * by the native calls. 501 1.39 thorpej */ 502 1.40 thorpej 503 1.40 thorpej /* 504 1.40 thorpej * timerfd_create() is handled by the standard COMPAT_LINUX call. 505 1.40 thorpej */ 506 1.40 thorpej 507 1.40 thorpej int 508 1.40 thorpej linux32_sys_timerfd_gettime(struct lwp *l, 509 1.40 thorpej const struct linux32_sys_timerfd_gettime_args *uap, register_t *retval) 510 1.40 thorpej { 511 1.40 thorpej /* { 512 1.40 thorpej syscallarg(int) fd; 513 1.40 thorpej syscallarg(struct linux32_itimerspec *) tim; 514 1.40 thorpej } */ 515 1.40 thorpej struct itimerspec its; 516 1.40 thorpej struct linux32_itimerspec lits; 517 1.40 thorpej int error; 518 1.40 thorpej 519 1.40 thorpej error = do_timerfd_gettime(l, SCARG(uap, fd), &its, retval); 520 1.40 thorpej if (error == 0) { 521 1.40 thorpej native_to_linux32_itimerspec(&lits, &its); 522 1.40 thorpej error = copyout(&lits, SCARG(uap, tim), sizeof(lits)); 523 1.40 thorpej } 524 1.40 thorpej 525 1.40 thorpej return error; 526 1.40 thorpej } 527 1.40 thorpej 528 1.40 thorpej int 529 1.40 thorpej linux32_sys_timerfd_settime(struct lwp *l, 530 1.40 thorpej const struct linux32_sys_timerfd_settime_args *uap, register_t *retval) 531 1.40 thorpej { 532 1.40 thorpej /* { 533 1.40 thorpej syscallarg(int) fd; 534 1.40 thorpej syscallarg(int) flags; 535 1.40 thorpej syscallarg(const struct linux32_itimerspec *) tim; 536 1.40 thorpej syscallarg(struct linux32_itimerspec *) otim; 537 1.40 thorpej } */ 538 1.40 thorpej struct itimerspec nits, oits, *oitsp = NULL; 539 1.40 thorpej struct linux32_itimerspec lits; 540 1.40 thorpej int nflags; 541 1.40 thorpej int error; 542 1.40 thorpej 543 1.40 thorpej error = copyin(SCARG(uap, tim), &lits, sizeof(lits)); 544 1.40 thorpej if (error) { 545 1.40 thorpej return error; 546 1.40 thorpej } 547 1.40 thorpej linux32_to_native_itimerspec(&nits, &lits); 548 1.40 thorpej 549 1.40 thorpej error = linux_to_native_timerfd_settime_flags(&nflags, 550 1.40 thorpej SCARG(uap, flags)); 551 1.40 thorpej if (error) { 552 1.40 thorpej return error; 553 1.40 thorpej } 554 1.40 thorpej 555 1.40 thorpej if (SCARG(uap, otim)) { 556 1.40 thorpej oitsp = &oits; 557 1.40 thorpej } 558 1.40 thorpej 559 1.40 thorpej error = do_timerfd_settime(l, SCARG(uap, fd), nflags, 560 1.40 thorpej &nits, oitsp, retval); 561 1.40 thorpej if (error == 0 && oitsp != NULL) { 562 1.40 thorpej native_to_linux32_itimerspec(&lits, oitsp); 563 1.40 thorpej error = copyout(&lits, SCARG(uap, otim), sizeof(lits)); 564 1.40 thorpej } 565 1.40 thorpej 566 1.40 thorpej return error; 567 1.40 thorpej } 568