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