1 1.38 christos /* $NetBSD: kern_time_50.c,v 1.38 2024/01/19 18:39:15 christos Exp $ */ 2 1.2 christos 3 1.2 christos /*- 4 1.8 rmind * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 5 1.2 christos * All rights reserved. 6 1.2 christos * 7 1.2 christos * This code is derived from software contributed to The NetBSD Foundation 8 1.2 christos * by Christos Zoulas. 9 1.2 christos * 10 1.2 christos * Redistribution and use in source and binary forms, with or without 11 1.2 christos * modification, are permitted provided that the following conditions 12 1.2 christos * are met: 13 1.2 christos * 1. Redistributions of source code must retain the above copyright 14 1.2 christos * notice, this list of conditions and the following disclaimer. 15 1.2 christos * 2. Redistributions in binary form must reproduce the above copyright 16 1.2 christos * notice, this list of conditions and the following disclaimer in the 17 1.2 christos * documentation and/or other materials provided with the distribution. 18 1.2 christos * 19 1.2 christos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.2 christos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.2 christos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.2 christos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.2 christos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.2 christos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.2 christos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.2 christos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.2 christos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.2 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.2 christos * POSSIBILITY OF SUCH DAMAGE. 30 1.2 christos */ 31 1.2 christos #include <sys/cdefs.h> 32 1.38 christos __KERNEL_RCSID(0, "$NetBSD: kern_time_50.c,v 1.38 2024/01/19 18:39:15 christos Exp $"); 33 1.2 christos 34 1.2 christos #ifdef _KERNEL_OPT 35 1.33 pgoyette #include "opt_compat_netbsd.h" 36 1.8 rmind #include "opt_aio.h" 37 1.2 christos #include "opt_ntp.h" 38 1.8 rmind #include "opt_mqueue.h" 39 1.2 christos #endif 40 1.2 christos 41 1.2 christos #include <sys/param.h> 42 1.22 apb #include <sys/conf.h> 43 1.2 christos #include <sys/systm.h> 44 1.2 christos #include <sys/namei.h> 45 1.2 christos #include <sys/filedesc.h> 46 1.2 christos #include <sys/kernel.h> 47 1.2 christos #include <sys/file.h> 48 1.2 christos #include <sys/stat.h> 49 1.2 christos #include <sys/socketvar.h> 50 1.2 christos #include <sys/vnode.h> 51 1.2 christos #include <sys/proc.h> 52 1.2 christos #include <sys/uio.h> 53 1.2 christos #include <sys/dirent.h> 54 1.2 christos #include <sys/kauth.h> 55 1.2 christos #include <sys/time.h> 56 1.2 christos #include <sys/timex.h> 57 1.21 apb #include <sys/clockctl.h> 58 1.2 christos #include <sys/aio.h> 59 1.2 christos #include <sys/poll.h> 60 1.33 pgoyette #include <sys/syscall.h> 61 1.2 christos #include <sys/syscallargs.h> 62 1.33 pgoyette #include <sys/syscallvar.h> 63 1.25 pgoyette #include <sys/sysctl.h> 64 1.2 christos #include <sys/resource.h> 65 1.33 pgoyette #include <sys/compat_stub.h> 66 1.2 christos 67 1.2 christos #include <compat/common/compat_util.h> 68 1.25 pgoyette #include <compat/common/compat_mod.h> 69 1.2 christos #include <compat/sys/time.h> 70 1.2 christos #include <compat/sys/timex.h> 71 1.2 christos #include <compat/sys/resource.h> 72 1.2 christos #include <compat/sys/clockctl.h> 73 1.2 christos 74 1.25 pgoyette struct timeval50 boottime50; 75 1.25 pgoyette 76 1.33 pgoyette static const struct syscall_package kern_time_50_syscalls[] = { 77 1.33 pgoyette { SYS_compat_50_clock_gettime, 0, 78 1.33 pgoyette (sy_call_t *)compat_50_sys_clock_gettime }, 79 1.33 pgoyette { SYS_compat_50_clock_settime, 0, 80 1.33 pgoyette (sy_call_t *)compat_50_sys_clock_settime }, 81 1.33 pgoyette { SYS_compat_50_clock_getres, 0, 82 1.33 pgoyette (sy_call_t *)compat_50_sys_clock_getres}, 83 1.33 pgoyette { SYS_compat_50_nanosleep, 0, (sy_call_t *)compat_50_sys_nanosleep }, 84 1.33 pgoyette { SYS_compat_50_gettimeofday, 0, 85 1.33 pgoyette (sy_call_t *)compat_50_sys_gettimeofday }, 86 1.33 pgoyette { SYS_compat_50_settimeofday, 0, 87 1.33 pgoyette (sy_call_t *)compat_50_sys_settimeofday }, 88 1.33 pgoyette { SYS_compat_50_adjtime, 0, (sy_call_t *)compat_50_sys_adjtime }, 89 1.33 pgoyette { SYS_compat_50_setitimer, 0, (sy_call_t *)compat_50_sys_setitimer }, 90 1.33 pgoyette { SYS_compat_50_getitimer, 0, (sy_call_t *)compat_50_sys_getitimer }, 91 1.33 pgoyette { SYS_compat_50_aio_suspend, 0, 92 1.33 pgoyette (sy_call_t *)compat_50_sys_aio_suspend }, 93 1.33 pgoyette { SYS_compat_50_mq_timedsend, 0, 94 1.33 pgoyette (sy_call_t *)compat_50_sys_mq_timedsend }, 95 1.33 pgoyette { SYS_compat_50_mq_timedreceive, 0, 96 1.33 pgoyette (sy_call_t *)compat_50_sys_mq_timedreceive }, 97 1.33 pgoyette { SYS_compat_50_getrusage, 0, (sy_call_t *)compat_50_sys_getrusage }, 98 1.33 pgoyette { SYS_compat_50_timer_settime, 0, 99 1.33 pgoyette (sy_call_t *)compat_50_sys_timer_settime }, 100 1.33 pgoyette { SYS_compat_50_timer_gettime, 0, 101 1.33 pgoyette (sy_call_t *)compat_50_sys_timer_gettime }, 102 1.33 pgoyette { SYS_compat_50___ntp_gettime30, 0, 103 1.33 pgoyette (sy_call_t *)compat_50_sys___ntp_gettime30 }, 104 1.33 pgoyette { 0, 0, NULL } 105 1.33 pgoyette }; 106 1.33 pgoyette 107 1.2 christos int 108 1.2 christos compat_50_sys_clock_gettime(struct lwp *l, 109 1.2 christos const struct compat_50_sys_clock_gettime_args *uap, register_t *retval) 110 1.2 christos { 111 1.2 christos /* { 112 1.2 christos syscallarg(clockid_t) clock_id; 113 1.2 christos syscallarg(struct timespec50 *) tp; 114 1.2 christos } */ 115 1.15 njoly int error; 116 1.2 christos struct timespec ats; 117 1.2 christos struct timespec50 ats50; 118 1.2 christos 119 1.15 njoly error = clock_gettime1(SCARG(uap, clock_id), &ats); 120 1.15 njoly if (error != 0) 121 1.15 njoly return error; 122 1.15 njoly 123 1.2 christos timespec_to_timespec50(&ats, &ats50); 124 1.2 christos 125 1.2 christos return copyout(&ats50, SCARG(uap, tp), sizeof(ats50)); 126 1.2 christos } 127 1.2 christos 128 1.2 christos /* ARGSUSED */ 129 1.2 christos int 130 1.2 christos compat_50_sys_clock_settime(struct lwp *l, 131 1.2 christos const struct compat_50_sys_clock_settime_args *uap, register_t *retval) 132 1.2 christos { 133 1.2 christos /* { 134 1.2 christos syscallarg(clockid_t) clock_id; 135 1.2 christos syscallarg(const struct timespec50 *) tp; 136 1.2 christos } */ 137 1.2 christos int error; 138 1.2 christos struct timespec ats; 139 1.2 christos struct timespec50 ats50; 140 1.2 christos 141 1.2 christos error = copyin(SCARG(uap, tp), &ats50, sizeof(ats50)); 142 1.2 christos if (error) 143 1.2 christos return error; 144 1.2 christos timespec50_to_timespec(&ats50, &ats); 145 1.2 christos 146 1.2 christos return clock_settime1(l->l_proc, SCARG(uap, clock_id), &ats, 147 1.2 christos true); 148 1.2 christos } 149 1.2 christos 150 1.2 christos 151 1.2 christos int 152 1.2 christos compat_50_sys_clock_getres(struct lwp *l, 153 1.2 christos const struct compat_50_sys_clock_getres_args *uap, register_t *retval) 154 1.2 christos { 155 1.2 christos /* { 156 1.2 christos syscallarg(clockid_t) clock_id; 157 1.2 christos syscallarg(struct timespec50 *) tp; 158 1.2 christos } */ 159 1.2 christos struct timespec50 ats50; 160 1.14 njoly struct timespec ats; 161 1.29 maxv int error; 162 1.2 christos 163 1.14 njoly error = clock_getres1(SCARG(uap, clock_id), &ats); 164 1.14 njoly if (error != 0) 165 1.14 njoly return error; 166 1.14 njoly 167 1.14 njoly if (SCARG(uap, tp)) { 168 1.14 njoly timespec_to_timespec50(&ats, &ats50); 169 1.14 njoly error = copyout(&ats50, SCARG(uap, tp), sizeof(ats50)); 170 1.2 christos } 171 1.2 christos 172 1.2 christos return error; 173 1.2 christos } 174 1.2 christos 175 1.2 christos /* ARGSUSED */ 176 1.2 christos int 177 1.2 christos compat_50_sys_nanosleep(struct lwp *l, 178 1.2 christos const struct compat_50_sys_nanosleep_args *uap, register_t *retval) 179 1.2 christos { 180 1.2 christos /* { 181 1.2 christos syscallarg(struct timespec50 *) rqtp; 182 1.2 christos syscallarg(struct timespec50 *) rmtp; 183 1.2 christos } */ 184 1.2 christos struct timespec rmt, rqt; 185 1.2 christos struct timespec50 rmt50, rqt50; 186 1.2 christos int error, error1; 187 1.2 christos 188 1.2 christos error = copyin(SCARG(uap, rqtp), &rqt50, sizeof(rqt50)); 189 1.2 christos if (error) 190 1.2 christos return error; 191 1.2 christos timespec50_to_timespec(&rqt50, &rqt); 192 1.2 christos 193 1.23 christos error = nanosleep1(l, CLOCK_MONOTONIC, 0, &rqt, 194 1.23 christos SCARG(uap, rmtp) ? &rmt : NULL); 195 1.2 christos if (SCARG(uap, rmtp) == NULL || (error != 0 && error != EINTR)) 196 1.2 christos return error; 197 1.2 christos 198 1.2 christos timespec_to_timespec50(&rmt, &rmt50); 199 1.2 christos error1 = copyout(&rmt50, SCARG(uap, rmtp), sizeof(*SCARG(uap, rmtp))); 200 1.2 christos return error1 ? error1 : error; 201 1.2 christos } 202 1.2 christos 203 1.2 christos /* ARGSUSED */ 204 1.2 christos int 205 1.2 christos compat_50_sys_gettimeofday(struct lwp *l, 206 1.2 christos const struct compat_50_sys_gettimeofday_args *uap, register_t *retval) 207 1.2 christos { 208 1.2 christos /* { 209 1.2 christos syscallarg(struct timeval50 *) tp; 210 1.2 christos syscallarg(void *) tzp; really "struct timezone *"; 211 1.2 christos } */ 212 1.2 christos struct timeval atv; 213 1.2 christos struct timeval50 atv50; 214 1.2 christos int error = 0; 215 1.2 christos struct timezone tzfake; 216 1.2 christos 217 1.2 christos if (SCARG(uap, tp)) { 218 1.2 christos microtime(&atv); 219 1.2 christos timeval_to_timeval50(&atv, &atv50); 220 1.2 christos error = copyout(&atv50, SCARG(uap, tp), sizeof(*SCARG(uap, tp))); 221 1.2 christos if (error) 222 1.2 christos return error; 223 1.2 christos } 224 1.2 christos if (SCARG(uap, tzp)) { 225 1.2 christos /* 226 1.2 christos * NetBSD has no kernel notion of time zone, so we just 227 1.2 christos * fake up a timezone struct and return it if demanded. 228 1.2 christos */ 229 1.37 riastrad memset(&tzfake, 0, sizeof(tzfake)); 230 1.2 christos tzfake.tz_minuteswest = 0; 231 1.2 christos tzfake.tz_dsttime = 0; 232 1.2 christos error = copyout(&tzfake, SCARG(uap, tzp), sizeof(tzfake)); 233 1.2 christos } 234 1.2 christos return error; 235 1.2 christos } 236 1.2 christos 237 1.2 christos /* ARGSUSED */ 238 1.2 christos int 239 1.2 christos compat_50_sys_settimeofday(struct lwp *l, 240 1.2 christos const struct compat_50_sys_settimeofday_args *uap, register_t *retval) 241 1.2 christos { 242 1.2 christos /* { 243 1.2 christos syscallarg(const struct timeval50 *) tv; 244 1.2 christos syscallarg(const void *) tzp; really "const struct timezone *"; 245 1.2 christos } */ 246 1.2 christos struct timeval50 atv50; 247 1.2 christos struct timeval atv; 248 1.2 christos int error = copyin(SCARG(uap, tv), &atv50, sizeof(atv50)); 249 1.2 christos if (error) 250 1.2 christos return error; 251 1.2 christos timeval50_to_timeval(&atv50, &atv); 252 1.2 christos return settimeofday1(&atv, false, SCARG(uap, tzp), l, true); 253 1.2 christos } 254 1.2 christos 255 1.2 christos /* ARGSUSED */ 256 1.2 christos int 257 1.2 christos compat_50_sys_adjtime(struct lwp *l, 258 1.2 christos const struct compat_50_sys_adjtime_args *uap, register_t *retval) 259 1.2 christos { 260 1.2 christos /* { 261 1.2 christos syscallarg(const struct timeval50 *) delta; 262 1.2 christos syscallarg(struct timeval50 *) olddelta; 263 1.2 christos } */ 264 1.2 christos int error; 265 1.2 christos struct timeval50 delta50, olddelta50; 266 1.2 christos struct timeval delta, olddelta; 267 1.2 christos 268 1.2 christos if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME, 269 1.2 christos KAUTH_REQ_SYSTEM_TIME_ADJTIME, NULL, NULL, NULL)) != 0) 270 1.2 christos return error; 271 1.2 christos 272 1.2 christos if (SCARG(uap, delta)) { 273 1.2 christos error = copyin(SCARG(uap, delta), &delta50, 274 1.2 christos sizeof(*SCARG(uap, delta))); 275 1.2 christos if (error) 276 1.2 christos return (error); 277 1.2 christos timeval50_to_timeval(&delta50, &delta); 278 1.2 christos } 279 1.2 christos adjtime1(SCARG(uap, delta) ? &delta : NULL, 280 1.2 christos SCARG(uap, olddelta) ? &olddelta : NULL, l->l_proc); 281 1.2 christos if (SCARG(uap, olddelta)) { 282 1.2 christos timeval_to_timeval50(&olddelta, &olddelta50); 283 1.2 christos error = copyout(&olddelta50, SCARG(uap, olddelta), 284 1.2 christos sizeof(*SCARG(uap, olddelta))); 285 1.2 christos } 286 1.2 christos return error; 287 1.2 christos } 288 1.2 christos 289 1.2 christos /* BSD routine to set/arm an interval timer. */ 290 1.2 christos /* ARGSUSED */ 291 1.2 christos int 292 1.2 christos compat_50_sys_getitimer(struct lwp *l, 293 1.2 christos const struct compat_50_sys_getitimer_args *uap, register_t *retval) 294 1.2 christos { 295 1.2 christos /* { 296 1.2 christos syscallarg(int) which; 297 1.2 christos syscallarg(struct itimerval50 *) itv; 298 1.2 christos } */ 299 1.2 christos struct proc *p = l->l_proc; 300 1.2 christos struct itimerval aitv; 301 1.2 christos struct itimerval50 aitv50; 302 1.2 christos int error; 303 1.2 christos 304 1.2 christos error = dogetitimer(p, SCARG(uap, which), &aitv); 305 1.2 christos if (error) 306 1.2 christos return error; 307 1.2 christos itimerval_to_itimerval50(&aitv, &aitv50); 308 1.2 christos return copyout(&aitv50, SCARG(uap, itv), sizeof(*SCARG(uap, itv))); 309 1.2 christos } 310 1.2 christos 311 1.2 christos int 312 1.2 christos compat_50_sys_setitimer(struct lwp *l, 313 1.2 christos const struct compat_50_sys_setitimer_args *uap, register_t *retval) 314 1.2 christos { 315 1.2 christos /* { 316 1.2 christos syscallarg(int) which; 317 1.2 christos syscallarg(const struct itimerval50 *) itv; 318 1.2 christos syscallarg(struct itimerval50 *) oitv; 319 1.2 christos } */ 320 1.2 christos struct proc *p = l->l_proc; 321 1.2 christos int which = SCARG(uap, which); 322 1.2 christos struct compat_50_sys_getitimer_args getargs; 323 1.2 christos const struct itimerval50 *itvp; 324 1.2 christos struct itimerval50 aitv50; 325 1.2 christos struct itimerval aitv; 326 1.2 christos int error; 327 1.2 christos 328 1.2 christos itvp = SCARG(uap, itv); 329 1.2 christos if (itvp && 330 1.31 christos (error = copyin(itvp, &aitv50, sizeof(aitv50))) != 0) 331 1.2 christos return (error); 332 1.2 christos itimerval50_to_itimerval(&aitv50, &aitv); 333 1.2 christos if (SCARG(uap, oitv) != NULL) { 334 1.2 christos SCARG(&getargs, which) = which; 335 1.2 christos SCARG(&getargs, itv) = SCARG(uap, oitv); 336 1.2 christos if ((error = compat_50_sys_getitimer(l, &getargs, retval)) != 0) 337 1.2 christos return (error); 338 1.2 christos } 339 1.2 christos if (itvp == 0) 340 1.2 christos return (0); 341 1.2 christos 342 1.2 christos return dosetitimer(p, which, &aitv); 343 1.2 christos } 344 1.2 christos 345 1.2 christos int 346 1.2 christos compat_50_sys_aio_suspend(struct lwp *l, 347 1.2 christos const struct compat_50_sys_aio_suspend_args *uap, register_t *retval) 348 1.2 christos { 349 1.2 christos /* { 350 1.2 christos syscallarg(const struct aiocb *const[]) list; 351 1.2 christos syscallarg(int) nent; 352 1.2 christos syscallarg(const struct timespec50 *) timeout; 353 1.2 christos } */ 354 1.8 rmind #ifdef AIO 355 1.2 christos struct aiocb **list; 356 1.2 christos struct timespec ts; 357 1.2 christos struct timespec50 ts50; 358 1.2 christos int error, nent; 359 1.2 christos 360 1.2 christos nent = SCARG(uap, nent); 361 1.2 christos if (nent <= 0 || nent > aio_listio_max) 362 1.2 christos return EAGAIN; 363 1.2 christos 364 1.2 christos if (SCARG(uap, timeout)) { 365 1.2 christos /* Convert timespec to ticks */ 366 1.2 christos error = copyin(SCARG(uap, timeout), &ts50, 367 1.2 christos sizeof(*SCARG(uap, timeout))); 368 1.2 christos if (error) 369 1.2 christos return error; 370 1.2 christos timespec50_to_timespec(&ts50, &ts); 371 1.2 christos } 372 1.10 yamt list = kmem_alloc(nent * sizeof(*list), KM_SLEEP); 373 1.10 yamt error = copyin(SCARG(uap, list), list, nent * sizeof(*list)); 374 1.2 christos if (error) 375 1.2 christos goto out; 376 1.2 christos error = aio_suspend1(l, list, nent, SCARG(uap, timeout) ? &ts : NULL); 377 1.2 christos out: 378 1.10 yamt kmem_free(list, nent * sizeof(*list)); 379 1.2 christos return error; 380 1.2 christos #else 381 1.2 christos return ENOSYS; 382 1.2 christos #endif 383 1.2 christos } 384 1.2 christos 385 1.2 christos int 386 1.2 christos compat_50_sys_mq_timedsend(struct lwp *l, 387 1.2 christos const struct compat_50_sys_mq_timedsend_args *uap, register_t *retval) 388 1.2 christos { 389 1.2 christos /* { 390 1.2 christos syscallarg(mqd_t) mqdes; 391 1.2 christos syscallarg(const char *) msg_ptr; 392 1.2 christos syscallarg(size_t) msg_len; 393 1.2 christos syscallarg(unsigned) msg_prio; 394 1.2 christos syscallarg(const struct timespec50 *) abs_timeout; 395 1.2 christos } */ 396 1.8 rmind #ifdef MQUEUE 397 1.9 rmind struct timespec50 ts50; 398 1.9 rmind struct timespec ts, *tsp; 399 1.2 christos int error; 400 1.2 christos 401 1.2 christos /* Get and convert time value */ 402 1.2 christos if (SCARG(uap, abs_timeout)) { 403 1.2 christos error = copyin(SCARG(uap, abs_timeout), &ts50, sizeof(ts50)); 404 1.2 christos if (error) 405 1.2 christos return error; 406 1.2 christos timespec50_to_timespec(&ts50, &ts); 407 1.9 rmind tsp = &ts; 408 1.9 rmind } else { 409 1.9 rmind tsp = NULL; 410 1.9 rmind } 411 1.2 christos 412 1.9 rmind return mq_send1(SCARG(uap, mqdes), SCARG(uap, msg_ptr), 413 1.9 rmind SCARG(uap, msg_len), SCARG(uap, msg_prio), tsp); 414 1.8 rmind #else 415 1.8 rmind return ENOSYS; 416 1.8 rmind #endif 417 1.2 christos } 418 1.2 christos 419 1.2 christos int 420 1.2 christos compat_50_sys_mq_timedreceive(struct lwp *l, 421 1.2 christos const struct compat_50_sys_mq_timedreceive_args *uap, register_t *retval) 422 1.2 christos { 423 1.2 christos /* { 424 1.2 christos syscallarg(mqd_t) mqdes; 425 1.2 christos syscallarg(char *) msg_ptr; 426 1.2 christos syscallarg(size_t) msg_len; 427 1.2 christos syscallarg(unsigned *) msg_prio; 428 1.2 christos syscallarg(const struct timespec50 *) abs_timeout; 429 1.2 christos } */ 430 1.8 rmind #ifdef MQUEUE 431 1.9 rmind struct timespec ts, *tsp; 432 1.9 rmind struct timespec50 ts50; 433 1.2 christos ssize_t mlen; 434 1.9 rmind int error; 435 1.2 christos 436 1.2 christos /* Get and convert time value */ 437 1.2 christos if (SCARG(uap, abs_timeout)) { 438 1.2 christos error = copyin(SCARG(uap, abs_timeout), &ts50, sizeof(ts50)); 439 1.2 christos if (error) 440 1.2 christos return error; 441 1.2 christos 442 1.2 christos timespec50_to_timespec(&ts50, &ts); 443 1.9 rmind tsp = &ts; 444 1.9 rmind } else { 445 1.9 rmind tsp = NULL; 446 1.9 rmind } 447 1.2 christos 448 1.9 rmind error = mq_recv1(SCARG(uap, mqdes), SCARG(uap, msg_ptr), 449 1.9 rmind SCARG(uap, msg_len), SCARG(uap, msg_prio), tsp, &mlen); 450 1.2 christos if (error == 0) 451 1.2 christos *retval = mlen; 452 1.2 christos 453 1.2 christos return error; 454 1.8 rmind #else 455 1.8 rmind return ENOSYS; 456 1.8 rmind #endif 457 1.2 christos } 458 1.2 christos 459 1.2 christos int 460 1.2 christos compat_50_sys_getrusage(struct lwp *l, 461 1.2 christos const struct compat_50_sys_getrusage_args *uap, register_t *retval) 462 1.2 christos { 463 1.2 christos /* { 464 1.2 christos syscallarg(int) who; 465 1.2 christos syscallarg(struct rusage50 *) rusage; 466 1.2 christos } */ 467 1.24 njoly int error; 468 1.2 christos struct rusage ru; 469 1.2 christos struct rusage50 ru50; 470 1.2 christos struct proc *p = l->l_proc; 471 1.2 christos 472 1.24 njoly error = getrusage1(p, SCARG(uap, who), &ru); 473 1.24 njoly if (error != 0) 474 1.24 njoly return error; 475 1.2 christos 476 1.2 christos rusage_to_rusage50(&ru, &ru50); 477 1.2 christos return copyout(&ru50, SCARG(uap, rusage), sizeof(ru50)); 478 1.2 christos } 479 1.2 christos 480 1.2 christos 481 1.2 christos /* Return the time remaining until a POSIX timer fires. */ 482 1.2 christos int 483 1.2 christos compat_50_sys_timer_gettime(struct lwp *l, 484 1.2 christos const struct compat_50_sys_timer_gettime_args *uap, register_t *retval) 485 1.2 christos { 486 1.2 christos /* { 487 1.2 christos syscallarg(timer_t) timerid; 488 1.2 christos syscallarg(struct itimerspec50 *) value; 489 1.2 christos } */ 490 1.2 christos struct itimerspec its; 491 1.2 christos struct itimerspec50 its50; 492 1.2 christos int error; 493 1.2 christos 494 1.2 christos if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, 495 1.2 christos &its)) != 0) 496 1.2 christos return error; 497 1.2 christos itimerspec_to_itimerspec50(&its, &its50); 498 1.2 christos 499 1.2 christos return copyout(&its50, SCARG(uap, value), sizeof(its50)); 500 1.2 christos } 501 1.2 christos 502 1.2 christos /* Set and arm a POSIX realtime timer */ 503 1.2 christos int 504 1.2 christos compat_50_sys_timer_settime(struct lwp *l, 505 1.2 christos const struct compat_50_sys_timer_settime_args *uap, register_t *retval) 506 1.2 christos { 507 1.2 christos /* { 508 1.2 christos syscallarg(timer_t) timerid; 509 1.2 christos syscallarg(int) flags; 510 1.2 christos syscallarg(const struct itimerspec50 *) value; 511 1.2 christos syscallarg(struct itimerspec50 *) ovalue; 512 1.2 christos } */ 513 1.2 christos int error; 514 1.2 christos struct itimerspec value, ovalue, *ovp = NULL; 515 1.2 christos struct itimerspec50 value50, ovalue50; 516 1.2 christos 517 1.2 christos if ((error = copyin(SCARG(uap, value), &value50, sizeof(value50))) != 0) 518 1.2 christos return error; 519 1.2 christos 520 1.2 christos itimerspec50_to_itimerspec(&value50, &value); 521 1.2 christos if (SCARG(uap, ovalue)) 522 1.2 christos ovp = &ovalue; 523 1.2 christos 524 1.2 christos if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp, 525 1.2 christos SCARG(uap, flags), l->l_proc)) != 0) 526 1.2 christos return error; 527 1.2 christos 528 1.2 christos if (ovp) { 529 1.2 christos itimerspec_to_itimerspec50(&ovalue, &ovalue50); 530 1.2 christos return copyout(&ovalue50, SCARG(uap, ovalue), sizeof(ovalue50)); 531 1.2 christos } 532 1.2 christos return 0; 533 1.2 christos } 534 1.2 christos 535 1.2 christos /* 536 1.2 christos * ntp_gettime() - NTP user application interface 537 1.2 christos */ 538 1.2 christos int 539 1.2 christos compat_50_sys___ntp_gettime30(struct lwp *l, 540 1.2 christos const struct compat_50_sys___ntp_gettime30_args *uap, register_t *retval) 541 1.2 christos { 542 1.33 pgoyette if (vec_ntp_gettime == NULL) 543 1.33 pgoyette return ENOSYS; /* No NTP available in kernel */ 544 1.33 pgoyette 545 1.2 christos /* { 546 1.2 christos syscallarg(struct ntptimeval *) ntvp; 547 1.2 christos } */ 548 1.2 christos struct ntptimeval ntv; 549 1.2 christos struct ntptimeval50 ntv50; 550 1.2 christos int error; 551 1.2 christos 552 1.2 christos if (SCARG(uap, ntvp)) { 553 1.33 pgoyette (*vec_ntp_gettime)(&ntv); 554 1.32 riastrad memset(&ntv50, 0, sizeof(ntv50)); 555 1.2 christos timespec_to_timespec50(&ntv.time, &ntv50.time); 556 1.2 christos ntv50.maxerror = ntv.maxerror; 557 1.2 christos ntv50.esterror = ntv.esterror; 558 1.2 christos ntv50.tai = ntv.tai; 559 1.2 christos ntv50.time_state = ntv.time_state; 560 1.2 christos 561 1.2 christos error = copyout(&ntv50, SCARG(uap, ntvp), sizeof(ntv50)); 562 1.2 christos if (error) 563 1.2 christos return error; 564 1.2 christos } 565 1.33 pgoyette *retval = (*vec_ntp_timestatus)(); 566 1.2 christos return 0; 567 1.2 christos } 568 1.25 pgoyette 569 1.35 pgoyette SYSCTL_SETUP(compat_sysctl_time, "Old system boottime") 570 1.25 pgoyette { 571 1.25 pgoyette struct timeval tv; 572 1.25 pgoyette 573 1.34 thorpej getmicroboottime(&tv); 574 1.25 pgoyette timeval_to_timeval50(&tv, &boottime50); 575 1.25 pgoyette 576 1.25 pgoyette sysctl_createv(clog, 0, NULL, NULL, 577 1.25 pgoyette CTLFLAG_PERMANENT, 578 1.25 pgoyette CTLTYPE_STRUCT, "oboottime", 579 1.25 pgoyette SYSCTL_DESCR("System boot time"), 580 1.25 pgoyette NULL, 0, &boottime50, sizeof(boottime50), 581 1.25 pgoyette CTL_KERN, KERN_OBOOTTIME, CTL_EOL); 582 1.25 pgoyette } 583 1.33 pgoyette 584 1.33 pgoyette int 585 1.33 pgoyette kern_time_50_init(void) 586 1.33 pgoyette { 587 1.33 pgoyette int error; 588 1.33 pgoyette 589 1.33 pgoyette error = syscall_establish(NULL, kern_time_50_syscalls); 590 1.33 pgoyette 591 1.33 pgoyette return error; 592 1.33 pgoyette } 593 1.33 pgoyette 594 1.33 pgoyette int 595 1.33 pgoyette kern_time_50_fini(void) 596 1.33 pgoyette { 597 1.33 pgoyette int error; 598 1.33 pgoyette 599 1.33 pgoyette error = syscall_disestablish(NULL, kern_time_50_syscalls); 600 1.33 pgoyette 601 1.33 pgoyette return error; 602 1.33 pgoyette } 603