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