xref: /netbsd-src/sys/compat/netbsd32/netbsd32_epoll.c (revision 6e339175dc49f1f09598b03e65f50186614f10a5)
1*6e339175Smrg /*	$NetBSD: netbsd32_epoll.c,v 1.5 2023/09/02 21:11:54 mrg Exp $	*/
255a1c974Srin 
355a1c974Srin /*-
455a1c974Srin  * SPDX-License-Identifier: BSD-2-Clause
555a1c974Srin  *
655a1c974Srin  * Copyright (c) 2007 Roman Divacky
755a1c974Srin  * Copyright (c) 2014 Dmitry Chagin <dchagin@FreeBSD.org>
855a1c974Srin  *
955a1c974Srin  * Redistribution and use in source and binary forms, with or without
1055a1c974Srin  * modification, are permitted provided that the following conditions
1155a1c974Srin  * are met:
1255a1c974Srin  * 1. Redistributions of source code must retain the above copyright
1355a1c974Srin  *    notice, this list of conditions and the following disclaimer.
1455a1c974Srin  * 2. Redistributions in binary form must reproduce the above copyright
1555a1c974Srin  *    notice, this list of conditions and the following disclaimer in the
1655a1c974Srin  *    documentation and/or other materials provided with the distribution.
1755a1c974Srin  *
1855a1c974Srin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1955a1c974Srin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2055a1c974Srin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2155a1c974Srin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2255a1c974Srin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2355a1c974Srin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2455a1c974Srin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2555a1c974Srin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2655a1c974Srin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2755a1c974Srin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2855a1c974Srin  * SUCH DAMAGE.
2955a1c974Srin  */
3055a1c974Srin #include <sys/cdefs.h>
31*6e339175Smrg __KERNEL_RCSID(0, "$NetBSD: netbsd32_epoll.c,v 1.5 2023/09/02 21:11:54 mrg Exp $");
3255a1c974Srin 
3355a1c974Srin #include <sys/types.h>
3455a1c974Srin #include <sys/epoll.h>
3555a1c974Srin #include <sys/kmem.h>
3655a1c974Srin #include <sys/systm.h>
3755a1c974Srin #include <sys/syscall.h>
3855a1c974Srin #include <sys/syscallargs.h>
3955a1c974Srin 
4055a1c974Srin #include <compat/netbsd32/netbsd32.h>
4155a1c974Srin #include <compat/netbsd32/netbsd32_conv.h>
4255a1c974Srin #include <compat/netbsd32/netbsd32_syscall.h>
4355a1c974Srin #include <compat/netbsd32/netbsd32_syscallargs.h>
4455a1c974Srin 
4555a1c974Srin int
netbsd32_epoll_create1(struct lwp * l,const struct netbsd32_epoll_create1_args * uap,register_t * retval)4655a1c974Srin netbsd32_epoll_create1(struct lwp *l,
4755a1c974Srin     const struct netbsd32_epoll_create1_args *uap, register_t *retval)
4855a1c974Srin {
4955a1c974Srin 	/* {
5055a1c974Srin 		syscallarg(int)		flags;
5155a1c974Srin 	} */
5255a1c974Srin 	struct sys_epoll_create1_args ua;
5355a1c974Srin 
5455a1c974Srin 	NETBSD32TO64_UAP(flags);
5555a1c974Srin 	return sys_epoll_create1(l, &ua, retval);
5655a1c974Srin }
5755a1c974Srin 
5855a1c974Srin int
netbsd32_epoll_ctl(struct lwp * l,const struct netbsd32_epoll_ctl_args * uap,register_t * retval)5955a1c974Srin netbsd32_epoll_ctl(struct lwp *l, const struct netbsd32_epoll_ctl_args *uap,
6055a1c974Srin     register_t *retval)
6155a1c974Srin {
6255a1c974Srin 	/* {
6355a1c974Srin 		syscallarg(int) epfd;
6455a1c974Srin 		syscallarg(int) op;
6555a1c974Srin 		syscallarg(int) fd;
6655a1c974Srin 		syscallarg(netbsd32_epoll_eventp_t) event;
6755a1c974Srin 	} */
6855a1c974Srin 	struct epoll_event ee, *eep;
6955a1c974Srin 	int error;
7055a1c974Srin 
7155a1c974Srin 	if (SCARG(uap, op) != EPOLL_CTL_DEL) {
7255a1c974Srin 		struct netbsd32_epoll_event ee32;
7355a1c974Srin 
7455a1c974Srin 		error = copyin(SCARG_P32(uap, event), &ee32, sizeof(ee32));
7555a1c974Srin 		if (error != 0)
7655a1c974Srin 			return error;
7755a1c974Srin 
7855a1c974Srin 		netbsd32_to_epoll_event(&ee32, &ee);
7955a1c974Srin 		eep = &ee;
8055a1c974Srin 	} else
8155a1c974Srin 		eep = NULL;
8255a1c974Srin 
8355a1c974Srin 	return epoll_ctl_common(l, retval, SCARG(uap, epfd), SCARG(uap, op),
8455a1c974Srin 	    SCARG(uap, fd), eep);
8555a1c974Srin }
8655a1c974Srin 
8755a1c974Srin int
netbsd32_epoll_pwait2(struct lwp * l,const struct netbsd32_epoll_pwait2_args * uap,register_t * retval)8855a1c974Srin netbsd32_epoll_pwait2(struct lwp *l,
8955a1c974Srin     const struct netbsd32_epoll_pwait2_args *uap, register_t *retval)
9055a1c974Srin {
9155a1c974Srin 	/* {
9255a1c974Srin 		syscallarg(int) epfd;
9355a1c974Srin 		syscallarg(netbsd32_epoll_eventp_t) events;
9455a1c974Srin 		syscallarg(int) maxevents;
9555a1c974Srin 		syscallarg(netbsd32_timespecp_t) timeout;
9655a1c974Srin 		syscallarg(netbsd32_sigsetp_t) sigmask;
9755a1c974Srin 	} */
9855a1c974Srin 	struct epoll_event *events;
9955a1c974Srin 	struct timespec ts, *tsp;
10055a1c974Srin 	sigset_t ss, *ssp;
10155a1c974Srin 	int error;
10255a1c974Srin 	const int maxevents = SCARG(uap, maxevents);
10355a1c974Srin 
10455a1c974Srin 	if (maxevents <= 0 || maxevents >= EPOLL_MAX_EVENTS)
10555a1c974Srin 		return EINVAL;
10655a1c974Srin 
10755a1c974Srin 	if (SCARG_P32(uap, timeout) != NULL) {
10855a1c974Srin 		struct netbsd32_timespec ts32;
10955a1c974Srin 
11055a1c974Srin 		error = copyin(SCARG_P32(uap, timeout), &ts32, sizeof(ts32));
11155a1c974Srin 		if (error != 0)
11255a1c974Srin 			return error;
11355a1c974Srin 
11455a1c974Srin 		netbsd32_to_timespec(&ts32, &ts);
11555a1c974Srin 		tsp = &ts;
11655a1c974Srin 	} else
11755a1c974Srin 		tsp = NULL;
11855a1c974Srin 
11955a1c974Srin 	if (SCARG_P32(uap, sigmask) != NULL) {
12055a1c974Srin 		error = copyin(SCARG_P32(uap, sigmask), &ss, sizeof(ss));
12155a1c974Srin 		if (error != 0)
12255a1c974Srin 			return error;
12355a1c974Srin 
12455a1c974Srin 		ssp = &ss;
12555a1c974Srin 	} else
12655a1c974Srin 		ssp = NULL;
12755a1c974Srin 
12855a1c974Srin 	events = kmem_alloc(maxevents * sizeof(*events), KM_SLEEP);
12955a1c974Srin 
13055a1c974Srin 	error = epoll_wait_common(l, retval, SCARG(uap, epfd), events,
13155a1c974Srin 	    maxevents, tsp, ssp);
1326217f200Srin 	if (error != 0 || *retval == 0)
1336217f200Srin 		goto out;
13455a1c974Srin 
13555a1c974Srin 	struct netbsd32_epoll_event *events32 =
13655a1c974Srin 	    kmem_alloc(*retval * sizeof(*events32), KM_SLEEP);
13755a1c974Srin 
138*6e339175Smrg 	for (register_t i = 0; i < *retval; i++)
13955a1c974Srin 		netbsd32_from_epoll_event(&events[i], &events32[i]);
14055a1c974Srin 
14155a1c974Srin 	error = copyout(events, SCARG_P32(uap, events),
14255a1c974Srin 	    *retval * sizeof(*events32));
14355a1c974Srin 
14455a1c974Srin 	kmem_free(events32, *retval * sizeof(*events32));
14555a1c974Srin 
1466217f200Srin  out:
1476217f200Srin 	kmem_free(events, maxevents * sizeof(*events));
14855a1c974Srin 	return error;
14955a1c974Srin }
150