Home | History | Annotate | Line # | Download | only in common
      1 /*	$NetBSD: linux32_unistd.c,v 1.45 2026/09/20 13:43:52 riastradh Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. All advertising materials mentioning features or use of this software
     15  *    must display the following acknowledgement:
     16  *	This product includes software developed by Emmanuel Dreyfus
     17  * 4. The name of the author may not be used to endorse or promote
     18  *    products derived from this software without specific prior written
     19  *    permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS''
     22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     23  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
     25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     31  * POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 #include <sys/cdefs.h>
     35 
     36 __KERNEL_RCSID(0, "$NetBSD: linux32_unistd.c,v 1.45 2026/09/20 13:43:52 riastradh Exp $");
     37 
     38 #include <sys/types.h>
     39 #include <sys/param.h>
     40 #include <sys/fstypes.h>
     41 #include <sys/signal.h>
     42 #include <sys/dirent.h>
     43 #include <sys/kernel.h>
     44 #include <sys/fcntl.h>
     45 #include <sys/select.h>
     46 #include <sys/proc.h>
     47 #include <sys/ucred.h>
     48 #include <sys/swap.h>
     49 #include <sys/kauth.h>
     50 #include <sys/filedesc.h>
     51 #include <sys/vfs_syscalls.h>
     52 
     53 #include <machine/types.h>
     54 
     55 #include <sys/syscallargs.h>
     56 
     57 #include <compat/netbsd32/netbsd32.h>
     58 #include <compat/netbsd32/netbsd32_conv.h>
     59 
     60 #include <compat/linux/common/linux_types.h>
     61 #include <compat/linux/common/linux_signal.h>
     62 #include <compat/linux/common/linux_machdep.h>
     63 #include <compat/linux/common/linux_misc.h>
     64 #include <compat/linux/common/linux_oldolduname.h>
     65 #include <compat/linux/common/linux_ipc.h>
     66 #include <compat/linux/common/linux_sem.h>
     67 #include <compat/linux/common/linux_fcntl.h>
     68 #include <compat/linux/linux_syscallargs.h>
     69 
     70 #include <compat/linux32/common/linux32_types.h>
     71 #include <compat/linux32/common/linux32_signal.h>
     72 #include <compat/linux32/common/linux32_machdep.h>
     73 #include <compat/linux32/common/linux32_sched.h>
     74 #include <compat/linux32/common/linux32_sysctl.h>
     75 #include <compat/linux32/common/linux32_socketcall.h>
     76 #include <compat/linux32/linux32_syscall.h>
     77 #include <compat/linux32/linux32_syscallargs.h>
     78 
     79 static int linux32_select1(struct lwp *, register_t *,
     80     int, fd_set *, fd_set *, fd_set *, struct timeval *);
     81 
     82 int
     83 linux32_sys_brk(struct lwp *l, const struct linux32_sys_brk_args *uap, register_t *retval)
     84 {
     85 	/* {
     86 		syscallarg(netbsd32_charp) nsize;
     87 	} */
     88 	struct linux_sys_brk_args ua;
     89 
     90 	memset(&ua, 0, sizeof(ua));
     91 	NETBSD32TOP_UAP(nsize, char);
     92 	return linux_sys_brk(l, &ua, retval);
     93 }
     94 
     95 int
     96 linux32_sys_llseek(struct lwp *l, const struct linux32_sys_llseek_args *uap, register_t *retval)
     97 {
     98 	/* {
     99 		syscallarg(int) fd;
    100                 syscallarg(u_int32_t) ohigh;
    101                 syscallarg(u_int32_t) olow;
    102 		syscallarg(netbsd32_voidp) res;
    103 		syscallarg(int) whence;
    104 	} */
    105 	struct linux_sys_llseek_args ua;
    106 
    107 	memset(&ua, 0, sizeof(ua));
    108 	NETBSD32TO64_UAP(fd);
    109 	NETBSD32TO64_UAP(ohigh);
    110 	NETBSD32TO64_UAP(olow);
    111 	NETBSD32TOP_UAP(res, void);
    112 	NETBSD32TO64_UAP(whence);
    113 
    114 	return linux_sys_llseek(l, &ua, retval);
    115 }
    116 
    117 int
    118 linux32_sys_select(struct lwp *l, const struct linux32_sys_select_args *uap, register_t *retval)
    119 {
    120 	/* {
    121 		syscallarg(int) nfds;
    122 		syscallarg(netbsd32_fd_setp_t) readfds;
    123 		syscallarg(netbsd32_fd_setp_t) writefds;
    124 		syscallarg(netbsd32_fd_setp_t) exceptfds;
    125 		syscallarg(netbsd32_timeval50p_t) timeout;
    126 	} */
    127 
    128 	return linux32_select1(l, retval, SCARG(uap, nfds),
    129 	    SCARG_P32(uap, readfds),
    130 	    SCARG_P32(uap, writefds),
    131 	    SCARG_P32(uap, exceptfds),
    132 	    SCARG_P32(uap, timeout));
    133 }
    134 
    135 int
    136 linux32_sys_oldselect(struct lwp *l, const struct linux32_sys_oldselect_args *uap, register_t *retval)
    137 {
    138 	/* {
    139 		syscallarg(linux32_oldselectp_t) lsp;
    140 	} */
    141 	struct linux32_oldselect lsp32;
    142 	int error;
    143 
    144 	if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0)
    145 		return error;
    146 
    147 	return linux32_select1(l, retval, lsp32.nfds,
    148 	     NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds),
    149 	     NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout));
    150 }
    151 
    152 static int
    153 linux32_select1(struct lwp *l, register_t *retval, int nfds,
    154 		fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
    155 		struct timeval *timeout)
    156 {
    157 	struct timespec ts0, ts1, uts, *ts = NULL;
    158 	struct netbsd32_timeval50 utv32;
    159 	int error;
    160 
    161 
    162 	/*
    163 	 * Store current time for computation of the amount of
    164 	 * time left.
    165 	 */
    166 	if (timeout) {
    167 		if ((error = copyin(timeout, &utv32, sizeof(utv32))))
    168 			return error;
    169 
    170 		uts.tv_sec = utv32.tv_sec;
    171 		uts.tv_nsec = (long)((unsigned long)utv32.tv_usec * 1000);
    172 
    173 		if (itimespecfix(&uts)) {
    174 			/*
    175 			 * The timeval was invalid.  Convert it to something
    176 			 * valid that will act as it does under Linux.
    177 			 */
    178 			uts.tv_sec += uts.tv_nsec / 1000000000;
    179 			uts.tv_nsec %= 1000000000;
    180 			if (uts.tv_nsec < 0) {
    181 				uts.tv_sec -= 1;
    182 				uts.tv_nsec += 1000000000;
    183 			}
    184 			if (uts.tv_sec < 0)
    185 				timespecclear(&uts);
    186 		}
    187 		nanotime(&ts0);
    188 		ts = &uts;
    189 	} else
    190 		timespecclear(&uts); /* XXX GCC4 */
    191 
    192 	error = selcommon(retval, nfds, readfds, writefds, exceptfds, ts, NULL);
    193 
    194 	if (error) {
    195 		/*
    196 		 * See fs/select.c in the Linux kernel.  Without this,
    197 		 * Maelstrom doesn't work.
    198 		 */
    199 		if (error == ERESTART)
    200 			error = EINTR;
    201 		return error;
    202 	}
    203 
    204 	if (timeout) {
    205 		if (*retval) {
    206 			/*
    207 			 * Compute how much time was left of the timeout,
    208 			 * by subtracting the current time and the time
    209 			 * before we started the call, and subtracting
    210 			 * that result from the user-supplied value.
    211 			 */
    212 			nanotime(&ts1);
    213 			timespecsub(&ts1, &ts0, &ts1);
    214 			timespecsub(&uts, &ts1, &uts);
    215 			if (uts.tv_sec < 0)
    216 				timespecclear(&uts);
    217 		} else {
    218 			timespecclear(&uts);
    219 		}
    220 
    221 		utv32.tv_sec = uts.tv_sec;
    222 		utv32.tv_usec = uts.tv_nsec / 1000;
    223 
    224 		if ((error = copyout(&utv32, timeout, sizeof(utv32))))
    225 			return error;
    226 	}
    227 
    228 	return 0;
    229 }
    230 
    231 int
    232 linux32_sys_pselect6(struct lwp *l, const struct linux32_sys_pselect6_args *uap,
    233     register_t *retval)
    234 {
    235 	/* {
    236 		syscallarg(int) nfds;
    237 		syscallarg(netbsd32_fd_setp_t) readfds;
    238 		syscallarg(netbsd32_fd_setp_t) writefds;
    239 		syscallarg(netbsd32_fd_setp_t) exceptfds;
    240 		syscallarg(linux32_timespecp_t) timeout;
    241 		syscallarg(linux32_sized_sigsetp_t) ss;
    242 	} */
    243 	struct timespec uts, ts0, ts1, *tsp;
    244 	linux32_sized_sigset_t lsss;
    245 	struct linux32_timespec lts;
    246 	linux32_sigset_t lss;
    247 	sigset_t *ssp;
    248 	sigset_t ss;
    249 	int error;
    250 	void *p;
    251 
    252 	ssp = NULL;
    253 	if ((p = SCARG_P32(uap, ss)) != NULL) {
    254 		if ((error = copyin(p, &lsss, sizeof(lsss))) != 0)
    255 			return (error);
    256 		if (lsss.ss_len != sizeof(lss))
    257 			return (EINVAL);
    258 		if ((p = NETBSD32PTR64(lsss.ss)) != NULL) {
    259 			if ((error = copyin(p, &lss, sizeof(lss))) != 0)
    260 				return (error);
    261 			linux32_to_native_sigset(&ss, &lss);
    262 			ssp = &ss;
    263 		}
    264 	}
    265 
    266 	if ((p = SCARG_P32(uap, timeout)) != NULL) {
    267 		error = copyin(p, &lts, sizeof(lts));
    268 		if (error != 0)
    269 			return (error);
    270 		linux32_to_native_timespec(&uts, &lts);
    271 
    272 		if (itimespecfix(&uts))
    273 			return (EINVAL);
    274 
    275 		nanotime(&ts0);
    276 		tsp = &uts;
    277 	} else {
    278 		tsp = NULL;
    279 	}
    280 
    281 	error = selcommon(retval, SCARG(uap, nfds), SCARG_P32(uap, readfds),
    282 	    SCARG_P32(uap, writefds), SCARG_P32(uap, exceptfds), tsp, ssp);
    283 
    284 	if (error == 0 && tsp != NULL) {
    285 		if (retval != 0) {
    286 			/*
    287 			 * Compute how much time was left of the timeout,
    288 			 * by subtracting the current time and the time
    289 			 * before we started the call, and subtracting
    290 			 * that result from the user-supplied value.
    291 			 */
    292 			nanotime(&ts1);
    293 			timespecsub(&ts1, &ts0, &ts1);
    294 			timespecsub(&uts, &ts1, &uts);
    295 			if (uts.tv_sec < 0)
    296 				timespecclear(&uts);
    297 		} else {
    298 			timespecclear(&uts);
    299 		}
    300 
    301 		native_to_linux32_timespec(&lts, &uts);
    302 		error = copyout(&lts, SCARG_P32(uap, timeout), sizeof(lts));
    303 	}
    304 
    305 	return (error);
    306 }
    307 
    308 int
    309 linux32_sys_pipe(struct lwp *l, const struct linux32_sys_pipe_args *uap,
    310     register_t *retval)
    311 {
    312 	/* {
    313 		syscallarg(netbsd32_intp) fd;
    314 	} */
    315 	int f[2], error;
    316 
    317 	if ((error = pipe1(l, f, 0)))
    318 		return error;
    319 
    320 	if ((error = copyout(f, SCARG_P32(uap, fd), sizeof(f))) != 0)
    321 		return error;
    322 	retval[0] = 0;
    323 	return 0;
    324 }
    325 
    326 int
    327 linux32_sys_pipe2(struct lwp *l, const struct linux32_sys_pipe2_args *uap,
    328     register_t *retval)
    329 {
    330 	/* {
    331 		syscallarg(netbsd32_intp) fd;
    332 	} */
    333 	int f[2], flags, error;
    334 
    335 	flags = linux_to_bsd_ioflags(SCARG(uap, flags));
    336 	if ((flags & ~(O_CLOEXEC|O_NONBLOCK)) != 0)
    337 		return EINVAL;
    338 
    339 	if ((error = pipe1(l, f, flags)))
    340 		return error;
    341 
    342 	if ((error = copyout(f, SCARG_P32(uap, fd), sizeof(f))) != 0)
    343 		return error;
    344 	retval[0] = 0;
    345 	return 0;
    346 }
    347 
    348 int
    349 linux32_sys_dup3(struct lwp *l, const struct linux32_sys_dup3_args *uap,
    350     register_t *retval)
    351 {
    352 	/* {
    353 		syscallarg(int) from;
    354 		syscallarg(int) to;
    355 		syscallarg(int) flags;
    356 	} */
    357 	struct linux_sys_dup3_args ua;
    358 
    359 	memset(&ua, 0, sizeof(ua));
    360 	NETBSD32TO64_UAP(from);
    361 	NETBSD32TO64_UAP(to);
    362 	NETBSD32TO64_UAP(flags);
    363 
    364 	return linux_sys_dup3(l, &ua, retval);
    365 }
    366 
    367 
    368 int
    369 linux32_sys_openat(struct lwp *l, const struct linux32_sys_openat_args *uap, register_t *retval)
    370 {
    371 	/* {
    372 		syscallarg(int) fd;
    373 		syscallarg(const netbsd32_charp) path;
    374 		syscallarg(int) flags;
    375 		syscallarg(int) mode;
    376 	} */
    377 	struct linux_sys_openat_args ua;
    378 
    379 	memset(&ua, 0, sizeof(ua));
    380 	NETBSD32TO64_UAP(fd);
    381 	NETBSD32TOP_UAP(path, const char);
    382 	NETBSD32TO64_UAP(flags);
    383 	NETBSD32TO64_UAP(mode);
    384 
    385 	return linux_sys_openat(l, &ua, retval);
    386 }
    387 
    388 int
    389 linux32_sys_mknodat(struct lwp *l, const struct linux32_sys_mknodat_args *uap, register_t *retval)
    390 {
    391 	/* {
    392 		syscallarg(int) fd;
    393 		syscallarg(const netbsd32_charp) path;
    394 		syscallarg(linux_umode_t) mode;
    395 		syscallarg(unsigned) dev;
    396 	} */
    397 	struct linux_sys_mknodat_args ua;
    398 
    399 	memset(&ua, 0, sizeof(ua));
    400 	NETBSD32TO64_UAP(fd);
    401 	NETBSD32TOP_UAP(path, const char);
    402 	NETBSD32TO64_UAP(mode);
    403 	NETBSD32TO64_UAP(dev);
    404 
    405 	return linux_sys_mknodat(l, &ua, retval);
    406 }
    407 
    408 int
    409 linux32_sys_linkat(struct lwp *l, const struct linux32_sys_linkat_args *uap, register_t *retval)
    410 {
    411 	/* {
    412 		syscallarg(int) fd1;
    413 		syscallarg(netbsd32_charp) name1;
    414 		syscallarg(int) fd2;
    415 		syscallarg(netbsd32_charp) name2;
    416 		syscallarg(int) flags;
    417 	} */
    418 	int fd1 = SCARG(uap, fd1);
    419 	const char *name1 = SCARG_P32(uap, name1);
    420 	int fd2 = SCARG(uap, fd2);
    421 	const char *name2 = SCARG_P32(uap, name2);
    422 	int follow;
    423 
    424 	follow = SCARG(uap, flags) & LINUX_AT_SYMLINK_FOLLOW;
    425 
    426 	return do_sys_linkat(l, fd1, name1, fd2, name2, follow, retval);
    427 }
    428 
    429 int
    430 linux32_sys_unlink(struct lwp *l, const struct linux32_sys_unlink_args *uap, register_t *retval)
    431 {
    432 	/* {
    433 		syscallarg(const netbsd32_charp) path;
    434 	} */
    435 	struct linux_sys_unlink_args ua;
    436 
    437 	memset(&ua, 0, sizeof(ua));
    438 	NETBSD32TOP_UAP(path, const char);
    439 
    440 	return linux_sys_unlink(l, &ua, retval);
    441 }
    442 
    443 int
    444 linux32_sys_unlinkat(struct lwp *l, const struct linux32_sys_unlinkat_args *uap, register_t *retval)
    445 {
    446 	/* {
    447 		syscallarg(int) fd;
    448 		syscallarg(const netbsd32_charp) path;
    449 		syscallarg(int) flag;
    450 	} */
    451 	struct linux_sys_unlinkat_args ua;
    452 
    453 	memset(&ua, 0, sizeof(ua));
    454 	NETBSD32TO64_UAP(fd);
    455 	NETBSD32TOP_UAP(path, const char);
    456 	NETBSD32TO64_UAP(flag);
    457 
    458 	return linux_sys_unlinkat(l, &ua, retval);
    459 }
    460 
    461 int
    462 linux32_sys_fchmodat(struct lwp *l, const struct linux32_sys_fchmodat_args *uap, register_t *retval)
    463 {
    464 	/* {
    465 		syscallarg(int) fd;
    466 		syscallarg(netbsd_charp) path;
    467 		syscallarg(linux_umode_t) mode;
    468 	} */
    469 
    470 	return do_sys_chmodat(l, SCARG(uap, fd), SCARG_P32(uap, path),
    471 			      SCARG(uap, mode), AT_SYMLINK_FOLLOW);
    472 }
    473 
    474 int
    475 linux32_sys_fchownat(struct lwp *l, const struct linux32_sys_fchownat_args *uap, register_t *retval)
    476 {
    477 	/* {
    478 		syscallarg(int) fd;
    479 		syscallarg(netbsd_charp) path;
    480 		syscallarg(uid_t) owner;
    481 		syscallarg(gid_t) group;
    482 		syscallarg(int) flag;
    483 	} */
    484 	int flag;
    485 
    486 	flag = linux_to_bsd_atflags(SCARG(uap, flag));
    487 	return do_sys_chownat(l, SCARG(uap, fd), SCARG_P32(uap, path),
    488 			      SCARG(uap, owner), SCARG(uap, group), flag);
    489 }
    490 
    491 int
    492 linux32_sys_faccessat(struct lwp *l, const struct linux32_sys_faccessat_args *uap, register_t *retval)
    493 {
    494 	/* {
    495 		syscallarg(int) fd;
    496 		syscallarg(netbsd_charp) path;
    497 		syscallarg(int) amode;
    498 	} */
    499 
    500 	return do_sys_accessat(l, SCARG(uap, fd), SCARG_P32(uap, path),
    501 	     SCARG(uap, amode), AT_SYMLINK_FOLLOW);
    502 }
    503 
    504 int
    505 linux32_sys_utimensat(struct lwp *l, const struct linux32_sys_utimensat_args *uap, register_t *retval)
    506 {
    507 	/* {
    508 		syscallarg(int) fd;
    509 		syscallarg(const netbsd32_charp) path;
    510 		syscallarg(const linux32_timespecp_t) times;
    511 		syscallarg(int) flags;
    512 	} */
    513 	int error;
    514 	struct linux32_timespec lts[2];
    515 	struct timespec *tsp = NULL, ts[2];
    516 
    517 	if (SCARG_P32(uap, times)) {
    518 		error = copyin(SCARG_P32(uap, times), &lts, sizeof(lts));
    519 		if (error != 0)
    520 			return error;
    521 		linux32_to_native_timespec(&ts[0], &lts[0]);
    522 		linux32_to_native_timespec(&ts[1], &lts[1]);
    523 		tsp = ts;
    524 	}
    525 
    526 	return linux_do_sys_utimensat(l, SCARG(uap, fd), SCARG_P32(uap, path),
    527 	    tsp, SCARG(uap, flag), retval);
    528 }
    529 
    530 int
    531 linux32_sys_creat(struct lwp *l, const struct linux32_sys_creat_args *uap, register_t *retval)
    532 {
    533 	/* {
    534 		syscallarg(const netbsd32_charp) path;
    535 		syscallarg(int) mode;
    536 	} */
    537 	struct sys_open_args ua;
    538 
    539 	memset(&ua, 0, sizeof(ua));
    540 	NETBSD32TOP_UAP(path, const char);
    541 	SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY;
    542 	NETBSD32TO64_UAP(mode);
    543 
    544 	return sys_open(l, &ua, retval);
    545 }
    546 
    547 int
    548 linux32_sys_mknod(struct lwp *l, const struct linux32_sys_mknod_args *uap, register_t *retval)
    549 {
    550 	/* {
    551 		syscallarg(const netbsd32_charp) path;
    552 		syscallarg(int) mode;
    553 		syscallarg(int) dev;
    554 	} */
    555 	struct linux_sys_mknod_args ua;
    556 
    557 	memset(&ua, 0, sizeof(ua));
    558 	NETBSD32TOP_UAP(path, const char);
    559 	NETBSD32TO64_UAP(mode);
    560 	NETBSD32TO64_UAP(dev);
    561 
    562 	return linux_sys_mknod(l, &ua, retval);
    563 }
    564 
    565 #ifdef LINUX32_SYS_break
    566 int
    567 linux32_sys_break(struct lwp *l, const struct linux32_sys_break_args *uap, register_t *retval)
    568 {
    569 #if 0
    570 	/* {
    571 		syscallarg(const netbsd32_charp) nsize;
    572 	} */
    573 #endif
    574 
    575 	return ENOSYS;
    576 }
    577 #endif
    578 
    579 int
    580 linux32_sys_swapon(struct lwp *l, const struct linux32_sys_swapon_args *uap, register_t *retval)
    581 {
    582 	/* {
    583 		syscallarg(const netbsd32_charp) name;
    584 	} */
    585 	struct sys_swapctl_args ua;
    586 
    587 	memset(&ua, 0, sizeof(ua));
    588         SCARG(&ua, cmd) = SWAP_ON;
    589         SCARG(&ua, arg) = SCARG_P32(uap, name);
    590         SCARG(&ua, misc) = 0;   /* priority */
    591         return (sys_swapctl(l, &ua, retval));
    592 }
    593 
    594 int
    595 linux32_sys_swapoff(struct lwp *l, const struct linux32_sys_swapoff_args *uap, register_t *retval)
    596 {
    597 	/* {
    598 		syscallarg(const netbsd32_charp) path;
    599 	} */
    600 	struct sys_swapctl_args ua;
    601 
    602 	memset(&ua, 0, sizeof(ua));
    603         SCARG(&ua, cmd) = SWAP_OFF;
    604         SCARG(&ua, arg) = SCARG_P32(uap, path);
    605         SCARG(&ua, misc) = 0;   /* priority */
    606         return (sys_swapctl(l, &ua, retval));
    607 }
    608 
    609 
    610 int
    611 linux32_sys_reboot(struct lwp *l, const struct linux32_sys_reboot_args *uap, register_t *retval)
    612 {
    613 	/* {
    614 		syscallarg(int) magic1;
    615 		syscallarg(int) magic2;
    616 		syscallarg(int) cmd;
    617 		syscallarg(netbsd32_voidp) arg;
    618 	} */
    619 	struct linux_sys_reboot_args ua;
    620 
    621 	memset(&ua, 0, sizeof(ua));
    622 	NETBSD32TO64_UAP(magic1);
    623 	NETBSD32TO64_UAP(magic2);
    624 	NETBSD32TO64_UAP(cmd);
    625 	NETBSD32TOP_UAP(arg, void);
    626 
    627 	return linux_sys_reboot(l, &ua, retval);
    628 }
    629 
    630 int
    631 linux32_sys_setresuid(struct lwp *l, const struct linux32_sys_setresuid_args *uap, register_t *retval)
    632 {
    633 	/* {
    634 		syscallarg(uid_t) ruid;
    635 		syscallarg(uid_t) euid;
    636 		syscallarg(uid_t) suid;
    637 	} */
    638 	struct linux_sys_setresuid_args ua;
    639 
    640 	memset(&ua, 0, sizeof(ua));
    641 	NETBSD32TO64_UAP(ruid);
    642 	NETBSD32TO64_UAP(euid);
    643 	NETBSD32TO64_UAP(suid);
    644 
    645 	return linux_sys_setresuid(l, &ua, retval);
    646 }
    647 
    648 int
    649 linux32_sys_getresuid(struct lwp *l, const struct linux32_sys_getresuid_args *uap, register_t *retval)
    650 {
    651 	/* {
    652 		syscallarg(linux32_uidp_t) ruid;
    653 		syscallarg(linux32_uidp_t) euid;
    654 		syscallarg(linux32_uidp_t) suid;
    655 	} */
    656 	kauth_cred_t pc = l->l_cred;
    657 	int error;
    658 	uid_t uid;
    659 
    660 	uid = kauth_cred_getuid(pc);
    661 	if ((error = copyout(&uid, SCARG_P32(uap, ruid), sizeof(uid_t))) != 0)
    662 		return error;
    663 
    664 	uid = kauth_cred_geteuid(pc);
    665 	if ((error = copyout(&uid, SCARG_P32(uap, euid), sizeof(uid_t))) != 0)
    666 		return error;
    667 
    668 	uid = kauth_cred_getsvuid(pc);
    669 	return copyout(&uid, SCARG_P32(uap, suid), sizeof(uid_t));
    670 }
    671 
    672 int
    673 linux32_sys_setresgid(struct lwp *l, const struct linux32_sys_setresgid_args *uap, register_t *retval)
    674 {
    675 	/* {
    676 		syscallarg(gid_t) rgid;
    677 		syscallarg(gid_t) egid;
    678 		syscallarg(gid_t) sgid;
    679 	} */
    680 	struct linux_sys_setresgid_args ua;
    681 
    682 	memset(&ua, 0, sizeof(ua));
    683 	NETBSD32TO64_UAP(rgid);
    684 	NETBSD32TO64_UAP(egid);
    685 	NETBSD32TO64_UAP(sgid);
    686 
    687 	return linux_sys_setresgid(l, &ua, retval);
    688 }
    689 
    690 int
    691 linux32_sys_getresgid(struct lwp *l, const struct linux32_sys_getresgid_args *uap, register_t *retval)
    692 {
    693 	/* {
    694 		syscallarg(linux32_gidp_t) rgid;
    695 		syscallarg(linux32_gidp_t) egid;
    696 		syscallarg(linux32_gidp_t) sgid;
    697 	} */
    698 	kauth_cred_t pc = l->l_cred;
    699 	int error;
    700 	gid_t gid;
    701 
    702 	gid = kauth_cred_getgid(pc);
    703 	if ((error = copyout(&gid, SCARG_P32(uap, rgid), sizeof(gid_t))) != 0)
    704 		return error;
    705 
    706 	gid = kauth_cred_getegid(pc);
    707 	if ((error = copyout(&gid, SCARG_P32(uap, egid), sizeof(gid_t))) != 0)
    708 		return error;
    709 
    710 	gid = kauth_cred_getsvgid(pc);
    711 	return copyout(&gid, SCARG_P32(uap, sgid), sizeof(gid_t));
    712 }
    713 
    714 int
    715 linux32_sys_nice(struct lwp *l, const struct linux32_sys_nice_args *uap, register_t *retval)
    716 {
    717 	/* {
    718 		syscallarg(int) incr;
    719 	} */
    720 	struct proc *p = l->l_proc;
    721 	struct sys_setpriority_args bsa;
    722 	int error;
    723 
    724 	memset(&bsa, 0, sizeof(bsa));
    725 	SCARG(&bsa, which) = PRIO_PROCESS;
    726 	SCARG(&bsa, who) = 0;
    727 	SCARG(&bsa, prio) = p->p_nice - NZERO + SCARG(uap, incr);
    728 
    729 	error = sys_setpriority(l, &bsa, retval);
    730 	return (error) ? EPERM : 0;
    731 }
    732 
    733 int
    734 linux32_sys_alarm(struct lwp *l, const struct linux32_sys_alarm_args *uap, register_t *retval)
    735 {
    736 	/* {
    737 		syscallarg(unsigned int) secs;
    738 	} */
    739 	struct linux_sys_alarm_args ua;
    740 
    741 	memset(&ua, 0, sizeof(ua));
    742 	NETBSD32TO64_UAP(secs);
    743 
    744 	return linux_sys_alarm(l, &ua, retval);
    745 }
    746 
    747 int
    748 linux32_sys_fdatasync(struct lwp *l, const struct linux32_sys_fdatasync_args *uap, register_t *retval)
    749 {
    750 	/* {
    751 		syscallarg(int) fd;
    752 	} */
    753 	struct linux_sys_fdatasync_args ua;
    754 
    755 	memset(&ua, 0, sizeof(ua));
    756 	NETBSD32TO64_UAP(fd);
    757 
    758 	return linux_sys_fdatasync(l, &ua, retval);
    759 }
    760 
    761 int
    762 linux32_sys_setfsuid(struct lwp *l, const struct linux32_sys_setfsuid_args *uap, register_t *retval)
    763 {
    764 	/* {
    765 		syscallarg(uid_t) uid;
    766 	} */
    767 	struct linux_sys_setfsuid_args ua;
    768 
    769 	memset(&ua, 0, sizeof(ua));
    770 	NETBSD32TO64_UAP(uid);
    771 
    772 	return linux_sys_setfsuid(l, &ua, retval);
    773 }
    774 
    775 int
    776 linux32_sys_setfsgid(struct lwp *l, const struct linux32_sys_setfsgid_args *uap, register_t *retval)
    777 {
    778 	/* {
    779 		syscallarg(gid_t) gid;
    780 	} */
    781 	struct linux_sys_setfsgid_args ua;
    782 
    783 	memset(&ua, 0, sizeof(ua));
    784 	NETBSD32TO64_UAP(gid);
    785 
    786 	return linux_sys_setfsgid(l, &ua, retval);
    787 }
    788 
    789 /*
    790  * pread(2).
    791  */
    792 int
    793 linux32_sys_pread(struct lwp *l,
    794     const struct linux32_sys_pread_args *uap, register_t *retval)
    795 {
    796 	/* {
    797 		syscallarg(int) fd;
    798 		syscallarg(netbsd32_voidp) buf;
    799 		syscallarg(netbsd32_size_t) nbyte;
    800 		syscallarg(netbsd32_off_t) offset;
    801 	} */
    802 	struct sys_pread_args pra;
    803 
    804 	memset(&pra, 0, sizeof(pra));
    805 	SCARG(&pra, fd) = SCARG(uap, fd);
    806 	SCARG(&pra, buf) = SCARG_P32(uap, buf);
    807 	SCARG(&pra, nbyte) = SCARG(uap, nbyte);
    808 	SCARG(&pra, PAD) = 0;
    809 	SCARG(&pra, offset) = SCARG(uap, offset);
    810 
    811 	return sys_pread(l, &pra, retval);
    812 }
    813 
    814 /*
    815  * pwrite(2).
    816  */
    817 int
    818 linux32_sys_pwrite(struct lwp *l,
    819     const struct linux32_sys_pwrite_args *uap, register_t *retval)
    820 {
    821 	/* {
    822 		syscallarg(int) fd;
    823 		syscallarg(const netbsd32_voidp) buf;
    824 		syscallarg(netbsd32_size_t) nbyte;
    825 		syscallarg(netbsd32_off_t) offset;
    826 	} */
    827 	struct sys_pwrite_args pra;
    828 
    829 	memset(&pra, 0, sizeof(pra));
    830 	SCARG(&pra, fd) = SCARG(uap, fd);
    831 	SCARG(&pra, buf) = SCARG_P32(uap, buf);
    832 	SCARG(&pra, nbyte) = SCARG(uap, nbyte);
    833 	SCARG(&pra, PAD) = 0;
    834 	SCARG(&pra, offset) = SCARG(uap, offset);
    835 
    836 	return sys_pwrite(l, &pra, retval);
    837 }
    838 
    839 /*
    840  * fallocate(2)
    841  */
    842 int
    843 linux32_sys_fallocate(struct lwp *l,
    844     const struct linux32_sys_fallocate_args *uap, register_t *retval)
    845 {
    846 	/*
    847 	 * For now just return EOPNOTSUPP, this makes glibc posix_fallocate()
    848 	 * to fallback to emulation.
    849 	 * XXX Right now no filesystem actually implements fallocate support,
    850 	 * so no need for mapping.
    851 	 */
    852 	return EOPNOTSUPP;
    853 }
    854