1 /* $NetBSD: kern_50.c,v 1.2 2019/01/27 02:08:39 pgoyette Exp $ */ 2 3 /*- 4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Christos Zoulas. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: kern_50.c,v 1.2 2019/01/27 02:08:39 pgoyette Exp $"); 33 34 #if defined(_KERNEL_OPT) 35 #include "opt_compat_netbsd.h" 36 #endif 37 38 #include <sys/param.h> 39 #include <sys/lwp.h> 40 #include <sys/proc.h> 41 #include <sys/syscall.h> 42 #include <sys/syscallvar.h> 43 #include <sys/syscallargs.h> 44 45 #include <compat/sys/resource.h> 46 #include <compat/sys/time.h> 47 48 #include <compat/common/compat_mod.h> 49 50 static const struct syscall_package kern_50_syscalls[] = { 51 { SYS_compat_50__lwp_park, 0, (sy_call_t *)compat_50_sys__lwp_park }, 52 { SYS_compat_50___sigtimedwait, 0, 53 (sy_call_t *)compat_50_sys___sigtimedwait }, 54 { SYS_compat_50_wait4, 0, (sy_call_t *)compat_50_sys_wait4 }, 55 { 0, 0, NULL } 56 }; 57 58 int 59 compat_50_sys__lwp_park(struct lwp *l, 60 const struct compat_50_sys__lwp_park_args *uap, register_t *retval) 61 { 62 /* { 63 syscallarg(const struct timespec50 *) ts; 64 syscallarg(lwpid_t) unpark; 65 syscallarg(const void *) hint; 66 syscallarg(const void *) unparkhint; 67 } */ 68 struct timespec ts, *tsp; 69 struct timespec50 ts50; 70 int error; 71 72 if (SCARG(uap, ts) == NULL) 73 tsp = NULL; 74 else { 75 error = copyin(SCARG(uap, ts), &ts50, sizeof(ts50)); 76 if (error != 0) 77 return error; 78 timespec50_to_timespec(&ts50, &ts); 79 tsp = &ts; 80 } 81 82 if (SCARG(uap, unpark) != 0) { 83 error = lwp_unpark(SCARG(uap, unpark), SCARG(uap, unparkhint)); 84 if (error != 0) 85 return error; 86 } 87 88 return lwp_park(CLOCK_REALTIME, TIMER_ABSTIME, tsp, SCARG(uap, hint)); 89 } 90 91 static int 92 tscopyin(const void *u, void *s, size_t len) 93 { 94 struct timespec50 ts50; 95 int error; 96 97 KASSERT(len == sizeof(struct timespec)); 98 error = copyin(u, &ts50, sizeof(ts50)); 99 if (error) 100 return error; 101 timespec50_to_timespec(&ts50, s); 102 return 0; 103 } 104 105 static int 106 tscopyout(const void *s, void *u, size_t len) 107 { 108 struct timespec50 ts50; 109 110 KASSERT(len == sizeof(struct timespec)); 111 timespec_to_timespec50(s, &ts50); 112 return copyout(&ts50, u, sizeof(ts50)); 113 } 114 115 int 116 compat_50_sys___sigtimedwait(struct lwp *l, 117 const struct compat_50_sys___sigtimedwait_args *uap, register_t *retval) 118 { 119 int res; 120 121 res = sigtimedwait1(l, 122 (const struct sys_____sigtimedwait50_args *)uap, retval, copyin, 123 copyout, tscopyin, tscopyout); 124 if (!res) 125 *retval = 0; /* XXX NetBSD<=5 was not POSIX compliant */ 126 return res; 127 } 128 129 int 130 compat_50_sys_wait4(struct lwp *l, const struct compat_50_sys_wait4_args *uap, 131 register_t *retval) 132 { 133 /* { 134 syscallarg(int) pid; 135 syscallarg(int *) status; 136 syscallarg(int) options; 137 syscallarg(struct rusage50 *) rusage; 138 } */ 139 int status, error, pid = SCARG(uap, pid); 140 struct rusage50 ru50; 141 struct rusage ru; 142 143 error = do_sys_wait(&pid, &status, SCARG(uap, options), 144 SCARG(uap, rusage) != NULL ? &ru : NULL); 145 146 retval[0] = pid; 147 if (pid == 0) 148 return error; 149 150 if (SCARG(uap, rusage)) { 151 rusage_to_rusage50(&ru, &ru50); 152 error = copyout(&ru50, SCARG(uap, rusage), sizeof(ru50)); 153 } 154 155 if (error == 0 && SCARG(uap, status)) 156 error = copyout(&status, SCARG(uap, status), sizeof(status)); 157 158 return error; 159 } 160 161 int 162 kern_50_init(void) 163 { 164 165 return syscall_establish(NULL, kern_50_syscalls); 166 } 167 168 int 169 kern_50_fini(void) 170 { 171 172 return syscall_disestablish(NULL, kern_50_syscalls); 173 } 174