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