netbsd32_compat_50.c revision 1.3 1 /* $NetBSD: netbsd32_compat_50.c,v 1.3 2009/01/26 13:00:04 njoly Exp $ */
2
3 /*-
4 * Copyright (c) 2008 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 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_50.c,v 1.3 2009/01/26 13:00:04 njoly Exp $");
40
41 #if defined(_KERNEL_OPT)
42 #include "opt_sysv.h"
43 #endif
44
45 #include "fs_lfs.h"
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/malloc.h>
50 #include <sys/mount.h>
51 #include <sys/socket.h>
52 #include <sys/socketvar.h>
53 #include <sys/stat.h>
54 #include <sys/time.h>
55 #include <sys/ktrace.h>
56 #include <sys/eventvar.h>
57 #include <sys/resourcevar.h>
58 #include <sys/vnode.h>
59 #include <sys/file.h>
60 #include <sys/filedesc.h>
61 #include <sys/poll.h>
62 #include <sys/namei.h>
63 #include <sys/statvfs.h>
64 #include <sys/syscallargs.h>
65 #include <sys/proc.h>
66 #include <sys/dirent.h>
67 #include <sys/kauth.h>
68 #include <sys/vfs_syscalls.h>
69 #include <sys/ipc.h>
70 #include <sys/msg.h>
71 #include <sys/sem.h>
72 #include <sys/shm.h>
73
74 #include <compat/netbsd32/netbsd32.h>
75 #include <compat/netbsd32/netbsd32_syscallargs.h>
76 #include <compat/netbsd32/netbsd32_conv.h>
77 #include <compat/sys/mount.h>
78 #include <compat/sys/time.h>
79
80
81 /*
82 * Common routine to set access and modification times given a vnode.
83 */
84 static int
85 get_utimes32(const netbsd32_timeval50p_t *tptr, struct timeval *tv,
86 struct timeval **tvp)
87 {
88 int error;
89 struct netbsd32_timeval50 tv32[2];
90
91 if (tptr == NULL) {
92 *tvp = NULL;
93 return 0;
94 }
95
96 error = copyin(tptr, tv32, sizeof(tv32));
97 if (error)
98 return error;
99 netbsd32_to_timeval50(&tv32[0], &tv[0]);
100 netbsd32_to_timeval50(&tv32[1], &tv[1]);
101
102 *tvp = tv;
103 return 0;
104 }
105
106 int
107 compat_50_netbsd32_mknod(struct lwp *l,
108 const struct compat_50_netbsd32_mknod_args *uap, register_t *retval)
109 {
110 /* {
111 syscallarg(netbsd32_charp) path;
112 syscallarg(mode_t) mode;
113 syscallarg(uint32_t) dev;
114 } */
115 return do_sys_mknod(l, SCARG_P32(uap, path), SCARG(uap, mode),
116 SCARG(uap, dev), retval);
117 }
118
119 int
120 compat_50_netbsd32_select(struct lwp *l,
121 const struct compat_50_netbsd32_select_args *uap, register_t *retval)
122 {
123 /* {
124 syscallarg(int) nd;
125 syscallarg(netbsd32_fd_setp_t) in;
126 syscallarg(netbsd32_fd_setp_t) ou;
127 syscallarg(netbsd32_fd_setp_t) ex;
128 syscallarg(netbsd32_timeval50p_t) tv;
129 } */
130 int error;
131 struct netbsd32_timeval50 tv32;
132 struct timeval atv, *tv = NULL;
133
134 if (SCARG_P32(uap, tv)) {
135 error = copyin(SCARG_P32(uap, tv), &tv32, sizeof(tv32));
136 if (error != 0)
137 return error;
138 netbsd32_to_timeval50(&tv32, &atv);
139 tv = &atv;
140 }
141
142 return selcommon(l, retval, SCARG(uap, nd), SCARG_P32(uap, in),
143 SCARG_P32(uap, ou), SCARG_P32(uap, ex), tv, NULL);
144 return 0;
145 }
146
147 int
148 compat_50_netbsd32_gettimeofday(struct lwp *l,
149 const struct compat_50_netbsd32_gettimeofday_args *uap, register_t *retval)
150 {
151 /* {
152 syscallarg(netbsd32_timeval50p_t) tp;
153 syscallarg(netbsd32_timezonep_t) tzp;
154 } */
155 struct timeval atv;
156 struct netbsd32_timeval50 tv32;
157 int error = 0;
158 struct netbsd32_timezone tzfake;
159
160 if (SCARG_P32(uap, tp)) {
161 microtime(&atv);
162 netbsd32_from_timeval50(&atv, &tv32);
163 error = copyout(&tv32, SCARG_P32(uap, tp), sizeof(tv32));
164 if (error)
165 return error;
166 }
167 if (SCARG_P32(uap, tzp)) {
168 /*
169 * NetBSD has no kernel notion of time zone, so we just
170 * fake up a timezone struct and return it if demanded.
171 */
172 tzfake.tz_minuteswest = 0;
173 tzfake.tz_dsttime = 0;
174 error = copyout(&tzfake, SCARG_P32(uap, tzp), sizeof(tzfake));
175 }
176 return error;
177 }
178
179 int
180 compat_50_netbsd32_settimeofday(struct lwp *l,
181 const struct compat_50_netbsd32_settimeofday_args *uap, register_t *retval)
182 {
183 /* {
184 syscallarg(const netbsd32_timeval50p_t) tv;
185 syscallarg(const netbsd32_timezonep_t) tzp;
186 } */
187 struct netbsd32_timeval50 atv32;
188 struct timeval atv;
189 struct timespec ats;
190 int error;
191 struct proc *p = l->l_proc;
192
193 /* Verify all parameters before changing time. */
194
195 /*
196 * NetBSD has no kernel notion of time zone, and only an
197 * obsolete program would try to set it, so we log a warning.
198 */
199 if (SCARG_P32(uap, tzp))
200 printf("pid %d attempted to set the "
201 "(obsolete) kernel time zone\n", p->p_pid);
202
203 if (SCARG_P32(uap, tv) == 0)
204 return 0;
205
206 if ((error = copyin(SCARG_P32(uap, tv), &atv32, sizeof(atv32))) != 0)
207 return error;
208
209 netbsd32_to_timeval50(&atv32, &atv);
210 TIMEVAL_TO_TIMESPEC(&atv, &ats);
211 return settime(p, &ats);
212 }
213
214 int
215 compat_50_netbsd32_utimes(struct lwp *l,
216 const struct compat_50_netbsd32_utimes_args *uap, register_t *retval)
217 {
218 /* {
219 syscallarg(const netbsd32_charp) path;
220 syscallarg(const netbsd32_timeval50p_t) tptr;
221 } */
222 int error;
223 struct timeval tv[2], *tvp;
224
225 error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp);
226 if (error != 0)
227 return error;
228
229 return do_sys_utimes(l, NULL, SCARG_P32(uap, path), FOLLOW,
230 tvp, UIO_SYSSPACE);
231 }
232
233 int
234 compat_50_netbsd32_adjtime(struct lwp *l,
235 const struct compat_50_netbsd32_adjtime_args *uap, register_t *retval)
236 {
237 /* {
238 syscallarg(const netbsd32_timeval50p_t) delta;
239 syscallarg(netbsd32_timeval50p_t) olddelta;
240 } */
241 struct netbsd32_timeval50 atv;
242 int error;
243
244 extern int time_adjusted; /* in kern_ntptime.c */
245 extern int64_t time_adjtime; /* in kern_ntptime.c */
246
247 if ((error = kauth_authorize_system(l->l_cred,
248 KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_ADJTIME, NULL, NULL,
249 NULL)) != 0)
250 return (error);
251
252 if (SCARG_P32(uap, olddelta)) {
253 atv.tv_sec = time_adjtime / 1000000;
254 atv.tv_usec = time_adjtime % 1000000;
255 if (atv.tv_usec < 0) {
256 atv.tv_usec += 1000000;
257 atv.tv_sec--;
258 }
259 (void) copyout(&atv,
260 SCARG_P32(uap, olddelta),
261 sizeof(atv));
262 if (error)
263 return (error);
264 }
265
266 if (SCARG_P32(uap, delta)) {
267 error = copyin(SCARG_P32(uap, delta), &atv,
268 sizeof(struct timeval));
269 if (error)
270 return (error);
271
272 time_adjtime = (int64_t)atv.tv_sec * 1000000 + atv.tv_usec;
273
274 if (time_adjtime)
275 /* We need to save the system time during shutdown */
276 time_adjusted |= 1;
277 }
278
279 return 0;
280 }
281
282 #if defined(LFS) || !defined(_KERNEL)
283 int
284 compat_50_netbsd32_lfs_segwait(struct lwp *l,
285 const struct compat_50_netbsd32_lfs_segwait_args *uap, register_t *retval)
286 {
287 return 0;
288 }
289 #endif
290
291 int
292 compat_50_netbsd32_futimes(struct lwp *l,
293 const struct compat_50_netbsd32_futimes_args *uap, register_t *retval)
294 {
295 /* {
296 syscallarg(int) fd;
297 syscallarg(const netbsd32_timeval50p_t) tptr;
298 } */
299 int error;
300 file_t *fp;
301 struct timeval tv[2], *tvp;
302
303 error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp);
304 if (error != 0)
305 return error;
306
307 /* fd_getvnode() will use the descriptor for us */
308 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
309 return error;
310
311 error = do_sys_utimes(l, fp->f_data, NULL, 0, tvp, UIO_SYSSPACE);
312
313 fd_putfile(SCARG(uap, fd));
314 return error;
315 }
316
317 int
318 compat_50_netbsd32_clock_gettime(struct lwp *l,
319 const struct compat_50_netbsd32_clock_gettime_args *uap, register_t *retval)
320 {
321 /* {
322 syscallarg(netbsd32_clockid_t) clock_id;
323 syscallarg(netbsd32_timespec50p_t) tp;
324 } */
325 clockid_t clock_id;
326 struct timespec ats;
327 struct netbsd32_timespec50 ts32;
328
329 clock_id = SCARG(uap, clock_id);
330 if (clock_id != CLOCK_REALTIME)
331 return (EINVAL);
332
333 nanotime(&ats);
334 netbsd32_from_timespec50(&ats, &ts32);
335
336 return copyout(&ts32, SCARG_P32(uap, tp), sizeof(ts32));
337 }
338
339 int
340 compat_50_netbsd32_clock_settime(struct lwp *l,
341 const struct compat_50_netbsd32_clock_settime_args *uap, register_t *retval)
342 {
343 /* {
344 syscallarg(netbsd32_clockid_t) clock_id;
345 syscallarg(const netbsd32_timespec50p_t) tp;
346 } */
347 struct netbsd32_timespec50 ts32;
348 clockid_t clock_id;
349 struct timespec ats;
350 int error;
351
352 clock_id = SCARG(uap, clock_id);
353 if (clock_id != CLOCK_REALTIME)
354 return (EINVAL);
355
356 if ((error = copyin(SCARG_P32(uap, tp), &ts32, sizeof(ts32))) != 0)
357 return (error);
358
359 netbsd32_to_timespec50(&ts32, &ats);
360 return settime(l->l_proc, &ats);
361 }
362
363 int
364 compat_50_netbsd32_clock_getres(struct lwp *l,
365 const struct compat_50_netbsd32_clock_getres_args *uap, register_t *retval)
366 {
367 /* {
368 syscallarg(netbsd32_clockid_t) clock_id;
369 syscallarg(netbsd32_timespec50p_t) tp;
370 } */
371 struct netbsd32_timespec50 ts32;
372 clockid_t clock_id;
373 struct timespec ts;
374 int error = 0;
375
376 clock_id = SCARG(uap, clock_id);
377 if (clock_id != CLOCK_REALTIME)
378 return (EINVAL);
379
380 if (SCARG_P32(uap, tp)) {
381 ts.tv_sec = 0;
382 ts.tv_nsec = 1000000000 / hz;
383
384 netbsd32_from_timespec50(&ts, &ts32);
385 error = copyout(&ts, SCARG_P32(uap, tp), sizeof(ts));
386 }
387
388 return error;
389 }
390
391 int
392 compat_50_netbsd32_timer_settime(struct lwp *l,
393 const struct compat_50_netbsd32_timer_settime_args *uap, register_t *retval)
394 {
395 /* {
396 syscallarg(netbsd32_timer_t) timerid;
397 syscallarg(int) flags;
398 syscallarg(const netbsd32_itimerspec50p_t) value;
399 syscallarg(netbsd32_itimerspec50p_t) ovalue;
400 } */
401 int error;
402 struct itimerspec value, ovalue, *ovp = NULL;
403 struct netbsd32_itimerspec50 its32;
404
405 if ((error = copyin(SCARG_P32(uap, value), &its32, sizeof(its32))) != 0)
406 return (error);
407 netbsd32_to_timespec50(&its32.it_interval, &value.it_interval);
408 netbsd32_to_timespec50(&its32.it_value, &value.it_value);
409
410 if (SCARG_P32(uap, ovalue))
411 ovp = &ovalue;
412
413 if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp,
414 SCARG(uap, flags), l->l_proc)) != 0)
415 return error;
416
417 if (ovp) {
418 netbsd32_from_timespec50(&ovp->it_interval, &its32.it_interval);
419 netbsd32_from_timespec50(&ovp->it_value, &its32.it_value);
420 return copyout(&its32, SCARG_P32(uap, ovalue), sizeof(its32));
421 }
422 return 0;
423 }
424
425 int
426 compat_50_netbsd32_timer_gettime(struct lwp *l, const struct compat_50_netbsd32_timer_gettime_args *uap, register_t *retval)
427 {
428 /* {
429 syscallarg(netbsd32_timer_t) timerid;
430 syscallarg(netbsd32_itimerspec50p_t) value;
431 } */
432 int error;
433 struct itimerspec its;
434 struct netbsd32_itimerspec50 its32;
435
436 if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc,
437 &its)) != 0)
438 return error;
439
440 netbsd32_from_timespec50(&its.it_interval, &its32.it_interval);
441 netbsd32_from_timespec50(&its.it_value, &its32.it_value);
442
443 return copyout(&its32, SCARG_P32(uap, value), sizeof(its32));
444 }
445
446 int
447 compat_50_netbsd32_nanosleep(struct lwp *l,
448 const struct compat_50_netbsd32_nanosleep_args *uap, register_t *retval)
449 {
450 /* {
451 syscallarg(const netbsd32_timespec50p_t) rqtp;
452 syscallarg(netbsd32_timespecp_t) rmtp;
453 } */
454 static int nanowait;
455 struct netbsd32_timespec50 ts32;
456 struct timespec rqt, ctime, rmt;
457 int error, timo;
458
459 error = copyin(SCARG_P32(uap, rqtp), &ts32, sizeof(ts32));
460 if (error)
461 return (error);
462
463 netbsd32_to_timespec50(&ts32, &rqt);
464 if (itimespecfix(&rqt))
465 return (EINVAL);
466
467 getnanotime(&ctime);
468 timespecadd(&rqt, &ctime, &rqt);
469 timo = tshzto(&rqt);
470 /*
471 * Avoid inadvertantly sleeping forever
472 */
473 if (timo == 0)
474 timo = 1;
475
476 error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo);
477 if (error == ERESTART)
478 error = EINTR;
479 if (error == EWOULDBLOCK)
480 error = 0;
481
482 if (SCARG_P32(uap, rmtp)) {
483 int error1;
484
485 getnanotime(&rmt);
486
487 timespecsub(&rqt, &rmt, &rmt);
488 if (rmt.tv_sec < 0)
489 timespecclear(&rmt);
490
491 netbsd32_from_timespec50(&rmt, &ts32);
492 error1 = copyout(&ts32, SCARG_P32(uap,rmtp), sizeof(ts32));
493 if (error1)
494 return (error1);
495 }
496
497 return error;
498 }
499
500 static int
501 compat_50_netbsd32_sigtimedwait_put_info(const void *src, void *dst, size_t size)
502 {
503 const siginfo_t *info = src;
504 siginfo32_t info32;
505
506 netbsd32_si_to_si32(&info32, info);
507
508 return copyout(&info32, dst, sizeof(info32));
509 }
510
511 static int
512 compat_50_netbsd32_sigtimedwait_fetch_timeout(const void *src, void *dst, size_t size)
513 {
514 struct timespec *ts = dst;
515 struct netbsd32_timespec50 ts32;
516 int error;
517
518 error = copyin(src, &ts32, sizeof(ts32));
519 if (error)
520 return error;
521
522 netbsd32_to_timespec50(&ts32, ts);
523 return 0;
524 }
525
526 static int
527 compat_50_netbsd32_sigtimedwait_put_timeout(const void *src, void *dst, size_t size)
528 {
529 const struct timespec *ts = src;
530 struct netbsd32_timespec50 ts32;
531
532 netbsd32_from_timespec50(ts, &ts32);
533
534 return copyout(&ts32, dst, sizeof(ts32));
535 }
536
537 int
538 compat_50_netbsd32___sigtimedwait(struct lwp *l,
539 const struct compat_50_netbsd32___sigtimedwait_args *uap, register_t *retval)
540 {
541 /* {
542 syscallarg(netbsd32_sigsetp_t) set;
543 syscallarg(netbsd32_siginfop_t) info;
544 syscallarg(netbsd32_timespec50p_t) timeout;
545 } */
546 struct sys_____sigtimedwait50_args ua;
547
548 NETBSD32TOP_UAP(set, const sigset_t);
549 NETBSD32TOP_UAP(info, siginfo_t);
550 NETBSD32TOP_UAP(timeout, struct timespec);
551
552 return __sigtimedwait1(l, &ua, retval,
553 compat_50_netbsd32_sigtimedwait_put_info,
554 compat_50_netbsd32_sigtimedwait_fetch_timeout,
555 compat_50_netbsd32_sigtimedwait_put_timeout);
556 return 0;
557 }
558
559 int
560 compat_50_netbsd32_lutimes(struct lwp *l,
561 const struct compat_50_netbsd32_lutimes_args *uap, register_t *retval)
562 {
563 /* {
564 syscallarg(const netbsd32_charp) path;
565 syscallarg(const netbsd32_timeval50p_t) tptr;
566 } */
567 int error;
568 struct timeval tv[2], *tvp;
569
570 error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp);
571 if (error != 0)
572 return error;
573
574 return do_sys_utimes(l, NULL, SCARG_P32(uap, path), NOFOLLOW,
575 tvp, UIO_SYSSPACE);
576 }
577
578 int
579 compat_50_netbsd32__lwp_park(struct lwp *l,
580 const struct compat_50_netbsd32__lwp_park_args *uap, register_t *retval)
581 {
582 /* {
583 syscallarg(const netbsd32_timespec50p) ts;
584 syscallarg(lwpid_t) unpark;
585 syscallarg(netbsd32_voidp) hint;
586 syscallarg(netbsd32_voidp) unparkhint;
587 } */
588 struct timespec ts, *tsp;
589 struct netbsd32_timespec50 ts32;
590 int error;
591
592 if (SCARG_P32(uap, ts) == NULL)
593 tsp = NULL;
594 else {
595 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof ts32);
596 if (error != 0)
597 return error;
598 netbsd32_to_timespec50(&ts32, &ts);
599 tsp = &ts;
600 }
601
602 if (SCARG(uap, unpark) != 0) {
603 error = lwp_unpark(SCARG(uap, unpark),
604 SCARG_P32(uap, unparkhint));
605 if (error != 0)
606 return error;
607 }
608
609 return lwp_park(tsp, SCARG_P32(uap, hint));
610 return 0;
611 }
612
613 static int
614 netbsd32_kevent_fetch_timeout(const void *src, void *dest, size_t length)
615 {
616 struct netbsd32_timespec50 ts32;
617 int error;
618
619 KASSERT(length == sizeof(struct timespec50));
620
621 error = copyin(src, &ts32, sizeof(ts32));
622 if (error)
623 return error;
624 netbsd32_to_timespec50(&ts32, (struct timespec *)dest);
625 return 0;
626 }
627
628 static int
629 netbsd32_kevent_fetch_changes(void *private, const struct kevent *changelist,
630 struct kevent *changes, size_t index, int n)
631 {
632 const struct netbsd32_kevent *src =
633 (const struct netbsd32_kevent *)changelist;
634 struct netbsd32_kevent *kev32, *changes32 = private;
635 int error, i;
636
637 error = copyin(src + index, changes32, n * sizeof(*changes32));
638 if (error)
639 return error;
640 for (i = 0, kev32 = changes32; i < n; i++, kev32++, changes++)
641 netbsd32_to_kevent(kev32, changes);
642 return 0;
643 }
644
645 static int
646 netbsd32_kevent_put_events(void *private, struct kevent *events,
647 struct kevent *eventlist, size_t index, int n)
648 {
649 struct netbsd32_kevent *kev32, *events32 = private;
650 int i;
651
652 for (i = 0, kev32 = events32; i < n; i++, kev32++, events++)
653 netbsd32_from_kevent(events, kev32);
654 kev32 = (struct netbsd32_kevent *)eventlist;
655 return copyout(events32, kev32, n * sizeof(*events32));
656 }
657
658 int
659 compat_50_netbsd32_kevent(struct lwp *l,
660 const struct compat_50_netbsd32_kevent_args *uap, register_t *retval)
661 {
662 /* {
663 syscallarg(int) fd;
664 syscallarg(netbsd32_keventp_t) changelist;
665 syscallarg(netbsd32_size_t) nchanges;
666 syscallarg(netbsd32_keventp_t) eventlist;
667 syscallarg(netbsd32_size_t) nevents;
668 syscallarg(netbsd32_timespec50p_t) timeout;
669 } */
670 int error;
671 size_t maxalloc, nchanges, nevents;
672 struct kevent_ops netbsd32_kevent_ops = {
673 keo_fetch_timeout: netbsd32_kevent_fetch_timeout,
674 keo_fetch_changes: netbsd32_kevent_fetch_changes,
675 keo_put_events: netbsd32_kevent_put_events,
676 };
677
678 nchanges = SCARG(uap, nchanges);
679 nevents = SCARG(uap, nevents);
680 maxalloc = MIN(KQ_NEVENTS, MAX(nchanges, nevents));
681 netbsd32_kevent_ops.keo_private =
682 malloc(maxalloc * sizeof(struct netbsd32_kevent), M_TEMP,
683 M_WAITOK);
684
685 error = kevent1(retval, SCARG(uap, fd),
686 NETBSD32PTR64(SCARG(uap, changelist)), nchanges,
687 NETBSD32PTR64(SCARG(uap, eventlist)), nevents,
688 NETBSD32PTR64(SCARG(uap, timeout)), &netbsd32_kevent_ops);
689
690 free(netbsd32_kevent_ops.keo_private, M_TEMP);
691 return error;
692 return 0;
693 }
694
695 int
696 compat_50_netbsd32_pselect(struct lwp *l,
697 const struct compat_50_netbsd32_pselect_args *uap, register_t *retval)
698 {
699 /* {
700 syscallarg(int) nd;
701 syscallarg(netbsd32_fd_setp_t) in;
702 syscallarg(netbsd32_fd_setp_t) ou;
703 syscallarg(netbsd32_fd_setp_t) ex;
704 syscallarg(const netbsd32_timespec50p_t) ts;
705 syscallarg(const netbsd32_sigsetp_t) mask;
706 } */
707 int error;
708 struct netbsd32_timespec50 ts32;
709 struct timespec ts;
710 struct timeval atv, *tv = NULL;
711 sigset_t amask, *mask = NULL;
712
713 if (SCARG_P32(uap, ts)) {
714 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof(ts32));
715 if (error != 0)
716 return error;
717 netbsd32_to_timespec50(&ts32, &ts);
718 atv.tv_sec = ts.tv_sec;
719 atv.tv_usec = ts.tv_nsec / 1000;
720 tv = &atv;
721 }
722 if (SCARG_P32(uap, mask)) {
723 error = copyin(SCARG_P32(uap, mask), &amask, sizeof(amask));
724 if (error != 0)
725 return error;
726 mask = &amask;
727 }
728
729 return selcommon(l, retval, SCARG(uap, nd), SCARG_P32(uap, in),
730 SCARG_P32(uap, ou), SCARG_P32(uap, ex), tv, mask);
731 return 0;
732 }
733
734 int
735 compat_50_netbsd32_pollts(struct lwp *l,
736 const struct compat_50_netbsd32_pollts_args *uap, register_t *retval)
737 {
738 /* {
739 syscallarg(struct netbsd32_pollfdp_t) fds;
740 syscallarg(u_int) nfds;
741 syscallarg(const netbsd32_timespec50p_t) ts;
742 syscallarg(const netbsd32_sigsetp_t) mask;
743 } */
744 int error;
745 struct netbsd32_timespec50 ts32;
746 struct timespec ts;
747 struct timeval atv, *tv = NULL;
748 sigset_t amask, *mask = NULL;
749
750 if (SCARG_P32(uap, ts)) {
751 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof(ts32));
752 if (error != 0)
753 return error;
754 netbsd32_to_timespec50(&ts32, &ts);
755 atv.tv_sec = ts.tv_sec;
756 atv.tv_usec = ts.tv_nsec / 1000;
757 tv = &atv;
758 }
759 if (NETBSD32PTR64( SCARG(uap, mask))) {
760 error = copyin(SCARG_P32(uap, mask), &amask, sizeof(amask));
761 if (error != 0)
762 return error;
763 mask = &amask;
764 }
765
766 return pollcommon(l, retval, SCARG_P32(uap, fds),
767 SCARG(uap, nfds), tv, mask);
768 }
769
770 int
771 compat_50_netbsd32___stat30(struct lwp *l,
772 const struct compat_50_netbsd32___stat30_args *uap, register_t *retval)
773 {
774 /* {
775 syscallarg(const netbsd32_charp) path;
776 syscallarg(netbsd32_stat50p_t) ub;
777 } */
778 struct netbsd32_stat50 sb32;
779 struct stat sb;
780 int error;
781 const char *path;
782
783 path = SCARG_P32(uap, path);
784
785 error = do_sys_stat(path, FOLLOW, &sb);
786 if (error)
787 return error;
788 netbsd32_from___stat50(&sb, &sb32);
789 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32));
790 return error;
791 }
792
793 int
794 compat_50_netbsd32___fstat30(struct lwp *l,
795 const struct compat_50_netbsd32___fstat30_args *uap, register_t *retval)
796 {
797 /* {
798 syscallarg(int) fd;
799 syscallarg(netbsd32_stat50p_t) sb;
800 } */
801 struct netbsd32_stat50 sb32;
802 struct stat ub;
803 int error;
804
805 error = do_sys_fstat(SCARG(uap, fd), &ub);
806 if (error == 0) {
807 netbsd32_from___stat50(&ub, &sb32);
808 error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32));
809 }
810 return error;
811 }
812
813 int
814 compat_50_netbsd32___lstat30(struct lwp *l,
815 const struct compat_50_netbsd32___lstat30_args *uap, register_t *retval)
816 {
817 /* {
818 syscallarg(const netbsd32_charp) path;
819 syscallarg(netbsd32_stat50p_t) ub;
820 } */
821 struct netbsd32_stat50 sb32;
822 struct stat sb;
823 int error;
824 const char *path;
825
826 path = SCARG_P32(uap, path);
827
828 error = do_sys_stat(path, NOFOLLOW, &sb);
829 if (error)
830 return error;
831 netbsd32_from___stat50(&sb, &sb32);
832 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32));
833 return error;
834 }
835
836 int
837 compat_50_netbsd32___fhstat40(struct lwp *l, const struct compat_50_netbsd32___fhstat40_args *uap, register_t *retval)
838 {
839 /* {
840 syscallarg(const netbsd32_pointer_t) fhp;
841 syscallarg(netbsd32_size_t) fh_size;
842 syscallarg(netbsd32_stat50p_t) sb;
843 } */
844 struct stat sb;
845 struct netbsd32_stat50 sb32;
846 int error;
847
848 error = do_fhstat(l, SCARG_P32(uap, fhp), SCARG(uap, fh_size), &sb);
849 if (error != 0) {
850 netbsd32_from___stat50(&sb, &sb32);
851 error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb));
852 }
853 return error;
854 }
855
856 int
857 compat_50_netbsd32_wait4(struct lwp *l, const struct compat_50_netbsd32_wait4_args *uap, register_t *retval)
858 {
859 /* {
860 syscallarg(int) pid;
861 syscallarg(netbsd32_intp) status;
862 syscallarg(int) options;
863 syscallarg(netbsd32_rusage50p_t) rusage;
864 } */
865 int status, error;
866 int was_zombie;
867 struct rusage ru;
868 struct netbsd32_rusage50 ru32;
869 int pid = SCARG(uap, pid);
870
871 error = do_sys_wait(l, &pid, &status, SCARG(uap, options),
872 SCARG_P32(uap, rusage) != NULL ? &ru : NULL, &was_zombie);
873
874 retval[0] = pid;
875 if (pid == 0)
876 return error;
877
878 if (SCARG_P32(uap, rusage)) {
879 netbsd32_from_rusage50(&ru, &ru32);
880 error = copyout(&ru32, SCARG_P32(uap, rusage), sizeof(ru32));
881 }
882
883 if (error == 0 && SCARG_P32(uap, status))
884 error = copyout(&status, SCARG_P32(uap, status), sizeof(status));
885
886 return error;
887 }
888
889
890 int
891 compat_50_netbsd32_getrusage(struct lwp *l, const struct compat_50_netbsd32_getrusage_args *uap, register_t *retval)
892 {
893 /* {
894 syscallarg(int) who;
895 syscallarg(netbsd32_rusage50p_t) rusage;
896 } */
897 struct proc *p = l->l_proc;
898 struct rusage *rup;
899 struct netbsd32_rusage50 ru;
900
901 switch (SCARG(uap, who)) {
902
903 case RUSAGE_SELF:
904 rup = &p->p_stats->p_ru;
905 mutex_enter(p->p_lock);
906 calcru(p, &rup->ru_utime, &rup->ru_stime, NULL, NULL);
907 mutex_exit(p->p_lock);
908 break;
909
910 case RUSAGE_CHILDREN:
911 rup = &p->p_stats->p_cru;
912 break;
913
914 default:
915 return (EINVAL);
916 }
917 netbsd32_from_rusage50(rup, &ru);
918 return copyout(&ru, SCARG_P32(uap, rusage), sizeof(ru));
919 }
920
921 int
922 compat_50_netbsd32_setitimer(struct lwp *l,
923 const struct compat_50_netbsd32_setitimer_args *uap, register_t *retval)
924 {
925 /* {
926 syscallarg(int) which;
927 syscallarg(const netbsd32_itimerval50p_t) itv;
928 syscallarg(netbsd32_itimerval50p_t) oitv;
929 } */
930 struct proc *p = l->l_proc;
931 struct netbsd32_itimerval50 s32it, *itv32;
932 int which = SCARG(uap, which);
933 struct compat_50_netbsd32_getitimer_args getargs;
934 struct itimerval aitv;
935 int error;
936
937 if ((u_int)which > ITIMER_PROF)
938 return (EINVAL);
939 itv32 = SCARG_P32(uap, itv);
940 if (itv32) {
941 if ((error = copyin(itv32, &s32it, sizeof(s32it))))
942 return (error);
943 netbsd32_to_itimerval50(&s32it, &aitv);
944 }
945 if (SCARG_P32(uap, oitv) != 0) {
946 SCARG(&getargs, which) = which;
947 SCARG(&getargs, itv) = SCARG(uap, oitv);
948 if ((error = compat_50_netbsd32_getitimer(l, &getargs, retval)) != 0)
949 return (error);
950 }
951 if (itv32 == 0)
952 return 0;
953
954 return dosetitimer(p, which, &aitv);
955 }
956
957 int
958 compat_50_netbsd32_getitimer(struct lwp *l, const struct compat_50_netbsd32_getitimer_args *uap, register_t *retval)
959 {
960 /* {
961 syscallarg(int) which;
962 syscallarg(netbsd32_itimerval50p_t) itv;
963 } */
964 struct proc *p = l->l_proc;
965 struct netbsd32_itimerval50 s32it;
966 struct itimerval aitv;
967 int error;
968
969 error = dogetitimer(p, SCARG(uap, which), &aitv);
970 if (error)
971 return error;
972
973 netbsd32_from_itimerval50(&aitv, &s32it);
974 return copyout(&s32it, SCARG_P32(uap, itv), sizeof(s32it));
975 }
976
977 #if defined(SYSVSEM)
978
979 int
980 compat_50_netbsd32___semctl14(struct lwp *l, const struct compat_50_netbsd32___semctl14_args *uap, register_t *retval)
981 {
982 return do_netbsd32___semctl14(l, uap, retval, NULL);
983 }
984
985 int
986 do_netbsd32___semctl14(struct lwp *l, const struct compat_50_netbsd32___semctl14_args *uap, register_t *retval, void *vkarg)
987 {
988 /* {
989 syscallarg(int) semid;
990 syscallarg(int) semnum;
991 syscallarg(int) cmd;
992 syscallarg(netbsd32_semun50p_t) arg;
993 } */
994 struct semid_ds sembuf;
995 struct netbsd32_semid_ds50 sembuf32;
996 int cmd, error;
997 void *pass_arg;
998 union __semun karg;
999 union netbsd32_semun50 karg32;
1000
1001 cmd = SCARG(uap, cmd);
1002
1003 switch (cmd) {
1004 case IPC_SET:
1005 case IPC_STAT:
1006 pass_arg = &sembuf;
1007 break;
1008
1009 case GETALL:
1010 case SETVAL:
1011 case SETALL:
1012 pass_arg = &karg;
1013 break;
1014 default:
1015 pass_arg = NULL;
1016 break;
1017 }
1018
1019 if (pass_arg) {
1020 if (vkarg != NULL)
1021 karg32 = *(union netbsd32_semun50 *)vkarg;
1022 else {
1023 error = copyin(SCARG_P32(uap, arg), &karg32,
1024 sizeof(karg32));
1025 if (error)
1026 return error;
1027 }
1028 if (pass_arg == &karg) {
1029 switch (cmd) {
1030 case GETALL:
1031 case SETALL:
1032 karg.array = NETBSD32PTR64(karg32.array);
1033 break;
1034 case SETVAL:
1035 karg.val = karg32.val;
1036 break;
1037 }
1038 }
1039 if (cmd == IPC_SET) {
1040 error = copyin(NETBSD32PTR64(karg32.buf), &sembuf32,
1041 sizeof(sembuf32));
1042 if (error)
1043 return (error);
1044 netbsd32_to_semid_ds50(&sembuf32, &sembuf);
1045 }
1046 }
1047
1048 error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd,
1049 pass_arg, retval);
1050
1051 if (error == 0 && cmd == IPC_STAT) {
1052 netbsd32_from_semid_ds50(&sembuf, &sembuf32);
1053 error = copyout(&sembuf32, NETBSD32PTR64(karg32.buf),
1054 sizeof(sembuf32));
1055 }
1056
1057 return (error);
1058 }
1059 #endif
1060
1061 #if defined(SYSVMSG)
1062
1063 int
1064 compat_50_netbsd32___msgctl13(struct lwp *l, const struct compat_50_netbsd32___msgctl13_args *uap, register_t *retval)
1065 {
1066 /* {
1067 syscallarg(int) msqid;
1068 syscallarg(int) cmd;
1069 syscallarg(netbsd32_msqid_ds50p_t) buf;
1070 } */
1071 struct msqid_ds ds;
1072 struct netbsd32_msqid_ds50 ds32;
1073 int error, cmd;
1074
1075 cmd = SCARG(uap, cmd);
1076 if (cmd == IPC_SET) {
1077 error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32));
1078 if (error)
1079 return error;
1080 netbsd32_to_msqid_ds50(&ds32, &ds);
1081 }
1082
1083 error = msgctl1(l, SCARG(uap, msqid), cmd,
1084 (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
1085
1086 if (error == 0 && cmd == IPC_STAT) {
1087 netbsd32_from_msqid_ds50(&ds, &ds32);
1088 error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32));
1089 }
1090
1091 return error;
1092 }
1093 #endif
1094
1095 #if defined(SYSVSHM)
1096
1097 int
1098 compat_50_netbsd32___shmctl13(struct lwp *l, const struct compat_50_netbsd32___shmctl13_args *uap, register_t *retval)
1099 {
1100 /* {
1101 syscallarg(int) shmid;
1102 syscallarg(int) cmd;
1103 syscallarg(netbsd32_shmid_ds50p_t) buf;
1104 } */
1105 struct shmid_ds ds;
1106 struct netbsd32_shmid_ds50 ds32;
1107 int error, cmd;
1108
1109 cmd = SCARG(uap, cmd);
1110 if (cmd == IPC_SET) {
1111 error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32));
1112 if (error)
1113 return error;
1114 netbsd32_to_shmid_ds50(&ds32, &ds);
1115 }
1116
1117 error = shmctl1(l, SCARG(uap, shmid), cmd,
1118 (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL);
1119
1120 if (error == 0 && cmd == IPC_STAT) {
1121 netbsd32_from_shmid_ds50(&ds, &ds32);
1122 error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32));
1123 }
1124
1125 return error;
1126 }
1127 #endif
1128