Home | History | Annotate | Line # | Download | only in netbsd32
      1 /*	$NetBSD: netbsd32_epoll.c,v 1.6 2026/09/20 13:45:00 riastradh Exp $	*/
      2 
      3 /*-
      4  * SPDX-License-Identifier: BSD-2-Clause
      5  *
      6  * Copyright (c) 2007 Roman Divacky
      7  * Copyright (c) 2014 Dmitry Chagin <dchagin (at) FreeBSD.org>
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  * SUCH DAMAGE.
     29  */
     30 #include <sys/cdefs.h>
     31 __KERNEL_RCSID(0, "$NetBSD: netbsd32_epoll.c,v 1.6 2026/09/20 13:45:00 riastradh Exp $");
     32 
     33 #include <sys/types.h>
     34 #include <sys/epoll.h>
     35 #include <sys/kmem.h>
     36 #include <sys/systm.h>
     37 #include <sys/syscall.h>
     38 #include <sys/syscallargs.h>
     39 
     40 #include <compat/netbsd32/netbsd32.h>
     41 #include <compat/netbsd32/netbsd32_conv.h>
     42 #include <compat/netbsd32/netbsd32_syscall.h>
     43 #include <compat/netbsd32/netbsd32_syscallargs.h>
     44 
     45 int
     46 netbsd32_epoll_create1(struct lwp *l,
     47     const struct netbsd32_epoll_create1_args *uap, register_t *retval)
     48 {
     49 	/* {
     50 		syscallarg(int)		flags;
     51 	} */
     52 	struct sys_epoll_create1_args ua;
     53 
     54 	memset(&ua, 0, sizeof(ua));
     55 	NETBSD32TO64_UAP(flags);
     56 	return sys_epoll_create1(l, &ua, retval);
     57 }
     58 
     59 int
     60 netbsd32_epoll_ctl(struct lwp *l, const struct netbsd32_epoll_ctl_args *uap,
     61     register_t *retval)
     62 {
     63 	/* {
     64 		syscallarg(int) epfd;
     65 		syscallarg(int) op;
     66 		syscallarg(int) fd;
     67 		syscallarg(netbsd32_epoll_eventp_t) event;
     68 	} */
     69 	struct epoll_event ee, *eep;
     70 	int error;
     71 
     72 	if (SCARG(uap, op) != EPOLL_CTL_DEL) {
     73 		struct netbsd32_epoll_event ee32;
     74 
     75 		error = copyin(SCARG_P32(uap, event), &ee32, sizeof(ee32));
     76 		if (error != 0)
     77 			return error;
     78 
     79 		netbsd32_to_epoll_event(&ee32, &ee);
     80 		eep = &ee;
     81 	} else
     82 		eep = NULL;
     83 
     84 	return epoll_ctl_common(l, retval, SCARG(uap, epfd), SCARG(uap, op),
     85 	    SCARG(uap, fd), eep);
     86 }
     87 
     88 int
     89 netbsd32_epoll_pwait2(struct lwp *l,
     90     const struct netbsd32_epoll_pwait2_args *uap, register_t *retval)
     91 {
     92 	/* {
     93 		syscallarg(int) epfd;
     94 		syscallarg(netbsd32_epoll_eventp_t) events;
     95 		syscallarg(int) maxevents;
     96 		syscallarg(netbsd32_timespecp_t) timeout;
     97 		syscallarg(netbsd32_sigsetp_t) sigmask;
     98 	} */
     99 	struct epoll_event *events;
    100 	struct timespec ts, *tsp;
    101 	sigset_t ss, *ssp;
    102 	int error;
    103 	const int maxevents = SCARG(uap, maxevents);
    104 
    105 	if (maxevents <= 0 || maxevents >= EPOLL_MAX_EVENTS)
    106 		return EINVAL;
    107 
    108 	if (SCARG_P32(uap, timeout) != NULL) {
    109 		struct netbsd32_timespec ts32;
    110 
    111 		error = copyin(SCARG_P32(uap, timeout), &ts32, sizeof(ts32));
    112 		if (error != 0)
    113 			return error;
    114 
    115 		netbsd32_to_timespec(&ts32, &ts);
    116 		tsp = &ts;
    117 	} else
    118 		tsp = NULL;
    119 
    120 	if (SCARG_P32(uap, sigmask) != NULL) {
    121 		error = copyin(SCARG_P32(uap, sigmask), &ss, sizeof(ss));
    122 		if (error != 0)
    123 			return error;
    124 
    125 		ssp = &ss;
    126 	} else
    127 		ssp = NULL;
    128 
    129 	events = kmem_alloc(maxevents * sizeof(*events), KM_SLEEP);
    130 
    131 	error = epoll_wait_common(l, retval, SCARG(uap, epfd), events,
    132 	    maxevents, tsp, ssp);
    133 	if (error != 0 || *retval == 0)
    134 		goto out;
    135 
    136 	struct netbsd32_epoll_event *events32 =
    137 	    kmem_alloc(*retval * sizeof(*events32), KM_SLEEP);
    138 
    139 	for (register_t i = 0; i < *retval; i++)
    140 		netbsd32_from_epoll_event(&events[i], &events32[i]);
    141 
    142 	error = copyout(events, SCARG_P32(uap, events),
    143 	    *retval * sizeof(*events32));
    144 
    145 	kmem_free(events32, *retval * sizeof(*events32));
    146 
    147  out:
    148 	kmem_free(events, maxevents * sizeof(*events));
    149 	return error;
    150 }
    151