1 /* $NetBSD: kern_time_50.c,v 1.11 2009/11/04 21:23:02 rmind Exp $ */
4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: kern_time_50.c,v 1.11 2009/11/04 21:23:02 rmind Exp $");
37 #include "opt_mqueue.h"
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/namei.h>
43 #include <sys/filedesc.h>
44 #include <sys/kernel.h>
47 #include <sys/socketvar.h>
48 #include <sys/vnode.h>
49 #include <sys/mount.h>
52 #include <sys/dirent.h>
53 #include <sys/malloc.h>
54 #include <sys/kauth.h>
56 #include <sys/timex.h>
57 #include <sys/timetc.h>
60 #include <sys/syscallargs.h>
61 #include <sys/resource.h>
63 #include <compat/common/compat_util.h>
64 #include <compat/sys/time.h>
65 #include <compat/sys/timex.h>
66 #include <compat/sys/resource.h>
67 #include <compat/sys/clockctl.h>
70 compat_50_kevent_fetch_timeout(const void *src
, void *dest
, size_t length
)
72 struct timespec50 ts50
;
75 KASSERT(length
== sizeof(struct timespec
));
77 error
= copyin(src
, &ts50
, sizeof(ts50
));
80 timespec50_to_timespec(&ts50
, (struct timespec
*)dest
);
85 compat_50_sys_kevent(struct lwp
*l
, const struct compat_50_sys_kevent_args
*uap
,
90 syscallarg(keventp_t) changelist;
91 syscallarg(size_t) nchanges;
92 syscallarg(keventp_t) eventlist;
93 syscallarg(size_t) nevents;
94 syscallarg(struct timespec50) timeout;
96 static const struct kevent_ops compat_50_kevent_ops
= {
98 .keo_fetch_timeout
= compat_50_kevent_fetch_timeout
,
99 .keo_fetch_changes
= kevent_fetch_changes
,
100 .keo_put_events
= kevent_put_events
,
103 return kevent1(retval
, SCARG(uap
, fd
), SCARG(uap
, changelist
),
104 SCARG(uap
, nchanges
), SCARG(uap
, eventlist
), SCARG(uap
, nevents
),
105 (const struct timespec
*)(const void *)SCARG(uap
, timeout
),
106 &compat_50_kevent_ops
);
110 compat_50_sys_clock_gettime(struct lwp
*l
,
111 const struct compat_50_sys_clock_gettime_args
*uap
, register_t
*retval
)
114 syscallarg(clockid_t) clock_id;
115 syscallarg(struct timespec50 *) tp;
119 struct timespec50 ats50
;
121 clock_id
= SCARG(uap
, clock_id
);
126 case CLOCK_MONOTONIC
:
132 timespec_to_timespec50(&ats
, &ats50
);
134 return copyout(&ats50
, SCARG(uap
, tp
), sizeof(ats50
));
139 compat_50_sys_clock_settime(struct lwp
*l
,
140 const struct compat_50_sys_clock_settime_args
*uap
, register_t
*retval
)
143 syscallarg(clockid_t) clock_id;
144 syscallarg(const struct timespec50 *) tp;
148 struct timespec50 ats50
;
150 error
= copyin(SCARG(uap
, tp
), &ats50
, sizeof(ats50
));
153 timespec50_to_timespec(&ats50
, &ats
);
155 return clock_settime1(l
->l_proc
, SCARG(uap
, clock_id
), &ats
,
161 compat_50_sys_clock_getres(struct lwp
*l
,
162 const struct compat_50_sys_clock_getres_args
*uap
, register_t
*retval
)
165 syscallarg(clockid_t) clock_id;
166 syscallarg(struct timespec50 *) tp;
169 struct timespec50 ats50
;
172 clock_id
= SCARG(uap
, clock_id
);
175 case CLOCK_MONOTONIC
:
177 if (tc_getfrequency() > 1000000000)
180 ats50
.tv_nsec
= 1000000000 / tc_getfrequency();
187 error
= copyout(&ats50
, SCARG(uap
, tp
), sizeof(*SCARG(uap
, tp
)));
194 compat_50_sys_nanosleep(struct lwp
*l
,
195 const struct compat_50_sys_nanosleep_args
*uap
, register_t
*retval
)
198 syscallarg(struct timespec50 *) rqtp;
199 syscallarg(struct timespec50 *) rmtp;
201 struct timespec rmt
, rqt
;
202 struct timespec50 rmt50
, rqt50
;
205 error
= copyin(SCARG(uap
, rqtp
), &rqt50
, sizeof(rqt50
));
208 timespec50_to_timespec(&rqt50
, &rqt
);
210 error
= nanosleep1(l
, &rqt
, SCARG(uap
, rmtp
) ? &rmt
: NULL
);
211 if (SCARG(uap
, rmtp
) == NULL
|| (error
!= 0 && error
!= EINTR
))
214 timespec_to_timespec50(&rmt
, &rmt50
);
215 error1
= copyout(&rmt50
, SCARG(uap
, rmtp
), sizeof(*SCARG(uap
, rmtp
)));
216 return error1
? error1
: error
;
221 compat_50_sys_gettimeofday(struct lwp
*l
,
222 const struct compat_50_sys_gettimeofday_args
*uap
, register_t
*retval
)
225 syscallarg(struct timeval50 *) tp;
226 syscallarg(void *) tzp; really "struct timezone *";
229 struct timeval50 atv50
;
231 struct timezone tzfake
;
233 if (SCARG(uap
, tp
)) {
235 timeval_to_timeval50(&atv
, &atv50
);
236 error
= copyout(&atv50
, SCARG(uap
, tp
), sizeof(*SCARG(uap
, tp
)));
240 if (SCARG(uap
, tzp
)) {
242 * NetBSD has no kernel notion of time zone, so we just
243 * fake up a timezone struct and return it if demanded.
245 tzfake
.tz_minuteswest
= 0;
246 tzfake
.tz_dsttime
= 0;
247 error
= copyout(&tzfake
, SCARG(uap
, tzp
), sizeof(tzfake
));
254 compat_50_sys_settimeofday(struct lwp
*l
,
255 const struct compat_50_sys_settimeofday_args
*uap
, register_t
*retval
)
258 syscallarg(const struct timeval50 *) tv;
259 syscallarg(const void *) tzp; really "const struct timezone *";
261 struct timeval50 atv50
;
263 int error
= copyin(SCARG(uap
, tv
), &atv50
, sizeof(atv50
));
266 timeval50_to_timeval(&atv50
, &atv
);
267 return settimeofday1(&atv
, false, SCARG(uap
, tzp
), l
, true);
272 compat_50_sys_adjtime(struct lwp
*l
,
273 const struct compat_50_sys_adjtime_args
*uap
, register_t
*retval
)
276 syscallarg(const struct timeval50 *) delta;
277 syscallarg(struct timeval50 *) olddelta;
280 struct timeval50 delta50
, olddelta50
;
281 struct timeval delta
, olddelta
;
283 if ((error
= kauth_authorize_system(l
->l_cred
, KAUTH_SYSTEM_TIME
,
284 KAUTH_REQ_SYSTEM_TIME_ADJTIME
, NULL
, NULL
, NULL
)) != 0)
287 if (SCARG(uap
, delta
)) {
288 error
= copyin(SCARG(uap
, delta
), &delta50
,
289 sizeof(*SCARG(uap
, delta
)));
292 timeval50_to_timeval(&delta50
, &delta
);
294 adjtime1(SCARG(uap
, delta
) ? &delta
: NULL
,
295 SCARG(uap
, olddelta
) ? &olddelta
: NULL
, l
->l_proc
);
296 if (SCARG(uap
, olddelta
)) {
297 timeval_to_timeval50(&olddelta
, &olddelta50
);
298 error
= copyout(&olddelta50
, SCARG(uap
, olddelta
),
299 sizeof(*SCARG(uap
, olddelta
)));
304 /* BSD routine to set/arm an interval timer. */
307 compat_50_sys_getitimer(struct lwp
*l
,
308 const struct compat_50_sys_getitimer_args
*uap
, register_t
*retval
)
311 syscallarg(int) which;
312 syscallarg(struct itimerval50 *) itv;
314 struct proc
*p
= l
->l_proc
;
315 struct itimerval aitv
;
316 struct itimerval50 aitv50
;
319 error
= dogetitimer(p
, SCARG(uap
, which
), &aitv
);
322 itimerval_to_itimerval50(&aitv
, &aitv50
);
323 return copyout(&aitv50
, SCARG(uap
, itv
), sizeof(*SCARG(uap
, itv
)));
327 compat_50_sys_setitimer(struct lwp
*l
,
328 const struct compat_50_sys_setitimer_args
*uap
, register_t
*retval
)
331 syscallarg(int) which;
332 syscallarg(const struct itimerval50 *) itv;
333 syscallarg(struct itimerval50 *) oitv;
335 struct proc
*p
= l
->l_proc
;
336 int which
= SCARG(uap
, which
);
337 struct compat_50_sys_getitimer_args getargs
;
338 const struct itimerval50
*itvp
;
339 struct itimerval50 aitv50
;
340 struct itimerval aitv
;
343 if ((u_int
)which
> ITIMER_PROF
)
345 itvp
= SCARG(uap
, itv
);
347 (error
= copyin(itvp
, &aitv50
, sizeof(aitv50
)) != 0))
349 itimerval50_to_itimerval(&aitv50
, &aitv
);
350 if (SCARG(uap
, oitv
) != NULL
) {
351 SCARG(&getargs
, which
) = which
;
352 SCARG(&getargs
, itv
) = SCARG(uap
, oitv
);
353 if ((error
= compat_50_sys_getitimer(l
, &getargs
, retval
)) != 0)
359 return dosetitimer(p
, which
, &aitv
);
363 compat_50_sys_aio_suspend(struct lwp
*l
,
364 const struct compat_50_sys_aio_suspend_args
*uap
, register_t
*retval
)
367 syscallarg(const struct aiocb *const[]) list;
368 syscallarg(int) nent;
369 syscallarg(const struct timespec50 *) timeout;
374 struct timespec50 ts50
;
377 nent
= SCARG(uap
, nent
);
378 if (nent
<= 0 || nent
> aio_listio_max
)
381 if (SCARG(uap
, timeout
)) {
382 /* Convert timespec to ticks */
383 error
= copyin(SCARG(uap
, timeout
), &ts50
,
384 sizeof(*SCARG(uap
, timeout
)));
387 timespec50_to_timespec(&ts50
, &ts
);
389 list
= kmem_alloc(nent
* sizeof(*list
), KM_SLEEP
);
390 error
= copyin(SCARG(uap
, list
), list
, nent
* sizeof(*list
));
393 error
= aio_suspend1(l
, list
, nent
, SCARG(uap
, timeout
) ? &ts
: NULL
);
395 kmem_free(list
, nent
* sizeof(*list
));
403 compat_50_sys_select(struct lwp
*l
,
404 const struct compat_50_sys_select_args
*uap
, register_t
*retval
)
408 syscallarg(fd_set *) in;
409 syscallarg(fd_set *) ou;
410 syscallarg(fd_set *) ex;
411 syscallarg(struct timeval50 *) tv;
413 struct timespec ats
, *ts
= NULL
;
414 struct timeval50 atv50
;
417 if (SCARG(uap
, tv
)) {
418 error
= copyin(SCARG(uap
, tv
), (void *)&atv50
, sizeof(atv50
));
421 ats
.tv_sec
= atv50
.tv_sec
;
422 ats
.tv_nsec
= atv50
.tv_usec
* 1000;
426 return selcommon(retval
, SCARG(uap
, nd
), SCARG(uap
, in
),
427 SCARG(uap
, ou
), SCARG(uap
, ex
), ts
, NULL
);
431 compat_50_sys_pselect(struct lwp
*l
,
432 const struct compat_50_sys_pselect_args
*uap
, register_t
*retval
)
436 syscallarg(fd_set *) in;
437 syscallarg(fd_set *) ou;
438 syscallarg(fd_set *) ex;
439 syscallarg(const struct timespec50 *) ts;
440 syscallarg(sigset_t *) mask;
442 struct timespec50 ats50
;
443 struct timespec ats
, *ts
= NULL
;
444 sigset_t amask
, *mask
= NULL
;
447 if (SCARG(uap
, ts
)) {
448 error
= copyin(SCARG(uap
, ts
), &ats50
, sizeof(ats50
));
451 timespec50_to_timespec(&ats50
, &ats
);
454 if (SCARG(uap
, mask
) != NULL
) {
455 error
= copyin(SCARG(uap
, mask
), &amask
, sizeof(amask
));
461 return selcommon(retval
, SCARG(uap
, nd
), SCARG(uap
, in
),
462 SCARG(uap
, ou
), SCARG(uap
, ex
), ts
, mask
);
465 compat_50_sys_pollts(struct lwp
*l
, const struct compat_50_sys_pollts_args
*uap
,
469 syscallarg(struct pollfd *) fds;
470 syscallarg(u_int) nfds;
471 syscallarg(const struct timespec50 *) ts;
472 syscallarg(const sigset_t *) mask;
474 struct timespec ats
, *ts
= NULL
;
475 struct timespec50 ats50
;
476 sigset_t amask
, *mask
= NULL
;
479 if (SCARG(uap
, ts
)) {
480 error
= copyin(SCARG(uap
, ts
), &ats50
, sizeof(ats50
));
483 timespec50_to_timespec(&ats50
, &ats
);
486 if (SCARG(uap
, mask
)) {
487 error
= copyin(SCARG(uap
, mask
), &amask
, sizeof(amask
));
493 return pollcommon(retval
, SCARG(uap
, fds
), SCARG(uap
, nfds
), ts
, mask
);
497 compat_50_sys__lwp_park(struct lwp
*l
,
498 const struct compat_50_sys__lwp_park_args
*uap
, register_t
*retval
)
501 syscallarg(const struct timespec50 *) ts;
502 syscallarg(lwpid_t) unpark;
503 syscallarg(const void *) hint;
504 syscallarg(const void *) unparkhint;
506 struct timespec ts
, *tsp
;
507 struct timespec50 ts50
;
510 if (SCARG(uap
, ts
) == NULL
)
513 error
= copyin(SCARG(uap
, ts
), &ts50
, sizeof(ts50
));
516 timespec50_to_timespec(&ts50
, &ts
);
520 if (SCARG(uap
, unpark
) != 0) {
521 error
= lwp_unpark(SCARG(uap
, unpark
), SCARG(uap
, unparkhint
));
526 return lwp_park(tsp
, SCARG(uap
, hint
));
530 compat_50_sys_mq_timedsend(struct lwp
*l
,
531 const struct compat_50_sys_mq_timedsend_args
*uap
, register_t
*retval
)
534 syscallarg(mqd_t) mqdes;
535 syscallarg(const char *) msg_ptr;
536 syscallarg(size_t) msg_len;
537 syscallarg(unsigned) msg_prio;
538 syscallarg(const struct timespec50 *) abs_timeout;
541 struct timespec50 ts50
;
542 struct timespec ts
, *tsp
;
545 /* Get and convert time value */
546 if (SCARG(uap
, abs_timeout
)) {
547 error
= copyin(SCARG(uap
, abs_timeout
), &ts50
, sizeof(ts50
));
550 timespec50_to_timespec(&ts50
, &ts
);
556 return mq_send1(SCARG(uap
, mqdes
), SCARG(uap
, msg_ptr
),
557 SCARG(uap
, msg_len
), SCARG(uap
, msg_prio
), tsp
);
564 compat_50_sys_mq_timedreceive(struct lwp
*l
,
565 const struct compat_50_sys_mq_timedreceive_args
*uap
, register_t
*retval
)
568 syscallarg(mqd_t) mqdes;
569 syscallarg(char *) msg_ptr;
570 syscallarg(size_t) msg_len;
571 syscallarg(unsigned *) msg_prio;
572 syscallarg(const struct timespec50 *) abs_timeout;
575 struct timespec ts
, *tsp
;
576 struct timespec50 ts50
;
580 /* Get and convert time value */
581 if (SCARG(uap
, abs_timeout
)) {
582 error
= copyin(SCARG(uap
, abs_timeout
), &ts50
, sizeof(ts50
));
586 timespec50_to_timespec(&ts50
, &ts
);
592 error
= mq_recv1(SCARG(uap
, mqdes
), SCARG(uap
, msg_ptr
),
593 SCARG(uap
, msg_len
), SCARG(uap
, msg_prio
), tsp
, &mlen
);
604 tscopyin(const void *u
, void *s
, size_t len
)
606 struct timespec50 ts50
;
607 KASSERT(len
== sizeof(ts50
));
608 int error
= copyin(u
, &ts50
, len
);
611 timespec50_to_timespec(&ts50
, s
);
616 tscopyout(const void *s
, void *u
, size_t len
)
618 struct timespec50 ts50
;
619 KASSERT(len
== sizeof(ts50
));
620 timespec_to_timespec50(s
, &ts50
);
621 int error
= copyout(&ts50
, u
, len
);
628 compat_50_sys___sigtimedwait(struct lwp
*l
,
629 const struct compat_50_sys___sigtimedwait_args
*uap
, register_t
*retval
)
632 return __sigtimedwait1(l
,
633 (const struct sys_____sigtimedwait50_args
*)uap
, retval
, copyout
,
634 tscopyin
, tscopyout
);
638 rusage_to_rusage50(const struct rusage
*ru
, struct rusage50
*ru50
)
640 (void)memcpy(&ru50
->ru_first
, &ru
->ru_first
,
641 (char *)&ru50
->ru_last
- (char *)&ru50
->ru_first
+
642 sizeof(ru50
->ru_last
));
643 ru50
->ru_maxrss
= ru
->ru_maxrss
;
644 timeval_to_timeval50(&ru
->ru_utime
, &ru50
->ru_utime
);
645 timeval_to_timeval50(&ru
->ru_stime
, &ru50
->ru_stime
);
649 compat_50_sys_getrusage(struct lwp
*l
,
650 const struct compat_50_sys_getrusage_args
*uap
, register_t
*retval
)
654 syscallarg(struct rusage50 *) rusage;
657 struct rusage50 ru50
;
658 struct proc
*p
= l
->l_proc
;
660 switch (SCARG(uap
, who
)) {
662 mutex_enter(p
->p_lock
);
663 memcpy(&ru
, &p
->p_stats
->p_ru
, sizeof(ru
));
664 calcru(p
, &ru
.ru_utime
, &ru
.ru_stime
, NULL
, NULL
);
665 mutex_exit(p
->p_lock
);
668 case RUSAGE_CHILDREN
:
669 mutex_enter(p
->p_lock
);
670 memcpy(&ru
, &p
->p_stats
->p_cru
, sizeof(ru
));
671 mutex_exit(p
->p_lock
);
677 rusage_to_rusage50(&ru
, &ru50
);
678 return copyout(&ru50
, SCARG(uap
, rusage
), sizeof(ru50
));
682 /* Return the time remaining until a POSIX timer fires. */
684 compat_50_sys_timer_gettime(struct lwp
*l
,
685 const struct compat_50_sys_timer_gettime_args
*uap
, register_t
*retval
)
688 syscallarg(timer_t) timerid;
689 syscallarg(struct itimerspec50 *) value;
691 struct itimerspec its
;
692 struct itimerspec50 its50
;
695 if ((error
= dotimer_gettime(SCARG(uap
, timerid
), l
->l_proc
,
698 itimerspec_to_itimerspec50(&its
, &its50
);
700 return copyout(&its50
, SCARG(uap
, value
), sizeof(its50
));
703 /* Set and arm a POSIX realtime timer */
705 compat_50_sys_timer_settime(struct lwp
*l
,
706 const struct compat_50_sys_timer_settime_args
*uap
, register_t
*retval
)
709 syscallarg(timer_t) timerid;
710 syscallarg(int) flags;
711 syscallarg(const struct itimerspec50 *) value;
712 syscallarg(struct itimerspec50 *) ovalue;
715 struct itimerspec value
, ovalue
, *ovp
= NULL
;
716 struct itimerspec50 value50
, ovalue50
;
718 if ((error
= copyin(SCARG(uap
, value
), &value50
, sizeof(value50
))) != 0)
721 itimerspec50_to_itimerspec(&value50
, &value
);
722 if (SCARG(uap
, ovalue
))
725 if ((error
= dotimer_settime(SCARG(uap
, timerid
), &value
, ovp
,
726 SCARG(uap
, flags
), l
->l_proc
)) != 0)
730 itimerspec_to_itimerspec50(&ovalue
, &ovalue50
);
731 return copyout(&ovalue50
, SCARG(uap
, ovalue
), sizeof(ovalue50
));
737 * ntp_gettime() - NTP user application interface
740 compat_50_sys___ntp_gettime30(struct lwp
*l
,
741 const struct compat_50_sys___ntp_gettime30_args
*uap
, register_t
*retval
)
745 syscallarg(struct ntptimeval *) ntvp;
747 struct ntptimeval ntv
;
748 struct ntptimeval50 ntv50
;
751 if (SCARG(uap
, ntvp
)) {
753 timespec_to_timespec50(&ntv
.time
, &ntv50
.time
);
754 ntv50
.maxerror
= ntv
.maxerror
;
755 ntv50
.esterror
= ntv
.esterror
;
757 ntv50
.time_state
= ntv
.time_state
;
759 error
= copyout(&ntv50
, SCARG(uap
, ntvp
), sizeof(ntv50
));
763 *retval
= ntp_timestatus();
770 compat50_clockctlioctl(dev_t dev
, u_long cmd
, void *data
, int flags
,
776 case CLOCKCTL_OSETTIMEOFDAY
: {
777 struct timeval50 tv50
;
779 struct clockctl50_settimeofday
*args
= data
;
781 error
= copyin(args
->tv
, &tv50
, sizeof(tv50
));
784 timeval50_to_timeval(&tv50
, &tv
);
785 error
= settimeofday1(&tv
, false, args
->tzp
, l
, false);
788 case CLOCKCTL_OADJTIME
: {
789 struct timeval atv
, oldatv
;
790 struct timeval50 atv50
;
791 struct clockctl50_adjtime
*args
= data
;
794 error
= copyin(args
->delta
, &atv50
, sizeof(atv50
));
797 timeval50_to_timeval(&atv50
, &atv
);
799 adjtime1(args
->delta
? &atv
: NULL
,
800 args
->olddelta
? &oldatv
: NULL
, l
->l_proc
);
801 if (args
->olddelta
) {
802 timeval_to_timeval50(&oldatv
, &atv50
);
803 error
= copyout(&atv50
, args
->olddelta
, sizeof(atv50
));
807 case CLOCKCTL_OCLOCK_SETTIME
: {
808 struct timespec50 tp50
;
810 struct clockctl50_clock_settime
*args
= data
;
812 error
= copyin(args
->tp
, &tp50
, sizeof(tp50
));
815 timespec50_to_timespec(&tp50
, &tp
);
816 error
= clock_settime1(l
->l_proc
, args
->clock_id
, &tp
, true);
826 compat_50_sys_wait4(struct lwp
*l
, const struct compat_50_sys_wait4_args
*uap
,
831 syscallarg(int *) status;
832 syscallarg(int) options;
833 syscallarg(struct rusage50 *) rusage;
835 int status
, error
, pid
= SCARG(uap
, pid
);
836 struct rusage50 ru50
;
839 error
= do_sys_wait(&pid
, &status
, SCARG(uap
, options
),
840 SCARG(uap
, rusage
) != NULL
? &ru
: NULL
);
846 if (SCARG(uap
, rusage
)) {
847 rusage_to_rusage50(&ru
, &ru50
);
848 error
= copyout(&ru50
, SCARG(uap
, rusage
), sizeof(ru50
));
851 if (error
== 0 && SCARG(uap
, status
))
852 error
= copyout(&status
, SCARG(uap
, status
), sizeof(status
));