1 /* $NetBSD: netbsd32_compat_50.c,v 1.15 2010/04/08 11:51:14 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.15 2010/04/08 11:51:14 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 int error; 316 struct timespec ats; 317 struct netbsd32_timespec50 ts32; 318 319 error = clock_gettime1(SCARG(uap, clock_id), &ats); 320 if (error != 0) 321 return error; 322 323 netbsd32_from_timespec50(&ats, &ts32); 324 return copyout(&ts32, SCARG_P32(uap, tp), sizeof(ts32)); 325 } 326 327 int 328 compat_50_netbsd32_clock_settime(struct lwp *l, 329 const struct compat_50_netbsd32_clock_settime_args *uap, register_t *retval) 330 { 331 /* { 332 syscallarg(netbsd32_clockid_t) clock_id; 333 syscallarg(const netbsd32_timespec50p_t) tp; 334 } */ 335 struct netbsd32_timespec50 ts32; 336 struct timespec ats; 337 int error; 338 339 if ((error = copyin(SCARG_P32(uap, tp), &ts32, sizeof(ts32))) != 0) 340 return (error); 341 342 netbsd32_to_timespec50(&ts32, &ats); 343 return clock_settime1(l->l_proc, SCARG(uap, clock_id), &ats, true); 344 } 345 346 int 347 compat_50_netbsd32_clock_getres(struct lwp *l, 348 const struct compat_50_netbsd32_clock_getres_args *uap, register_t *retval) 349 { 350 /* { 351 syscallarg(netbsd32_clockid_t) clock_id; 352 syscallarg(netbsd32_timespec50p_t) tp; 353 } */ 354 struct netbsd32_timespec50 ts32; 355 struct timespec ts; 356 int error = 0; 357 358 error = clock_getres1(SCARG(uap, clock_id), &ts); 359 if (error != 0) 360 return error; 361 362 if (SCARG_P32(uap, tp)) { 363 netbsd32_from_timespec50(&ts, &ts32); 364 error = copyout(&ts32, SCARG_P32(uap, tp), sizeof(ts32)); 365 } 366 367 return error; 368 } 369 370 int 371 compat_50_netbsd32_timer_settime(struct lwp *l, 372 const struct compat_50_netbsd32_timer_settime_args *uap, register_t *retval) 373 { 374 /* { 375 syscallarg(netbsd32_timer_t) timerid; 376 syscallarg(int) flags; 377 syscallarg(const netbsd32_itimerspec50p_t) value; 378 syscallarg(netbsd32_itimerspec50p_t) ovalue; 379 } */ 380 int error; 381 struct itimerspec value, ovalue, *ovp = NULL; 382 struct netbsd32_itimerspec50 its32; 383 384 if ((error = copyin(SCARG_P32(uap, value), &its32, sizeof(its32))) != 0) 385 return (error); 386 netbsd32_to_timespec50(&its32.it_interval, &value.it_interval); 387 netbsd32_to_timespec50(&its32.it_value, &value.it_value); 388 389 if (SCARG_P32(uap, ovalue)) 390 ovp = &ovalue; 391 392 if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp, 393 SCARG(uap, flags), l->l_proc)) != 0) 394 return error; 395 396 if (ovp) { 397 netbsd32_from_timespec50(&ovp->it_interval, &its32.it_interval); 398 netbsd32_from_timespec50(&ovp->it_value, &its32.it_value); 399 return copyout(&its32, SCARG_P32(uap, ovalue), sizeof(its32)); 400 } 401 return 0; 402 } 403 404 int 405 compat_50_netbsd32_timer_gettime(struct lwp *l, const struct compat_50_netbsd32_timer_gettime_args *uap, register_t *retval) 406 { 407 /* { 408 syscallarg(netbsd32_timer_t) timerid; 409 syscallarg(netbsd32_itimerspec50p_t) value; 410 } */ 411 int error; 412 struct itimerspec its; 413 struct netbsd32_itimerspec50 its32; 414 415 if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, 416 &its)) != 0) 417 return error; 418 419 netbsd32_from_timespec50(&its.it_interval, &its32.it_interval); 420 netbsd32_from_timespec50(&its.it_value, &its32.it_value); 421 422 return copyout(&its32, SCARG_P32(uap, value), sizeof(its32)); 423 } 424 425 int 426 compat_50_netbsd32_nanosleep(struct lwp *l, 427 const struct compat_50_netbsd32_nanosleep_args *uap, register_t *retval) 428 { 429 /* { 430 syscallarg(const netbsd32_timespec50p_t) rqtp; 431 syscallarg(netbsd32_timespecp_t) rmtp; 432 } */ 433 struct netbsd32_timespec50 ts32; 434 struct timespec rqt, rmt; 435 int error, error1; 436 437 error = copyin(SCARG_P32(uap, rqtp), &ts32, sizeof(ts32)); 438 if (error) 439 return (error); 440 netbsd32_to_timespec50(&ts32, &rqt); 441 442 error = nanosleep1(l, &rqt, SCARG_P32(uap, rmtp) ? &rmt : NULL); 443 if (SCARG_P32(uap, rmtp) == NULL || (error != 0 && error != EINTR)) 444 return error; 445 446 netbsd32_from_timespec50(&rmt, &ts32); 447 error1 = copyout(&ts32, SCARG_P32(uap,rmtp), sizeof(ts32)); 448 return error1 ? error1 : error; 449 } 450 451 static int 452 compat_50_netbsd32_sigtimedwait_put_info(const void *src, void *dst, size_t size) 453 { 454 const siginfo_t *info = src; 455 siginfo32_t info32; 456 457 netbsd32_si_to_si32(&info32, info); 458 459 return copyout(&info32, dst, sizeof(info32)); 460 } 461 462 static int 463 compat_50_netbsd32_sigtimedwait_fetch_timeout(const void *src, void *dst, size_t size) 464 { 465 struct timespec *ts = dst; 466 struct netbsd32_timespec50 ts32; 467 int error; 468 469 error = copyin(src, &ts32, sizeof(ts32)); 470 if (error) 471 return error; 472 473 netbsd32_to_timespec50(&ts32, ts); 474 return 0; 475 } 476 477 static int 478 compat_50_netbsd32_sigtimedwait_put_timeout(const void *src, void *dst, size_t size) 479 { 480 const struct timespec *ts = src; 481 struct netbsd32_timespec50 ts32; 482 483 netbsd32_from_timespec50(ts, &ts32); 484 485 return copyout(&ts32, dst, sizeof(ts32)); 486 } 487 488 int 489 compat_50_netbsd32___sigtimedwait(struct lwp *l, 490 const struct compat_50_netbsd32___sigtimedwait_args *uap, register_t *retval) 491 { 492 /* { 493 syscallarg(netbsd32_sigsetp_t) set; 494 syscallarg(netbsd32_siginfop_t) info; 495 syscallarg(netbsd32_timespec50p_t) timeout; 496 } */ 497 struct sys_____sigtimedwait50_args ua; 498 499 NETBSD32TOP_UAP(set, const sigset_t); 500 NETBSD32TOP_UAP(info, siginfo_t); 501 NETBSD32TOP_UAP(timeout, struct timespec); 502 503 return sigtimedwait1(l, &ua, retval, 504 compat_50_netbsd32_sigtimedwait_put_info, 505 compat_50_netbsd32_sigtimedwait_fetch_timeout, 506 compat_50_netbsd32_sigtimedwait_put_timeout); 507 return 0; 508 } 509 510 int 511 compat_50_netbsd32_lutimes(struct lwp *l, 512 const struct compat_50_netbsd32_lutimes_args *uap, register_t *retval) 513 { 514 /* { 515 syscallarg(const netbsd32_charp) path; 516 syscallarg(const netbsd32_timeval50p_t) tptr; 517 } */ 518 int error; 519 struct timeval tv[2], *tvp; 520 521 error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp); 522 if (error != 0) 523 return error; 524 525 return do_sys_utimes(l, NULL, SCARG_P32(uap, path), NOFOLLOW, 526 tvp, UIO_SYSSPACE); 527 } 528 529 int 530 compat_50_netbsd32__lwp_park(struct lwp *l, 531 const struct compat_50_netbsd32__lwp_park_args *uap, register_t *retval) 532 { 533 /* { 534 syscallarg(const netbsd32_timespec50p) ts; 535 syscallarg(lwpid_t) unpark; 536 syscallarg(netbsd32_voidp) hint; 537 syscallarg(netbsd32_voidp) unparkhint; 538 } */ 539 struct timespec ts, *tsp; 540 struct netbsd32_timespec50 ts32; 541 int error; 542 543 if (SCARG_P32(uap, ts) == NULL) 544 tsp = NULL; 545 else { 546 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof ts32); 547 if (error != 0) 548 return error; 549 netbsd32_to_timespec50(&ts32, &ts); 550 tsp = &ts; 551 } 552 553 if (SCARG(uap, unpark) != 0) { 554 error = lwp_unpark(SCARG(uap, unpark), 555 SCARG_P32(uap, unparkhint)); 556 if (error != 0) 557 return error; 558 } 559 560 return lwp_park(tsp, SCARG_P32(uap, hint)); 561 return 0; 562 } 563 564 static int 565 netbsd32_kevent_fetch_timeout(const void *src, void *dest, size_t length) 566 { 567 struct netbsd32_timespec50 ts32; 568 int error; 569 570 KASSERT(length == sizeof(struct timespec50)); 571 572 error = copyin(src, &ts32, sizeof(ts32)); 573 if (error) 574 return error; 575 netbsd32_to_timespec50(&ts32, (struct timespec *)dest); 576 return 0; 577 } 578 579 static int 580 netbsd32_kevent_fetch_changes(void *private, const struct kevent *changelist, 581 struct kevent *changes, size_t index, int n) 582 { 583 const struct netbsd32_kevent *src = 584 (const struct netbsd32_kevent *)changelist; 585 struct netbsd32_kevent *kev32, *changes32 = private; 586 int error, i; 587 588 error = copyin(src + index, changes32, n * sizeof(*changes32)); 589 if (error) 590 return error; 591 for (i = 0, kev32 = changes32; i < n; i++, kev32++, changes++) 592 netbsd32_to_kevent(kev32, changes); 593 return 0; 594 } 595 596 static int 597 netbsd32_kevent_put_events(void *private, struct kevent *events, 598 struct kevent *eventlist, size_t index, int n) 599 { 600 struct netbsd32_kevent *kev32, *events32 = private; 601 int i; 602 603 for (i = 0, kev32 = events32; i < n; i++, kev32++, events++) 604 netbsd32_from_kevent(events, kev32); 605 kev32 = (struct netbsd32_kevent *)eventlist; 606 return copyout(events32, kev32, n * sizeof(*events32)); 607 } 608 609 int 610 compat_50_netbsd32_kevent(struct lwp *l, 611 const struct compat_50_netbsd32_kevent_args *uap, register_t *retval) 612 { 613 /* { 614 syscallarg(int) fd; 615 syscallarg(netbsd32_keventp_t) changelist; 616 syscallarg(netbsd32_size_t) nchanges; 617 syscallarg(netbsd32_keventp_t) eventlist; 618 syscallarg(netbsd32_size_t) nevents; 619 syscallarg(netbsd32_timespec50p_t) timeout; 620 } */ 621 int error; 622 size_t maxalloc, nchanges, nevents; 623 struct kevent_ops netbsd32_kevent_ops = { 624 keo_fetch_timeout: netbsd32_kevent_fetch_timeout, 625 keo_fetch_changes: netbsd32_kevent_fetch_changes, 626 keo_put_events: netbsd32_kevent_put_events, 627 }; 628 629 nchanges = SCARG(uap, nchanges); 630 nevents = SCARG(uap, nevents); 631 maxalloc = MIN(KQ_NEVENTS, MAX(nchanges, nevents)); 632 netbsd32_kevent_ops.keo_private = 633 malloc(maxalloc * sizeof(struct netbsd32_kevent), M_TEMP, 634 M_WAITOK); 635 636 error = kevent1(retval, SCARG(uap, fd), 637 NETBSD32PTR64(SCARG(uap, changelist)), nchanges, 638 NETBSD32PTR64(SCARG(uap, eventlist)), nevents, 639 NETBSD32PTR64(SCARG(uap, timeout)), &netbsd32_kevent_ops); 640 641 free(netbsd32_kevent_ops.keo_private, M_TEMP); 642 return error; 643 return 0; 644 } 645 646 int 647 compat_50_netbsd32_pselect(struct lwp *l, 648 const struct compat_50_netbsd32_pselect_args *uap, register_t *retval) 649 { 650 /* { 651 syscallarg(int) nd; 652 syscallarg(netbsd32_fd_setp_t) in; 653 syscallarg(netbsd32_fd_setp_t) ou; 654 syscallarg(netbsd32_fd_setp_t) ex; 655 syscallarg(const netbsd32_timespec50p_t) ts; 656 syscallarg(const netbsd32_sigsetp_t) mask; 657 } */ 658 int error; 659 struct netbsd32_timespec50 ts32; 660 struct timespec ats, *ts = NULL; 661 sigset_t amask, *mask = NULL; 662 663 if (SCARG_P32(uap, ts)) { 664 error = copyin(SCARG_P32(uap, ts), &ts32, sizeof(ts32)); 665 if (error != 0) 666 return error; 667 netbsd32_to_timespec50(&ts32, &ats); 668 ts = &ats; 669 } 670 if (SCARG_P32(uap, mask)) { 671 error = copyin(SCARG_P32(uap, mask), &amask, sizeof(amask)); 672 if (error != 0) 673 return error; 674 mask = &amask; 675 } 676 677 return selcommon(retval, SCARG(uap, nd), SCARG_P32(uap, in), 678 SCARG_P32(uap, ou), SCARG_P32(uap, ex), ts, mask); 679 return 0; 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 struct proc *p = l->l_proc; 841 struct rusage *rup; 842 struct netbsd32_rusage50 ru; 843 844 switch (SCARG(uap, who)) { 845 846 case RUSAGE_SELF: 847 rup = &p->p_stats->p_ru; 848 mutex_enter(p->p_lock); 849 calcru(p, &rup->ru_utime, &rup->ru_stime, NULL, NULL); 850 mutex_exit(p->p_lock); 851 break; 852 853 case RUSAGE_CHILDREN: 854 rup = &p->p_stats->p_cru; 855 break; 856 857 default: 858 return (EINVAL); 859 } 860 netbsd32_from_rusage50(rup, &ru); 861 return copyout(&ru, SCARG_P32(uap, rusage), sizeof(ru)); 862 } 863 864 int 865 compat_50_netbsd32_setitimer(struct lwp *l, 866 const struct compat_50_netbsd32_setitimer_args *uap, register_t *retval) 867 { 868 /* { 869 syscallarg(int) which; 870 syscallarg(const netbsd32_itimerval50p_t) itv; 871 syscallarg(netbsd32_itimerval50p_t) oitv; 872 } */ 873 struct proc *p = l->l_proc; 874 struct netbsd32_itimerval50 s32it, *itv32; 875 int which = SCARG(uap, which); 876 struct compat_50_netbsd32_getitimer_args getargs; 877 struct itimerval aitv; 878 int error; 879 880 if ((u_int)which > ITIMER_PROF) 881 return (EINVAL); 882 itv32 = SCARG_P32(uap, itv); 883 if (itv32) { 884 if ((error = copyin(itv32, &s32it, sizeof(s32it)))) 885 return (error); 886 netbsd32_to_itimerval50(&s32it, &aitv); 887 } 888 if (SCARG_P32(uap, oitv) != 0) { 889 SCARG(&getargs, which) = which; 890 SCARG(&getargs, itv) = SCARG(uap, oitv); 891 if ((error = compat_50_netbsd32_getitimer(l, &getargs, retval)) != 0) 892 return (error); 893 } 894 if (itv32 == 0) 895 return 0; 896 897 return dosetitimer(p, which, &aitv); 898 } 899 900 int 901 compat_50_netbsd32_getitimer(struct lwp *l, const struct compat_50_netbsd32_getitimer_args *uap, register_t *retval) 902 { 903 /* { 904 syscallarg(int) which; 905 syscallarg(netbsd32_itimerval50p_t) itv; 906 } */ 907 struct proc *p = l->l_proc; 908 struct netbsd32_itimerval50 s32it; 909 struct itimerval aitv; 910 int error; 911 912 error = dogetitimer(p, SCARG(uap, which), &aitv); 913 if (error) 914 return error; 915 916 netbsd32_from_itimerval50(&aitv, &s32it); 917 return copyout(&s32it, SCARG_P32(uap, itv), sizeof(s32it)); 918 } 919 920 #if defined(SYSVSEM) 921 922 int 923 compat_50_netbsd32___semctl14(struct lwp *l, const struct compat_50_netbsd32___semctl14_args *uap, register_t *retval) 924 { 925 return do_netbsd32___semctl14(l, uap, retval, NULL); 926 } 927 928 int 929 do_netbsd32___semctl14(struct lwp *l, const struct compat_50_netbsd32___semctl14_args *uap, register_t *retval, void *vkarg) 930 { 931 /* { 932 syscallarg(int) semid; 933 syscallarg(int) semnum; 934 syscallarg(int) cmd; 935 syscallarg(netbsd32_semun50p_t) arg; 936 } */ 937 struct semid_ds sembuf; 938 struct netbsd32_semid_ds50 sembuf32; 939 int cmd, error; 940 void *pass_arg; 941 union __semun karg; 942 union netbsd32_semun50 karg32; 943 944 cmd = SCARG(uap, cmd); 945 946 switch (cmd) { 947 case IPC_SET: 948 case IPC_STAT: 949 pass_arg = &sembuf; 950 break; 951 952 case GETALL: 953 case SETVAL: 954 case SETALL: 955 pass_arg = &karg; 956 break; 957 default: 958 pass_arg = NULL; 959 break; 960 } 961 962 if (pass_arg) { 963 if (vkarg != NULL) 964 karg32 = *(union netbsd32_semun50 *)vkarg; 965 else { 966 error = copyin(SCARG_P32(uap, arg), &karg32, 967 sizeof(karg32)); 968 if (error) 969 return error; 970 } 971 if (pass_arg == &karg) { 972 switch (cmd) { 973 case GETALL: 974 case SETALL: 975 karg.array = NETBSD32PTR64(karg32.array); 976 break; 977 case SETVAL: 978 karg.val = karg32.val; 979 break; 980 } 981 } 982 if (cmd == IPC_SET) { 983 error = copyin(NETBSD32PTR64(karg32.buf), &sembuf32, 984 sizeof(sembuf32)); 985 if (error) 986 return (error); 987 netbsd32_to_semid_ds50(&sembuf32, &sembuf); 988 } 989 } 990 991 error = semctl1(l, SCARG(uap, semid), SCARG(uap, semnum), cmd, 992 pass_arg, retval); 993 994 if (error == 0 && cmd == IPC_STAT) { 995 netbsd32_from_semid_ds50(&sembuf, &sembuf32); 996 error = copyout(&sembuf32, NETBSD32PTR64(karg32.buf), 997 sizeof(sembuf32)); 998 } 999 1000 return (error); 1001 } 1002 #endif 1003 1004 #if defined(SYSVMSG) 1005 1006 int 1007 compat_50_netbsd32___msgctl13(struct lwp *l, const struct compat_50_netbsd32___msgctl13_args *uap, register_t *retval) 1008 { 1009 /* { 1010 syscallarg(int) msqid; 1011 syscallarg(int) cmd; 1012 syscallarg(netbsd32_msqid_ds50p_t) buf; 1013 } */ 1014 struct msqid_ds ds; 1015 struct netbsd32_msqid_ds50 ds32; 1016 int error, cmd; 1017 1018 cmd = SCARG(uap, cmd); 1019 if (cmd == IPC_SET) { 1020 error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32)); 1021 if (error) 1022 return error; 1023 netbsd32_to_msqid_ds50(&ds32, &ds); 1024 } 1025 1026 error = msgctl1(l, SCARG(uap, msqid), cmd, 1027 (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL); 1028 1029 if (error == 0 && cmd == IPC_STAT) { 1030 netbsd32_from_msqid_ds50(&ds, &ds32); 1031 error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32)); 1032 } 1033 1034 return error; 1035 } 1036 #endif 1037 1038 #if defined(SYSVSHM) 1039 1040 int 1041 compat_50_netbsd32___shmctl13(struct lwp *l, const struct compat_50_netbsd32___shmctl13_args *uap, register_t *retval) 1042 { 1043 /* { 1044 syscallarg(int) shmid; 1045 syscallarg(int) cmd; 1046 syscallarg(netbsd32_shmid_ds50p_t) buf; 1047 } */ 1048 struct shmid_ds ds; 1049 struct netbsd32_shmid_ds50 ds32; 1050 int error, cmd; 1051 1052 cmd = SCARG(uap, cmd); 1053 if (cmd == IPC_SET) { 1054 error = copyin(SCARG_P32(uap, buf), &ds32, sizeof(ds32)); 1055 if (error) 1056 return error; 1057 netbsd32_to_shmid_ds50(&ds32, &ds); 1058 } 1059 1060 error = shmctl1(l, SCARG(uap, shmid), cmd, 1061 (cmd == IPC_SET || cmd == IPC_STAT) ? &ds : NULL); 1062 1063 if (error == 0 && cmd == IPC_STAT) { 1064 netbsd32_from_shmid_ds50(&ds, &ds32); 1065 error = copyout(&ds32, SCARG_P32(uap, buf), sizeof(ds32)); 1066 } 1067 1068 return error; 1069 } 1070 #endif 1071