1 1.4 christos /* $NetBSD: kern_select_50.c,v 1.4 2023/07/28 18:19:00 christos Exp $ */ 2 1.1 pooka 3 1.1 pooka /*- 4 1.1 pooka * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 5 1.1 pooka * All rights reserved. 6 1.1 pooka * 7 1.1 pooka * This code is derived from software contributed to The NetBSD Foundation 8 1.1 pooka * by Christos Zoulas. 9 1.1 pooka * 10 1.1 pooka * Redistribution and use in source and binary forms, with or without 11 1.1 pooka * modification, are permitted provided that the following conditions 12 1.1 pooka * are met: 13 1.1 pooka * 1. Redistributions of source code must retain the above copyright 14 1.1 pooka * notice, this list of conditions and the following disclaimer. 15 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 pooka * notice, this list of conditions and the following disclaimer in the 17 1.1 pooka * documentation and/or other materials provided with the distribution. 18 1.1 pooka * 19 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 pooka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 pooka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 pooka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 pooka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 pooka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 pooka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 pooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 pooka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 pooka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 pooka * POSSIBILITY OF SUCH DAMAGE. 30 1.1 pooka */ 31 1.1 pooka #include <sys/cdefs.h> 32 1.4 christos __KERNEL_RCSID(0, "$NetBSD: kern_select_50.c,v 1.4 2023/07/28 18:19:00 christos Exp $"); 33 1.2 pgoyette 34 1.2 pgoyette #if defined(_KERNEL_OPT) 35 1.2 pgoyette #include "opt_compat_netbsd.h" 36 1.2 pgoyette #endif 37 1.1 pooka 38 1.1 pooka #include <sys/param.h> 39 1.1 pooka #include <sys/event.h> 40 1.1 pooka #include <sys/poll.h> 41 1.1 pooka #include <sys/select.h> 42 1.1 pooka #include <sys/time.h> 43 1.2 pgoyette #include <sys/syscall.h> 44 1.2 pgoyette #include <sys/syscallvar.h> 45 1.1 pooka #include <sys/syscallargs.h> 46 1.1 pooka 47 1.4 christos #include <compat/sys/event.h> 48 1.1 pooka #include <compat/sys/time.h> 49 1.2 pgoyette #include <compat/common/compat_mod.h> 50 1.2 pgoyette 51 1.2 pgoyette static const struct syscall_package kern_select_50_syscalls[] = { 52 1.2 pgoyette { SYS_compat_50_kevent, 0, (sy_call_t *)compat_50_sys_kevent }, 53 1.2 pgoyette { SYS_compat_50_select, 0, (sy_call_t *)compat_50_sys_select }, 54 1.2 pgoyette { SYS_compat_50_pselect, 0, (sy_call_t *)compat_50_sys_pselect }, 55 1.2 pgoyette { SYS_compat_50_pollts, 0, (sy_call_t *)compat_50_sys_pollts }, 56 1.2 pgoyette { 0, 0, NULL } 57 1.2 pgoyette }; 58 1.1 pooka 59 1.1 pooka static int 60 1.1 pooka compat_50_kevent_fetch_timeout(const void *src, void *dest, size_t length) 61 1.1 pooka { 62 1.1 pooka struct timespec50 ts50; 63 1.1 pooka int error; 64 1.1 pooka 65 1.1 pooka KASSERT(length == sizeof(struct timespec)); 66 1.1 pooka 67 1.1 pooka error = copyin(src, &ts50, sizeof(ts50)); 68 1.1 pooka if (error) 69 1.1 pooka return error; 70 1.1 pooka timespec50_to_timespec(&ts50, (struct timespec *)dest); 71 1.1 pooka return 0; 72 1.1 pooka } 73 1.1 pooka 74 1.1 pooka int 75 1.1 pooka compat_50_sys_kevent(struct lwp *l, const struct compat_50_sys_kevent_args *uap, 76 1.1 pooka register_t *retval) 77 1.1 pooka { 78 1.1 pooka /* { 79 1.1 pooka syscallarg(int) fd; 80 1.4 christos syscallarg(struct kevent100 *) changelist; 81 1.1 pooka syscallarg(size_t) nchanges; 82 1.4 christos syscallarg(struct kevent100 *) eventlist; 83 1.1 pooka syscallarg(size_t) nevents; 84 1.1 pooka syscallarg(struct timespec50) timeout; 85 1.1 pooka } */ 86 1.1 pooka static const struct kevent_ops compat_50_kevent_ops = { 87 1.1 pooka .keo_private = NULL, 88 1.1 pooka .keo_fetch_timeout = compat_50_kevent_fetch_timeout, 89 1.4 christos .keo_fetch_changes = compat_100___kevent50_fetch_changes, 90 1.4 christos .keo_put_events = compat_100___kevent50_put_events, 91 1.1 pooka }; 92 1.1 pooka 93 1.4 christos return kevent1(retval, SCARG(uap, fd), 94 1.4 christos (const struct kevent *)(const void *)SCARG(uap, changelist), SCARG(uap, nchanges), 95 1.4 christos (struct kevent *)(void *)SCARG(uap, eventlist), SCARG(uap, nevents), 96 1.1 pooka (const struct timespec *)(const void *)SCARG(uap, timeout), 97 1.1 pooka &compat_50_kevent_ops); 98 1.1 pooka } 99 1.1 pooka 100 1.1 pooka int 101 1.1 pooka compat_50_sys_select(struct lwp *l, 102 1.1 pooka const struct compat_50_sys_select_args *uap, register_t *retval) 103 1.1 pooka { 104 1.1 pooka /* { 105 1.1 pooka syscallarg(int) nd; 106 1.1 pooka syscallarg(fd_set *) in; 107 1.1 pooka syscallarg(fd_set *) ou; 108 1.1 pooka syscallarg(fd_set *) ex; 109 1.1 pooka syscallarg(struct timeval50 *) tv; 110 1.1 pooka } */ 111 1.1 pooka struct timespec ats, *ts = NULL; 112 1.1 pooka struct timeval50 atv50; 113 1.1 pooka int error; 114 1.1 pooka 115 1.1 pooka if (SCARG(uap, tv)) { 116 1.1 pooka error = copyin(SCARG(uap, tv), (void *)&atv50, sizeof(atv50)); 117 1.1 pooka if (error) 118 1.1 pooka return error; 119 1.3 kamil 120 1.3 kamil if (atv50.tv_usec < 0 || atv50.tv_usec >= 1000000) 121 1.3 kamil return EINVAL; 122 1.3 kamil 123 1.1 pooka ats.tv_sec = atv50.tv_sec; 124 1.1 pooka ats.tv_nsec = atv50.tv_usec * 1000; 125 1.1 pooka ts = &ats; 126 1.1 pooka } 127 1.1 pooka 128 1.1 pooka return selcommon(retval, SCARG(uap, nd), SCARG(uap, in), 129 1.1 pooka SCARG(uap, ou), SCARG(uap, ex), ts, NULL); 130 1.1 pooka } 131 1.1 pooka 132 1.1 pooka int 133 1.1 pooka compat_50_sys_pselect(struct lwp *l, 134 1.1 pooka const struct compat_50_sys_pselect_args *uap, register_t *retval) 135 1.1 pooka { 136 1.1 pooka /* { 137 1.1 pooka syscallarg(int) nd; 138 1.1 pooka syscallarg(fd_set *) in; 139 1.1 pooka syscallarg(fd_set *) ou; 140 1.1 pooka syscallarg(fd_set *) ex; 141 1.1 pooka syscallarg(const struct timespec50 *) ts; 142 1.1 pooka syscallarg(sigset_t *) mask; 143 1.1 pooka } */ 144 1.1 pooka struct timespec50 ats50; 145 1.1 pooka struct timespec ats, *ts = NULL; 146 1.1 pooka sigset_t amask, *mask = NULL; 147 1.1 pooka int error; 148 1.1 pooka 149 1.1 pooka if (SCARG(uap, ts)) { 150 1.1 pooka error = copyin(SCARG(uap, ts), &ats50, sizeof(ats50)); 151 1.1 pooka if (error) 152 1.1 pooka return error; 153 1.1 pooka timespec50_to_timespec(&ats50, &ats); 154 1.1 pooka ts = &ats; 155 1.1 pooka } 156 1.1 pooka if (SCARG(uap, mask) != NULL) { 157 1.1 pooka error = copyin(SCARG(uap, mask), &amask, sizeof(amask)); 158 1.1 pooka if (error) 159 1.1 pooka return error; 160 1.1 pooka mask = &amask; 161 1.1 pooka } 162 1.1 pooka 163 1.1 pooka return selcommon(retval, SCARG(uap, nd), SCARG(uap, in), 164 1.1 pooka SCARG(uap, ou), SCARG(uap, ex), ts, mask); 165 1.1 pooka } 166 1.1 pooka 167 1.1 pooka int 168 1.1 pooka compat_50_sys_pollts(struct lwp *l, const struct compat_50_sys_pollts_args *uap, 169 1.1 pooka register_t *retval) 170 1.1 pooka { 171 1.1 pooka /* { 172 1.1 pooka syscallarg(struct pollfd *) fds; 173 1.1 pooka syscallarg(u_int) nfds; 174 1.1 pooka syscallarg(const struct timespec50 *) ts; 175 1.1 pooka syscallarg(const sigset_t *) mask; 176 1.1 pooka } */ 177 1.1 pooka struct timespec ats, *ts = NULL; 178 1.1 pooka struct timespec50 ats50; 179 1.1 pooka sigset_t amask, *mask = NULL; 180 1.1 pooka int error; 181 1.1 pooka 182 1.1 pooka if (SCARG(uap, ts)) { 183 1.1 pooka error = copyin(SCARG(uap, ts), &ats50, sizeof(ats50)); 184 1.1 pooka if (error) 185 1.1 pooka return error; 186 1.1 pooka timespec50_to_timespec(&ats50, &ats); 187 1.1 pooka ts = &ats; 188 1.1 pooka } 189 1.1 pooka if (SCARG(uap, mask)) { 190 1.1 pooka error = copyin(SCARG(uap, mask), &amask, sizeof(amask)); 191 1.1 pooka if (error) 192 1.1 pooka return error; 193 1.1 pooka mask = &amask; 194 1.1 pooka } 195 1.1 pooka 196 1.1 pooka return pollcommon(retval, SCARG(uap, fds), SCARG(uap, nfds), ts, mask); 197 1.1 pooka } 198 1.2 pgoyette 199 1.2 pgoyette int 200 1.2 pgoyette kern_select_50_init(void) 201 1.2 pgoyette { 202 1.2 pgoyette 203 1.2 pgoyette return syscall_establish(NULL, kern_select_50_syscalls); 204 1.2 pgoyette } 205 1.2 pgoyette 206 1.2 pgoyette int 207 1.2 pgoyette kern_select_50_fini(void) 208 1.2 pgoyette { 209 1.2 pgoyette 210 1.2 pgoyette return syscall_disestablish(NULL, kern_select_50_syscalls); 211 1.2 pgoyette } 212