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