Home | History | Annotate | Line # | Download | only in netbsd32
netbsd32_compat_50.c revision 1.3.2.1
      1  1.3.2.1       jym /*	$NetBSD: netbsd32_compat_50.c,v 1.3.2.1 2009/05/13 17:18:59 jym Exp $	*/
      2      1.2  christos 
      3      1.2  christos /*-
      4      1.2  christos  * Copyright (c) 2008 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  * 3. All advertising materials mentioning features or use of this software
     19      1.2  christos  *    must display the following acknowledgement:
     20      1.2  christos  *        This product includes software developed by the NetBSD
     21      1.2  christos  *        Foundation, Inc. and its contributors.
     22      1.2  christos  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23      1.2  christos  *    contributors may be used to endorse or promote products derived
     24      1.2  christos  *    from this software without specific prior written permission.
     25      1.2  christos  *
     26      1.2  christos  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27      1.2  christos  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28      1.2  christos  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29      1.2  christos  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30      1.2  christos  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31      1.2  christos  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32      1.2  christos  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33      1.2  christos  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34      1.2  christos  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35      1.2  christos  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36      1.2  christos  * POSSIBILITY OF SUCH DAMAGE.
     37      1.2  christos  */
     38      1.2  christos #include <sys/cdefs.h>
     39  1.3.2.1       jym __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_50.c,v 1.3.2.1 2009/05/13 17:18:59 jym Exp $");
     40      1.2  christos 
     41      1.2  christos #if defined(_KERNEL_OPT)
     42      1.2  christos #include "opt_sysv.h"
     43      1.2  christos #endif
     44      1.2  christos 
     45      1.2  christos #include "fs_lfs.h"
     46      1.2  christos 
     47      1.2  christos #include <sys/param.h>
     48      1.2  christos #include <sys/systm.h>
     49      1.2  christos #include <sys/malloc.h>
     50      1.2  christos #include <sys/mount.h>
     51      1.2  christos #include <sys/socket.h>
     52      1.2  christos #include <sys/socketvar.h>
     53      1.2  christos #include <sys/stat.h>
     54      1.2  christos #include <sys/time.h>
     55      1.2  christos #include <sys/ktrace.h>
     56      1.2  christos #include <sys/eventvar.h>
     57      1.2  christos #include <sys/resourcevar.h>
     58      1.2  christos #include <sys/vnode.h>
     59      1.2  christos #include <sys/file.h>
     60      1.2  christos #include <sys/filedesc.h>
     61      1.2  christos #include <sys/poll.h>
     62      1.2  christos #include <sys/namei.h>
     63      1.2  christos #include <sys/statvfs.h>
     64      1.2  christos #include <sys/syscallargs.h>
     65      1.2  christos #include <sys/proc.h>
     66      1.2  christos #include <sys/dirent.h>
     67      1.2  christos #include <sys/kauth.h>
     68      1.2  christos #include <sys/vfs_syscalls.h>
     69      1.2  christos #include <sys/ipc.h>
     70      1.2  christos #include <sys/msg.h>
     71      1.2  christos #include <sys/sem.h>
     72      1.2  christos #include <sys/shm.h>
     73      1.2  christos 
     74      1.2  christos #include <compat/netbsd32/netbsd32.h>
     75      1.2  christos #include <compat/netbsd32/netbsd32_syscallargs.h>
     76      1.2  christos #include <compat/netbsd32/netbsd32_conv.h>
     77      1.2  christos #include <compat/sys/mount.h>
     78      1.2  christos #include <compat/sys/time.h>
     79      1.2  christos 
     80      1.2  christos 
     81      1.2  christos /*
     82      1.2  christos  * Common routine to set access and modification times given a vnode.
     83      1.2  christos  */
     84      1.2  christos static int
     85      1.2  christos get_utimes32(const netbsd32_timeval50p_t *tptr, struct timeval *tv,
     86      1.2  christos     struct timeval **tvp)
     87      1.2  christos {
     88      1.2  christos 	int error;
     89      1.2  christos 	struct netbsd32_timeval50 tv32[2];
     90      1.2  christos 
     91      1.2  christos 	if (tptr == NULL) {
     92      1.2  christos 		*tvp = NULL;
     93      1.2  christos 		return 0;
     94      1.2  christos 	}
     95      1.2  christos 
     96      1.2  christos 	error = copyin(tptr, tv32, sizeof(tv32));
     97      1.2  christos 	if (error)
     98      1.2  christos 		return error;
     99      1.2  christos 	netbsd32_to_timeval50(&tv32[0], &tv[0]);
    100      1.2  christos 	netbsd32_to_timeval50(&tv32[1], &tv[1]);
    101      1.2  christos 
    102      1.2  christos 	*tvp = tv;
    103      1.2  christos 	return 0;
    104      1.2  christos }
    105      1.2  christos 
    106      1.2  christos int
    107      1.2  christos compat_50_netbsd32_mknod(struct lwp *l,
    108      1.2  christos     const struct compat_50_netbsd32_mknod_args *uap, register_t *retval)
    109      1.2  christos {
    110      1.2  christos 	/* {
    111      1.2  christos 		syscallarg(netbsd32_charp) path;
    112      1.2  christos 		syscallarg(mode_t) mode;
    113      1.2  christos 		syscallarg(uint32_t) dev;
    114      1.2  christos 	} */
    115      1.2  christos 	return do_sys_mknod(l, SCARG_P32(uap, path), SCARG(uap, mode),
    116      1.2  christos 	    SCARG(uap, dev), retval);
    117      1.2  christos }
    118      1.2  christos 
    119      1.2  christos int
    120      1.2  christos compat_50_netbsd32_select(struct lwp *l,
    121      1.2  christos     const struct compat_50_netbsd32_select_args *uap, register_t *retval)
    122      1.2  christos {
    123      1.2  christos 	/* {
    124      1.2  christos 		syscallarg(int) nd;
    125      1.2  christos 		syscallarg(netbsd32_fd_setp_t) in;
    126      1.2  christos 		syscallarg(netbsd32_fd_setp_t) ou;
    127      1.2  christos 		syscallarg(netbsd32_fd_setp_t) ex;
    128      1.2  christos 		syscallarg(netbsd32_timeval50p_t) tv;
    129      1.2  christos 	} */
    130      1.2  christos 	int error;
    131      1.2  christos 	struct netbsd32_timeval50 tv32;
    132  1.3.2.1       jym 	struct timespec ats, *ts = NULL;
    133      1.2  christos 
    134      1.2  christos 	if (SCARG_P32(uap, tv)) {
    135      1.2  christos 		error = copyin(SCARG_P32(uap, tv), &tv32, sizeof(tv32));
    136      1.2  christos 		if (error != 0)
    137      1.2  christos 			return error;
    138  1.3.2.1       jym 		ats.tv_sec = tv32.tv_sec;
    139  1.3.2.1       jym 		ats.tv_nsec = tv32.tv_usec * 1000;
    140  1.3.2.1       jym 		ts = &ats;
    141      1.2  christos 	}
    142      1.2  christos 
    143      1.2  christos 	return selcommon(l, retval, SCARG(uap, nd), SCARG_P32(uap, in),
    144  1.3.2.1       jym 	    SCARG_P32(uap, ou), SCARG_P32(uap, ex), ts, NULL);
    145      1.2  christos 	return 0;
    146      1.2  christos }
    147      1.2  christos 
    148      1.2  christos int
    149      1.2  christos compat_50_netbsd32_gettimeofday(struct lwp *l,
    150      1.2  christos     const struct compat_50_netbsd32_gettimeofday_args *uap, register_t *retval)
    151      1.2  christos {
    152      1.2  christos 	/* {
    153      1.2  christos 		syscallarg(netbsd32_timeval50p_t) tp;
    154      1.2  christos 		syscallarg(netbsd32_timezonep_t) tzp;
    155      1.2  christos 	} */
    156      1.2  christos 	struct timeval atv;
    157      1.2  christos 	struct netbsd32_timeval50 tv32;
    158      1.2  christos 	int error = 0;
    159      1.2  christos 	struct netbsd32_timezone tzfake;
    160      1.2  christos 
    161      1.2  christos 	if (SCARG_P32(uap, tp)) {
    162      1.2  christos 		microtime(&atv);
    163      1.2  christos 		netbsd32_from_timeval50(&atv, &tv32);
    164      1.2  christos 		error = copyout(&tv32, SCARG_P32(uap, tp), sizeof(tv32));
    165      1.2  christos 		if (error)
    166      1.2  christos 			return error;
    167      1.2  christos 	}
    168      1.2  christos 	if (SCARG_P32(uap, tzp)) {
    169      1.2  christos 		/*
    170      1.2  christos 		 * NetBSD has no kernel notion of time zone, so we just
    171      1.2  christos 		 * fake up a timezone struct and return it if demanded.
    172      1.2  christos 		 */
    173      1.2  christos 		tzfake.tz_minuteswest = 0;
    174      1.2  christos 		tzfake.tz_dsttime = 0;
    175      1.2  christos 		error = copyout(&tzfake, SCARG_P32(uap, tzp), sizeof(tzfake));
    176      1.2  christos 	}
    177      1.2  christos 	return error;
    178      1.2  christos }
    179      1.2  christos 
    180      1.2  christos int
    181      1.2  christos compat_50_netbsd32_settimeofday(struct lwp *l,
    182      1.2  christos     const struct compat_50_netbsd32_settimeofday_args *uap, register_t *retval)
    183      1.2  christos {
    184      1.2  christos 	/* {
    185      1.2  christos 		syscallarg(const netbsd32_timeval50p_t) tv;
    186      1.2  christos 		syscallarg(const netbsd32_timezonep_t) tzp;
    187      1.2  christos 	} */
    188      1.2  christos 	struct netbsd32_timeval50 atv32;
    189      1.2  christos 	struct timeval atv;
    190      1.2  christos 	struct timespec ats;
    191      1.2  christos 	int error;
    192      1.2  christos 	struct proc *p = l->l_proc;
    193      1.2  christos 
    194      1.2  christos 	/* Verify all parameters before changing time. */
    195      1.2  christos 
    196      1.2  christos 	/*
    197      1.2  christos 	 * NetBSD has no kernel notion of time zone, and only an
    198      1.2  christos 	 * obsolete program would try to set it, so we log a warning.
    199      1.2  christos 	 */
    200      1.2  christos 	if (SCARG_P32(uap, tzp))
    201      1.2  christos 		printf("pid %d attempted to set the "
    202      1.2  christos 		    "(obsolete) kernel time zone\n", p->p_pid);
    203      1.2  christos 
    204      1.2  christos 	if (SCARG_P32(uap, tv) == 0)
    205      1.2  christos 		return 0;
    206      1.2  christos 
    207      1.2  christos 	if ((error = copyin(SCARG_P32(uap, tv), &atv32, sizeof(atv32))) != 0)
    208      1.2  christos 		return error;
    209      1.2  christos 
    210      1.2  christos 	netbsd32_to_timeval50(&atv32, &atv);
    211      1.2  christos 	TIMEVAL_TO_TIMESPEC(&atv, &ats);
    212      1.2  christos 	return settime(p, &ats);
    213      1.2  christos }
    214      1.2  christos 
    215      1.2  christos int
    216      1.2  christos compat_50_netbsd32_utimes(struct lwp *l,
    217      1.2  christos     const struct compat_50_netbsd32_utimes_args *uap, register_t *retval)
    218      1.2  christos {
    219      1.2  christos 	/* {
    220      1.2  christos 		syscallarg(const netbsd32_charp) path;
    221      1.2  christos 		syscallarg(const netbsd32_timeval50p_t) tptr;
    222      1.2  christos 	} */
    223      1.2  christos 	int error;
    224      1.2  christos 	struct timeval tv[2], *tvp;
    225      1.2  christos 
    226      1.2  christos 	error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp);
    227      1.2  christos 	if (error != 0)
    228      1.2  christos 		return error;
    229      1.2  christos 
    230      1.2  christos 	return do_sys_utimes(l, NULL, SCARG_P32(uap, path), FOLLOW,
    231      1.2  christos 	    tvp, UIO_SYSSPACE);
    232      1.2  christos }
    233      1.2  christos 
    234      1.2  christos int
    235      1.2  christos compat_50_netbsd32_adjtime(struct lwp *l,
    236      1.2  christos     const struct compat_50_netbsd32_adjtime_args *uap, register_t *retval)
    237      1.2  christos {
    238      1.2  christos 	/* {
    239      1.2  christos 		syscallarg(const netbsd32_timeval50p_t) delta;
    240      1.2  christos 		syscallarg(netbsd32_timeval50p_t) olddelta;
    241      1.2  christos 	} */
    242      1.2  christos 	struct netbsd32_timeval50 atv;
    243      1.2  christos 	int error;
    244      1.2  christos 
    245      1.2  christos 	extern int time_adjusted;     /* in kern_ntptime.c */
    246      1.2  christos 	extern int64_t time_adjtime;  /* in kern_ntptime.c */
    247      1.2  christos 
    248      1.2  christos 	if ((error = kauth_authorize_system(l->l_cred,
    249      1.2  christos 	    KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_ADJTIME, NULL, NULL,
    250      1.2  christos 	    NULL)) != 0)
    251      1.2  christos 		return (error);
    252      1.2  christos 
    253      1.2  christos 	if (SCARG_P32(uap, olddelta)) {
    254      1.2  christos 		atv.tv_sec = time_adjtime / 1000000;
    255      1.2  christos 		atv.tv_usec = time_adjtime % 1000000;
    256      1.2  christos 		if (atv.tv_usec < 0) {
    257      1.2  christos 			atv.tv_usec += 1000000;
    258      1.2  christos 			atv.tv_sec--;
    259      1.2  christos 		}
    260      1.2  christos 		(void) copyout(&atv,
    261      1.2  christos 			       SCARG_P32(uap, olddelta),
    262      1.2  christos 			       sizeof(atv));
    263      1.2  christos 		if (error)
    264      1.2  christos 			return (error);
    265      1.2  christos 	}
    266      1.2  christos 
    267      1.2  christos 	if (SCARG_P32(uap, delta)) {
    268      1.2  christos 		error = copyin(SCARG_P32(uap, delta), &atv,
    269      1.2  christos 			       sizeof(struct timeval));
    270      1.2  christos 		if (error)
    271      1.2  christos 			return (error);
    272      1.2  christos 
    273      1.2  christos 		time_adjtime = (int64_t)atv.tv_sec * 1000000 + atv.tv_usec;
    274      1.2  christos 
    275      1.2  christos 		if (time_adjtime)
    276      1.2  christos 			/* We need to save the system time during shutdown */
    277      1.2  christos 			time_adjusted |= 1;
    278      1.2  christos 	}
    279      1.2  christos 
    280      1.2  christos 	return 0;
    281      1.2  christos }
    282      1.2  christos 
    283      1.2  christos #if defined(LFS) || !defined(_KERNEL)
    284      1.2  christos int
    285      1.2  christos compat_50_netbsd32_lfs_segwait(struct lwp *l,
    286      1.2  christos     const struct compat_50_netbsd32_lfs_segwait_args *uap, register_t *retval)
    287      1.2  christos {
    288      1.2  christos 	return 0;
    289      1.2  christos }
    290      1.2  christos #endif
    291      1.2  christos 
    292      1.2  christos int
    293      1.2  christos compat_50_netbsd32_futimes(struct lwp *l,
    294      1.2  christos     const struct compat_50_netbsd32_futimes_args *uap, register_t *retval)
    295      1.2  christos {
    296      1.2  christos 	/* {
    297      1.2  christos 		syscallarg(int) fd;
    298      1.2  christos 		syscallarg(const netbsd32_timeval50p_t) tptr;
    299      1.2  christos 	} */
    300      1.2  christos 	int error;
    301      1.2  christos 	file_t *fp;
    302      1.2  christos 	struct timeval tv[2], *tvp;
    303      1.2  christos 
    304      1.2  christos 	error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp);
    305      1.2  christos 	if (error != 0)
    306      1.2  christos 		return error;
    307      1.2  christos 
    308      1.2  christos 	/* fd_getvnode() will use the descriptor for us */
    309      1.2  christos 	if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
    310      1.2  christos 		return error;
    311      1.2  christos 
    312      1.2  christos 	error = do_sys_utimes(l, fp->f_data, NULL, 0, tvp, UIO_SYSSPACE);
    313      1.2  christos 
    314      1.2  christos 	fd_putfile(SCARG(uap, fd));
    315      1.2  christos 	return error;
    316      1.2  christos }
    317      1.2  christos 
    318      1.2  christos int
    319      1.2  christos compat_50_netbsd32_clock_gettime(struct lwp *l,
    320      1.2  christos     const struct compat_50_netbsd32_clock_gettime_args *uap, register_t *retval)
    321      1.2  christos {
    322      1.2  christos 	/* {
    323      1.2  christos 		syscallarg(netbsd32_clockid_t) clock_id;
    324      1.2  christos 		syscallarg(netbsd32_timespec50p_t) tp;
    325      1.2  christos 	} */
    326      1.2  christos 	clockid_t clock_id;
    327      1.2  christos 	struct timespec ats;
    328      1.2  christos 	struct netbsd32_timespec50 ts32;
    329      1.2  christos 
    330      1.2  christos 	clock_id = SCARG(uap, clock_id);
    331      1.2  christos 	if (clock_id != CLOCK_REALTIME)
    332      1.2  christos 		return (EINVAL);
    333      1.2  christos 
    334      1.2  christos 	nanotime(&ats);
    335      1.2  christos 	netbsd32_from_timespec50(&ats, &ts32);
    336      1.2  christos 
    337      1.2  christos 	return copyout(&ts32, SCARG_P32(uap, tp), sizeof(ts32));
    338      1.2  christos }
    339      1.2  christos 
    340      1.2  christos int
    341      1.2  christos compat_50_netbsd32_clock_settime(struct lwp *l,
    342      1.2  christos     const struct compat_50_netbsd32_clock_settime_args *uap, register_t *retval)
    343      1.2  christos {
    344      1.2  christos 	/* {
    345      1.2  christos 		syscallarg(netbsd32_clockid_t) clock_id;
    346      1.2  christos 		syscallarg(const netbsd32_timespec50p_t) tp;
    347      1.2  christos 	} */
    348      1.2  christos 	struct netbsd32_timespec50 ts32;
    349      1.2  christos 	clockid_t clock_id;
    350      1.2  christos 	struct timespec ats;
    351      1.2  christos 	int error;
    352      1.2  christos 
    353      1.2  christos 	clock_id = SCARG(uap, clock_id);
    354      1.2  christos 	if (clock_id != CLOCK_REALTIME)
    355      1.2  christos 		return (EINVAL);
    356      1.2  christos 
    357      1.2  christos 	if ((error = copyin(SCARG_P32(uap, tp), &ts32, sizeof(ts32))) != 0)
    358      1.2  christos 		return (error);
    359      1.2  christos 
    360      1.2  christos 	netbsd32_to_timespec50(&ts32, &ats);
    361      1.2  christos 	return settime(l->l_proc, &ats);
    362      1.2  christos }
    363      1.2  christos 
    364      1.2  christos int
    365      1.2  christos compat_50_netbsd32_clock_getres(struct lwp *l,
    366      1.2  christos     const struct compat_50_netbsd32_clock_getres_args *uap, register_t *retval)
    367      1.2  christos {
    368      1.2  christos 	/* {
    369      1.2  christos 		syscallarg(netbsd32_clockid_t) clock_id;
    370      1.2  christos 		syscallarg(netbsd32_timespec50p_t) tp;
    371      1.2  christos 	} */
    372      1.2  christos 	struct netbsd32_timespec50 ts32;
    373      1.2  christos 	clockid_t clock_id;
    374      1.2  christos 	struct timespec ts;
    375      1.2  christos 	int error = 0;
    376      1.2  christos 
    377      1.2  christos 	clock_id = SCARG(uap, clock_id);
    378      1.2  christos 	if (clock_id != CLOCK_REALTIME)
    379      1.2  christos 		return (EINVAL);
    380      1.2  christos 
    381      1.2  christos 	if (SCARG_P32(uap, tp)) {
    382      1.2  christos 		ts.tv_sec = 0;
    383      1.2  christos 		ts.tv_nsec = 1000000000 / hz;
    384      1.2  christos 
    385      1.2  christos 		netbsd32_from_timespec50(&ts, &ts32);
    386      1.2  christos 		error = copyout(&ts, SCARG_P32(uap, tp), sizeof(ts));
    387      1.2  christos 	}
    388      1.2  christos 
    389      1.2  christos 	return error;
    390      1.2  christos }
    391      1.2  christos 
    392      1.2  christos int
    393      1.2  christos compat_50_netbsd32_timer_settime(struct lwp *l,
    394      1.2  christos     const struct compat_50_netbsd32_timer_settime_args *uap, register_t *retval)
    395      1.2  christos {
    396      1.2  christos 	/* {
    397      1.2  christos 		syscallarg(netbsd32_timer_t) timerid;
    398      1.2  christos 		syscallarg(int) flags;
    399      1.2  christos 		syscallarg(const netbsd32_itimerspec50p_t) value;
    400      1.2  christos 		syscallarg(netbsd32_itimerspec50p_t) ovalue;
    401      1.2  christos 	} */
    402      1.2  christos 	int error;
    403      1.2  christos 	struct itimerspec value, ovalue, *ovp = NULL;
    404      1.2  christos 	struct netbsd32_itimerspec50 its32;
    405      1.2  christos 
    406      1.2  christos 	if ((error = copyin(SCARG_P32(uap, value), &its32, sizeof(its32))) != 0)
    407      1.2  christos 		return (error);
    408      1.2  christos 	netbsd32_to_timespec50(&its32.it_interval, &value.it_interval);
    409      1.2  christos 	netbsd32_to_timespec50(&its32.it_value, &value.it_value);
    410      1.2  christos 
    411      1.2  christos 	if (SCARG_P32(uap, ovalue))
    412      1.2  christos 		ovp = &ovalue;
    413      1.2  christos 
    414      1.2  christos 	if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp,
    415      1.2  christos 	    SCARG(uap, flags), l->l_proc)) != 0)
    416      1.2  christos 		return error;
    417      1.2  christos 
    418      1.2  christos 	if (ovp) {
    419      1.2  christos 		netbsd32_from_timespec50(&ovp->it_interval, &its32.it_interval);
    420      1.2  christos 		netbsd32_from_timespec50(&ovp->it_value, &its32.it_value);
    421      1.2  christos 		return copyout(&its32, SCARG_P32(uap, ovalue), sizeof(its32));
    422      1.2  christos 	}
    423      1.2  christos 	return 0;
    424      1.2  christos }
    425      1.2  christos 
    426      1.2  christos int
    427      1.2  christos compat_50_netbsd32_timer_gettime(struct lwp *l, const struct compat_50_netbsd32_timer_gettime_args *uap, register_t *retval)
    428      1.2  christos {
    429      1.2  christos 	/* {
    430      1.2  christos 		syscallarg(netbsd32_timer_t) timerid;
    431      1.2  christos 		syscallarg(netbsd32_itimerspec50p_t) value;
    432      1.2  christos 	} */
    433      1.2  christos 	int error;
    434      1.2  christos 	struct itimerspec its;
    435      1.2  christos 	struct netbsd32_itimerspec50 its32;
    436      1.2  christos 
    437      1.2  christos 	if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc,
    438      1.2  christos 	    &its)) != 0)
    439      1.2  christos 		return error;
    440      1.2  christos 
    441      1.2  christos 	netbsd32_from_timespec50(&its.it_interval, &its32.it_interval);
    442      1.2  christos 	netbsd32_from_timespec50(&its.it_value, &its32.it_value);
    443      1.2  christos 
    444      1.2  christos 	return copyout(&its32, SCARG_P32(uap, value), sizeof(its32));
    445      1.2  christos }
    446      1.2  christos 
    447      1.2  christos int
    448      1.2  christos compat_50_netbsd32_nanosleep(struct lwp *l,
    449      1.2  christos     const struct compat_50_netbsd32_nanosleep_args *uap, register_t *retval)
    450      1.2  christos {
    451      1.2  christos 	/* {
    452      1.2  christos 		syscallarg(const netbsd32_timespec50p_t) rqtp;
    453      1.2  christos 		syscallarg(netbsd32_timespecp_t) rmtp;
    454      1.2  christos 	} */
    455      1.2  christos 	static int nanowait;
    456      1.2  christos 	struct netbsd32_timespec50 ts32;
    457      1.2  christos 	struct timespec rqt, ctime, rmt;
    458      1.2  christos 	int error, timo;
    459      1.2  christos 
    460      1.2  christos 	error = copyin(SCARG_P32(uap, rqtp), &ts32, sizeof(ts32));
    461      1.2  christos 	if (error)
    462      1.2  christos 		return (error);
    463      1.2  christos 
    464      1.2  christos 	netbsd32_to_timespec50(&ts32, &rqt);
    465      1.2  christos 	if (itimespecfix(&rqt))
    466      1.2  christos 		return (EINVAL);
    467      1.2  christos 
    468      1.2  christos 	getnanotime(&ctime);
    469      1.2  christos 	timespecadd(&rqt, &ctime, &rqt);
    470      1.2  christos 	timo = tshzto(&rqt);
    471      1.2  christos 	/*
    472      1.2  christos 	 * Avoid inadvertantly sleeping forever
    473      1.2  christos 	 */
    474      1.2  christos 	if (timo == 0)
    475      1.2  christos 		timo = 1;
    476      1.2  christos 
    477      1.2  christos 	error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo);
    478      1.2  christos 	if (error == ERESTART)
    479      1.2  christos 		error = EINTR;
    480      1.2  christos 	if (error == EWOULDBLOCK)
    481      1.2  christos 		error = 0;
    482      1.2  christos 
    483      1.2  christos 	if (SCARG_P32(uap, rmtp)) {
    484      1.2  christos 		int error1;
    485      1.2  christos 
    486      1.2  christos 		getnanotime(&rmt);
    487      1.2  christos 
    488      1.2  christos 		timespecsub(&rqt, &rmt, &rmt);
    489      1.2  christos 		if (rmt.tv_sec < 0)
    490      1.2  christos 			timespecclear(&rmt);
    491      1.2  christos 
    492      1.2  christos 		netbsd32_from_timespec50(&rmt, &ts32);
    493      1.2  christos 		error1 = copyout(&ts32, SCARG_P32(uap,rmtp), sizeof(ts32));
    494      1.2  christos 		if (error1)
    495      1.2  christos 			return (error1);
    496      1.2  christos 	}
    497      1.2  christos 
    498      1.2  christos 	return error;
    499      1.2  christos }
    500      1.2  christos 
    501      1.2  christos static int
    502      1.2  christos compat_50_netbsd32_sigtimedwait_put_info(const void *src, void *dst, size_t size)
    503      1.2  christos {
    504      1.2  christos 	const siginfo_t *info = src;
    505      1.2  christos 	siginfo32_t info32;
    506      1.2  christos 
    507      1.2  christos 	netbsd32_si_to_si32(&info32, info);
    508      1.2  christos 
    509      1.2  christos 	return copyout(&info32, dst, sizeof(info32));
    510      1.2  christos }
    511      1.2  christos 
    512      1.2  christos static int
    513      1.2  christos compat_50_netbsd32_sigtimedwait_fetch_timeout(const void *src, void *dst, size_t size)
    514      1.2  christos {
    515      1.2  christos 	struct timespec *ts = dst;
    516      1.2  christos 	struct netbsd32_timespec50 ts32;
    517      1.2  christos 	int error;
    518      1.2  christos 
    519      1.2  christos 	error = copyin(src, &ts32, sizeof(ts32));
    520      1.2  christos 	if (error)
    521      1.2  christos 		return error;
    522      1.2  christos 
    523      1.2  christos 	netbsd32_to_timespec50(&ts32, ts);
    524      1.2  christos 	return 0;
    525      1.2  christos }
    526      1.2  christos 
    527      1.2  christos static int
    528      1.2  christos compat_50_netbsd32_sigtimedwait_put_timeout(const void *src, void *dst, size_t size)
    529      1.2  christos {
    530      1.2  christos 	const struct timespec *ts = src;
    531      1.2  christos 	struct netbsd32_timespec50 ts32;
    532      1.2  christos 
    533      1.2  christos 	netbsd32_from_timespec50(ts, &ts32);
    534      1.2  christos 
    535      1.2  christos 	return copyout(&ts32, dst, sizeof(ts32));
    536      1.2  christos }
    537      1.2  christos 
    538      1.2  christos int
    539      1.2  christos compat_50_netbsd32___sigtimedwait(struct lwp *l,
    540      1.2  christos     const struct compat_50_netbsd32___sigtimedwait_args *uap, register_t *retval)
    541      1.2  christos {
    542      1.2  christos 	/* {
    543      1.2  christos 		syscallarg(netbsd32_sigsetp_t) set;
    544      1.2  christos 		syscallarg(netbsd32_siginfop_t) info;
    545      1.2  christos 		syscallarg(netbsd32_timespec50p_t) timeout;
    546      1.2  christos 	} */
    547      1.2  christos 	struct sys_____sigtimedwait50_args ua;
    548      1.2  christos 
    549      1.2  christos 	NETBSD32TOP_UAP(set, const sigset_t);
    550      1.2  christos 	NETBSD32TOP_UAP(info, siginfo_t);
    551      1.2  christos 	NETBSD32TOP_UAP(timeout, struct timespec);
    552      1.2  christos 
    553      1.2  christos 	return __sigtimedwait1(l, &ua, retval,
    554      1.2  christos 	    compat_50_netbsd32_sigtimedwait_put_info,
    555      1.2  christos 	    compat_50_netbsd32_sigtimedwait_fetch_timeout,
    556      1.2  christos 	    compat_50_netbsd32_sigtimedwait_put_timeout);
    557      1.2  christos 	return 0;
    558      1.2  christos }
    559      1.2  christos 
    560      1.2  christos int
    561      1.2  christos compat_50_netbsd32_lutimes(struct lwp *l,
    562      1.2  christos     const struct compat_50_netbsd32_lutimes_args *uap, register_t *retval)
    563      1.2  christos {
    564      1.2  christos 	/* {
    565      1.2  christos 		syscallarg(const netbsd32_charp) path;
    566      1.2  christos 		syscallarg(const netbsd32_timeval50p_t) tptr;
    567      1.2  christos 	} */
    568      1.2  christos 	int error;
    569      1.2  christos 	struct timeval tv[2], *tvp;
    570      1.2  christos 
    571      1.2  christos 	error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp);
    572      1.2  christos 	if (error != 0)
    573      1.2  christos 		return error;
    574      1.2  christos 
    575      1.2  christos 	return do_sys_utimes(l, NULL, SCARG_P32(uap, path), NOFOLLOW,
    576      1.2  christos 	    tvp, UIO_SYSSPACE);
    577      1.2  christos }
    578      1.2  christos 
    579      1.2  christos int
    580      1.2  christos compat_50_netbsd32__lwp_park(struct lwp *l,
    581      1.2  christos     const struct compat_50_netbsd32__lwp_park_args *uap, register_t *retval)
    582      1.2  christos {
    583      1.2  christos 	/* {
    584      1.2  christos 		syscallarg(const netbsd32_timespec50p) ts;
    585      1.2  christos 		syscallarg(lwpid_t) unpark;
    586      1.2  christos 		syscallarg(netbsd32_voidp) hint;
    587      1.2  christos 		syscallarg(netbsd32_voidp) unparkhint;
    588      1.2  christos 	} */
    589      1.2  christos 	struct timespec ts, *tsp;
    590      1.2  christos 	struct netbsd32_timespec50 ts32;
    591      1.2  christos 	int error;
    592      1.2  christos 
    593      1.2  christos 	if (SCARG_P32(uap, ts) == NULL)
    594      1.2  christos 		tsp = NULL;
    595      1.2  christos 	else {
    596      1.2  christos 		error = copyin(SCARG_P32(uap, ts), &ts32, sizeof ts32);
    597      1.2  christos 		if (error != 0)
    598      1.2  christos 			return error;
    599      1.2  christos 		netbsd32_to_timespec50(&ts32, &ts);
    600      1.2  christos 		tsp = &ts;
    601      1.2  christos 	}
    602      1.2  christos 
    603      1.2  christos 	if (SCARG(uap, unpark) != 0) {
    604      1.2  christos 		error = lwp_unpark(SCARG(uap, unpark),
    605      1.2  christos 		    SCARG_P32(uap, unparkhint));
    606      1.2  christos 		if (error != 0)
    607      1.2  christos 			return error;
    608      1.2  christos 	}
    609      1.2  christos 
    610      1.2  christos 	return lwp_park(tsp, SCARG_P32(uap, hint));
    611      1.2  christos 	return 0;
    612      1.2  christos }
    613      1.2  christos 
    614      1.2  christos static int
    615      1.2  christos netbsd32_kevent_fetch_timeout(const void *src, void *dest, size_t length)
    616      1.2  christos {
    617      1.2  christos 	struct netbsd32_timespec50 ts32;
    618      1.2  christos 	int error;
    619      1.2  christos 
    620      1.2  christos 	KASSERT(length == sizeof(struct timespec50));
    621      1.2  christos 
    622      1.2  christos 	error = copyin(src, &ts32, sizeof(ts32));
    623      1.2  christos 	if (error)
    624      1.2  christos 		return error;
    625      1.2  christos 	netbsd32_to_timespec50(&ts32, (struct timespec *)dest);
    626      1.2  christos 	return 0;
    627      1.2  christos }
    628      1.2  christos 
    629      1.2  christos static int
    630      1.2  christos netbsd32_kevent_fetch_changes(void *private, const struct kevent *changelist,
    631      1.2  christos     struct kevent *changes, size_t index, int n)
    632      1.2  christos {
    633      1.2  christos 	const struct netbsd32_kevent *src =
    634      1.2  christos 	    (const struct netbsd32_kevent *)changelist;
    635      1.2  christos 	struct netbsd32_kevent *kev32, *changes32 = private;
    636      1.2  christos 	int error, i;
    637      1.2  christos 
    638      1.2  christos 	error = copyin(src + index, changes32, n * sizeof(*changes32));
    639      1.2  christos 	if (error)
    640      1.2  christos 		return error;
    641      1.2  christos 	for (i = 0, kev32 = changes32; i < n; i++, kev32++, changes++)
    642      1.2  christos 		netbsd32_to_kevent(kev32, changes);
    643      1.2  christos 	return 0;
    644      1.2  christos }
    645      1.2  christos 
    646      1.2  christos static int
    647      1.2  christos netbsd32_kevent_put_events(void *private, struct kevent *events,
    648      1.2  christos     struct kevent *eventlist, size_t index, int n)
    649      1.2  christos {
    650      1.2  christos 	struct netbsd32_kevent *kev32, *events32 = private;
    651      1.2  christos 	int i;
    652      1.2  christos 
    653      1.2  christos 	for (i = 0, kev32 = events32; i < n; i++, kev32++, events++)
    654      1.2  christos 		netbsd32_from_kevent(events, kev32);
    655      1.2  christos 	kev32 = (struct netbsd32_kevent *)eventlist;
    656      1.2  christos 	return  copyout(events32, kev32, n * sizeof(*events32));
    657      1.2  christos }
    658      1.2  christos 
    659      1.2  christos int
    660      1.2  christos compat_50_netbsd32_kevent(struct lwp *l,
    661      1.2  christos     const struct compat_50_netbsd32_kevent_args *uap, register_t *retval)
    662      1.2  christos {
    663      1.2  christos 	/* {
    664      1.2  christos 		syscallarg(int) fd;
    665      1.2  christos 		syscallarg(netbsd32_keventp_t) changelist;
    666      1.2  christos 		syscallarg(netbsd32_size_t) nchanges;
    667      1.2  christos 		syscallarg(netbsd32_keventp_t) eventlist;
    668      1.2  christos 		syscallarg(netbsd32_size_t) nevents;
    669      1.2  christos 		syscallarg(netbsd32_timespec50p_t) timeout;
    670      1.2  christos 	} */
    671      1.2  christos 	int error;
    672      1.2  christos 	size_t maxalloc, nchanges, nevents;
    673      1.2  christos 	struct kevent_ops netbsd32_kevent_ops = {
    674      1.2  christos 		keo_fetch_timeout: netbsd32_kevent_fetch_timeout,
    675      1.2  christos 		keo_fetch_changes: netbsd32_kevent_fetch_changes,
    676      1.2  christos 		keo_put_events: netbsd32_kevent_put_events,
    677      1.2  christos 	};
    678      1.2  christos 
    679      1.2  christos 	nchanges = SCARG(uap, nchanges);
    680      1.2  christos 	nevents = SCARG(uap, nevents);
    681      1.2  christos 	maxalloc = MIN(KQ_NEVENTS, MAX(nchanges, nevents));
    682      1.2  christos 	netbsd32_kevent_ops.keo_private =
    683      1.2  christos 	    malloc(maxalloc * sizeof(struct netbsd32_kevent), M_TEMP,
    684      1.2  christos 	    M_WAITOK);
    685      1.2  christos 
    686      1.2  christos 	error = kevent1(retval, SCARG(uap, fd),
    687      1.2  christos 	    NETBSD32PTR64(SCARG(uap, changelist)), nchanges,
    688      1.2  christos 	    NETBSD32PTR64(SCARG(uap, eventlist)), nevents,
    689      1.2  christos 	    NETBSD32PTR64(SCARG(uap, timeout)), &netbsd32_kevent_ops);
    690      1.2  christos 
    691      1.2  christos 	free(netbsd32_kevent_ops.keo_private, M_TEMP);
    692      1.2  christos 	return error;
    693      1.2  christos 	return 0;
    694      1.2  christos }
    695      1.2  christos 
    696      1.2  christos int
    697      1.2  christos compat_50_netbsd32_pselect(struct lwp *l,
    698      1.2  christos     const struct compat_50_netbsd32_pselect_args *uap, register_t *retval)
    699      1.2  christos {
    700      1.2  christos 	/* {
    701      1.2  christos 		syscallarg(int) nd;
    702      1.2  christos 		syscallarg(netbsd32_fd_setp_t) in;
    703      1.2  christos 		syscallarg(netbsd32_fd_setp_t) ou;
    704      1.2  christos 		syscallarg(netbsd32_fd_setp_t) ex;
    705      1.2  christos 		syscallarg(const netbsd32_timespec50p_t) ts;
    706      1.2  christos 		syscallarg(const netbsd32_sigsetp_t) mask;
    707      1.2  christos 	} */
    708      1.2  christos 	int error;
    709      1.2  christos 	struct netbsd32_timespec50 ts32;
    710  1.3.2.1       jym 	struct timespec ats, *ts = NULL;
    711      1.2  christos 	sigset_t amask, *mask = NULL;
    712      1.2  christos 
    713      1.2  christos 	if (SCARG_P32(uap, ts)) {
    714      1.2  christos 		error = copyin(SCARG_P32(uap, ts), &ts32, sizeof(ts32));
    715      1.2  christos 		if (error != 0)
    716      1.2  christos 			return error;
    717  1.3.2.1       jym 		netbsd32_to_timespec50(&ts32, &ats);
    718  1.3.2.1       jym 		ts = &ats;
    719      1.2  christos 	}
    720      1.2  christos 	if (SCARG_P32(uap, mask)) {
    721      1.2  christos 		error = copyin(SCARG_P32(uap, mask), &amask, sizeof(amask));
    722      1.2  christos 		if (error != 0)
    723      1.2  christos 			return error;
    724      1.2  christos 		mask = &amask;
    725      1.2  christos 	}
    726      1.2  christos 
    727      1.2  christos 	return selcommon(l, retval, SCARG(uap, nd), SCARG_P32(uap, in),
    728  1.3.2.1       jym 	    SCARG_P32(uap, ou), SCARG_P32(uap, ex), ts, mask);
    729      1.2  christos 	return 0;
    730      1.2  christos }
    731      1.2  christos 
    732      1.2  christos int
    733      1.2  christos compat_50_netbsd32_pollts(struct lwp *l,
    734      1.2  christos     const struct compat_50_netbsd32_pollts_args *uap, register_t *retval)
    735      1.2  christos {
    736      1.2  christos 	/* {
    737      1.2  christos 		syscallarg(struct netbsd32_pollfdp_t) fds;
    738      1.2  christos 		syscallarg(u_int) nfds;
    739      1.2  christos 		syscallarg(const netbsd32_timespec50p_t) ts;
    740      1.2  christos 		syscallarg(const netbsd32_sigsetp_t) mask;
    741      1.2  christos 	} */
    742      1.2  christos 	int error;
    743      1.2  christos 	struct netbsd32_timespec50 ts32;
    744  1.3.2.1       jym 	struct timespec ats, *ts = NULL;
    745      1.2  christos 	sigset_t amask, *mask = NULL;
    746      1.2  christos 
    747      1.2  christos 	if (SCARG_P32(uap, ts)) {
    748      1.2  christos 		error = copyin(SCARG_P32(uap, ts), &ts32, sizeof(ts32));
    749      1.2  christos 		if (error != 0)
    750      1.2  christos 			return error;
    751  1.3.2.1       jym 		netbsd32_to_timespec50(&ts32, &ats);
    752  1.3.2.1       jym 		ts = &ats;
    753      1.2  christos 	}
    754      1.2  christos 	if (NETBSD32PTR64( SCARG(uap, mask))) {
    755      1.2  christos 		error = copyin(SCARG_P32(uap, mask), &amask, sizeof(amask));
    756      1.2  christos 		if (error != 0)
    757      1.2  christos 			return error;
    758      1.2  christos 		mask = &amask;
    759      1.2  christos 	}
    760      1.2  christos 
    761      1.2  christos 	return pollcommon(l, retval, SCARG_P32(uap, fds),
    762  1.3.2.1       jym 	    SCARG(uap, nfds), ts, mask);
    763      1.2  christos }
    764      1.2  christos 
    765      1.2  christos int
    766      1.2  christos compat_50_netbsd32___stat30(struct lwp *l,
    767      1.2  christos     const struct compat_50_netbsd32___stat30_args *uap, register_t *retval)
    768      1.2  christos {
    769      1.2  christos 	/* {
    770      1.2  christos 		syscallarg(const netbsd32_charp) path;
    771      1.2  christos 		syscallarg(netbsd32_stat50p_t) ub;
    772      1.2  christos 	} */
    773      1.2  christos 	struct netbsd32_stat50 sb32;
    774      1.2  christos 	struct stat sb;
    775      1.2  christos 	int error;
    776      1.2  christos 	const char *path;
    777      1.2  christos 
    778      1.2  christos 	path = SCARG_P32(uap, path);
    779      1.2  christos 
    780      1.2  christos 	error = do_sys_stat(path, FOLLOW, &sb);
    781      1.2  christos 	if (error)
    782      1.2  christos 		return error;
    783      1.2  christos 	netbsd32_from___stat50(&sb, &sb32);
    784      1.2  christos 	error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32));
    785      1.2  christos 	return error;
    786      1.2  christos }
    787      1.2  christos 
    788      1.2  christos int
    789      1.2  christos compat_50_netbsd32___fstat30(struct lwp *l,
    790      1.2  christos     const struct compat_50_netbsd32___fstat30_args *uap, register_t *retval)
    791      1.2  christos {
    792      1.2  christos 	/* {
    793      1.2  christos 		syscallarg(int) fd;
    794      1.2  christos 		syscallarg(netbsd32_stat50p_t) sb;
    795      1.2  christos 	} */
    796      1.2  christos 	struct netbsd32_stat50 sb32;
    797      1.2  christos 	struct stat ub;
    798      1.3     njoly 	int error;
    799      1.2  christos 
    800      1.3     njoly 	error = do_sys_fstat(SCARG(uap, fd), &ub);
    801      1.2  christos 	if (error == 0) {
    802      1.2  christos 		netbsd32_from___stat50(&ub, &sb32);
    803      1.2  christos 		error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32));
    804      1.2  christos 	}
    805      1.2  christos 	return error;
    806      1.2  christos }
    807      1.2  christos 
    808      1.2  christos int
    809      1.2  christos compat_50_netbsd32___lstat30(struct lwp *l,
    810      1.2  christos     const struct compat_50_netbsd32___lstat30_args *uap, register_t *retval)
    811      1.2  christos {
    812      1.2  christos 	/* {
    813      1.2  christos 		syscallarg(const netbsd32_charp) path;
    814      1.2  christos 		syscallarg(netbsd32_stat50p_t) ub;
    815      1.2  christos 	} */
    816      1.2  christos 	struct netbsd32_stat50 sb32;
    817      1.2  christos 	struct stat sb;
    818      1.2  christos 	int error;
    819      1.2  christos 	const char *path;
    820      1.2  christos 
    821      1.2  christos 	path = SCARG_P32(uap, path);
    822      1.2  christos 
    823      1.2  christos 	error = do_sys_stat(path, NOFOLLOW, &sb);
    824      1.2  christos 	if (error)
    825      1.2  christos 		return error;
    826      1.2  christos 	netbsd32_from___stat50(&sb, &sb32);
    827      1.2  christos 	error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32));
    828      1.2  christos 	return error;
    829      1.2  christos }
    830      1.2  christos 
    831      1.2  christos int
    832      1.2  christos compat_50_netbsd32___fhstat40(struct lwp *l, const struct compat_50_netbsd32___fhstat40_args *uap, register_t *retval)
    833      1.2  christos {
    834      1.2  christos 	/* {
    835      1.2  christos 		syscallarg(const netbsd32_pointer_t) fhp;
    836      1.2  christos 		syscallarg(netbsd32_size_t) fh_size;
    837      1.2  christos 		syscallarg(netbsd32_stat50p_t) sb;
    838      1.2  christos 	} */
    839      1.2  christos 	struct stat sb;
    840      1.2  christos 	struct netbsd32_stat50 sb32;
    841      1.2  christos 	int error;
    842      1.2  christos 
    843      1.2  christos 	error = do_fhstat(l, SCARG_P32(uap, fhp), SCARG(uap, fh_size), &sb);
    844      1.2  christos 	if (error != 0) {
    845      1.2  christos 		netbsd32_from___stat50(&sb, &sb32);
    846      1.2  christos 		error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb));
    847      1.2  christos 	}
    848      1.2  christos 	return error;
    849      1.2  christos }
    850      1.2  christos 
    851      1.2  christos int
    852      1.2  christos compat_50_netbsd32_wait4(struct lwp *l, const struct compat_50_netbsd32_wait4_args *uap, register_t *retval)
    853      1.2  christos {
    854      1.2  christos 	/* {
    855      1.2  christos 		syscallarg(int) pid;
    856      1.2  christos 		syscallarg(netbsd32_intp) status;
    857      1.2  christos 		syscallarg(int) options;
    858      1.2  christos 		syscallarg(netbsd32_rusage50p_t) rusage;
    859      1.2  christos 	} */
    860      1.2  christos 	int		status, error;
    861      1.2  christos 	int		was_zombie;
    862      1.2  christos 	struct rusage	ru;
    863      1.2  christos 	struct netbsd32_rusage50	ru32;
    864      1.2  christos 	int pid = SCARG(uap, pid);
    865      1.2  christos 
    866      1.2  christos 	error = do_sys_wait(l, &pid, &status, SCARG(uap, options),
    867      1.2  christos 	    SCARG_P32(uap, rusage) != NULL ? &ru : NULL, &was_zombie);
    868      1.2  christos 
    869      1.2  christos 	retval[0] = pid;
    870      1.2  christos 	if (pid == 0)
    871      1.2  christos 		return error;
    872      1.2  christos 
    873      1.2  christos 	if (SCARG_P32(uap, rusage)) {
    874      1.2  christos 		netbsd32_from_rusage50(&ru, &ru32);
    875      1.2  christos 		error = copyout(&ru32, SCARG_P32(uap, rusage), sizeof(ru32));
    876      1.2  christos 	}
    877      1.2  christos 
    878      1.2  christos 	if (error == 0 && SCARG_P32(uap, status))
    879      1.2  christos 		error = copyout(&status, SCARG_P32(uap, status), sizeof(status));
    880      1.2  christos 
    881      1.2  christos 	return error;
    882      1.2  christos }
    883      1.2  christos 
    884      1.2  christos 
    885      1.2  christos int
    886      1.2  christos compat_50_netbsd32_getrusage(struct lwp *l, const struct compat_50_netbsd32_getrusage_args *uap, register_t *retval)
    887      1.2  christos {
    888      1.2  christos 	/* {
    889      1.2  christos 		syscallarg(int) who;
    890      1.2  christos 		syscallarg(netbsd32_rusage50p_t) rusage;
    891      1.2  christos 	} */
    892      1.2  christos 	struct proc *p = l->l_proc;
    893      1.2  christos 	struct rusage *rup;
    894      1.2  christos 	struct netbsd32_rusage50 ru;
    895      1.2  christos 
    896      1.2  christos 	switch (SCARG(uap, who)) {
    897      1.2  christos 
    898      1.2  christos 	case RUSAGE_SELF:
    899      1.2  christos 		rup = &p->p_stats->p_ru;
    900      1.2  christos 		mutex_enter(p->p_lock);
    901      1.2  christos 		calcru(p, &rup->ru_utime, &rup->ru_stime, NULL, NULL);
    902      1.2  christos 		mutex_exit(p->p_lock);
    903      1.2  christos 		break;
    904      1.2  christos 
    905      1.2  christos 	case RUSAGE_CHILDREN:
    906      1.2  christos 		rup = &p->p_stats->p_cru;
    907      1.2  christos 		break;
    908      1.2  christos 
    909      1.2  christos 	default:
    910      1.2  christos 		return (EINVAL);
    911      1.2  christos 	}
    912      1.2  christos 	netbsd32_from_rusage50(rup, &ru);
    913      1.2  christos 	return copyout(&ru, SCARG_P32(uap, rusage), sizeof(ru));
    914      1.2  christos }
    915      1.2  christos 
    916      1.2  christos int
    917      1.2  christos compat_50_netbsd32_setitimer(struct lwp *l,
    918      1.2  christos     const struct compat_50_netbsd32_setitimer_args *uap, register_t *retval)
    919      1.2  christos {
    920      1.2  christos 	/* {
    921      1.2  christos 		syscallarg(int) which;
    922      1.2  christos 		syscallarg(const netbsd32_itimerval50p_t) itv;
    923      1.2  christos 		syscallarg(netbsd32_itimerval50p_t) oitv;
    924      1.2  christos 	} */
    925      1.2  christos 	struct proc *p = l->l_proc;
    926      1.2  christos 	struct netbsd32_itimerval50 s32it, *itv32;
    927      1.2  christos 	int which = SCARG(uap, which);
    928      1.2  christos 	struct compat_50_netbsd32_getitimer_args getargs;
    929      1.2  christos 	struct itimerval aitv;
    930      1.2  christos 	int error;
    931      1.2  christos 
    932      1.2  christos 	if ((u_int)which > ITIMER_PROF)
    933      1.2  christos 		return (EINVAL);
    934      1.2  christos 	itv32 = SCARG_P32(uap, itv);
    935      1.2  christos 	if (itv32) {
    936      1.2  christos 		if ((error = copyin(itv32, &s32it, sizeof(s32it))))
    937      1.2  christos 			return (error);
    938      1.2  christos 		netbsd32_to_itimerval50(&s32it, &aitv);
    939      1.2  christos 	}
    940      1.2  christos 	if (SCARG_P32(uap, oitv) != 0) {
    941      1.2  christos 		SCARG(&getargs, which) = which;
    942      1.2  christos 		SCARG(&getargs, itv) = SCARG(uap, oitv);
    943      1.2  christos 		if ((error = compat_50_netbsd32_getitimer(l, &getargs, retval)) != 0)
    944      1.2  christos 			return (error);
    945      1.2  christos 	}
    946      1.2  christos 	if (itv32 == 0)
    947      1.2  christos 		return 0;
    948      1.2  christos 
    949      1.2  christos 	return dosetitimer(p, which, &aitv);
    950      1.2  christos }
    951      1.2  christos 
    952      1.2  christos int
    953      1.2  christos compat_50_netbsd32_getitimer(struct lwp *l, const struct compat_50_netbsd32_getitimer_args *uap, register_t *retval)
    954      1.2  christos {
    955      1.2  christos 	/* {
    956      1.2  christos 		syscallarg(int) which;
    957      1.2  christos 		syscallarg(netbsd32_itimerval50p_t) itv;
    958      1.2  christos 	} */
    959      1.2  christos 	struct proc *p = l->l_proc;
    960      1.2  christos 	struct netbsd32_itimerval50 s32it;
    961      1.2  christos 	struct itimerval aitv;
    962      1.2  christos 	int error;
    963      1.2  christos 
    964      1.2  christos 	error = dogetitimer(p, SCARG(uap, which), &aitv);
    965      1.2  christos 	if (error)
    966      1.2  christos 		return error;
    967      1.2  christos 
    968      1.2  christos 	netbsd32_from_itimerval50(&aitv, &s32it);
    969      1.2  christos 	return copyout(&s32it, SCARG_P32(uap, itv), sizeof(s32it));
    970      1.2  christos }
    971      1.2  christos 
    972      1.2  christos #if defined(SYSVSEM)
    973      1.2  christos 
    974      1.2  christos int
    975      1.2  christos compat_50_netbsd32___semctl14(struct lwp *l, const struct compat_50_netbsd32___semctl14_args *uap, register_t *retval)
    976      1.2  christos {
    977      1.2  christos 	return do_netbsd32___semctl14(l, uap, retval, NULL);
    978      1.2  christos }
    979      1.2  christos 
    980      1.2  christos int
    981      1.2  christos do_netbsd32___semctl14(struct lwp *l, const struct compat_50_netbsd32___semctl14_args *uap, register_t *retval, void *vkarg)
    982      1.2  christos {
    983      1.2  christos 	/* {
    984      1.2  christos 		syscallarg(int) semid;
    985      1.2  christos 		syscallarg(int) semnum;
    986      1.2  christos 		syscallarg(int) cmd;
    987      1.2  christos 		syscallarg(netbsd32_semun50p_t) arg;
    988      1.2  christos 	} */
    989      1.2  christos 	struct semid_ds sembuf;
    990      1.2  christos 	struct netbsd32_semid_ds50 sembuf32;
    991      1.2  christos 	int cmd, error;
    992      1.2  christos 	void *pass_arg;
    993      1.2  christos 	union __semun karg;
    994      1.2  christos 	union netbsd32_semun50 karg32;
    995      1.2  christos 
    996      1.2  christos 	cmd = SCARG(uap, cmd);
    997      1.2  christos 
    998      1.2  christos 	switch (cmd) {
    999      1.2  christos 	case IPC_SET:
   1000      1.2  christos 	case IPC_STAT:
   1001      1.2  christos 		pass_arg = &sembuf;
   1002      1.2  christos 		break;
   1003      1.2  christos 
   1004      1.2  christos 	case GETALL:
   1005      1.2  christos 	case SETVAL:
   1006      1.2  christos 	case SETALL:
   1007      1.2  christos 		pass_arg = &karg;
   1008      1.2  christos 		break;
   1009      1.2  christos 	default:
   1010      1.2  christos 		pass_arg = NULL;
   1011      1.2  christos 		break;
   1012      1.2  christos 	}
   1013      1.2  christos 
   1014      1.2  christos 	if (pass_arg) {
   1015      1.2  christos 		if (vkarg != NULL)
   1016      1.2  christos 			karg32 = *(union netbsd32_semun50 *)vkarg;
   1017      1.2  christos 		else {
   1018      1.2  christos 			error = copyin(SCARG_P32(uap, arg), &karg32,
   1019      1.2  christos 					sizeof(karg32));
   1020      1.2  christos 			if (error)
   1021      1.2  christos 				return error;
   1022      1.2  christos 		}
   1023      1.2  christos 		if (pass_arg == &karg) {
   1024      1.2  christos 			switch (cmd) {
   1025      1.2  christos 			case GETALL:
   1026      1.2  christos 			case SETALL:
   1027      1.2  christos 				karg.array = NETBSD32PTR64(karg32.array);
   1028      1.2  christos 				break;
   1029      1.2  christos 			case SETVAL:
   1030      1.2  christos 				karg.val = karg32.val;
   1031      1.2  christos 				break;
   1032      1.2  christos 			}
   1033      1.2  christos 		}
   1034      1.2  christos 		if (cmd == IPC_SET) {
   1035      1.2  christos 			error = copyin(NETBSD32PTR64(karg32.buf), &sembuf32,
   1036      1.2  christos 			    sizeof(sembuf32));
   1037      1.2  christos 			if (error)
   1038      1.2  christos 				return (error);
   1039      1.2  christos 			netbsd32_to_semid_ds50(&sembuf32, &sembuf);
   1040      1.2  christos 		}
   1041      1.2  christos 	}
   1042      1.2  christos 
   1043      1.2  christos 	error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd,
   1044      1.2  christos 	    pass_arg, retval);
   1045      1.2  christos 
   1046      1.2  christos 	if (error == 0 && cmd == IPC_STAT) {
   1047      1.2  christos 		netbsd32_from_semid_ds50(&sembuf, &sembuf32);
   1048      1.2  christos 		error = copyout(&sembuf32, NETBSD32PTR64(karg32.buf),
   1049      1.2  christos 		    sizeof(sembuf32));
   1050      1.2  christos 	}
   1051      1.2  christos 
   1052      1.2  christos 	return (error);
   1053      1.2  christos }
   1054      1.2  christos #endif
   1055      1.2  christos 
   1056      1.2  christos #if defined(SYSVMSG)
   1057      1.2  christos 
   1058      1.2  christos int
   1059      1.2  christos compat_50_netbsd32___msgctl13(struct lwp *l, const struct compat_50_netbsd32___msgctl13_args *uap, register_t *retval)
   1060      1.2  christos {
   1061      1.2  christos 	/* {
   1062      1.2  christos 		syscallarg(int) msqid;
   1063      1.2  christos 		syscallarg(int) cmd;
   1064      1.2  christos 		syscallarg(netbsd32_msqid_ds50p_t) buf;
   1065      1.2  christos 	} */
   1066      1.2  christos 	struct msqid_ds ds;
   1067      1.2  christos 	struct netbsd32_msqid_ds50 ds32;
   1068      1.2  christos 	int error, cmd;
   1069      1.2  christos 
   1070      1.2  christos 	cmd = SCARG(uap, cmd);
   1071      1.2  christos 	if (cmd == IPC_SET) {
   1072      1.2  christos 		error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32));
   1073      1.2  christos 		if (error)
   1074      1.2  christos 			return error;
   1075      1.2  christos 		netbsd32_to_msqid_ds50(&ds32, &ds);
   1076      1.2  christos 	}
   1077      1.2  christos 
   1078      1.2  christos 	error = msgctl1(l, SCARG(uap, msqid), cmd,
   1079      1.2  christos 	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
   1080      1.2  christos 
   1081      1.2  christos 	if (error == 0 && cmd == IPC_STAT) {
   1082      1.2  christos 		netbsd32_from_msqid_ds50(&ds, &ds32);
   1083      1.2  christos 		error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32));
   1084      1.2  christos 	}
   1085      1.2  christos 
   1086      1.2  christos 	return error;
   1087      1.2  christos }
   1088      1.2  christos #endif
   1089      1.2  christos 
   1090      1.2  christos #if defined(SYSVSHM)
   1091      1.2  christos 
   1092      1.2  christos int
   1093      1.2  christos compat_50_netbsd32___shmctl13(struct lwp *l, const struct compat_50_netbsd32___shmctl13_args *uap, register_t *retval)
   1094      1.2  christos {
   1095      1.2  christos 	/* {
   1096      1.2  christos 		syscallarg(int) shmid;
   1097      1.2  christos 		syscallarg(int) cmd;
   1098      1.2  christos 		syscallarg(netbsd32_shmid_ds50p_t) buf;
   1099      1.2  christos 	} */
   1100      1.2  christos 	struct shmid_ds ds;
   1101      1.2  christos 	struct netbsd32_shmid_ds50 ds32;
   1102      1.2  christos 	int error, cmd;
   1103      1.2  christos 
   1104      1.2  christos 	cmd = SCARG(uap, cmd);
   1105      1.2  christos 	if (cmd == IPC_SET) {
   1106      1.2  christos 		error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32));
   1107      1.2  christos 		if (error)
   1108      1.2  christos 			return error;
   1109      1.2  christos 		netbsd32_to_shmid_ds50(&ds32, &ds);
   1110      1.2  christos 	}
   1111      1.2  christos 
   1112      1.2  christos 	error = shmctl1(l, SCARG(uap, shmid), cmd,
   1113      1.2  christos 	    (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
   1114      1.2  christos 
   1115      1.2  christos 	if (error == 0 && cmd == IPC_STAT) {
   1116      1.2  christos 		netbsd32_from_shmid_ds50(&ds, &ds32);
   1117      1.2  christos 		error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32));
   1118      1.2  christos 	}
   1119      1.2  christos 
   1120      1.2  christos 	return error;
   1121      1.2  christos }
   1122      1.2  christos #endif
   1123