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 = ⅇ
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