1 /* $NetBSD: linux32_unistd.c,v 1.13 2007/11/07 00:24:31 njoly Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Emmanuel Dreyfus 17 * 4. The name of the author may not be used to endorse or promote 18 * products derived from this software without specific prior written 19 * permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS'' 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 36 __KERNEL_RCSID(0, "$NetBSD: linux32_unistd.c,v 1.13 2007/11/07 00:24:31 njoly Exp $"); 37 38 #include <sys/types.h> 39 #include <sys/param.h> 40 #include <sys/fstypes.h> 41 #include <sys/signal.h> 42 #include <sys/dirent.h> 43 #include <sys/kernel.h> 44 #include <sys/fcntl.h> 45 #include <sys/select.h> 46 #include <sys/proc.h> 47 #include <sys/ucred.h> 48 #include <sys/swap.h> 49 50 #include <machine/types.h> 51 52 #include <sys/syscallargs.h> 53 54 #include <compat/netbsd32/netbsd32.h> 55 #include <compat/netbsd32/netbsd32_conv.h> 56 #include <compat/netbsd32/netbsd32_syscallargs.h> 57 58 #include <compat/linux/common/linux_types.h> 59 #include <compat/linux/common/linux_signal.h> 60 #include <compat/linux/common/linux_machdep.h> 61 #include <compat/linux/common/linux_misc.h> 62 #include <compat/linux/common/linux_oldolduname.h> 63 #include <compat/linux/linux_syscallargs.h> 64 65 #include <compat/linux32/common/linux32_types.h> 66 #include <compat/linux32/common/linux32_signal.h> 67 #include <compat/linux32/common/linux32_machdep.h> 68 #include <compat/linux32/common/linux32_sysctl.h> 69 #include <compat/linux32/common/linux32_socketcall.h> 70 #include <compat/linux32/linux32_syscallargs.h> 71 72 static int linux32_select1(struct lwp *, register_t *, 73 int, fd_set *, fd_set *, fd_set *, struct timeval *); 74 75 int 76 linux32_sys_brk(l, v, retval) 77 struct lwp *l; 78 void *v; 79 register_t *retval; 80 { 81 struct linux32_sys_brk_args /* { 82 syscallarg(netbsd32_charp) nsize; 83 } */ *uap = v; 84 struct linux_sys_brk_args ua; 85 86 NETBSD32TOP_UAP(nsize, char); 87 return linux_sys_brk(l, &ua, retval); 88 } 89 90 int 91 linux32_sys_llseek(l, v, retval) 92 struct lwp *l; 93 void *v; 94 register_t *retval; 95 { 96 struct linux32_sys_llseek_args /* { 97 syscallcarg(int) fd; 98 syscallarg(u_int32_t) ohigh; 99 syscallarg(u_int32_t) olow; 100 syscallarg(netbsd32_void *) res; 101 syscallcarg(int) whence; 102 } */ *uap = v; 103 struct linux_sys_llseek_args ua; 104 105 NETBSD32TO64_UAP(fd); 106 NETBSD32TO64_UAP(ohigh); 107 NETBSD32TO64_UAP(olow); 108 NETBSD32TOP_UAP(res, char); 109 NETBSD32TO64_UAP(whence); 110 111 return linux_sys_llseek(l, &ua, retval); 112 } 113 114 int 115 linux32_sys_readlink(l, v, retval) 116 struct lwp *l; 117 void *v; 118 register_t *retval; 119 { 120 struct linux32_sys_readlink_args /* { 121 syscallarg(const netbsd32_charp) name; 122 syscallarg(netbsd32_charp) buf; 123 syscallarg(int) count; 124 } */ *uap = v; 125 struct linux_sys_readlink_args ua; 126 127 NETBSD32TOP_UAP(name, const char); 128 NETBSD32TOP_UAP(buf, char) 129 NETBSD32TO64_UAP(count); 130 131 return linux_sys_readlink(l, &ua, retval); 132 } 133 134 135 int 136 linux32_sys_select(l, v, retval) 137 struct lwp *l; 138 void *v; 139 register_t *retval; 140 { 141 struct linux32_sys_select_args /* { 142 syscallarg(int) nfds; 143 syscallarg(netbsd32_fd_setp_t) readfds; 144 syscallarg(netbsd32_fd_setp_t) writefds; 145 syscallarg(netbsd32_fd_setp_t) exceptfds; 146 syscallarg(netbsd32_timevalp_t) timeout; 147 } */ *uap = v; 148 149 return linux32_select1(l, retval, SCARG(uap, nfds), 150 SCARG_P32(uap, readfds), 151 SCARG_P32(uap, writefds), 152 SCARG_P32(uap, exceptfds), 153 SCARG_P32(uap, timeout)); 154 } 155 156 int 157 linux32_sys_oldselect(l, v, retval) 158 struct lwp *l; 159 void *v; 160 register_t *retval; 161 { 162 struct linux32_sys_oldselect_args /* { 163 syscallarg(linux32_oldselectp_t) lsp; 164 } */ *uap = v; 165 struct linux32_oldselect lsp32; 166 int error; 167 168 if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0) 169 return error; 170 171 return linux32_select1(l, retval, lsp32.nfds, 172 NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds), 173 NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout)); 174 } 175 176 static int 177 linux32_select1(l, retval, nfds, readfds, writefds, exceptfds, timeout) 178 struct lwp *l; 179 register_t *retval; 180 int nfds; 181 fd_set *readfds, *writefds, *exceptfds; 182 struct timeval *timeout; 183 { 184 struct timeval tv0, tv1, utv, *tv = NULL; 185 struct netbsd32_timeval utv32; 186 int error; 187 188 timerclear(&utv); /* XXX GCC4 */ 189 190 /* 191 * Store current time for computation of the amount of 192 * time left. 193 */ 194 if (timeout) { 195 if ((error = copyin(timeout, &utv32, sizeof(utv32)))) 196 return error; 197 198 netbsd32_to_timeval(&utv32, &utv); 199 200 if (itimerfix(&utv)) { 201 /* 202 * The timeval was invalid. Convert it to something 203 * valid that will act as it does under Linux. 204 */ 205 utv.tv_sec += utv.tv_usec / 1000000; 206 utv.tv_usec %= 1000000; 207 if (utv.tv_usec < 0) { 208 utv.tv_sec -= 1; 209 utv.tv_usec += 1000000; 210 } 211 if (utv.tv_sec < 0) 212 timerclear(&utv); 213 } 214 microtime(&tv0); 215 tv = &utv; 216 } 217 218 error = selcommon(l, retval, nfds, 219 readfds, writefds, exceptfds, tv, NULL); 220 221 if (error) { 222 /* 223 * See fs/select.c in the Linux kernel. Without this, 224 * Maelstrom doesn't work. 225 */ 226 if (error == ERESTART) 227 error = EINTR; 228 return error; 229 } 230 231 if (timeout) { 232 if (*retval) { 233 /* 234 * Compute how much time was left of the timeout, 235 * by subtracting the current time and the time 236 * before we started the call, and subtracting 237 * that result from the user-supplied value. 238 */ 239 microtime(&tv1); 240 timersub(&tv1, &tv0, &tv1); 241 timersub(&utv, &tv1, &utv); 242 if (utv.tv_sec < 0) 243 timerclear(&utv); 244 } else { 245 timerclear(&utv); 246 } 247 248 netbsd32_from_timeval(&utv, &utv32); 249 250 if ((error = copyout(&utv32, timeout, sizeof(utv32)))) 251 return error; 252 } 253 254 return 0; 255 } 256 257 int 258 linux32_sys_pipe(l, v, retval) 259 struct lwp *l; 260 void *v; 261 register_t *retval; 262 { 263 struct linux32_sys_pipe_args /* { 264 syscallarg(netbsd32_intp) fd; 265 } */ *uap = v; 266 int error; 267 int pfds[2]; 268 269 if ((error = sys_pipe(l, 0, retval))) 270 return error; 271 272 pfds[0] = (int)retval[0]; 273 pfds[1] = (int)retval[1]; 274 275 if ((error = copyout(pfds, SCARG_P32(uap, fd), 2 * sizeof (int))) != 0) 276 return error; 277 278 retval[0] = 0; 279 retval[1] = 0; 280 281 return 0; 282 } 283 284 285 int 286 linux32_sys_unlink(l, v, retval) 287 struct lwp *l; 288 void *v; 289 register_t *retval; 290 { 291 struct linux32_sys_unlink_args /* { 292 syscallarg(const netbsd32_charp) path; 293 } */ *uap = v; 294 struct linux_sys_unlink_args ua; 295 296 NETBSD32TOP_UAP(path, const char); 297 298 return linux_sys_unlink(l, &ua, retval); 299 } 300 301 int 302 linux32_sys_creat(l, v, retval) 303 struct lwp *l; 304 void *v; 305 register_t *retval; 306 { 307 struct linux32_sys_creat_args /* { 308 syscallarg(const netbsd32_charp) path; 309 syscallarg(int) mode; 310 } */ *uap = v; 311 struct sys_open_args ua; 312 313 NETBSD32TOP_UAP(path, const char); 314 SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY; 315 NETBSD32TO64_UAP(mode); 316 317 return sys_open(l, &ua, retval); 318 } 319 320 int 321 linux32_sys_mknod(l, v, retval) 322 struct lwp *l; 323 void *v; 324 register_t *retval; 325 { 326 struct linux32_sys_mknod_args /* { 327 syscallarg(const netbsd32_charp) path; 328 syscallarg(int) mode; 329 syscallarg(int) dev; 330 } */ *uap = v; 331 struct linux_sys_mknod_args ua; 332 333 NETBSD32TOP_UAP(path, const char); 334 NETBSD32TO64_UAP(mode); 335 NETBSD32TO64_UAP(dev); 336 337 return linux_sys_mknod(l, &ua, retval); 338 } 339 340 int 341 linux32_sys_chown16(l, v, retval) 342 struct lwp *l; 343 void *v; 344 register_t *retval; 345 { 346 struct linux32_sys_chown16_args /* { 347 syscallarg(const netbsd32_charp) path; 348 syscallarg(int) uid; 349 syscallarg(int) gid; 350 } */ *uap = v; 351 struct sys___posix_chown_args ua; 352 353 NETBSD32TOP_UAP(path, const char); 354 355 if ((linux32_uid_t)SCARG(uap, uid) == (linux32_uid_t)-1) 356 SCARG(&ua, uid) = (uid_t)-1; 357 else 358 SCARG(&ua, uid) = SCARG(uap, uid); 359 360 if ((linux32_gid_t)SCARG(uap, gid) == (linux32_gid_t)-1) 361 SCARG(&ua, gid) = (gid_t)-1; 362 else 363 SCARG(&ua, gid) = SCARG(uap, gid); 364 365 return sys___posix_chown(l, &ua, retval); 366 } 367 368 int 369 linux32_sys_lchown16(l, v, retval) 370 struct lwp *l; 371 void *v; 372 register_t *retval; 373 { 374 struct linux32_sys_lchown16_args /* { 375 syscallarg(const netbsd32_charp) path; 376 syscallarg(int) uid; 377 syscallarg(int) gid; 378 } */ *uap = v; 379 struct sys___posix_lchown_args ua; 380 381 NETBSD32TOP_UAP(path, const char); 382 383 if ((linux32_uid_t)SCARG(uap, uid) == (linux32_uid_t)-1) 384 SCARG(&ua, uid) = (uid_t)-1; 385 else 386 SCARG(&ua, uid) = SCARG(uap, uid); 387 388 if ((linux32_gid_t)SCARG(uap, gid) == (linux32_gid_t)-1) 389 SCARG(&ua, gid) = (gid_t)-1; 390 else 391 SCARG(&ua, gid) = SCARG(uap, gid); 392 393 return sys___posix_lchown(l, &ua, retval); 394 } 395 396 int 397 linux32_sys_break(l, v, retval) 398 struct lwp *l; 399 void *v; 400 register_t *retval; 401 { 402 #if 0 403 struct linux32_sys_break_args /* { 404 syscallarg(const netbsd32_charp) nsize; 405 } */ *uap = v; 406 #endif 407 408 return ENOSYS; 409 } 410 411 int 412 linux32_sys_rename(l, v, retval) 413 struct lwp *l; 414 void *v; 415 register_t *retval; 416 { 417 struct linux32_sys_rename_args /* { 418 syscallarg(const netbsd32_charp) from; 419 syscallarg(const netbsd32_charp) to; 420 } */ *uap = v; 421 struct sys_rename_args ua; 422 423 NETBSD32TOP_UAP(from, const char); 424 NETBSD32TOP_UAP(to, const char); 425 426 return sys___posix_rename(l, &ua, retval); 427 } 428 429 int 430 linux32_sys_getgroups16(l, v, retval) 431 struct lwp *l; 432 void *v; 433 register_t *retval; 434 { 435 struct linux32_sys_getgroups16_args /* { 436 syscallarg(int) gidsetsize; 437 syscallarg(linux32_gidp_t) gidset; 438 } */ *uap = v; 439 struct linux_sys_getgroups16_args ua; 440 441 NETBSD32TO64_UAP(gidsetsize); 442 NETBSD32TOP_UAP(gidset, linux_gid_t); 443 444 return linux_sys_getgroups16(l, &ua, retval); 445 } 446 447 int 448 linux32_sys_setgroups16(l, v, retval) 449 struct lwp *l; 450 void *v; 451 register_t *retval; 452 { 453 struct linux32_sys_setgroups16_args /* { 454 syscallarg(int) gidsetsize; 455 syscallarg(linux32_gidp_t) gidset; 456 } */ *uap = v; 457 struct linux_sys_setgroups16_args ua; 458 459 NETBSD32TO64_UAP(gidsetsize); 460 NETBSD32TOP_UAP(gidset, linux_gid_t); 461 462 return linux_sys_setgroups16(l, &ua, retval); 463 } 464 465 int 466 linux32_sys_swapon(l, v, retval) 467 struct lwp *l; 468 void *v; 469 register_t *retval; 470 { 471 struct linux32_sys_swapon_args /* { 472 syscallarg(const netbsd32_charp) name; 473 } */ *uap = v; 474 struct sys_swapctl_args ua; 475 476 SCARG(&ua, cmd) = SWAP_ON; 477 SCARG(&ua, arg) = SCARG_P32(uap, name); 478 SCARG(&ua, misc) = 0; /* priority */ 479 return (sys_swapctl(l, &ua, retval)); 480 } 481 482 int 483 linux32_sys_swapoff(l, v, retval) 484 struct lwp *l; 485 void *v; 486 register_t *retval; 487 { 488 struct linux32_sys_swapoff_args /* { 489 syscallarg(const netbsd32_charp) path; 490 } */ *uap = v; 491 struct sys_swapctl_args ua; 492 493 SCARG(&ua, cmd) = SWAP_OFF; 494 SCARG(&ua, arg) = SCARG_P32(uap, path); 495 SCARG(&ua, misc) = 0; /* priority */ 496 return (sys_swapctl(l, &ua, retval)); 497 } 498 499 500 int 501 linux32_sys_reboot(l, v, retval) 502 struct lwp *l; 503 void *v; 504 register_t *retval; 505 { 506 struct linux32_sys_reboot_args /* { 507 syscallarg(int) magic1; 508 syscallarg(int) magic2; 509 syscallarg(int) cmd; 510 syscallarg(netbsd32_voidp) arg; 511 } */ *uap = v; 512 struct linux_sys_reboot_args ua; 513 514 NETBSD32TO64_UAP(magic1); 515 NETBSD32TO64_UAP(magic2); 516 NETBSD32TO64_UAP(cmd); 517 NETBSD32TOP_UAP(arg, void); 518 519 return linux_sys_reboot(l, &ua, retval); 520 } 521 522 int 523 linux32_sys_truncate(l, v, retval) 524 struct lwp *l; 525 void *v; 526 register_t *retval; 527 { 528 struct linux32_sys_truncate_args /* { 529 syscallarg(const netbsd32_charp) path; 530 syscallarg(netbsd32_charp) buf; 531 syscallarg(int) count; 532 } */ *uap = v; 533 struct compat_43_sys_truncate_args ua; 534 535 NETBSD32TOP_UAP(path, const char); 536 NETBSD32TO64_UAP(length); 537 538 return compat_43_sys_truncate(l, &ua, retval); 539 } 540 541 int 542 linux32_sys_fchown16(l, v, retval) 543 struct lwp *l; 544 void *v; 545 register_t *retval; 546 { 547 struct linux32_sys_fchown16_args /* { 548 syscallarg(int) fd; 549 syscallarg(int) uid; 550 syscallarg(int) gid; 551 } */ *uap = v; 552 struct sys___posix_fchown_args ua; 553 554 SCARG(&ua, fd) = SCARG(uap, fd); 555 556 if ((linux32_uid_t)SCARG(uap, uid) == (linux32_uid_t)-1) 557 SCARG(&ua, uid) = (uid_t)-1; 558 else 559 SCARG(&ua, uid) = SCARG(uap, uid); 560 561 if ((linux32_gid_t)SCARG(uap, gid) == (linux32_gid_t)-1) 562 SCARG(&ua, gid) = (gid_t)-1; 563 else 564 SCARG(&ua, gid) = SCARG(uap, gid); 565 566 return sys___posix_fchown(l, &ua, retval); 567 } 568 569 int 570 linux32_sys_setresuid(l, v, retval) 571 struct lwp *l; 572 void *v; 573 register_t *retval; 574 { 575 struct linux32_sys_setresuid_args /* { 576 syscallarg(uid_t) ruid; 577 syscallarg(uid_t) euid; 578 syscallarg(uid_t) suid; 579 } */ *uap = v; 580 struct linux_sys_setresuid_args ua; 581 582 SCARG(&ua, ruid) = (SCARG(uap, ruid) == -1) ? -1 : SCARG(uap, ruid); 583 SCARG(&ua, euid) = (SCARG(uap, euid) == -1) ? -1 : SCARG(uap, euid); 584 SCARG(&ua, suid) = (SCARG(uap, suid) == -1) ? -1 : SCARG(uap, suid); 585 586 return linux_sys_setresuid(l, &ua, retval); 587 } 588 589 int 590 linux32_sys_setresgid(l, v, retval) 591 struct lwp *l; 592 void *v; 593 register_t *retval; 594 { 595 struct linux32_sys_setresgid_args /* { 596 syscallarg(gid_t) rgid; 597 syscallarg(gid_t) egid; 598 syscallarg(gid_t) sgid; 599 } */ *uap = v; 600 struct linux_sys_setresgid_args ua; 601 602 SCARG(&ua, rgid) = (SCARG(uap, rgid) == -1) ? -1 : SCARG(uap, rgid); 603 SCARG(&ua, egid) = (SCARG(uap, egid) == -1) ? -1 : SCARG(uap, egid); 604 SCARG(&ua, sgid) = (SCARG(uap, sgid) == -1) ? -1 : SCARG(uap, sgid); 605 606 return linux_sys_setresgid(l, &ua, retval); 607 } 608 609 int 610 linux32_sys_nice(l, v, retval) 611 struct lwp *l; 612 void *v; 613 register_t *retval; 614 { 615 struct linux32_sys_nice_args /* { 616 syscallarg(int) incr; 617 } */ *uap = v; 618 struct netbsd32_setpriority_args bsa; 619 620 SCARG(&bsa, which) = PRIO_PROCESS; 621 SCARG(&bsa, who) = 0; 622 SCARG(&bsa, prio) = SCARG(uap, incr); 623 624 return netbsd32_setpriority(l, &bsa, retval); 625 } 626 627 int 628 linux32_sys_alarm(l, v, retval) 629 struct lwp *l; 630 void *v; 631 register_t *retval; 632 { 633 struct linux32_sys_alarm_args /* { 634 syscallarg(unsigned int) secs; 635 } */ *uap = v; 636 struct linux_sys_alarm_args ua; 637 638 NETBSD32TO64_UAP(secs); 639 640 return linux_sys_alarm(l, &ua, retval); 641 } 642 643 int 644 linux32_sys_fdatasync(l, v, retval) 645 struct lwp *l; 646 void *v; 647 register_t *retval; 648 { 649 struct linux32_sys_fdatasync_args /* { 650 syscallarg(int) fd; 651 } */ *uap = v; 652 struct linux_sys_fdatasync_args ua; 653 654 NETBSD32TO64_UAP(fd); 655 656 return linux_sys_fdatasync(l, &ua, retval); 657 } 658 659 int 660 linux32_sys_setfsuid(l, v, retval) 661 struct lwp *l; 662 void *v; 663 register_t *retval; 664 { 665 struct linux32_sys_setfsuid_args /* { 666 syscallarg(uid_t) uid; 667 } */ *uap = v; 668 struct linux_sys_setfsuid_args ua; 669 670 NETBSD32TO64_UAP(uid); 671 672 return linux_sys_setfsuid(l, &ua, retval); 673 } 674 675 int 676 linux32_sys_setreuid16(l, v, retval) 677 struct lwp *l; 678 void *v; 679 register_t *retval; 680 { 681 struct linux32_sys_setreuid16_args /* { 682 syscallarg(int) ruid; 683 syscallarg(int) euid; 684 } */ *uap = v; 685 struct sys_setreuid_args bsa; 686 687 if ((linux32_uid_t)SCARG(uap, ruid) == (linux32_uid_t)-1) 688 SCARG(&bsa, ruid) = (uid_t)-1; 689 else 690 SCARG(&bsa, ruid) = SCARG(uap, ruid); 691 if ((linux32_uid_t)SCARG(uap, euid) == (linux32_uid_t)-1) 692 SCARG(&bsa, euid) = (uid_t)-1; 693 else 694 SCARG(&bsa, euid) = SCARG(uap, euid); 695 696 return sys_setreuid(l, &bsa, retval); 697 } 698 699 int 700 linux32_sys_setregid16(l, v, retval) 701 struct lwp *l; 702 void *v; 703 register_t *retval; 704 { 705 struct linux32_sys_setregid16_args /* { 706 syscallarg(int) rgid; 707 syscallarg(int) egid; 708 } */ *uap = v; 709 struct sys_setregid_args bsa; 710 711 if ((linux32_gid_t)SCARG(uap, rgid) == (linux32_gid_t)-1) 712 SCARG(&bsa, rgid) = (gid_t)-1; 713 else 714 SCARG(&bsa, rgid) = SCARG(uap, rgid); 715 if ((linux32_gid_t)SCARG(uap, egid) == (linux32_gid_t)-1) 716 SCARG(&bsa, egid) = (gid_t)-1; 717 else 718 SCARG(&bsa, egid) = SCARG(uap, egid); 719 720 return sys_setregid(l, &bsa, retval); 721 } 722 723 int 724 linux32_sys_setresuid16(l, v, retval) 725 struct lwp *l; 726 void *v; 727 register_t *retval; 728 { 729 struct linux32_sys_setresuid16_args /* { 730 syscallarg(uid_t) ruid; 731 syscallarg(uid_t) euid; 732 syscallarg(uid_t) suid; 733 } */ *uap = v; 734 struct linux32_sys_setresuid_args lsa; 735 736 if ((linux32_uid_t)SCARG(uap, ruid) == (linux32_uid_t)-1) 737 SCARG(&lsa, ruid) = (uid_t)-1; 738 else 739 SCARG(&lsa, ruid) = SCARG(uap, ruid); 740 if ((linux32_uid_t)SCARG(uap, euid) == (linux32_uid_t)-1) 741 SCARG(&lsa, euid) = (uid_t)-1; 742 else 743 SCARG(&lsa, euid) = SCARG(uap, euid); 744 if ((linux32_uid_t)SCARG(uap, suid) == (linux32_uid_t)-1) 745 SCARG(&lsa, suid) = (uid_t)-1; 746 else 747 SCARG(&lsa, suid) = SCARG(uap, euid); 748 749 return linux32_sys_setresuid(l, &lsa, retval); 750 } 751 752 int 753 linux32_sys_setresgid16(l, v, retval) 754 struct lwp *l; 755 void *v; 756 register_t *retval; 757 { 758 struct linux32_sys_setresgid16_args /* { 759 syscallarg(gid_t) rgid; 760 syscallarg(gid_t) egid; 761 syscallarg(gid_t) sgid; 762 } */ *uap = v; 763 struct linux32_sys_setresgid_args lsa; 764 765 if ((linux32_gid_t)SCARG(uap, rgid) == (linux32_gid_t)-1) 766 SCARG(&lsa, rgid) = (gid_t)-1; 767 else 768 SCARG(&lsa, rgid) = SCARG(uap, rgid); 769 if ((linux32_gid_t)SCARG(uap, egid) == (linux32_gid_t)-1) 770 SCARG(&lsa, egid) = (gid_t)-1; 771 else 772 SCARG(&lsa, egid) = SCARG(uap, egid); 773 if ((linux32_gid_t)SCARG(uap, sgid) == (linux32_gid_t)-1) 774 SCARG(&lsa, sgid) = (gid_t)-1; 775 else 776 SCARG(&lsa, sgid) = SCARG(uap, sgid); 777 778 return linux32_sys_setresgid(l, &lsa, retval); 779 } 780