1 /* $NetBSD: netbsd32_compat_50.c,v 1.10 2010/03/02 16:09:11 pooka 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.10 2010/03/02 16:09:11 pooka 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 static int nanowait; 445 struct netbsd32_timespec50 ts32; 446 struct timespec rqt, ctime, rmt; 447 int error, timo; 448 449 error = copyin(SCARG_P32(uap, rqtp), &ts32, sizeof(ts32)); 450 if (error) 451 return (error); 452 453 netbsd32_to_timespec50(&ts32, &rqt); 454 if (itimespecfix(&rqt)) 455 return (EINVAL); 456 457 getnanotime(&ctime); 458 timespecadd(&rqt, &ctime, &rqt); 459 timo = tshzto(&rqt); 460 /* 461 * Avoid inadvertantly sleeping forever 462 */ 463 if (timo == 0) 464 timo = 1; 465 466 error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo); 467 if (error == ERESTART) 468 error = EINTR; 469 if (error == EWOULDBLOCK) 470 error = 0; 471 472 if (SCARG_P32(uap, rmtp)) { 473 int error1; 474 475 getnanotime(&rmt); 476 477 timespecsub(&rqt, &rmt, &rmt); 478 if (rmt.tv_sec < 0) 479 timespecclear(&rmt); 480 481 netbsd32_from_timespec50(&rmt, &ts32); 482 error1 = copyout(&ts32, SCARG_P32(uap,rmtp), sizeof(ts32)); 483 if (error1) 484 return (error1); 485 } 486 487 return error; 488 } 489 490 static int 491 compat_50_netbsd32_sigtimedwait_put_info(const void *src, void *dst, size_t size) 492 { 493 const siginfo_t *info = src; 494 siginfo32_t info32; 495 496 netbsd32_si_to_si32(&info32, info); 497 498 return copyout(&info32, dst, sizeof(info32)); 499 } 500 501 static int 502 compat_50_netbsd32_sigtimedwait_fetch_timeout(const void *src, void *dst, size_t size) 503 { 504 struct timespec *ts = dst; 505 struct netbsd32_timespec50 ts32; 506 int error; 507 508 error = copyin(src, &ts32, sizeof(ts32)); 509 if (error) 510 return error; 511 512 netbsd32_to_timespec50(&ts32, ts); 513 return 0; 514 } 515 516 static int 517 compat_50_netbsd32_sigtimedwait_put_timeout(const void *src, void *dst, size_t size) 518 { 519 const struct timespec *ts = src; 520 struct netbsd32_timespec50 ts32; 521 522 netbsd32_from_timespec50(ts, &ts32); 523 524 return copyout(&ts32, dst, sizeof(ts32)); 525 } 526 527 int 528 compat_50_netbsd32___sigtimedwait(struct lwp *l, 529 const struct compat_50_netbsd32___sigtimedwait_args *uap, register_t *retval) 530 { 531 /* { 532 syscallarg(netbsd32_sigsetp_t) set; 533 syscallarg(netbsd32_siginfop_t) info; 534 syscallarg(netbsd32_timespec50p_t) timeout; 535 } */ 536 struct sys_____sigtimedwait50_args ua; 537 538 NETBSD32TOP_UAP(set, const sigset_t); 539 NETBSD32TOP_UAP(info, siginfo_t); 540 NETBSD32TOP_UAP(timeout, struct timespec); 541 542 return sigtimedwait1(l, &ua, retval, 543 compat_50_netbsd32_sigtimedwait_put_info, 544 compat_50_netbsd32_sigtimedwait_fetch_timeout, 545 compat_50_netbsd32_sigtimedwait_put_timeout); 546 return 0; 547 } 548 549 int 550 compat_50_netbsd32_lutimes(struct lwp *l, 551 const struct compat_50_netbsd32_lutimes_args *uap, register_t *retval) 552 { 553 /* { 554 syscallarg(const netbsd32_charp) path; 555 syscallarg(const netbsd32_timeval50p_t) tptr; 556 } */ 557 int error; 558 struct timeval tv[2], *tvp; 559 560 error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp); 561 if (error != 0) 562 return error; 563 564 return do_sys_utimes(l, NULL, SCARG_P32(uap, path), NOFOLLOW, 565 tvp, UIO_SYSSPACE); 566 } 567 568 int 569 compat_50_netbsd32__lwp_park(struct lwp *l, 570 const struct compat_50_netbsd32__lwp_park_args *uap, register_t *retval) 571 { 572 /* { 573 syscallarg(const netbsd32_timespec50p) ts; 574 syscallarg(lwpid_t) unpark; 575 syscallarg(netbsd32_voidp) hint; 576 syscallarg(netbsd32_voidp) unparkhint; 577 } */ 578 struct timespec ts, *tsp; 579 struct netbsd32_timespec50 ts32; 580 int error; 581 582 if (SCARG_P32(uap, ts) == NULL) 583 tsp = NULL; 584 else { 585 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof ts32); 586 if (error != 0) 587 return error; 588 netbsd32_to_timespec50(&ts32, &ts); 589 tsp = &ts; 590 } 591 592 if (SCARG(uap, unpark) != 0) { 593 error = lwp_unpark(SCARG(uap, unpark), 594 SCARG_P32(uap, unparkhint)); 595 if (error != 0) 596 return error; 597 } 598 599 return lwp_park(tsp, SCARG_P32(uap, hint)); 600 return 0; 601 } 602 603 static int 604 netbsd32_kevent_fetch_timeout(const void *src, void *dest, size_t length) 605 { 606 struct netbsd32_timespec50 ts32; 607 int error; 608 609 KASSERT(length == sizeof(struct timespec50)); 610 611 error = copyin(src, &ts32, sizeof(ts32)); 612 if (error) 613 return error; 614 netbsd32_to_timespec50(&ts32, (struct timespec *)dest); 615 return 0; 616 } 617 618 static int 619 netbsd32_kevent_fetch_changes(void *private, const struct kevent *changelist, 620 struct kevent *changes, size_t index, int n) 621 { 622 const struct netbsd32_kevent *src = 623 (const struct netbsd32_kevent *)changelist; 624 struct netbsd32_kevent *kev32, *changes32 = private; 625 int error, i; 626 627 error = copyin(src + index, changes32, n * sizeof(*changes32)); 628 if (error) 629 return error; 630 for (i = 0, kev32 = changes32; i < n; i++, kev32++, changes++) 631 netbsd32_to_kevent(kev32, changes); 632 return 0; 633 } 634 635 static int 636 netbsd32_kevent_put_events(void *private, struct kevent *events, 637 struct kevent *eventlist, size_t index, int n) 638 { 639 struct netbsd32_kevent *kev32, *events32 = private; 640 int i; 641 642 for (i = 0, kev32 = events32; i < n; i++, kev32++, events++) 643 netbsd32_from_kevent(events, kev32); 644 kev32 = (struct netbsd32_kevent *)eventlist; 645 return copyout(events32, kev32, n * sizeof(*events32)); 646 } 647 648 int 649 compat_50_netbsd32_kevent(struct lwp *l, 650 const struct compat_50_netbsd32_kevent_args *uap, register_t *retval) 651 { 652 /* { 653 syscallarg(int) fd; 654 syscallarg(netbsd32_keventp_t) changelist; 655 syscallarg(netbsd32_size_t) nchanges; 656 syscallarg(netbsd32_keventp_t) eventlist; 657 syscallarg(netbsd32_size_t) nevents; 658 syscallarg(netbsd32_timespec50p_t) timeout; 659 } */ 660 int error; 661 size_t maxalloc, nchanges, nevents; 662 struct kevent_ops netbsd32_kevent_ops = { 663 keo_fetch_timeout: netbsd32_kevent_fetch_timeout, 664 keo_fetch_changes: netbsd32_kevent_fetch_changes, 665 keo_put_events: netbsd32_kevent_put_events, 666 }; 667 668 nchanges = SCARG(uap, nchanges); 669 nevents = SCARG(uap, nevents); 670 maxalloc = MIN(KQ_NEVENTS, MAX(nchanges, nevents)); 671 netbsd32_kevent_ops.keo_private = 672 malloc(maxalloc * sizeof(struct netbsd32_kevent), M_TEMP, 673 M_WAITOK); 674 675 error = kevent1(retval, SCARG(uap, fd), 676 NETBSD32PTR64(SCARG(uap, changelist)), nchanges, 677 NETBSD32PTR64(SCARG(uap, eventlist)), nevents, 678 NETBSD32PTR64(SCARG(uap, timeout)), &netbsd32_kevent_ops); 679 680 free(netbsd32_kevent_ops.keo_private, M_TEMP); 681 return error; 682 return 0; 683 } 684 685 int 686 compat_50_netbsd32_pselect(struct lwp *l, 687 const struct compat_50_netbsd32_pselect_args *uap, register_t *retval) 688 { 689 /* { 690 syscallarg(int) nd; 691 syscallarg(netbsd32_fd_setp_t) in; 692 syscallarg(netbsd32_fd_setp_t) ou; 693 syscallarg(netbsd32_fd_setp_t) ex; 694 syscallarg(const netbsd32_timespec50p_t) ts; 695 syscallarg(const netbsd32_sigsetp_t) mask; 696 } */ 697 int error; 698 struct netbsd32_timespec50 ts32; 699 struct timespec ats, *ts = NULL; 700 sigset_t amask, *mask = NULL; 701 702 if (SCARG_P32(uap, ts)) { 703 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof(ts32)); 704 if (error != 0) 705 return error; 706 netbsd32_to_timespec50(&ts32, &ats); 707 ts = &ats; 708 } 709 if (SCARG_P32(uap, mask)) { 710 error = copyin(SCARG_P32(uap, mask), &amask, sizeof(amask)); 711 if (error != 0) 712 return error; 713 mask = &amask; 714 } 715 716 return selcommon(retval, SCARG(uap, nd), SCARG_P32(uap, in), 717 SCARG_P32(uap, ou), SCARG_P32(uap, ex), ts, mask); 718 return 0; 719 } 720 721 int 722 compat_50_netbsd32_pollts(struct lwp *l, 723 const struct compat_50_netbsd32_pollts_args *uap, register_t *retval) 724 { 725 /* { 726 syscallarg(struct netbsd32_pollfdp_t) fds; 727 syscallarg(u_int) nfds; 728 syscallarg(const netbsd32_timespec50p_t) ts; 729 syscallarg(const netbsd32_sigsetp_t) mask; 730 } */ 731 int error; 732 struct netbsd32_timespec50 ts32; 733 struct timespec ats, *ts = NULL; 734 sigset_t amask, *mask = NULL; 735 736 if (SCARG_P32(uap, ts)) { 737 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof(ts32)); 738 if (error != 0) 739 return error; 740 netbsd32_to_timespec50(&ts32, &ats); 741 ts = &ats; 742 } 743 if (NETBSD32PTR64( SCARG(uap, mask))) { 744 error = copyin(SCARG_P32(uap, mask), &amask, sizeof(amask)); 745 if (error != 0) 746 return error; 747 mask = &amask; 748 } 749 750 return pollcommon(retval, SCARG_P32(uap, fds), 751 SCARG(uap, nfds), ts, mask); 752 } 753 754 int 755 compat_50_netbsd32___stat30(struct lwp *l, 756 const struct compat_50_netbsd32___stat30_args *uap, register_t *retval) 757 { 758 /* { 759 syscallarg(const netbsd32_charp) path; 760 syscallarg(netbsd32_stat50p_t) ub; 761 } */ 762 struct netbsd32_stat50 sb32; 763 struct stat sb; 764 int error; 765 const char *path; 766 767 path = SCARG_P32(uap, path); 768 769 error = do_sys_stat(path, FOLLOW, &sb); 770 if (error) 771 return error; 772 netbsd32_from___stat50(&sb, &sb32); 773 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32)); 774 return error; 775 } 776 777 int 778 compat_50_netbsd32___fstat30(struct lwp *l, 779 const struct compat_50_netbsd32___fstat30_args *uap, register_t *retval) 780 { 781 /* { 782 syscallarg(int) fd; 783 syscallarg(netbsd32_stat50p_t) sb; 784 } */ 785 struct netbsd32_stat50 sb32; 786 struct stat ub; 787 int error; 788 789 error = do_sys_fstat(SCARG(uap, fd), &ub); 790 if (error == 0) { 791 netbsd32_from___stat50(&ub, &sb32); 792 error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32)); 793 } 794 return error; 795 } 796 797 int 798 compat_50_netbsd32___lstat30(struct lwp *l, 799 const struct compat_50_netbsd32___lstat30_args *uap, register_t *retval) 800 { 801 /* { 802 syscallarg(const netbsd32_charp) path; 803 syscallarg(netbsd32_stat50p_t) ub; 804 } */ 805 struct netbsd32_stat50 sb32; 806 struct stat sb; 807 int error; 808 const char *path; 809 810 path = SCARG_P32(uap, path); 811 812 error = do_sys_stat(path, NOFOLLOW, &sb); 813 if (error) 814 return error; 815 netbsd32_from___stat50(&sb, &sb32); 816 error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32)); 817 return error; 818 } 819 820 int 821 compat_50_netbsd32___fhstat40(struct lwp *l, const struct compat_50_netbsd32___fhstat40_args *uap, register_t *retval) 822 { 823 /* { 824 syscallarg(const netbsd32_pointer_t) fhp; 825 syscallarg(netbsd32_size_t) fh_size; 826 syscallarg(netbsd32_stat50p_t) sb; 827 } */ 828 struct stat sb; 829 struct netbsd32_stat50 sb32; 830 int error; 831 832 error = do_fhstat(l, SCARG_P32(uap, fhp), SCARG(uap, fh_size), &sb); 833 if (error != 0) { 834 netbsd32_from___stat50(&sb, &sb32); 835 error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb)); 836 } 837 return error; 838 } 839 840 int 841 compat_50_netbsd32_wait4(struct lwp *l, const struct compat_50_netbsd32_wait4_args *uap, register_t *retval) 842 { 843 /* { 844 syscallarg(int) pid; 845 syscallarg(netbsd32_intp) status; 846 syscallarg(int) options; 847 syscallarg(netbsd32_rusage50p_t) rusage; 848 } */ 849 int error, status, pid = SCARG(uap, pid); 850 struct netbsd32_rusage50 ru32; 851 struct rusage ru; 852 853 error = do_sys_wait(&pid, &status, SCARG(uap, options), 854 SCARG_P32(uap, rusage) != NULL ? &ru : NULL); 855 856 retval[0] = pid; 857 if (pid == 0) 858 return error; 859 860 if (SCARG_P32(uap, rusage)) { 861 netbsd32_from_rusage50(&ru, &ru32); 862 error = copyout(&ru32, SCARG_P32(uap, rusage), sizeof(ru32)); 863 } 864 865 if (error == 0 && SCARG_P32(uap, status)) 866 error = copyout(&status, SCARG_P32(uap, status), sizeof(status)); 867 868 return error; 869 } 870 871 872 int 873 compat_50_netbsd32_getrusage(struct lwp *l, const struct compat_50_netbsd32_getrusage_args *uap, register_t *retval) 874 { 875 /* { 876 syscallarg(int) who; 877 syscallarg(netbsd32_rusage50p_t) rusage; 878 } */ 879 struct proc *p = l->l_proc; 880 struct rusage *rup; 881 struct netbsd32_rusage50 ru; 882 883 switch (SCARG(uap, who)) { 884 885 case RUSAGE_SELF: 886 rup = &p->p_stats->p_ru; 887 mutex_enter(p->p_lock); 888 calcru(p, &rup->ru_utime, &rup->ru_stime, NULL, NULL); 889 mutex_exit(p->p_lock); 890 break; 891 892 case RUSAGE_CHILDREN: 893 rup = &p->p_stats->p_cru; 894 break; 895 896 default: 897 return (EINVAL); 898 } 899 netbsd32_from_rusage50(rup, &ru); 900 return copyout(&ru, SCARG_P32(uap, rusage), sizeof(ru)); 901 } 902 903 int 904 compat_50_netbsd32_setitimer(struct lwp *l, 905 const struct compat_50_netbsd32_setitimer_args *uap, register_t *retval) 906 { 907 /* { 908 syscallarg(int) which; 909 syscallarg(const netbsd32_itimerval50p_t) itv; 910 syscallarg(netbsd32_itimerval50p_t) oitv; 911 } */ 912 struct proc *p = l->l_proc; 913 struct netbsd32_itimerval50 s32it, *itv32; 914 int which = SCARG(uap, which); 915 struct compat_50_netbsd32_getitimer_args getargs; 916 struct itimerval aitv; 917 int error; 918 919 if ((u_int)which > ITIMER_PROF) 920 return (EINVAL); 921 itv32 = SCARG_P32(uap, itv); 922 if (itv32) { 923 if ((error = copyin(itv32, &s32it, sizeof(s32it)))) 924 return (error); 925 netbsd32_to_itimerval50(&s32it, &aitv); 926 } 927 if (SCARG_P32(uap, oitv) != 0) { 928 SCARG(&getargs, which) = which; 929 SCARG(&getargs, itv) = SCARG(uap, oitv); 930 if ((error = compat_50_netbsd32_getitimer(l, &getargs, retval)) != 0) 931 return (error); 932 } 933 if (itv32 == 0) 934 return 0; 935 936 return dosetitimer(p, which, &aitv); 937 } 938 939 int 940 compat_50_netbsd32_getitimer(struct lwp *l, const struct compat_50_netbsd32_getitimer_args *uap, register_t *retval) 941 { 942 /* { 943 syscallarg(int) which; 944 syscallarg(netbsd32_itimerval50p_t) itv; 945 } */ 946 struct proc *p = l->l_proc; 947 struct netbsd32_itimerval50 s32it; 948 struct itimerval aitv; 949 int error; 950 951 error = dogetitimer(p, SCARG(uap, which), &aitv); 952 if (error) 953 return error; 954 955 netbsd32_from_itimerval50(&aitv, &s32it); 956 return copyout(&s32it, SCARG_P32(uap, itv), sizeof(s32it)); 957 } 958 959 #if defined(SYSVSEM) 960 961 int 962 compat_50_netbsd32___semctl14(struct lwp *l, const struct compat_50_netbsd32___semctl14_args *uap, register_t *retval) 963 { 964 return do_netbsd32___semctl14(l, uap, retval, NULL); 965 } 966 967 int 968 do_netbsd32___semctl14(struct lwp *l, const struct compat_50_netbsd32___semctl14_args *uap, register_t *retval, void *vkarg) 969 { 970 /* { 971 syscallarg(int) semid; 972 syscallarg(int) semnum; 973 syscallarg(int) cmd; 974 syscallarg(netbsd32_semun50p_t) arg; 975 } */ 976 struct semid_ds sembuf; 977 struct netbsd32_semid_ds50 sembuf32; 978 int cmd, error; 979 void *pass_arg; 980 union __semun karg; 981 union netbsd32_semun50 karg32; 982 983 cmd = SCARG(uap, cmd); 984 985 switch (cmd) { 986 case IPC_SET: 987 case IPC_STAT: 988 pass_arg = &sembuf; 989 break; 990 991 case GETALL: 992 case SETVAL: 993 case SETALL: 994 pass_arg = &karg; 995 break; 996 default: 997 pass_arg = NULL; 998 break; 999 } 1000 1001 if (pass_arg) { 1002 if (vkarg != NULL) 1003 karg32 = *(union netbsd32_semun50 *)vkarg; 1004 else { 1005 error = copyin(SCARG_P32(uap, arg), &karg32, 1006 sizeof(karg32)); 1007 if (error) 1008 return error; 1009 } 1010 if (pass_arg == &karg) { 1011 switch (cmd) { 1012 case GETALL: 1013 case SETALL: 1014 karg.array = NETBSD32PTR64(karg32.array); 1015 break; 1016 case SETVAL: 1017 karg.val = karg32.val; 1018 break; 1019 } 1020 } 1021 if (cmd == IPC_SET) { 1022 error = copyin(NETBSD32PTR64(karg32.buf), &sembuf32, 1023 sizeof(sembuf32)); 1024 if (error) 1025 return (error); 1026 netbsd32_to_semid_ds50(&sembuf32, &sembuf); 1027 } 1028 } 1029 1030 error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd, 1031 pass_arg, retval); 1032 1033 if (error == 0 && cmd == IPC_STAT) { 1034 netbsd32_from_semid_ds50(&sembuf, &sembuf32); 1035 error = copyout(&sembuf32, NETBSD32PTR64(karg32.buf), 1036 sizeof(sembuf32)); 1037 } 1038 1039 return (error); 1040 } 1041 #endif 1042 1043 #if defined(SYSVMSG) 1044 1045 int 1046 compat_50_netbsd32___msgctl13(struct lwp *l, const struct compat_50_netbsd32___msgctl13_args *uap, register_t *retval) 1047 { 1048 /* { 1049 syscallarg(int) msqid; 1050 syscallarg(int) cmd; 1051 syscallarg(netbsd32_msqid_ds50p_t) buf; 1052 } */ 1053 struct msqid_ds ds; 1054 struct netbsd32_msqid_ds50 ds32; 1055 int error, cmd; 1056 1057 cmd = SCARG(uap, cmd); 1058 if (cmd == IPC_SET) { 1059 error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32)); 1060 if (error) 1061 return error; 1062 netbsd32_to_msqid_ds50(&ds32, &ds); 1063 } 1064 1065 error = msgctl1(l, SCARG(uap, msqid), cmd, 1066 (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL); 1067 1068 if (error == 0 && cmd == IPC_STAT) { 1069 netbsd32_from_msqid_ds50(&ds, &ds32); 1070 error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32)); 1071 } 1072 1073 return error; 1074 } 1075 #endif 1076 1077 #if defined(SYSVSHM) 1078 1079 int 1080 compat_50_netbsd32___shmctl13(struct lwp *l, const struct compat_50_netbsd32___shmctl13_args *uap, register_t *retval) 1081 { 1082 /* { 1083 syscallarg(int) shmid; 1084 syscallarg(int) cmd; 1085 syscallarg(netbsd32_shmid_ds50p_t) buf; 1086 } */ 1087 struct shmid_ds ds; 1088 struct netbsd32_shmid_ds50 ds32; 1089 int error, cmd; 1090 1091 cmd = SCARG(uap, cmd); 1092 if (cmd == IPC_SET) { 1093 error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32)); 1094 if (error) 1095 return error; 1096 netbsd32_to_shmid_ds50(&ds32, &ds); 1097 } 1098 1099 error = shmctl1(l, SCARG(uap, shmid), cmd, 1100 (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL); 1101 1102 if (error == 0 && cmd == IPC_STAT) { 1103 netbsd32_from_shmid_ds50(&ds, &ds32); 1104 error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32)); 1105 } 1106 1107 return error; 1108 } 1109 #endif 1110