Home | History | Annotate | Line # | Download | only in netbsd32
      1 /*	$NetBSD: netbsd32_epoll.c,v 1.5 2023/09/02 21:11:54 mrg 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.5 2023/09/02 21:11:54 mrg 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 	NETBSD32TO64_UAP(flags);
     55 	return sys_epoll_create1(l, &ua, retval);
     56 }
     57 
     58 int
     59 netbsd32_epoll_ctl(struct lwp *l, const struct netbsd32_epoll_ctl_args *uap,
     60     register_t *retval)
     61 {
     62 	/* {
     63 		syscallarg(int) epfd;
     64 		syscallarg(int) op;
     65 		syscallarg(int) fd;
     66 		syscallarg(netbsd32_epoll_eventp_t) event;
     67 	} */
     68 	struct epoll_event ee, *eep;
     69 	int error;
     70 
     71 	if (SCARG(uap, op) != EPOLL_CTL_DEL) {
     72 		struct netbsd32_epoll_event ee32;
     73 
     74 		error = copyin(SCARG_P32(uap, event), &ee32, sizeof(ee32));
     75 		if (error != 0)
     76 			return error;
     77 
     78 		netbsd32_to_epoll_event(&ee32, &ee);
     79 		eep = &ee;
     80 	} else
     81 		eep = NULL;
     82 
     83 	return epoll_ctl_common(l, retval, SCARG(uap, epfd), SCARG(uap, op),
     84 	    SCARG(uap, fd), eep);
     85 }
     86 
     87 int
     88 netbsd32_epoll_pwait2(struct lwp *l,
     89     const struct netbsd32_epoll_pwait2_args *uap, register_t *retval)
     90 {
     91 	/* {
     92 		syscallarg(int) epfd;
     93 		syscallarg(netbsd32_epoll_eventp_t) events;
     94 		syscallarg(int) maxevents;
     95 		syscallarg(netbsd32_timespecp_t) timeout;
     96 		syscallarg(netbsd32_sigsetp_t) sigmask;
     97 	} */
     98 	struct epoll_event *events;
     99 	struct timespec ts, *tsp;
    100 	sigset_t ss, *ssp;
    101 	int error;
    102 	const int maxevents = SCARG(uap, maxevents);
    103 
    104 	if (maxevents <= 0 || maxevents >= EPOLL_MAX_EVENTS)
    105 		return EINVAL;
    106 
    107 	if (SCARG_P32(uap, timeout) != NULL) {
    108 		struct netbsd32_timespec ts32;
    109 
    110 		error = copyin(SCARG_P32(uap, timeout), &ts32, sizeof(ts32));
    111 		if (error != 0)
    112 			return error;
    113 
    114 		netbsd32_to_timespec(&ts32, &ts);
    115 		tsp = &ts;
    116 	} else
    117 		tsp = NULL;
    118 
    119 	if (SCARG_P32(uap, sigmask) != NULL) {
    120 		error = copyin(SCARG_P32(uap, sigmask), &ss, sizeof(ss));
    121 		if (error != 0)
    122 			return error;
    123 
    124 		ssp = &ss;
    125 	} else
    126 		ssp = NULL;
    127 
    128 	events = kmem_alloc(maxevents * sizeof(*events), KM_SLEEP);
    129 
    130 	error = epoll_wait_common(l, retval, SCARG(uap, epfd), events,
    131 	    maxevents, tsp, ssp);
    132 	if (error != 0 || *retval == 0)
    133 		goto out;
    134 
    135 	struct netbsd32_epoll_event *events32 =
    136 	    kmem_alloc(*retval * sizeof(*events32), KM_SLEEP);
    137 
    138 	for (register_t i = 0; i < *retval; i++)
    139 		netbsd32_from_epoll_event(&events[i], &events32[i]);
    140 
    141 	error = copyout(events, SCARG_P32(uap, events),
    142 	    *retval * sizeof(*events32));
    143 
    144 	kmem_free(events32, *retval * sizeof(*events32));
    145 
    146  out:
    147 	kmem_free(events, maxevents * sizeof(*events));
    148 	return error;
    149 }
    150