Compat linux/linux32 nice(2) fix. The syscall argument is an increment to be added to the current nice value, not an absolute value to be set.diff -r1.103 -r1.104 src/sys/compat/linux/common/linux_misc_notalpha.c
(njoly)
--- src/sys/compat/linux/common/linux_misc_notalpha.c 2008/07/15 16:18:08 1.103
+++ src/sys/compat/linux/common/linux_misc_notalpha.c 2008/10/03 22:39:36 1.104
@@ -1,497 +1,499 @@ | @@ -1,497 +1,499 @@ | |||
1 | /* $NetBSD: linux_misc_notalpha.c,v 1.103 2008/07/15 16:18:08 christos Exp $ */ | 1 | /* $NetBSD: linux_misc_notalpha.c,v 1.104 2008/10/03 22:39:36 njoly Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Frank van der Linden and Eric Haszlakiewicz; by Jason R. Thorpe | 8 | * by Frank van der Linden and Eric Haszlakiewicz; by Jason R. Thorpe | |
9 | * of the Numerical Aerospace Simulation Facility, NASA Ames Research Center. | 9 | * of the Numerical Aerospace Simulation Facility, NASA Ames Research Center. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * | 19 | * | |
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
30 | * POSSIBILITY OF SUCH DAMAGE. | 30 | * POSSIBILITY OF SUCH DAMAGE. | |
31 | */ | 31 | */ | |
32 | 32 | |||
33 | #include <sys/cdefs.h> | 33 | #include <sys/cdefs.h> | |
34 | __KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.103 2008/07/15 16:18:08 christos Exp $"); | 34 | __KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.104 2008/10/03 22:39:36 njoly Exp $"); | |
35 | 35 | |||
36 | #include <sys/param.h> | 36 | #include <sys/param.h> | |
37 | #include <sys/systm.h> | 37 | #include <sys/systm.h> | |
38 | #include <sys/kernel.h> | 38 | #include <sys/kernel.h> | |
39 | #include <sys/mman.h> | 39 | #include <sys/mman.h> | |
40 | #include <sys/mount.h> | 40 | #include <sys/mount.h> | |
41 | #include <sys/malloc.h> | 41 | #include <sys/malloc.h> | |
42 | #include <sys/mbuf.h> | 42 | #include <sys/mbuf.h> | |
43 | #include <sys/namei.h> | 43 | #include <sys/namei.h> | |
44 | #include <sys/proc.h> | 44 | #include <sys/proc.h> | |
45 | #include <sys/prot.h> | 45 | #include <sys/prot.h> | |
46 | #include <sys/ptrace.h> | 46 | #include <sys/ptrace.h> | |
47 | #include <sys/resource.h> | 47 | #include <sys/resource.h> | |
48 | #include <sys/resourcevar.h> | 48 | #include <sys/resourcevar.h> | |
49 | #include <sys/time.h> | 49 | #include <sys/time.h> | |
50 | #include <sys/vfs_syscalls.h> | 50 | #include <sys/vfs_syscalls.h> | |
51 | #include <sys/wait.h> | 51 | #include <sys/wait.h> | |
52 | #include <sys/kauth.h> | 52 | #include <sys/kauth.h> | |
53 | 53 | |||
54 | #include <sys/syscallargs.h> | 54 | #include <sys/syscallargs.h> | |
55 | 55 | |||
56 | #include <compat/linux/common/linux_types.h> | 56 | #include <compat/linux/common/linux_types.h> | |
57 | #include <compat/linux/common/linux_fcntl.h> | 57 | #include <compat/linux/common/linux_fcntl.h> | |
58 | #include <compat/linux/common/linux_misc.h> | 58 | #include <compat/linux/common/linux_misc.h> | |
59 | #include <compat/linux/common/linux_mmap.h> | 59 | #include <compat/linux/common/linux_mmap.h> | |
60 | #include <compat/linux/common/linux_signal.h> | 60 | #include <compat/linux/common/linux_signal.h> | |
61 | #include <compat/linux/common/linux_util.h> | 61 | #include <compat/linux/common/linux_util.h> | |
62 | #include <compat/linux/common/linux_ipc.h> | 62 | #include <compat/linux/common/linux_ipc.h> | |
63 | #include <compat/linux/common/linux_sem.h> | 63 | #include <compat/linux/common/linux_sem.h> | |
64 | 64 | |||
65 | #include <compat/linux/linux_syscallargs.h> | 65 | #include <compat/linux/linux_syscallargs.h> | |
66 | 66 | |||
67 | /* | 67 | /* | |
68 | * This file contains routines which are used | 68 | * This file contains routines which are used | |
69 | * on every linux architechture except the Alpha. | 69 | * on every linux architechture except the Alpha. | |
70 | */ | 70 | */ | |
71 | 71 | |||
72 | /* Used on: arm, i386, m68k, mips, ppc, sparc, sparc64 */ | 72 | /* Used on: arm, i386, m68k, mips, ppc, sparc, sparc64 */ | |
73 | /* Not used on: alpha */ | 73 | /* Not used on: alpha */ | |
74 | 74 | |||
75 | #ifdef DEBUG_LINUX | 75 | #ifdef DEBUG_LINUX | |
76 | #define DPRINTF(a) uprintf a | 76 | #define DPRINTF(a) uprintf a | |
77 | #else | 77 | #else | |
78 | #define DPRINTF(a) | 78 | #define DPRINTF(a) | |
79 | #endif | 79 | #endif | |
80 | 80 | |||
81 | #ifndef COMPAT_LINUX32 | 81 | #ifndef COMPAT_LINUX32 | |
82 | #if !defined(__m68k__) && !defined(__amd64__) | 82 | #if !defined(__m68k__) && !defined(__amd64__) | |
83 | static void bsd_to_linux_statfs64(const struct statvfs *, | 83 | static void bsd_to_linux_statfs64(const struct statvfs *, | |
84 | struct linux_statfs64 *); | 84 | struct linux_statfs64 *); | |
85 | #endif | 85 | #endif | |
86 | 86 | |||
87 | /* | 87 | /* | |
88 | * Alarm. This is a libc call which uses setitimer(2) in NetBSD. | 88 | * Alarm. This is a libc call which uses setitimer(2) in NetBSD. | |
89 | * Fiddle with the timers to make it work. | 89 | * Fiddle with the timers to make it work. | |
90 | * | 90 | * | |
91 | * XXX This shouldn't be dicking about with the ptimer stuff directly. | 91 | * XXX This shouldn't be dicking about with the ptimer stuff directly. | |
92 | */ | 92 | */ | |
93 | int | 93 | int | |
94 | linux_sys_alarm(struct lwp *l, const struct linux_sys_alarm_args *uap, register_t *retval) | 94 | linux_sys_alarm(struct lwp *l, const struct linux_sys_alarm_args *uap, register_t *retval) | |
95 | { | 95 | { | |
96 | /* { | 96 | /* { | |
97 | syscallarg(unsigned int) secs; | 97 | syscallarg(unsigned int) secs; | |
98 | } */ | 98 | } */ | |
99 | struct proc *p = l->l_proc; | 99 | struct proc *p = l->l_proc; | |
100 | struct timespec now; | 100 | struct timespec now; | |
101 | struct itimerspec *itp, it; | 101 | struct itimerspec *itp, it; | |
102 | struct ptimer *ptp, *spare; | 102 | struct ptimer *ptp, *spare; | |
103 | extern kmutex_t timer_lock; | 103 | extern kmutex_t timer_lock; | |
104 | struct ptimers *pts; | 104 | struct ptimers *pts; | |
105 | 105 | |||
106 | if ((pts = p->p_timers) == NULL) | 106 | if ((pts = p->p_timers) == NULL) | |
107 | pts = timers_alloc(p); | 107 | pts = timers_alloc(p); | |
108 | spare = NULL; | 108 | spare = NULL; | |
109 | 109 | |||
110 | retry: | 110 | retry: | |
111 | mutex_spin_enter(&timer_lock); | 111 | mutex_spin_enter(&timer_lock); | |
112 | if (pts && pts->pts_timers[ITIMER_REAL]) | 112 | if (pts && pts->pts_timers[ITIMER_REAL]) | |
113 | itp = &pts->pts_timers[ITIMER_REAL]->pt_time; | 113 | itp = &pts->pts_timers[ITIMER_REAL]->pt_time; | |
114 | else | 114 | else | |
115 | itp = NULL; | 115 | itp = NULL; | |
116 | /* | 116 | /* | |
117 | * Clear any pending timer alarms. | 117 | * Clear any pending timer alarms. | |
118 | */ | 118 | */ | |
119 | if (itp) { | 119 | if (itp) { | |
120 | callout_stop(&pts->pts_timers[ITIMER_REAL]->pt_ch); | 120 | callout_stop(&pts->pts_timers[ITIMER_REAL]->pt_ch); | |
121 | timespecclear(&itp->it_interval); | 121 | timespecclear(&itp->it_interval); | |
122 | getnanotime(&now); | 122 | getnanotime(&now); | |
123 | if (timespecisset(&itp->it_value) && | 123 | if (timespecisset(&itp->it_value) && | |
124 | timespeccmp(&itp->it_value, &now, >)) | 124 | timespeccmp(&itp->it_value, &now, >)) | |
125 | timespecsub(&itp->it_value, &now, &itp->it_value); | 125 | timespecsub(&itp->it_value, &now, &itp->it_value); | |
126 | /* | 126 | /* | |
127 | * Return how many seconds were left (rounded up) | 127 | * Return how many seconds were left (rounded up) | |
128 | */ | 128 | */ | |
129 | retval[0] = itp->it_value.tv_sec; | 129 | retval[0] = itp->it_value.tv_sec; | |
130 | if (itp->it_value.tv_nsec) | 130 | if (itp->it_value.tv_nsec) | |
131 | retval[0]++; | 131 | retval[0]++; | |
132 | } else { | 132 | } else { | |
133 | retval[0] = 0; | 133 | retval[0] = 0; | |
134 | } | 134 | } | |
135 | 135 | |||
136 | /* | 136 | /* | |
137 | * alarm(0) just resets the timer. | 137 | * alarm(0) just resets the timer. | |
138 | */ | 138 | */ | |
139 | if (SCARG(uap, secs) == 0) { | 139 | if (SCARG(uap, secs) == 0) { | |
140 | if (itp) | 140 | if (itp) | |
141 | timespecclear(&itp->it_value); | 141 | timespecclear(&itp->it_value); | |
142 | mutex_spin_exit(&timer_lock); | 142 | mutex_spin_exit(&timer_lock); | |
143 | return 0; | 143 | return 0; | |
144 | } | 144 | } | |
145 | 145 | |||
146 | /* | 146 | /* | |
147 | * Check the new alarm time for sanity, and set it. | 147 | * Check the new alarm time for sanity, and set it. | |
148 | */ | 148 | */ | |
149 | timespecclear(&it.it_interval); | 149 | timespecclear(&it.it_interval); | |
150 | it.it_value.tv_sec = SCARG(uap, secs); | 150 | it.it_value.tv_sec = SCARG(uap, secs); | |
151 | it.it_value.tv_nsec = 0; | 151 | it.it_value.tv_nsec = 0; | |
152 | if (itimespecfix(&it.it_value) || itimespecfix(&it.it_interval)) { | 152 | if (itimespecfix(&it.it_value) || itimespecfix(&it.it_interval)) { | |
153 | mutex_spin_exit(&timer_lock); | 153 | mutex_spin_exit(&timer_lock); | |
154 | return (EINVAL); | 154 | return (EINVAL); | |
155 | } | 155 | } | |
156 | 156 | |||
157 | ptp = pts->pts_timers[ITIMER_REAL]; | 157 | ptp = pts->pts_timers[ITIMER_REAL]; | |
158 | if (ptp == NULL) { | 158 | if (ptp == NULL) { | |
159 | if (spare == NULL) { | 159 | if (spare == NULL) { | |
160 | mutex_spin_exit(&timer_lock); | 160 | mutex_spin_exit(&timer_lock); | |
161 | spare = pool_get(&ptimer_pool, PR_WAITOK); | 161 | spare = pool_get(&ptimer_pool, PR_WAITOK); | |
162 | goto retry; | 162 | goto retry; | |
163 | } | 163 | } | |
164 | ptp = spare; | 164 | ptp = spare; | |
165 | spare = NULL; | 165 | spare = NULL; | |
166 | ptp->pt_ev.sigev_notify = SIGEV_SIGNAL; | 166 | ptp->pt_ev.sigev_notify = SIGEV_SIGNAL; | |
167 | ptp->pt_ev.sigev_signo = SIGALRM; | 167 | ptp->pt_ev.sigev_signo = SIGALRM; | |
168 | ptp->pt_overruns = 0; | 168 | ptp->pt_overruns = 0; | |
169 | ptp->pt_proc = p; | 169 | ptp->pt_proc = p; | |
170 | ptp->pt_type = CLOCK_REALTIME; | 170 | ptp->pt_type = CLOCK_REALTIME; | |
171 | ptp->pt_entry = CLOCK_REALTIME; | 171 | ptp->pt_entry = CLOCK_REALTIME; | |
172 | ptp->pt_active = 0; | 172 | ptp->pt_active = 0; | |
173 | ptp->pt_queued = 0; | 173 | ptp->pt_queued = 0; | |
174 | callout_init(&ptp->pt_ch, CALLOUT_MPSAFE); | 174 | callout_init(&ptp->pt_ch, CALLOUT_MPSAFE); | |
175 | pts->pts_timers[ITIMER_REAL] = ptp; | 175 | pts->pts_timers[ITIMER_REAL] = ptp; | |
176 | } | 176 | } | |
177 | 177 | |||
178 | if (timespecisset(&it.it_value)) { | 178 | if (timespecisset(&it.it_value)) { | |
179 | /* | 179 | /* | |
180 | * Don't need to check tvhzto() return value, here. | 180 | * Don't need to check tvhzto() return value, here. | |
181 | * callout_reset() does it for us. | 181 | * callout_reset() does it for us. | |
182 | */ | 182 | */ | |
183 | getnanotime(&now); | 183 | getnanotime(&now); | |
184 | timespecadd(&it.it_value, &now, &it.it_value); | 184 | timespecadd(&it.it_value, &now, &it.it_value); | |
185 | callout_reset(&ptp->pt_ch, tshzto(&it.it_value), | 185 | callout_reset(&ptp->pt_ch, tshzto(&it.it_value), | |
186 | realtimerexpire, ptp); | 186 | realtimerexpire, ptp); | |
187 | } | 187 | } | |
188 | ptp->pt_time = it; | 188 | ptp->pt_time = it; | |
189 | mutex_spin_exit(&timer_lock); | 189 | mutex_spin_exit(&timer_lock); | |
190 | 190 | |||
191 | return 0; | 191 | return 0; | |
192 | } | 192 | } | |
193 | #endif /* !COMPAT_LINUX32 */ | 193 | #endif /* !COMPAT_LINUX32 */ | |
194 | 194 | |||
195 | #if !defined(__amd64__) | 195 | #if !defined(__amd64__) | |
196 | int | 196 | int | |
197 | linux_sys_nice(struct lwp *l, const struct linux_sys_nice_args *uap, register_t *retval) | 197 | linux_sys_nice(struct lwp *l, const struct linux_sys_nice_args *uap, register_t *retval) | |
198 | { | 198 | { | |
199 | /* { | 199 | /* { | |
200 | syscallarg(int) incr; | 200 | syscallarg(int) incr; | |
201 | } */ | 201 | } */ | |
202 | struct proc *p = l->l_proc; | |||
202 | struct sys_setpriority_args bsa; | 203 | struct sys_setpriority_args bsa; | |
203 | 204 | |||
204 | SCARG(&bsa, which) = PRIO_PROCESS; | 205 | SCARG(&bsa, which) = PRIO_PROCESS; | |
205 | SCARG(&bsa, who) = 0; | 206 | SCARG(&bsa, who) = 0; | |
206 | SCARG(&bsa, prio) = SCARG(uap, incr); | 207 | SCARG(&bsa, prio) = p->p_nice - NZERO + SCARG(uap, incr); | |
208 | ||||
207 | return sys_setpriority(l, &bsa, retval); | 209 | return sys_setpriority(l, &bsa, retval); | |
208 | } | 210 | } | |
209 | #endif /* !__amd64__ */ | 211 | #endif /* !__amd64__ */ | |
210 | 212 | |||
211 | #ifndef COMPAT_LINUX32 | 213 | #ifndef COMPAT_LINUX32 | |
212 | #ifndef __amd64__ | 214 | #ifndef __amd64__ | |
213 | /* | 215 | /* | |
214 | * The old Linux readdir was only able to read one entry at a time, | 216 | * The old Linux readdir was only able to read one entry at a time, | |
215 | * even though it had a 'count' argument. In fact, the emulation | 217 | * even though it had a 'count' argument. In fact, the emulation | |
216 | * of the old call was better than the original, because it did handle | 218 | * of the old call was better than the original, because it did handle | |
217 | * the count arg properly. Don't bother with it anymore now, and use | 219 | * the count arg properly. Don't bother with it anymore now, and use | |
218 | * it to distinguish between old and new. The difference is that the | 220 | * it to distinguish between old and new. The difference is that the | |
219 | * newer one actually does multiple entries, and the reclen field | 221 | * newer one actually does multiple entries, and the reclen field | |
220 | * really is the reclen, not the namelength. | 222 | * really is the reclen, not the namelength. | |
221 | */ | 223 | */ | |
222 | int | 224 | int | |
223 | linux_sys_readdir(struct lwp *l, const struct linux_sys_readdir_args *uap, register_t *retval) | 225 | linux_sys_readdir(struct lwp *l, const struct linux_sys_readdir_args *uap, register_t *retval) | |
224 | { | 226 | { | |
225 | /* { | 227 | /* { | |
226 | syscallarg(int) fd; | 228 | syscallarg(int) fd; | |
227 | syscallarg(struct linux_dirent *) dent; | 229 | syscallarg(struct linux_dirent *) dent; | |
228 | syscallarg(unsigned int) count; | 230 | syscallarg(unsigned int) count; | |
229 | } */ | 231 | } */ | |
230 | int error; | 232 | int error; | |
231 | struct linux_sys_getdents_args da; | 233 | struct linux_sys_getdents_args da; | |
232 | 234 | |||
233 | SCARG(&da, fd) = SCARG(uap, fd); | 235 | SCARG(&da, fd) = SCARG(uap, fd); | |
234 | SCARG(&da, dent) = SCARG(uap, dent); | 236 | SCARG(&da, dent) = SCARG(uap, dent); | |
235 | SCARG(&da, count) = 1; | 237 | SCARG(&da, count) = 1; | |
236 | 238 | |||
237 | error = linux_sys_getdents(l, &da, retval); | 239 | error = linux_sys_getdents(l, &da, retval); | |
238 | if (error == 0 && *retval > 1) | 240 | if (error == 0 && *retval > 1) | |
239 | *retval = 1; | 241 | *retval = 1; | |
240 | 242 | |||
241 | return error; | 243 | return error; | |
242 | } | 244 | } | |
243 | #endif /* !amd64 */ | 245 | #endif /* !amd64 */ | |
244 | 246 | |||
245 | /* | 247 | /* | |
246 | * I wonder why Linux has gettimeofday() _and_ time().. Still, we | 248 | * I wonder why Linux has gettimeofday() _and_ time().. Still, we | |
247 | * need to deal with it. | 249 | * need to deal with it. | |
248 | */ | 250 | */ | |
249 | int | 251 | int | |
250 | linux_sys_time(struct lwp *l, const struct linux_sys_time_args *uap, register_t *retval) | 252 | linux_sys_time(struct lwp *l, const struct linux_sys_time_args *uap, register_t *retval) | |
251 | { | 253 | { | |
252 | /* { | 254 | /* { | |
253 | syscallarg(linux_time_t) *t; | 255 | syscallarg(linux_time_t) *t; | |
254 | } */ | 256 | } */ | |
255 | struct timeval atv; | 257 | struct timeval atv; | |
256 | linux_time_t tt; | 258 | linux_time_t tt; | |
257 | int error; | 259 | int error; | |
258 | 260 | |||
259 | microtime(&atv); | 261 | microtime(&atv); | |
260 | 262 | |||
261 | tt = atv.tv_sec; | 263 | tt = atv.tv_sec; | |
262 | if (SCARG(uap, t) && (error = copyout(&tt, SCARG(uap, t), sizeof tt))) | 264 | if (SCARG(uap, t) && (error = copyout(&tt, SCARG(uap, t), sizeof tt))) | |
263 | return error; | 265 | return error; | |
264 | 266 | |||
265 | retval[0] = tt; | 267 | retval[0] = tt; | |
266 | return 0; | 268 | return 0; | |
267 | } | 269 | } | |
268 | 270 | |||
269 | /* | 271 | /* | |
270 | * utime(). Do conversion to things that utimes() understands, | 272 | * utime(). Do conversion to things that utimes() understands, | |
271 | * and pass it on. | 273 | * and pass it on. | |
272 | */ | 274 | */ | |
273 | int | 275 | int | |
274 | linux_sys_utime(struct lwp *l, const struct linux_sys_utime_args *uap, register_t *retval) | 276 | linux_sys_utime(struct lwp *l, const struct linux_sys_utime_args *uap, register_t *retval) | |
275 | { | 277 | { | |
276 | /* { | 278 | /* { | |
277 | syscallarg(const char *) path; | 279 | syscallarg(const char *) path; | |
278 | syscallarg(struct linux_utimbuf *)times; | 280 | syscallarg(struct linux_utimbuf *)times; | |
279 | } */ | 281 | } */ | |
280 | int error; | 282 | int error; | |
281 | struct timeval tv[2], *tvp; | 283 | struct timeval tv[2], *tvp; | |
282 | struct linux_utimbuf lut; | 284 | struct linux_utimbuf lut; | |
283 | 285 | |||
284 | if (SCARG(uap, times) != NULL) { | 286 | if (SCARG(uap, times) != NULL) { | |
285 | if ((error = copyin(SCARG(uap, times), &lut, sizeof lut))) | 287 | if ((error = copyin(SCARG(uap, times), &lut, sizeof lut))) | |
286 | return error; | 288 | return error; | |
287 | tv[0].tv_usec = tv[1].tv_usec = 0; | 289 | tv[0].tv_usec = tv[1].tv_usec = 0; | |
288 | tv[0].tv_sec = lut.l_actime; | 290 | tv[0].tv_sec = lut.l_actime; | |
289 | tv[1].tv_sec = lut.l_modtime; | 291 | tv[1].tv_sec = lut.l_modtime; | |
290 | tvp = tv; | 292 | tvp = tv; | |
291 | } else | 293 | } else | |
292 | tvp = NULL; | 294 | tvp = NULL; | |
293 | 295 | |||
294 | return do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW, | 296 | return do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW, | |
295 | tvp, UIO_SYSSPACE); | 297 | tvp, UIO_SYSSPACE); | |
296 | } | 298 | } | |
297 | 299 | |||
298 | #ifndef __amd64__ | 300 | #ifndef __amd64__ | |
299 | /* | 301 | /* | |
300 | * waitpid(2). Just forward on to linux_sys_wait4 with a NULL rusage. | 302 | * waitpid(2). Just forward on to linux_sys_wait4 with a NULL rusage. | |
301 | */ | 303 | */ | |
302 | int | 304 | int | |
303 | linux_sys_waitpid(struct lwp *l, const struct linux_sys_waitpid_args *uap, register_t *retval) | 305 | linux_sys_waitpid(struct lwp *l, const struct linux_sys_waitpid_args *uap, register_t *retval) | |
304 | { | 306 | { | |
305 | /* { | 307 | /* { | |
306 | syscallarg(int) pid; | 308 | syscallarg(int) pid; | |
307 | syscallarg(int *) status; | 309 | syscallarg(int *) status; | |
308 | syscallarg(int) options; | 310 | syscallarg(int) options; | |
309 | } */ | 311 | } */ | |
310 | struct linux_sys_wait4_args linux_w4a; | 312 | struct linux_sys_wait4_args linux_w4a; | |
311 | 313 | |||
312 | SCARG(&linux_w4a, pid) = SCARG(uap, pid); | 314 | SCARG(&linux_w4a, pid) = SCARG(uap, pid); | |
313 | SCARG(&linux_w4a, status) = SCARG(uap, status); | 315 | SCARG(&linux_w4a, status) = SCARG(uap, status); | |
314 | SCARG(&linux_w4a, options) = SCARG(uap, options); | 316 | SCARG(&linux_w4a, options) = SCARG(uap, options); | |
315 | SCARG(&linux_w4a, rusage) = NULL; | 317 | SCARG(&linux_w4a, rusage) = NULL; | |
316 | 318 | |||
317 | return linux_sys_wait4(l, &linux_w4a, retval); | 319 | return linux_sys_wait4(l, &linux_w4a, retval); | |
318 | } | 320 | } | |
319 | #endif /* !amd64 */ | 321 | #endif /* !amd64 */ | |
320 | 322 | |||
321 | int | 323 | int | |
322 | linux_sys_setresgid(struct lwp *l, const struct linux_sys_setresgid_args *uap, register_t *retval) | 324 | linux_sys_setresgid(struct lwp *l, const struct linux_sys_setresgid_args *uap, register_t *retval) | |
323 | { | 325 | { | |
324 | /* { | 326 | /* { | |
325 | syscallarg(gid_t) rgid; | 327 | syscallarg(gid_t) rgid; | |
326 | syscallarg(gid_t) egid; | 328 | syscallarg(gid_t) egid; | |
327 | syscallarg(gid_t) sgid; | 329 | syscallarg(gid_t) sgid; | |
328 | } */ | 330 | } */ | |
329 | 331 | |||
330 | /* | 332 | /* | |
331 | * Note: These checks are a little different than the NetBSD | 333 | * Note: These checks are a little different than the NetBSD | |
332 | * setregid(2) call performs. This precisely follows the | 334 | * setregid(2) call performs. This precisely follows the | |
333 | * behavior of the Linux kernel. | 335 | * behavior of the Linux kernel. | |
334 | */ | 336 | */ | |
335 | return do_setresgid(l, SCARG(uap,rgid), SCARG(uap, egid), | 337 | return do_setresgid(l, SCARG(uap,rgid), SCARG(uap, egid), | |
336 | SCARG(uap, sgid), | 338 | SCARG(uap, sgid), | |
337 | ID_R_EQ_R | ID_R_EQ_E | ID_R_EQ_S | | 339 | ID_R_EQ_R | ID_R_EQ_E | ID_R_EQ_S | | |
338 | ID_E_EQ_R | ID_E_EQ_E | ID_E_EQ_S | | 340 | ID_E_EQ_R | ID_E_EQ_E | ID_E_EQ_S | | |
339 | ID_S_EQ_R | ID_S_EQ_E | ID_S_EQ_S ); | 341 | ID_S_EQ_R | ID_S_EQ_E | ID_S_EQ_S ); | |
340 | } | 342 | } | |
341 | 343 | |||
342 | int | 344 | int | |
343 | linux_sys_getresgid(struct lwp *l, const struct linux_sys_getresgid_args *uap, register_t *retval) | 345 | linux_sys_getresgid(struct lwp *l, const struct linux_sys_getresgid_args *uap, register_t *retval) | |
344 | { | 346 | { | |
345 | /* { | 347 | /* { | |
346 | syscallarg(gid_t *) rgid; | 348 | syscallarg(gid_t *) rgid; | |
347 | syscallarg(gid_t *) egid; | 349 | syscallarg(gid_t *) egid; | |
348 | syscallarg(gid_t *) sgid; | 350 | syscallarg(gid_t *) sgid; | |
349 | } */ | 351 | } */ | |
350 | kauth_cred_t pc = l->l_cred; | 352 | kauth_cred_t pc = l->l_cred; | |
351 | int error; | 353 | int error; | |
352 | gid_t gid; | 354 | gid_t gid; | |
353 | 355 | |||
354 | /* | 356 | /* | |
355 | * Linux copies these values out to userspace like so: | 357 | * Linux copies these values out to userspace like so: | |
356 | * | 358 | * | |
357 | * 1. Copy out rgid. | 359 | * 1. Copy out rgid. | |
358 | * 2. If that succeeds, copy out egid. | 360 | * 2. If that succeeds, copy out egid. | |
359 | * 3. If both of those succeed, copy out sgid. | 361 | * 3. If both of those succeed, copy out sgid. | |
360 | */ | 362 | */ | |
361 | gid = kauth_cred_getgid(pc); | 363 | gid = kauth_cred_getgid(pc); | |
362 | if ((error = copyout(&gid, SCARG(uap, rgid), sizeof(gid_t))) != 0) | 364 | if ((error = copyout(&gid, SCARG(uap, rgid), sizeof(gid_t))) != 0) | |
363 | return (error); | 365 | return (error); | |
364 | 366 | |||
365 | gid = kauth_cred_getegid(pc); | 367 | gid = kauth_cred_getegid(pc); | |
366 | if ((error = copyout(&gid, SCARG(uap, egid), sizeof(gid_t))) != 0) | 368 | if ((error = copyout(&gid, SCARG(uap, egid), sizeof(gid_t))) != 0) | |
367 | return (error); | 369 | return (error); | |
368 | 370 | |||
369 | gid = kauth_cred_getsvgid(pc); | 371 | gid = kauth_cred_getsvgid(pc); | |
370 | 372 | |||
371 | return (copyout(&gid, SCARG(uap, sgid), sizeof(gid_t))); | 373 | return (copyout(&gid, SCARG(uap, sgid), sizeof(gid_t))); | |
372 | } | 374 | } | |
373 | 375 | |||
374 | #ifndef __amd64__ | 376 | #ifndef __amd64__ | |
375 | /* | 377 | /* | |
376 | * I wonder why Linux has settimeofday() _and_ stime().. Still, we | 378 | * I wonder why Linux has settimeofday() _and_ stime().. Still, we | |
377 | * need to deal with it. | 379 | * need to deal with it. | |
378 | */ | 380 | */ | |
379 | int | 381 | int | |
380 | linux_sys_stime(struct lwp *l, const struct linux_sys_stime_args *uap, register_t *retval) | 382 | linux_sys_stime(struct lwp *l, const struct linux_sys_stime_args *uap, register_t *retval) | |
381 | { | 383 | { | |
382 | /* { | 384 | /* { | |
383 | syscallarg(linux_time_t) *t; | 385 | syscallarg(linux_time_t) *t; | |
384 | } */ | 386 | } */ | |
385 | struct timespec ats; | 387 | struct timespec ats; | |
386 | linux_time_t tt; | 388 | linux_time_t tt; | |
387 | int error; | 389 | int error; | |
388 | 390 | |||
389 | if ((error = copyin(&tt, SCARG(uap, t), sizeof tt)) != 0) | 391 | if ((error = copyin(&tt, SCARG(uap, t), sizeof tt)) != 0) | |
390 | return error; | 392 | return error; | |
391 | 393 | |||
392 | ats.tv_sec = tt; | 394 | ats.tv_sec = tt; | |
393 | ats.tv_nsec = 0; | 395 | ats.tv_nsec = 0; | |
394 | 396 | |||
395 | if ((error = settime(l->l_proc, &ats))) | 397 | if ((error = settime(l->l_proc, &ats))) | |
396 | return (error); | 398 | return (error); | |
397 | 399 | |||
398 | return 0; | 400 | return 0; | |
399 | } | 401 | } | |
400 | #endif /* !amd64 */ | 402 | #endif /* !amd64 */ | |
401 | 403 | |||
402 | #if !defined(__m68k__) && !defined(__amd64__) | 404 | #if !defined(__m68k__) && !defined(__amd64__) | |
403 | /* | 405 | /* | |
404 | * Convert NetBSD statvfs structure to Linux statfs64 structure. | 406 | * Convert NetBSD statvfs structure to Linux statfs64 structure. | |
405 | * See comments in bsd_to_linux_statfs() for further background. | 407 | * See comments in bsd_to_linux_statfs() for further background. | |
406 | * We can safely pass correct bsize and frsize here, since Linux glibc | 408 | * We can safely pass correct bsize and frsize here, since Linux glibc | |
407 | * statvfs() doesn't use statfs64(). | 409 | * statvfs() doesn't use statfs64(). | |
408 | */ | 410 | */ | |
409 | static void | 411 | static void | |
410 | bsd_to_linux_statfs64(const struct statvfs *bsp, struct linux_statfs64 *lsp) | 412 | bsd_to_linux_statfs64(const struct statvfs *bsp, struct linux_statfs64 *lsp) | |
411 | { | 413 | { | |
412 | int i, div; | 414 | int i, div; | |
413 | 415 | |||
414 | for (i = 0; i < linux_fstypes_cnt; i++) { | 416 | for (i = 0; i < linux_fstypes_cnt; i++) { | |
415 | if (strcmp(bsp->f_fstypename, linux_fstypes[i].bsd) == 0) { | 417 | if (strcmp(bsp->f_fstypename, linux_fstypes[i].bsd) == 0) { | |
416 | lsp->l_ftype = linux_fstypes[i].linux; | 418 | lsp->l_ftype = linux_fstypes[i].linux; | |
417 | break; | 419 | break; | |
418 | } | 420 | } | |
419 | } | 421 | } | |
420 | 422 | |||
421 | if (i == linux_fstypes_cnt) { | 423 | if (i == linux_fstypes_cnt) { | |
422 | DPRINTF(("unhandled fstype in linux emulation: %s\n", | 424 | DPRINTF(("unhandled fstype in linux emulation: %s\n", | |
423 | bsp->f_fstypename)); | 425 | bsp->f_fstypename)); | |
424 | lsp->l_ftype = LINUX_DEFAULT_SUPER_MAGIC; | 426 | lsp->l_ftype = LINUX_DEFAULT_SUPER_MAGIC; | |
425 | } | 427 | } | |
426 | 428 | |||
427 | div = bsp->f_frsize ? (bsp->f_bsize / bsp->f_frsize) : 1; | 429 | div = bsp->f_frsize ? (bsp->f_bsize / bsp->f_frsize) : 1; | |
428 | if (div == 0) | 430 | if (div == 0) | |
429 | div = 1; | 431 | div = 1; | |
430 | lsp->l_fbsize = bsp->f_bsize; | 432 | lsp->l_fbsize = bsp->f_bsize; | |
431 | lsp->l_ffrsize = bsp->f_frsize; | 433 | lsp->l_ffrsize = bsp->f_frsize; | |
432 | lsp->l_fblocks = bsp->f_blocks / div; | 434 | lsp->l_fblocks = bsp->f_blocks / div; | |
433 | lsp->l_fbfree = bsp->f_bfree / div; | 435 | lsp->l_fbfree = bsp->f_bfree / div; | |
434 | lsp->l_fbavail = bsp->f_bavail / div; | 436 | lsp->l_fbavail = bsp->f_bavail / div; | |
435 | lsp->l_ffiles = bsp->f_files; | 437 | lsp->l_ffiles = bsp->f_files; | |
436 | lsp->l_fffree = bsp->f_ffree / div; | 438 | lsp->l_fffree = bsp->f_ffree / div; | |
437 | /* Linux sets the fsid to 0..., we don't */ | 439 | /* Linux sets the fsid to 0..., we don't */ | |
438 | lsp->l_ffsid.val[0] = bsp->f_fsidx.__fsid_val[0]; | 440 | lsp->l_ffsid.val[0] = bsp->f_fsidx.__fsid_val[0]; | |
439 | lsp->l_ffsid.val[1] = bsp->f_fsidx.__fsid_val[1]; | 441 | lsp->l_ffsid.val[1] = bsp->f_fsidx.__fsid_val[1]; | |
440 | lsp->l_fnamelen = bsp->f_namemax; | 442 | lsp->l_fnamelen = bsp->f_namemax; | |
441 | (void)memset(lsp->l_fspare, 0, sizeof(lsp->l_fspare)); | 443 | (void)memset(lsp->l_fspare, 0, sizeof(lsp->l_fspare)); | |
442 | } | 444 | } | |
443 | 445 | |||
444 | /* | 446 | /* | |
445 | * Implement the fs stat functions. Straightforward. | 447 | * Implement the fs stat functions. Straightforward. | |
446 | */ | 448 | */ | |
447 | int | 449 | int | |
448 | linux_sys_statfs64(struct lwp *l, const struct linux_sys_statfs64_args *uap, register_t *retval) | 450 | linux_sys_statfs64(struct lwp *l, const struct linux_sys_statfs64_args *uap, register_t *retval) | |
449 | { | 451 | { | |
450 | /* { | 452 | /* { | |
451 | syscallarg(const char *) path; | 453 | syscallarg(const char *) path; | |
452 | syscallarg(size_t) sz; | 454 | syscallarg(size_t) sz; | |
453 | syscallarg(struct linux_statfs64 *) sp; | 455 | syscallarg(struct linux_statfs64 *) sp; | |
454 | } */ | 456 | } */ | |
455 | struct statvfs *sb; | 457 | struct statvfs *sb; | |
456 | struct linux_statfs64 ltmp; | 458 | struct linux_statfs64 ltmp; | |
457 | int error; | 459 | int error; | |
458 | 460 | |||
459 | if (SCARG(uap, sz) != sizeof ltmp) | 461 | if (SCARG(uap, sz) != sizeof ltmp) | |
460 | return (EINVAL); | 462 | return (EINVAL); | |
461 | 463 | |||
462 | sb = STATVFSBUF_GET(); | 464 | sb = STATVFSBUF_GET(); | |
463 | error = do_sys_pstatvfs(l, SCARG(uap, path), ST_WAIT, sb); | 465 | error = do_sys_pstatvfs(l, SCARG(uap, path), ST_WAIT, sb); | |
464 | if (error == 0) { | 466 | if (error == 0) { | |
465 | bsd_to_linux_statfs64(sb, <mp); | 467 | bsd_to_linux_statfs64(sb, <mp); | |
466 | error = copyout(<mp, SCARG(uap, sp), sizeof ltmp); | 468 | error = copyout(<mp, SCARG(uap, sp), sizeof ltmp); | |
467 | } | 469 | } | |
468 | STATVFSBUF_PUT(sb); | 470 | STATVFSBUF_PUT(sb); | |
469 | return error; | 471 | return error; | |
470 | } | 472 | } | |
471 | 473 | |||
472 | int | 474 | int | |
473 | linux_sys_fstatfs64(struct lwp *l, const struct linux_sys_fstatfs64_args *uap, register_t *retval) | 475 | linux_sys_fstatfs64(struct lwp *l, const struct linux_sys_fstatfs64_args *uap, register_t *retval) | |
474 | { | 476 | { | |
475 | /* { | 477 | /* { | |
476 | syscallarg(int) fd; | 478 | syscallarg(int) fd; | |
477 | syscallarg(size_t) sz; | 479 | syscallarg(size_t) sz; | |
478 | syscallarg(struct linux_statfs64 *) sp; | 480 | syscallarg(struct linux_statfs64 *) sp; | |
479 | } */ | 481 | } */ | |
480 | struct statvfs *sb; | 482 | struct statvfs *sb; | |
481 | struct linux_statfs64 ltmp; | 483 | struct linux_statfs64 ltmp; | |
482 | int error; | 484 | int error; | |
483 | 485 | |||
484 | if (SCARG(uap, sz) != sizeof ltmp) | 486 | if (SCARG(uap, sz) != sizeof ltmp) | |
485 | return (EINVAL); | 487 | return (EINVAL); | |
486 | 488 | |||
487 | sb = STATVFSBUF_GET(); | 489 | sb = STATVFSBUF_GET(); | |
488 | error = do_sys_fstatvfs(l, SCARG(uap, fd), ST_WAIT, sb); | 490 | error = do_sys_fstatvfs(l, SCARG(uap, fd), ST_WAIT, sb); | |
489 | if (error == 0) { | 491 | if (error == 0) { | |
490 | bsd_to_linux_statfs64(sb, <mp); | 492 | bsd_to_linux_statfs64(sb, <mp); | |
491 | error = copyout(<mp, SCARG(uap, sp), sizeof ltmp); | 493 | error = copyout(<mp, SCARG(uap, sp), sizeof ltmp); | |
492 | } | 494 | } | |
493 | STATVFSBUF_PUT(sb); | 495 | STATVFSBUF_PUT(sb); | |
494 | return error; | 496 | return error; | |
495 | } | 497 | } | |
496 | #endif /* !__m68k__ && !__amd64__ */ | 498 | #endif /* !__m68k__ && !__amd64__ */ | |
497 | #endif /* !COMPAT_LINUX32 */ | 499 | #endif /* !COMPAT_LINUX32 */ |
--- src/sys/compat/linux32/common/linux32_unistd.c 2008/09/22 13:07:46 1.23
+++ src/sys/compat/linux32/common/linux32_unistd.c 2008/10/03 22:39:36 1.24
@@ -1,500 +1,501 @@ | @@ -1,500 +1,501 @@ | |||
1 | /* $NetBSD: linux32_unistd.c,v 1.23 2008/09/22 13:07:46 njoly Exp $ */ | 1 | /* $NetBSD: linux32_unistd.c,v 1.24 2008/10/03 22:39:36 njoly Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. | 4 | * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. | |
5 | * | 5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | 7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | 8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | 9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | 10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | 12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | 13 | * documentation and/or other materials provided with the distribution. | |
14 | * 3. All advertising materials mentioning features or use of this software | 14 | * 3. All advertising materials mentioning features or use of this software | |
15 | * must display the following acknowledgement: | 15 | * must display the following acknowledgement: | |
16 | * This product includes software developed by Emmanuel Dreyfus | 16 | * This product includes software developed by Emmanuel Dreyfus | |
17 | * 4. The name of the author may not be used to endorse or promote | 17 | * 4. The name of the author may not be used to endorse or promote | |
18 | * products derived from this software without specific prior written | 18 | * products derived from this software without specific prior written | |
19 | * permission. | 19 | * permission. | |
20 | * | 20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' | 21 | * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' | |
22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS | 24 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS | |
25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
31 | * POSSIBILITY OF SUCH DAMAGE. | 31 | * POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | 32 | */ | |
33 | 33 | |||
34 | #include <sys/cdefs.h> | 34 | #include <sys/cdefs.h> | |
35 | 35 | |||
36 | __KERNEL_RCSID(0, "$NetBSD: linux32_unistd.c,v 1.23 2008/09/22 13:07:46 njoly Exp $"); | 36 | __KERNEL_RCSID(0, "$NetBSD: linux32_unistd.c,v 1.24 2008/10/03 22:39:36 njoly Exp $"); | |
37 | 37 | |||
38 | #include <sys/types.h> | 38 | #include <sys/types.h> | |
39 | #include <sys/param.h> | 39 | #include <sys/param.h> | |
40 | #include <sys/fstypes.h> | 40 | #include <sys/fstypes.h> | |
41 | #include <sys/signal.h> | 41 | #include <sys/signal.h> | |
42 | #include <sys/dirent.h> | 42 | #include <sys/dirent.h> | |
43 | #include <sys/kernel.h> | 43 | #include <sys/kernel.h> | |
44 | #include <sys/fcntl.h> | 44 | #include <sys/fcntl.h> | |
45 | #include <sys/select.h> | 45 | #include <sys/select.h> | |
46 | #include <sys/proc.h> | 46 | #include <sys/proc.h> | |
47 | #include <sys/ucred.h> | 47 | #include <sys/ucred.h> | |
48 | #include <sys/swap.h> | 48 | #include <sys/swap.h> | |
49 | 49 | |||
50 | #include <machine/types.h> | 50 | #include <machine/types.h> | |
51 | 51 | |||
52 | #include <sys/syscallargs.h> | 52 | #include <sys/syscallargs.h> | |
53 | 53 | |||
54 | #include <compat/netbsd32/netbsd32.h> | 54 | #include <compat/netbsd32/netbsd32.h> | |
55 | #include <compat/netbsd32/netbsd32_conv.h> | 55 | #include <compat/netbsd32/netbsd32_conv.h> | |
56 | 56 | |||
57 | #include <compat/linux/common/linux_types.h> | 57 | #include <compat/linux/common/linux_types.h> | |
58 | #include <compat/linux/common/linux_signal.h> | 58 | #include <compat/linux/common/linux_signal.h> | |
59 | #include <compat/linux/common/linux_machdep.h> | 59 | #include <compat/linux/common/linux_machdep.h> | |
60 | #include <compat/linux/common/linux_misc.h> | 60 | #include <compat/linux/common/linux_misc.h> | |
61 | #include <compat/linux/common/linux_oldolduname.h> | 61 | #include <compat/linux/common/linux_oldolduname.h> | |
62 | #include <compat/linux/linux_syscallargs.h> | 62 | #include <compat/linux/linux_syscallargs.h> | |
63 | 63 | |||
64 | #include <compat/linux32/common/linux32_types.h> | 64 | #include <compat/linux32/common/linux32_types.h> | |
65 | #include <compat/linux32/common/linux32_signal.h> | 65 | #include <compat/linux32/common/linux32_signal.h> | |
66 | #include <compat/linux32/common/linux32_machdep.h> | 66 | #include <compat/linux32/common/linux32_machdep.h> | |
67 | #include <compat/linux32/common/linux32_sysctl.h> | 67 | #include <compat/linux32/common/linux32_sysctl.h> | |
68 | #include <compat/linux32/common/linux32_socketcall.h> | 68 | #include <compat/linux32/common/linux32_socketcall.h> | |
69 | #include <compat/linux32/linux32_syscallargs.h> | 69 | #include <compat/linux32/linux32_syscallargs.h> | |
70 | 70 | |||
71 | static int linux32_select1(struct lwp *, register_t *, | 71 | static int linux32_select1(struct lwp *, register_t *, | |
72 | int, fd_set *, fd_set *, fd_set *, struct timeval *); | 72 | int, fd_set *, fd_set *, fd_set *, struct timeval *); | |
73 | 73 | |||
74 | int | 74 | int | |
75 | linux32_sys_brk(struct lwp *l, const struct linux32_sys_brk_args *uap, register_t *retval) | 75 | linux32_sys_brk(struct lwp *l, const struct linux32_sys_brk_args *uap, register_t *retval) | |
76 | { | 76 | { | |
77 | /* { | 77 | /* { | |
78 | syscallarg(netbsd32_charp) nsize; | 78 | syscallarg(netbsd32_charp) nsize; | |
79 | } */ | 79 | } */ | |
80 | struct linux_sys_brk_args ua; | 80 | struct linux_sys_brk_args ua; | |
81 | 81 | |||
82 | NETBSD32TOP_UAP(nsize, char); | 82 | NETBSD32TOP_UAP(nsize, char); | |
83 | return linux_sys_brk(l, &ua, retval); | 83 | return linux_sys_brk(l, &ua, retval); | |
84 | } | 84 | } | |
85 | 85 | |||
86 | int | 86 | int | |
87 | linux32_sys_llseek(struct lwp *l, const struct linux32_sys_llseek_args *uap, register_t *retval) | 87 | linux32_sys_llseek(struct lwp *l, const struct linux32_sys_llseek_args *uap, register_t *retval) | |
88 | { | 88 | { | |
89 | /* { | 89 | /* { | |
90 | syscallcarg(int) fd; | 90 | syscallcarg(int) fd; | |
91 | syscallarg(u_int32_t) ohigh; | 91 | syscallarg(u_int32_t) ohigh; | |
92 | syscallarg(u_int32_t) olow; | 92 | syscallarg(u_int32_t) olow; | |
93 | syscallarg(netbsd32_caddr_t) res; | 93 | syscallarg(netbsd32_caddr_t) res; | |
94 | syscallcarg(int) whence; | 94 | syscallcarg(int) whence; | |
95 | } */ | 95 | } */ | |
96 | struct linux_sys_llseek_args ua; | 96 | struct linux_sys_llseek_args ua; | |
97 | 97 | |||
98 | NETBSD32TO64_UAP(fd); | 98 | NETBSD32TO64_UAP(fd); | |
99 | NETBSD32TO64_UAP(ohigh); | 99 | NETBSD32TO64_UAP(ohigh); | |
100 | NETBSD32TO64_UAP(olow); | 100 | NETBSD32TO64_UAP(olow); | |
101 | NETBSD32TOP_UAP(res, char); | 101 | NETBSD32TOP_UAP(res, char); | |
102 | NETBSD32TO64_UAP(whence); | 102 | NETBSD32TO64_UAP(whence); | |
103 | 103 | |||
104 | return linux_sys_llseek(l, &ua, retval); | 104 | return linux_sys_llseek(l, &ua, retval); | |
105 | } | 105 | } | |
106 | 106 | |||
107 | int | 107 | int | |
108 | linux32_sys_select(struct lwp *l, const struct linux32_sys_select_args *uap, register_t *retval) | 108 | linux32_sys_select(struct lwp *l, const struct linux32_sys_select_args *uap, register_t *retval) | |
109 | { | 109 | { | |
110 | /* { | 110 | /* { | |
111 | syscallarg(int) nfds; | 111 | syscallarg(int) nfds; | |
112 | syscallarg(netbsd32_fd_setp_t) readfds; | 112 | syscallarg(netbsd32_fd_setp_t) readfds; | |
113 | syscallarg(netbsd32_fd_setp_t) writefds; | 113 | syscallarg(netbsd32_fd_setp_t) writefds; | |
114 | syscallarg(netbsd32_fd_setp_t) exceptfds; | 114 | syscallarg(netbsd32_fd_setp_t) exceptfds; | |
115 | syscallarg(netbsd32_timevalp_t) timeout; | 115 | syscallarg(netbsd32_timevalp_t) timeout; | |
116 | } */ | 116 | } */ | |
117 | 117 | |||
118 | return linux32_select1(l, retval, SCARG(uap, nfds), | 118 | return linux32_select1(l, retval, SCARG(uap, nfds), | |
119 | SCARG_P32(uap, readfds), | 119 | SCARG_P32(uap, readfds), | |
120 | SCARG_P32(uap, writefds), | 120 | SCARG_P32(uap, writefds), | |
121 | SCARG_P32(uap, exceptfds), | 121 | SCARG_P32(uap, exceptfds), | |
122 | SCARG_P32(uap, timeout)); | 122 | SCARG_P32(uap, timeout)); | |
123 | } | 123 | } | |
124 | 124 | |||
125 | int | 125 | int | |
126 | linux32_sys_oldselect(struct lwp *l, const struct linux32_sys_oldselect_args *uap, register_t *retval) | 126 | linux32_sys_oldselect(struct lwp *l, const struct linux32_sys_oldselect_args *uap, register_t *retval) | |
127 | { | 127 | { | |
128 | /* { | 128 | /* { | |
129 | syscallarg(linux32_oldselectp_t) lsp; | 129 | syscallarg(linux32_oldselectp_t) lsp; | |
130 | } */ | 130 | } */ | |
131 | struct linux32_oldselect lsp32; | 131 | struct linux32_oldselect lsp32; | |
132 | int error; | 132 | int error; | |
133 | 133 | |||
134 | if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0) | 134 | if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0) | |
135 | return error; | 135 | return error; | |
136 | 136 | |||
137 | return linux32_select1(l, retval, lsp32.nfds, | 137 | return linux32_select1(l, retval, lsp32.nfds, | |
138 | NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds), | 138 | NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds), | |
139 | NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout)); | 139 | NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout)); | |
140 | } | 140 | } | |
141 | 141 | |||
142 | static int | 142 | static int | |
143 | linux32_select1(l, retval, nfds, readfds, writefds, exceptfds, timeout) | 143 | linux32_select1(l, retval, nfds, readfds, writefds, exceptfds, timeout) | |
144 | struct lwp *l; | 144 | struct lwp *l; | |
145 | register_t *retval; | 145 | register_t *retval; | |
146 | int nfds; | 146 | int nfds; | |
147 | fd_set *readfds, *writefds, *exceptfds; | 147 | fd_set *readfds, *writefds, *exceptfds; | |
148 | struct timeval *timeout; | 148 | struct timeval *timeout; | |
149 | { | 149 | { | |
150 | struct timeval tv0, tv1, utv, *tv = NULL; | 150 | struct timeval tv0, tv1, utv, *tv = NULL; | |
151 | struct netbsd32_timeval utv32; | 151 | struct netbsd32_timeval utv32; | |
152 | int error; | 152 | int error; | |
153 | 153 | |||
154 | timerclear(&utv); /* XXX GCC4 */ | 154 | timerclear(&utv); /* XXX GCC4 */ | |
155 | 155 | |||
156 | /* | 156 | /* | |
157 | * Store current time for computation of the amount of | 157 | * Store current time for computation of the amount of | |
158 | * time left. | 158 | * time left. | |
159 | */ | 159 | */ | |
160 | if (timeout) { | 160 | if (timeout) { | |
161 | if ((error = copyin(timeout, &utv32, sizeof(utv32)))) | 161 | if ((error = copyin(timeout, &utv32, sizeof(utv32)))) | |
162 | return error; | 162 | return error; | |
163 | 163 | |||
164 | netbsd32_to_timeval(&utv32, &utv); | 164 | netbsd32_to_timeval(&utv32, &utv); | |
165 | 165 | |||
166 | if (itimerfix(&utv)) { | 166 | if (itimerfix(&utv)) { | |
167 | /* | 167 | /* | |
168 | * The timeval was invalid. Convert it to something | 168 | * The timeval was invalid. Convert it to something | |
169 | * valid that will act as it does under Linux. | 169 | * valid that will act as it does under Linux. | |
170 | */ | 170 | */ | |
171 | utv.tv_sec += utv.tv_usec / 1000000; | 171 | utv.tv_sec += utv.tv_usec / 1000000; | |
172 | utv.tv_usec %= 1000000; | 172 | utv.tv_usec %= 1000000; | |
173 | if (utv.tv_usec < 0) { | 173 | if (utv.tv_usec < 0) { | |
174 | utv.tv_sec -= 1; | 174 | utv.tv_sec -= 1; | |
175 | utv.tv_usec += 1000000; | 175 | utv.tv_usec += 1000000; | |
176 | } | 176 | } | |
177 | if (utv.tv_sec < 0) | 177 | if (utv.tv_sec < 0) | |
178 | timerclear(&utv); | 178 | timerclear(&utv); | |
179 | } | 179 | } | |
180 | microtime(&tv0); | 180 | microtime(&tv0); | |
181 | tv = &utv; | 181 | tv = &utv; | |
182 | } | 182 | } | |
183 | 183 | |||
184 | error = selcommon(l, retval, nfds, | 184 | error = selcommon(l, retval, nfds, | |
185 | readfds, writefds, exceptfds, tv, NULL); | 185 | readfds, writefds, exceptfds, tv, NULL); | |
186 | 186 | |||
187 | if (error) { | 187 | if (error) { | |
188 | /* | 188 | /* | |
189 | * See fs/select.c in the Linux kernel. Without this, | 189 | * See fs/select.c in the Linux kernel. Without this, | |
190 | * Maelstrom doesn't work. | 190 | * Maelstrom doesn't work. | |
191 | */ | 191 | */ | |
192 | if (error == ERESTART) | 192 | if (error == ERESTART) | |
193 | error = EINTR; | 193 | error = EINTR; | |
194 | return error; | 194 | return error; | |
195 | } | 195 | } | |
196 | 196 | |||
197 | if (timeout) { | 197 | if (timeout) { | |
198 | if (*retval) { | 198 | if (*retval) { | |
199 | /* | 199 | /* | |
200 | * Compute how much time was left of the timeout, | 200 | * Compute how much time was left of the timeout, | |
201 | * by subtracting the current time and the time | 201 | * by subtracting the current time and the time | |
202 | * before we started the call, and subtracting | 202 | * before we started the call, and subtracting | |
203 | * that result from the user-supplied value. | 203 | * that result from the user-supplied value. | |
204 | */ | 204 | */ | |
205 | microtime(&tv1); | 205 | microtime(&tv1); | |
206 | timersub(&tv1, &tv0, &tv1); | 206 | timersub(&tv1, &tv0, &tv1); | |
207 | timersub(&utv, &tv1, &utv); | 207 | timersub(&utv, &tv1, &utv); | |
208 | if (utv.tv_sec < 0) | 208 | if (utv.tv_sec < 0) | |
209 | timerclear(&utv); | 209 | timerclear(&utv); | |
210 | } else { | 210 | } else { | |
211 | timerclear(&utv); | 211 | timerclear(&utv); | |
212 | } | 212 | } | |
213 | 213 | |||
214 | netbsd32_from_timeval(&utv, &utv32); | 214 | netbsd32_from_timeval(&utv, &utv32); | |
215 | 215 | |||
216 | if ((error = copyout(&utv32, timeout, sizeof(utv32)))) | 216 | if ((error = copyout(&utv32, timeout, sizeof(utv32)))) | |
217 | return error; | 217 | return error; | |
218 | } | 218 | } | |
219 | 219 | |||
220 | return 0; | 220 | return 0; | |
221 | } | 221 | } | |
222 | 222 | |||
223 | int | 223 | int | |
224 | linux32_sys_pipe(struct lwp *l, const struct linux32_sys_pipe_args *uap, register_t *retval) | 224 | linux32_sys_pipe(struct lwp *l, const struct linux32_sys_pipe_args *uap, register_t *retval) | |
225 | { | 225 | { | |
226 | /* { | 226 | /* { | |
227 | syscallarg(netbsd32_intp) fd; | 227 | syscallarg(netbsd32_intp) fd; | |
228 | } */ | 228 | } */ | |
229 | int error; | 229 | int error; | |
230 | int pfds[2]; | 230 | int pfds[2]; | |
231 | 231 | |||
232 | if ((error = sys_pipe(l, 0, retval))) | 232 | if ((error = sys_pipe(l, 0, retval))) | |
233 | return error; | 233 | return error; | |
234 | 234 | |||
235 | pfds[0] = (int)retval[0]; | 235 | pfds[0] = (int)retval[0]; | |
236 | pfds[1] = (int)retval[1]; | 236 | pfds[1] = (int)retval[1]; | |
237 | 237 | |||
238 | if ((error = copyout(pfds, SCARG_P32(uap, fd), 2 * sizeof (int))) != 0) | 238 | if ((error = copyout(pfds, SCARG_P32(uap, fd), 2 * sizeof (int))) != 0) | |
239 | return error; | 239 | return error; | |
240 | 240 | |||
241 | retval[0] = 0; | 241 | retval[0] = 0; | |
242 | retval[1] = 0; | 242 | retval[1] = 0; | |
243 | 243 | |||
244 | return 0; | 244 | return 0; | |
245 | } | 245 | } | |
246 | 246 | |||
247 | 247 | |||
248 | int | 248 | int | |
249 | linux32_sys_unlink(struct lwp *l, const struct linux32_sys_unlink_args *uap, register_t *retval) | 249 | linux32_sys_unlink(struct lwp *l, const struct linux32_sys_unlink_args *uap, register_t *retval) | |
250 | { | 250 | { | |
251 | /* { | 251 | /* { | |
252 | syscallarg(const netbsd32_charp) path; | 252 | syscallarg(const netbsd32_charp) path; | |
253 | } */ | 253 | } */ | |
254 | struct linux_sys_unlink_args ua; | 254 | struct linux_sys_unlink_args ua; | |
255 | 255 | |||
256 | NETBSD32TOP_UAP(path, const char); | 256 | NETBSD32TOP_UAP(path, const char); | |
257 | 257 | |||
258 | return linux_sys_unlink(l, &ua, retval); | 258 | return linux_sys_unlink(l, &ua, retval); | |
259 | } | 259 | } | |
260 | 260 | |||
261 | int | 261 | int | |
262 | linux32_sys_creat(struct lwp *l, const struct linux32_sys_creat_args *uap, register_t *retval) | 262 | linux32_sys_creat(struct lwp *l, const struct linux32_sys_creat_args *uap, register_t *retval) | |
263 | { | 263 | { | |
264 | /* { | 264 | /* { | |
265 | syscallarg(const netbsd32_charp) path; | 265 | syscallarg(const netbsd32_charp) path; | |
266 | syscallarg(int) mode; | 266 | syscallarg(int) mode; | |
267 | } */ | 267 | } */ | |
268 | struct sys_open_args ua; | 268 | struct sys_open_args ua; | |
269 | 269 | |||
270 | NETBSD32TOP_UAP(path, const char); | 270 | NETBSD32TOP_UAP(path, const char); | |
271 | SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY; | 271 | SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY; | |
272 | NETBSD32TO64_UAP(mode); | 272 | NETBSD32TO64_UAP(mode); | |
273 | 273 | |||
274 | return sys_open(l, &ua, retval); | 274 | return sys_open(l, &ua, retval); | |
275 | } | 275 | } | |
276 | 276 | |||
277 | int | 277 | int | |
278 | linux32_sys_mknod(struct lwp *l, const struct linux32_sys_mknod_args *uap, register_t *retval) | 278 | linux32_sys_mknod(struct lwp *l, const struct linux32_sys_mknod_args *uap, register_t *retval) | |
279 | { | 279 | { | |
280 | /* { | 280 | /* { | |
281 | syscallarg(const netbsd32_charp) path; | 281 | syscallarg(const netbsd32_charp) path; | |
282 | syscallarg(int) mode; | 282 | syscallarg(int) mode; | |
283 | syscallarg(int) dev; | 283 | syscallarg(int) dev; | |
284 | } */ | 284 | } */ | |
285 | struct linux_sys_mknod_args ua; | 285 | struct linux_sys_mknod_args ua; | |
286 | 286 | |||
287 | NETBSD32TOP_UAP(path, const char); | 287 | NETBSD32TOP_UAP(path, const char); | |
288 | NETBSD32TO64_UAP(mode); | 288 | NETBSD32TO64_UAP(mode); | |
289 | NETBSD32TO64_UAP(dev); | 289 | NETBSD32TO64_UAP(dev); | |
290 | 290 | |||
291 | return linux_sys_mknod(l, &ua, retval); | 291 | return linux_sys_mknod(l, &ua, retval); | |
292 | } | 292 | } | |
293 | 293 | |||
294 | int | 294 | int | |
295 | linux32_sys_break(struct lwp *l, const struct linux32_sys_break_args *uap, register_t *retval) | 295 | linux32_sys_break(struct lwp *l, const struct linux32_sys_break_args *uap, register_t *retval) | |
296 | { | 296 | { | |
297 | #if 0 | 297 | #if 0 | |
298 | /* { | 298 | /* { | |
299 | syscallarg(const netbsd32_charp) nsize; | 299 | syscallarg(const netbsd32_charp) nsize; | |
300 | } */ | 300 | } */ | |
301 | #endif | 301 | #endif | |
302 | 302 | |||
303 | return ENOSYS; | 303 | return ENOSYS; | |
304 | } | 304 | } | |
305 | 305 | |||
306 | int | 306 | int | |
307 | linux32_sys_swapon(struct lwp *l, const struct linux32_sys_swapon_args *uap, register_t *retval) | 307 | linux32_sys_swapon(struct lwp *l, const struct linux32_sys_swapon_args *uap, register_t *retval) | |
308 | { | 308 | { | |
309 | /* { | 309 | /* { | |
310 | syscallarg(const netbsd32_charp) name; | 310 | syscallarg(const netbsd32_charp) name; | |
311 | } */ | 311 | } */ | |
312 | struct sys_swapctl_args ua; | 312 | struct sys_swapctl_args ua; | |
313 | 313 | |||
314 | SCARG(&ua, cmd) = SWAP_ON; | 314 | SCARG(&ua, cmd) = SWAP_ON; | |
315 | SCARG(&ua, arg) = SCARG_P32(uap, name); | 315 | SCARG(&ua, arg) = SCARG_P32(uap, name); | |
316 | SCARG(&ua, misc) = 0; /* priority */ | 316 | SCARG(&ua, misc) = 0; /* priority */ | |
317 | return (sys_swapctl(l, &ua, retval)); | 317 | return (sys_swapctl(l, &ua, retval)); | |
318 | } | 318 | } | |
319 | 319 | |||
320 | int | 320 | int | |
321 | linux32_sys_swapoff(struct lwp *l, const struct linux32_sys_swapoff_args *uap, register_t *retval) | 321 | linux32_sys_swapoff(struct lwp *l, const struct linux32_sys_swapoff_args *uap, register_t *retval) | |
322 | { | 322 | { | |
323 | /* { | 323 | /* { | |
324 | syscallarg(const netbsd32_charp) path; | 324 | syscallarg(const netbsd32_charp) path; | |
325 | } */ | 325 | } */ | |
326 | struct sys_swapctl_args ua; | 326 | struct sys_swapctl_args ua; | |
327 | 327 | |||
328 | SCARG(&ua, cmd) = SWAP_OFF; | 328 | SCARG(&ua, cmd) = SWAP_OFF; | |
329 | SCARG(&ua, arg) = SCARG_P32(uap, path); | 329 | SCARG(&ua, arg) = SCARG_P32(uap, path); | |
330 | SCARG(&ua, misc) = 0; /* priority */ | 330 | SCARG(&ua, misc) = 0; /* priority */ | |
331 | return (sys_swapctl(l, &ua, retval)); | 331 | return (sys_swapctl(l, &ua, retval)); | |
332 | } | 332 | } | |
333 | 333 | |||
334 | 334 | |||
335 | int | 335 | int | |
336 | linux32_sys_reboot(struct lwp *l, const struct linux32_sys_reboot_args *uap, register_t *retval) | 336 | linux32_sys_reboot(struct lwp *l, const struct linux32_sys_reboot_args *uap, register_t *retval) | |
337 | { | 337 | { | |
338 | /* { | 338 | /* { | |
339 | syscallarg(int) magic1; | 339 | syscallarg(int) magic1; | |
340 | syscallarg(int) magic2; | 340 | syscallarg(int) magic2; | |
341 | syscallarg(int) cmd; | 341 | syscallarg(int) cmd; | |
342 | syscallarg(netbsd32_voidp) arg; | 342 | syscallarg(netbsd32_voidp) arg; | |
343 | } */ | 343 | } */ | |
344 | struct linux_sys_reboot_args ua; | 344 | struct linux_sys_reboot_args ua; | |
345 | 345 | |||
346 | NETBSD32TO64_UAP(magic1); | 346 | NETBSD32TO64_UAP(magic1); | |
347 | NETBSD32TO64_UAP(magic2); | 347 | NETBSD32TO64_UAP(magic2); | |
348 | NETBSD32TO64_UAP(cmd); | 348 | NETBSD32TO64_UAP(cmd); | |
349 | NETBSD32TOP_UAP(arg, void); | 349 | NETBSD32TOP_UAP(arg, void); | |
350 | 350 | |||
351 | return linux_sys_reboot(l, &ua, retval); | 351 | return linux_sys_reboot(l, &ua, retval); | |
352 | } | 352 | } | |
353 | 353 | |||
354 | int | 354 | int | |
355 | linux32_sys_setresuid(struct lwp *l, const struct linux32_sys_setresuid_args *uap, register_t *retval) | 355 | linux32_sys_setresuid(struct lwp *l, const struct linux32_sys_setresuid_args *uap, register_t *retval) | |
356 | { | 356 | { | |
357 | /* { | 357 | /* { | |
358 | syscallarg(uid_t) ruid; | 358 | syscallarg(uid_t) ruid; | |
359 | syscallarg(uid_t) euid; | 359 | syscallarg(uid_t) euid; | |
360 | syscallarg(uid_t) suid; | 360 | syscallarg(uid_t) suid; | |
361 | } */ | 361 | } */ | |
362 | struct linux_sys_setresuid_args ua; | 362 | struct linux_sys_setresuid_args ua; | |
363 | 363 | |||
364 | SCARG(&ua, ruid) = (SCARG(uap, ruid) == -1) ? -1 : SCARG(uap, ruid); | 364 | SCARG(&ua, ruid) = (SCARG(uap, ruid) == -1) ? -1 : SCARG(uap, ruid); | |
365 | SCARG(&ua, euid) = (SCARG(uap, euid) == -1) ? -1 : SCARG(uap, euid); | 365 | SCARG(&ua, euid) = (SCARG(uap, euid) == -1) ? -1 : SCARG(uap, euid); | |
366 | SCARG(&ua, suid) = (SCARG(uap, suid) == -1) ? -1 : SCARG(uap, suid); | 366 | SCARG(&ua, suid) = (SCARG(uap, suid) == -1) ? -1 : SCARG(uap, suid); | |
367 | 367 | |||
368 | return linux_sys_setresuid(l, &ua, retval); | 368 | return linux_sys_setresuid(l, &ua, retval); | |
369 | } | 369 | } | |
370 | 370 | |||
371 | int | 371 | int | |
372 | linux32_sys_setresgid(struct lwp *l, const struct linux32_sys_setresgid_args *uap, register_t *retval) | 372 | linux32_sys_setresgid(struct lwp *l, const struct linux32_sys_setresgid_args *uap, register_t *retval) | |
373 | { | 373 | { | |
374 | /* { | 374 | /* { | |
375 | syscallarg(gid_t) rgid; | 375 | syscallarg(gid_t) rgid; | |
376 | syscallarg(gid_t) egid; | 376 | syscallarg(gid_t) egid; | |
377 | syscallarg(gid_t) sgid; | 377 | syscallarg(gid_t) sgid; | |
378 | } */ | 378 | } */ | |
379 | struct linux_sys_setresgid_args ua; | 379 | struct linux_sys_setresgid_args ua; | |
380 | 380 | |||
381 | SCARG(&ua, rgid) = (SCARG(uap, rgid) == -1) ? -1 : SCARG(uap, rgid); | 381 | SCARG(&ua, rgid) = (SCARG(uap, rgid) == -1) ? -1 : SCARG(uap, rgid); | |
382 | SCARG(&ua, egid) = (SCARG(uap, egid) == -1) ? -1 : SCARG(uap, egid); | 382 | SCARG(&ua, egid) = (SCARG(uap, egid) == -1) ? -1 : SCARG(uap, egid); | |
383 | SCARG(&ua, sgid) = (SCARG(uap, sgid) == -1) ? -1 : SCARG(uap, sgid); | 383 | SCARG(&ua, sgid) = (SCARG(uap, sgid) == -1) ? -1 : SCARG(uap, sgid); | |
384 | 384 | |||
385 | return linux_sys_setresgid(l, &ua, retval); | 385 | return linux_sys_setresgid(l, &ua, retval); | |
386 | } | 386 | } | |
387 | 387 | |||
388 | int | 388 | int | |
389 | linux32_sys_nice(struct lwp *l, const struct linux32_sys_nice_args *uap, register_t *retval) | 389 | linux32_sys_nice(struct lwp *l, const struct linux32_sys_nice_args *uap, register_t *retval) | |
390 | { | 390 | { | |
391 | /* { | 391 | /* { | |
392 | syscallarg(int) incr; | 392 | syscallarg(int) incr; | |
393 | } */ | 393 | } */ | |
394 | struct proc *p = l->l_proc; | |||
394 | struct sys_setpriority_args bsa; | 395 | struct sys_setpriority_args bsa; | |
395 | 396 | |||
396 | SCARG(&bsa, which) = PRIO_PROCESS; | 397 | SCARG(&bsa, which) = PRIO_PROCESS; | |
397 | SCARG(&bsa, who) = 0; | 398 | SCARG(&bsa, who) = 0; | |
398 | SCARG(&bsa, prio) = SCARG(uap, incr); | 399 | SCARG(&bsa, prio) = p->p_nice - NZERO + SCARG(uap, incr); | |
399 | 400 | |||
400 | return sys_setpriority(l, &bsa, retval); | 401 | return sys_setpriority(l, &bsa, retval); | |
401 | } | 402 | } | |
402 | 403 | |||
403 | int | 404 | int | |
404 | linux32_sys_alarm(struct lwp *l, const struct linux32_sys_alarm_args *uap, register_t *retval) | 405 | linux32_sys_alarm(struct lwp *l, const struct linux32_sys_alarm_args *uap, register_t *retval) | |
405 | { | 406 | { | |
406 | /* { | 407 | /* { | |
407 | syscallarg(unsigned int) secs; | 408 | syscallarg(unsigned int) secs; | |
408 | } */ | 409 | } */ | |
409 | struct linux_sys_alarm_args ua; | 410 | struct linux_sys_alarm_args ua; | |
410 | 411 | |||
411 | NETBSD32TO64_UAP(secs); | 412 | NETBSD32TO64_UAP(secs); | |
412 | 413 | |||
413 | return linux_sys_alarm(l, &ua, retval); | 414 | return linux_sys_alarm(l, &ua, retval); | |
414 | } | 415 | } | |
415 | 416 | |||
416 | int | 417 | int | |
417 | linux32_sys_fdatasync(struct lwp *l, const struct linux32_sys_fdatasync_args *uap, register_t *retval) | 418 | linux32_sys_fdatasync(struct lwp *l, const struct linux32_sys_fdatasync_args *uap, register_t *retval) | |
418 | { | 419 | { | |
419 | /* { | 420 | /* { | |
420 | syscallarg(int) fd; | 421 | syscallarg(int) fd; | |
421 | } */ | 422 | } */ | |
422 | struct linux_sys_fdatasync_args ua; | 423 | struct linux_sys_fdatasync_args ua; | |
423 | 424 | |||
424 | NETBSD32TO64_UAP(fd); | 425 | NETBSD32TO64_UAP(fd); | |
425 | 426 | |||
426 | return linux_sys_fdatasync(l, &ua, retval); | 427 | return linux_sys_fdatasync(l, &ua, retval); | |
427 | } | 428 | } | |
428 | 429 | |||
429 | int | 430 | int | |
430 | linux32_sys_setfsuid(struct lwp *l, const struct linux32_sys_setfsuid_args *uap, register_t *retval) | 431 | linux32_sys_setfsuid(struct lwp *l, const struct linux32_sys_setfsuid_args *uap, register_t *retval) | |
431 | { | 432 | { | |
432 | /* { | 433 | /* { | |
433 | syscallarg(uid_t) uid; | 434 | syscallarg(uid_t) uid; | |
434 | } */ | 435 | } */ | |
435 | struct linux_sys_setfsuid_args ua; | 436 | struct linux_sys_setfsuid_args ua; | |
436 | 437 | |||
437 | NETBSD32TO64_UAP(uid); | 438 | NETBSD32TO64_UAP(uid); | |
438 | 439 | |||
439 | return linux_sys_setfsuid(l, &ua, retval); | 440 | return linux_sys_setfsuid(l, &ua, retval); | |
440 | } | 441 | } | |
441 | 442 | |||
442 | int | 443 | int | |
443 | linux32_sys_setfsgid(struct lwp *l, const struct linux32_sys_setfsgid_args *uap, register_t *retval) | 444 | linux32_sys_setfsgid(struct lwp *l, const struct linux32_sys_setfsgid_args *uap, register_t *retval) | |
444 | { | 445 | { | |
445 | /* { | 446 | /* { | |
446 | syscallarg(gid_t) gid; | 447 | syscallarg(gid_t) gid; | |
447 | } */ | 448 | } */ | |
448 | struct linux_sys_setfsgid_args ua; | 449 | struct linux_sys_setfsgid_args ua; | |
449 | 450 | |||
450 | NETBSD32TO64_UAP(gid); | 451 | NETBSD32TO64_UAP(gid); | |
451 | 452 | |||
452 | return linux_sys_setfsgid(l, &ua, retval); | 453 | return linux_sys_setfsgid(l, &ua, retval); | |
453 | } | 454 | } | |
454 | 455 | |||
455 | /* | 456 | /* | |
456 | * pread(2). | 457 | * pread(2). | |
457 | */ | 458 | */ | |
458 | int | 459 | int | |
459 | linux32_sys_pread(struct lwp *l, | 460 | linux32_sys_pread(struct lwp *l, | |
460 | const struct linux32_sys_pread_args *uap, register_t *retval) | 461 | const struct linux32_sys_pread_args *uap, register_t *retval) | |
461 | { | 462 | { | |
462 | /* { | 463 | /* { | |
463 | syscallarg(int) fd; | 464 | syscallarg(int) fd; | |
464 | syscallarg(netbsd32_voidp) buf; | 465 | syscallarg(netbsd32_voidp) buf; | |
465 | syscallarg(netbsd32_size_t) nbyte; | 466 | syscallarg(netbsd32_size_t) nbyte; | |
466 | syscallarg(linux32_off_t) offset; | 467 | syscallarg(linux32_off_t) offset; | |
467 | } */ | 468 | } */ | |
468 | struct sys_pread_args pra; | 469 | struct sys_pread_args pra; | |
469 | 470 | |||
470 | SCARG(&pra, fd) = SCARG(uap, fd); | 471 | SCARG(&pra, fd) = SCARG(uap, fd); | |
471 | SCARG(&pra, buf) = SCARG_P32(uap, buf); | 472 | SCARG(&pra, buf) = SCARG_P32(uap, buf); | |
472 | SCARG(&pra, nbyte) = SCARG(uap, nbyte); | 473 | SCARG(&pra, nbyte) = SCARG(uap, nbyte); | |
473 | SCARG(&pra, offset) = SCARG(uap, offset); | 474 | SCARG(&pra, offset) = SCARG(uap, offset); | |
474 | 475 | |||
475 | return sys_pread(l, &pra, retval); | 476 | return sys_pread(l, &pra, retval); | |
476 | } | 477 | } | |
477 | 478 | |||
478 | /* | 479 | /* | |
479 | * pwrite(2). | 480 | * pwrite(2). | |
480 | */ | 481 | */ | |
481 | int | 482 | int | |
482 | linux32_sys_pwrite(struct lwp *l, | 483 | linux32_sys_pwrite(struct lwp *l, | |
483 | const struct linux32_sys_pwrite_args *uap, register_t *retval) | 484 | const struct linux32_sys_pwrite_args *uap, register_t *retval) | |
484 | { | 485 | { | |
485 | /* { | 486 | /* { | |
486 | syscallarg(int) fd; | 487 | syscallarg(int) fd; | |
487 | syscallarg(const netbsd32_voidp) buf; | 488 | syscallarg(const netbsd32_voidp) buf; | |
488 | syscallarg(netbsd32_size_t) nbyte; | 489 | syscallarg(netbsd32_size_t) nbyte; | |
489 | syscallarg(linux32_off_t) offset; | 490 | syscallarg(linux32_off_t) offset; | |
490 | } */ | 491 | } */ | |
491 | struct sys_pwrite_args pra; | 492 | struct sys_pwrite_args pra; | |
492 | 493 | |||
493 | SCARG(&pra, fd) = SCARG(uap, fd); | 494 | SCARG(&pra, fd) = SCARG(uap, fd); | |
494 | SCARG(&pra, buf) = SCARG_P32(uap, buf); | 495 | SCARG(&pra, buf) = SCARG_P32(uap, buf); | |
495 | SCARG(&pra, nbyte) = SCARG(uap, nbyte); | 496 | SCARG(&pra, nbyte) = SCARG(uap, nbyte); | |
496 | SCARG(&pra, offset) = SCARG(uap, offset); | 497 | SCARG(&pra, offset) = SCARG(uap, offset); | |
497 | 498 | |||
498 | return sys_pwrite(l, &pra, retval); | 499 | return sys_pwrite(l, &pra, retval); | |
499 | } | 500 | } | |
500 | 501 |