1 /* $NetBSD: linux32_unistd.c,v 1.4 2006/09/13 19:55:49 manu 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.4 2006/09/13 19:55:49 manu 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/sa.h> 47 #include <sys/proc.h> 48 #include <sys/ucred.h> 49 #include <sys/swap.h> 50 51 #include <machine/types.h> 52 53 #include <sys/syscallargs.h> 54 55 #include <compat/netbsd32/netbsd32.h> 56 #include <compat/netbsd32/netbsd32_conv.h> 57 #include <compat/netbsd32/netbsd32_syscallargs.h> 58 59 #include <compat/linux/common/linux_types.h> 60 #include <compat/linux/common/linux_signal.h> 61 #include <compat/linux/common/linux_machdep.h> 62 #include <compat/linux/common/linux_misc.h> 63 #include <compat/linux/common/linux_oldolduname.h> 64 #include <compat/linux/linux_syscallargs.h> 65 66 #include <compat/linux32/common/linux32_types.h> 67 #include <compat/linux32/common/linux32_signal.h> 68 #include <compat/linux32/common/linux32_machdep.h> 69 #include <compat/linux32/common/linux32_sysctl.h> 70 #include <compat/linux32/common/linux32_socketcall.h> 71 #include <compat/linux32/linux32_syscallargs.h> 72 73 static int linux32_select1(struct lwp *, register_t *, 74 int, fd_set *, fd_set *, fd_set *, struct timeval *); 75 76 int 77 linux32_sys_brk(l, v, retval) 78 struct lwp *l; 79 void *v; 80 register_t *retval; 81 { 82 struct linux32_sys_brk_args /* { 83 syscallarg(netbsd32_charp) nsize; 84 } */ *uap = v; 85 struct linux_sys_brk_args ua; 86 87 NETBSD32TOP_UAP(nsize, char); 88 return linux_sys_brk(l, &ua, retval); 89 } 90 91 int 92 linux32_sys_access(l, v, retval) 93 struct lwp *l; 94 void *v; 95 register_t *retval; 96 { 97 struct linux32_sys_access_args /* { 98 syscallarg(const netbsd32_charp) path; 99 syscallarg(int) flags; 100 } */ *uap = v; 101 struct sys_access_args ua; 102 caddr_t sg; 103 104 NETBSD32TOP_UAP(path, const char); 105 NETBSD32TO64_UAP(flags); 106 107 sg = stackgap_init(l->l_proc, 0); 108 CHECK_ALT_EXIST(l, &sg, SCARG(&ua, path)); 109 110 return sys_access(l, &ua, retval); 111 } 112 113 int 114 linux32_sys_llseek(l, v, retval) 115 struct lwp *l; 116 void *v; 117 register_t *retval; 118 { 119 struct linux32_sys_llseek_args /* { 120 syscallcarg(int) fd; 121 syscallarg(u_int32_t) ohigh; 122 syscallarg(u_int32_t) olow; 123 syscallarg(netbsd32_caddr_t) res; 124 syscallcarg(int) whence; 125 } */ *uap = v; 126 struct linux_sys_llseek_args ua; 127 128 NETBSD32TO64_UAP(fd); 129 NETBSD32TO64_UAP(ohigh); 130 NETBSD32TO64_UAP(olow); 131 NETBSD32TOP_UAP(res, char); 132 NETBSD32TO64_UAP(whence); 133 134 return linux_sys_llseek(l, &ua, retval); 135 } 136 137 int 138 linux32_sys_readlink(l, v, retval) 139 struct lwp *l; 140 void *v; 141 register_t *retval; 142 { 143 struct linux32_sys_readlink_args /* { 144 syscallarg(const netbsd32_charp) name; 145 syscallarg(netbsd32_charp) buf; 146 syscallarg(int) count; 147 } */ *uap = v; 148 struct linux_sys_readlink_args ua; 149 150 NETBSD32TOP_UAP(name, const char); 151 NETBSD32TOP_UAP(buf, char) 152 NETBSD32TO64_UAP(count); 153 154 return linux_sys_readlink(l, &ua, retval); 155 } 156 157 158 int 159 linux32_sys_select(l, v, retval) 160 struct lwp *l; 161 void *v; 162 register_t *retval; 163 { 164 struct linux32_sys_select_args /* { 165 syscallarg(int) nfds; 166 syscallarg(netbsd32_fd_setp_t) readfds; 167 syscallarg(netbsd32_fd_setp_t) writefds; 168 syscallarg(netbsd32_fd_setp_t) exceptfds; 169 syscallarg(netbsd32_timevalp_t) timeout; 170 } */ *uap = v; 171 172 return linux32_select1(l, retval, SCARG(uap, nfds), 173 NETBSD32PTR64(SCARG(uap, readfds)), 174 NETBSD32PTR64(SCARG(uap, writefds)), 175 NETBSD32PTR64(SCARG(uap, exceptfds)), 176 NETBSD32PTR64(SCARG(uap, timeout))); 177 } 178 179 int 180 linux32_sys_oldselect(l, v, retval) 181 struct lwp *l; 182 void *v; 183 register_t *retval; 184 { 185 struct linux32_sys_oldselect_args /* { 186 syscallarg(linux32_oldselectp_t) lsp; 187 } */ *uap = v; 188 struct linux32_oldselect lsp32; 189 int error; 190 191 if ((error = copyin(NETBSD32PTR64(SCARG(uap, lsp)), 192 &lsp32, sizeof(lsp32))) != 0) 193 return error; 194 195 return linux32_select1(l, retval, lsp32.nfds, 196 NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds), 197 NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout)); 198 } 199 200 static int 201 linux32_select1(l, retval, nfds, readfds, writefds, exceptfds, timeout) 202 struct lwp *l; 203 register_t *retval; 204 int nfds; 205 fd_set *readfds, *writefds, *exceptfds; 206 struct timeval *timeout; 207 { 208 struct timeval tv0, tv1, utv, otv; 209 struct netbsd32_timeval utv32; 210 int error; 211 212 timerclear(&otv); /* XXX GCC4 */ 213 214 /* 215 * Store current time for computation of the amount of 216 * time left. 217 */ 218 if (timeout) { 219 if ((error = copyin(timeout, &utv32, sizeof(utv32)))) 220 return error; 221 222 netbsd32_to_timeval(&utv32, &utv); 223 otv = utv; 224 225 if (itimerfix(&utv)) { 226 /* 227 * The timeval was invalid. Convert it to something 228 * valid that will act as it does under Linux. 229 */ 230 utv.tv_sec += utv.tv_usec / 1000000; 231 utv.tv_usec %= 1000000; 232 if (utv.tv_usec < 0) { 233 utv.tv_sec -= 1; 234 utv.tv_usec += 1000000; 235 } 236 if (utv.tv_sec < 0) 237 timerclear(&utv); 238 } 239 microtime(&tv0); 240 } else { 241 timerclear(&utv); 242 } 243 244 error = selcommon(l, retval, nfds, 245 readfds, writefds, exceptfds, &utv, NULL); 246 247 if (error) { 248 /* 249 * See fs/select.c in the Linux kernel. Without this, 250 * Maelstrom doesn't work. 251 */ 252 if (error == ERESTART) 253 error = EINTR; 254 return error; 255 } 256 257 if (timeout) { 258 if (*retval) { 259 /* 260 * Compute how much time was left of the timeout, 261 * by subtracting the current time and the time 262 * before we started the call, and subtracting 263 * that result from the user-supplied value. 264 */ 265 microtime(&tv1); 266 timersub(&tv1, &tv0, &tv1); 267 timersub(&otv, &tv1, &utv); 268 if (utv.tv_sec < 0) 269 timerclear(&utv); 270 } else { 271 timerclear(&utv); 272 } 273 274 netbsd32_from_timeval(&utv, &utv32); 275 276 if ((error = copyout(&utv32, timeout, sizeof(utv32)))) 277 return error; 278 } 279 280 return 0; 281 } 282 283 int 284 linux32_sys_pipe(l, v, retval) 285 struct lwp *l; 286 void *v; 287 register_t *retval; 288 { 289 struct linux32_sys_pipe_args /* { 290 syscallarg(netbsd32_intp) fd; 291 } */ *uap = v; 292 int error; 293 int pfds[2]; 294 295 if ((error = sys_pipe(l, 0, retval))) 296 return error; 297 298 pfds[0] = (int)retval[0]; 299 pfds[1] = (int)retval[1]; 300 301 if ((error = copyout(pfds, NETBSD32PTR64(SCARG(uap, fd)), 302 2 * sizeof (int))) != 0) 303 return error; 304 305 retval[0] = 0; 306 retval[1] = 0; 307 308 return 0; 309 } 310 311 312 int 313 linux32_sys_unlink(l, v, retval) 314 struct lwp *l; 315 void *v; 316 register_t *retval; 317 { 318 struct linux32_sys_unlink_args /* { 319 syscallarg(const netbsd32_charp) path; 320 } */ *uap = v; 321 struct linux_sys_unlink_args ua; 322 323 NETBSD32TOP_UAP(path, const char); 324 325 return linux_sys_unlink(l, &ua, retval); 326 } 327 328 int 329 linux32_sys_chdir(l, v, retval) 330 struct lwp *l; 331 void *v; 332 register_t *retval; 333 { 334 struct linux32_sys_chdir_args /* { 335 syscallarg(const netbsd32_charp) path; 336 } */ *uap = v; 337 struct sys_chdir_args ua; 338 caddr_t sg = stackgap_init(l->l_proc, 0); 339 340 NETBSD32TOP_UAP(path, const char); 341 342 CHECK_ALT_EXIST(l, &sg, SCARG(&ua, path)); 343 344 return sys_chdir(l, &ua, retval); 345 } 346 347 int 348 linux32_sys_link(l, v, retval) 349 struct lwp *l; 350 void *v; 351 register_t *retval; 352 { 353 struct linux32_sys_link_args /* { 354 syscallarg(const netbsd32_charp) path; 355 syscallarg(const netbsd32_charp) link; 356 } */ *uap = v; 357 struct sys_link_args ua; 358 caddr_t sg = stackgap_init(l->l_proc, 0); 359 360 NETBSD32TOP_UAP(path, const char); 361 NETBSD32TOP_UAP(link, const char); 362 363 CHECK_ALT_EXIST(l, &sg, SCARG(&ua, path)); 364 CHECK_ALT_CREAT(l, &sg, SCARG(&ua, link)); 365 366 return sys_link(l, &ua, retval); 367 } 368 369 int 370 linux32_sys_creat(l, v, retval) 371 struct lwp *l; 372 void *v; 373 register_t *retval; 374 { 375 struct linux32_sys_creat_args /* { 376 syscallarg(const netbsd32_charp) path; 377 syscallarg(int) mode; 378 } */ *uap = v; 379 struct sys_open_args ua; 380 caddr_t sg = stackgap_init(l->l_proc, 0); 381 382 NETBSD32TOP_UAP(path, const char); 383 SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY; 384 NETBSD32TO64_UAP(mode); 385 386 CHECK_ALT_EXIST(l, &sg, SCARG(&ua, path)); 387 388 return sys_open(l, &ua, retval); 389 } 390 391 int 392 linux32_sys_mknod(l, v, retval) 393 struct lwp *l; 394 void *v; 395 register_t *retval; 396 { 397 struct linux32_sys_mknod_args /* { 398 syscallarg(const netbsd32_charp) path; 399 syscallarg(int) mode; 400 syscallarg(int) dev; 401 } */ *uap = v; 402 struct linux_sys_mknod_args ua; 403 404 NETBSD32TOP_UAP(path, const char); 405 NETBSD32TO64_UAP(mode); 406 NETBSD32TO64_UAP(dev); 407 408 return linux_sys_mknod(l, &ua, retval); 409 } 410 411 int 412 linux32_sys_chmod(l, v, retval) 413 struct lwp *l; 414 void *v; 415 register_t *retval; 416 { 417 struct linux32_sys_chmod_args /* { 418 syscallarg(const netbsd32_charp) path; 419 syscallarg(int) mode; 420 } */ *uap = v; 421 struct sys_chmod_args ua; 422 caddr_t sg = stackgap_init(l->l_proc, 0); 423 424 NETBSD32TOP_UAP(path, const char); 425 NETBSD32TO64_UAP(mode); 426 427 CHECK_ALT_EXIST(l, &sg, SCARG(&ua, path)); 428 429 return sys_chmod(l, &ua, retval); 430 } 431 432 int 433 linux32_sys_lchown16(l, v, retval) 434 struct lwp *l; 435 void *v; 436 register_t *retval; 437 { 438 struct linux32_sys_lchown16_args /* { 439 syscallarg(const netbsd32_charp) path; 440 syscallarg(int) uid; 441 syscallarg(int) gid; 442 } */ *uap = v; 443 struct sys___posix_lchown_args ua; 444 caddr_t sg = stackgap_init(l->l_proc, 0); 445 446 NETBSD32TOP_UAP(path, const char); 447 CHECK_ALT_SYMLINK(l, &sg, SCARG(&ua, path)); 448 449 if ((linux32_uid_t)SCARG(uap, uid) == (linux32_uid_t)-1) 450 SCARG(&ua, uid) = (uid_t)-1; 451 else 452 SCARG(&ua, uid) = SCARG(uap, uid); 453 454 if ((linux32_gid_t)SCARG(uap, gid) == (linux32_gid_t)-1) 455 SCARG(&ua, gid) = (gid_t)-1; 456 else 457 SCARG(&ua, gid) = SCARG(uap, gid); 458 459 return sys___posix_lchown(l, &ua, retval); 460 } 461 462 int 463 linux32_sys_break(l, v, retval) 464 struct lwp *l; 465 void *v; 466 register_t *retval; 467 { 468 #if 0 469 struct linux32_sys_break_args /* { 470 syscallarg(const netbsd32_charp) nsize; 471 } */ *uap = v; 472 #endif 473 474 return ENOSYS; 475 } 476 477 int 478 linux32_sys_rename(l, v, retval) 479 struct lwp *l; 480 void *v; 481 register_t *retval; 482 { 483 struct linux32_sys_rename_args /* { 484 syscallarg(const netbsd32_charp) from; 485 syscallarg(const netbsd32_charp) to; 486 } */ *uap = v; 487 struct sys_rename_args ua; 488 caddr_t sg = stackgap_init(l->l_proc, 0); 489 490 NETBSD32TOP_UAP(from, const char); 491 NETBSD32TOP_UAP(to, const char); 492 493 CHECK_ALT_EXIST(l, &sg, SCARG(&ua, from)); 494 CHECK_ALT_CREAT(l, &sg, SCARG(&ua, to)); 495 496 return sys___posix_rename(l, &ua, retval); 497 } 498 499 int 500 linux32_sys_mkdir(l, v, retval) 501 struct lwp *l; 502 void *v; 503 register_t *retval; 504 { 505 struct linux32_sys_mkdir_args /* { 506 syscallarg(const netbsd32_charp) path; 507 syscallarg(int) mode; 508 } */ *uap = v; 509 struct sys_mkdir_args ua; 510 caddr_t sg = stackgap_init(l->l_proc, 0); 511 512 NETBSD32TOP_UAP(path, const char); 513 NETBSD32TO64_UAP(mode); 514 515 CHECK_ALT_CREAT(l, &sg, SCARG(&ua, path)); 516 517 return sys_mkdir(l, &ua, retval); 518 } 519 520 int 521 linux32_sys_rmdir(l, v, retval) 522 struct lwp *l; 523 void *v; 524 register_t *retval; 525 { 526 struct linux32_sys_rmdir_args /* { 527 syscallarg(const netbsd32_charp) path; 528 } */ *uap = v; 529 struct sys_rmdir_args ua; 530 caddr_t sg = stackgap_init(l->l_proc, 0); 531 532 NETBSD32TOP_UAP(path, const char); 533 534 CHECK_ALT_EXIST(l, &sg, SCARG(&ua, path)); 535 536 return sys_rmdir(l, &ua, retval); 537 } 538 539 int 540 linux32_sys_getgroups16(l, v, retval) 541 struct lwp *l; 542 void *v; 543 register_t *retval; 544 { 545 struct linux32_sys_getgroups16_args /* { 546 syscallarg(int) gidsetsize; 547 syscallarg(linux32_gidp_t) gidset; 548 } */ *uap = v; 549 struct linux_sys_getgroups16_args ua; 550 551 NETBSD32TO64_UAP(gidsetsize); 552 NETBSD32TOP_UAP(gidset, linux_gid_t); 553 554 return linux_sys_getgroups16(l, &ua, retval); 555 } 556 557 int 558 linux32_sys_setgroups16(l, v, retval) 559 struct lwp *l; 560 void *v; 561 register_t *retval; 562 { 563 struct linux32_sys_setgroups16_args /* { 564 syscallarg(int) gidsetsize; 565 syscallarg(linux32_gidp_t) gidset; 566 } */ *uap = v; 567 struct linux_sys_setgroups16_args ua; 568 569 NETBSD32TO64_UAP(gidsetsize); 570 NETBSD32TOP_UAP(gidset, linux_gid_t); 571 572 return linux_sys_setgroups16(l, &ua, retval); 573 } 574 575 int 576 linux32_sys_symlink(l, v, retval) 577 struct lwp *l; 578 void *v; 579 register_t *retval; 580 { 581 struct linux32_sys_symlink_args /* { 582 syscallarg(const netbsd32_charp) path; 583 syscallarg(const netbsd32_charp) link; 584 } */ *uap = v; 585 struct sys_symlink_args ua; 586 caddr_t sg = stackgap_init(l->l_proc, 0); 587 588 NETBSD32TOP_UAP(path, const char); 589 NETBSD32TOP_UAP(link, const char); 590 591 CHECK_ALT_EXIST(l, &sg, SCARG(&ua, path)); 592 CHECK_ALT_CREAT(l, &sg, SCARG(&ua, link)); 593 594 return sys_symlink(l, &ua, retval); 595 } 596 597 598 int 599 linux32_sys_swapon(l, v, retval) 600 struct lwp *l; 601 void *v; 602 register_t *retval; 603 { 604 struct linux32_sys_swapon_args /* { 605 syscallarg(const netbsd32_charp) name; 606 } */ *uap = v; 607 struct sys_swapctl_args ua; 608 609 SCARG(&ua, cmd) = SWAP_ON; 610 SCARG(&ua, arg) = (void *)__UNCONST(NETBSD32PTR64(SCARG(uap, name))); 611 SCARG(&ua, misc) = 0; /* priority */ 612 return (sys_swapctl(l, &ua, retval)); 613 } 614 615 int 616 linux32_sys_swapoff(l, v, retval) 617 struct lwp *l; 618 void *v; 619 register_t *retval; 620 { 621 struct linux32_sys_swapoff_args /* { 622 syscallarg(const netbsd32_charp) path; 623 } */ *uap = v; 624 struct sys_swapctl_args ua; 625 626 SCARG(&ua, cmd) = SWAP_OFF; 627 SCARG(&ua, arg) = (void *)__UNCONST(NETBSD32PTR64(SCARG(uap, path))); 628 SCARG(&ua, misc) = 0; /* priority */ 629 return (sys_swapctl(l, &ua, retval)); 630 } 631 632 633 int 634 linux32_sys_reboot(l, v, retval) 635 struct lwp *l; 636 void *v; 637 register_t *retval; 638 { 639 struct linux32_sys_reboot_args /* { 640 syscallarg(int) magic1; 641 syscallarg(int) magic2; 642 syscallarg(int) cmd; 643 syscallarg(netbsd32_voidp) arg; 644 } */ *uap = v; 645 struct linux_sys_reboot_args ua; 646 647 NETBSD32TO64_UAP(magic1); 648 NETBSD32TO64_UAP(magic2); 649 NETBSD32TO64_UAP(cmd); 650 NETBSD32TOP_UAP(arg, void); 651 652 return linux_sys_reboot(l, &ua, retval); 653 } 654 655 int 656 linux32_sys_truncate(l, v, retval) 657 struct lwp *l; 658 void *v; 659 register_t *retval; 660 { 661 struct linux32_sys_truncate_args /* { 662 syscallarg(const netbsd32_charp) path; 663 syscallarg(netbsd32_charp) buf; 664 syscallarg(int) count; 665 } */ *uap = v; 666 struct compat_43_sys_truncate_args ua; 667 668 NETBSD32TOP_UAP(path, const char); 669 NETBSD32TO64_UAP(length); 670 671 return compat_43_sys_truncate(l, &ua, retval); 672 } 673 674 int 675 linux32_sys_fchown16(l, v, retval) 676 struct lwp *l; 677 void *v; 678 register_t *retval; 679 { 680 struct linux32_sys_fchown16_args /* { 681 syscallarg(int) fd; 682 syscallarg(int) uid; 683 syscallarg(int) gid; 684 } */ *uap = v; 685 struct sys___posix_fchown_args ua; 686 687 SCARG(&ua, fd) = SCARG(uap, fd); 688 689 if ((linux32_uid_t)SCARG(uap, uid) == (linux32_uid_t)-1) 690 SCARG(&ua, uid) = (uid_t)-1; 691 else 692 SCARG(&ua, uid) = SCARG(uap, uid); 693 694 if ((linux32_gid_t)SCARG(uap, gid) == (linux32_gid_t)-1) 695 SCARG(&ua, gid) = (gid_t)-1; 696 else 697 SCARG(&ua, gid) = SCARG(uap, gid); 698 699 return sys___posix_fchown(l, &ua, retval); 700 } 701 702 int 703 linux32_sys_setresuid(l, v, retval) 704 struct lwp *l; 705 void *v; 706 register_t *retval; 707 { 708 struct linux32_sys_setresuid_args /* { 709 syscallarg(uid_t) ruid; 710 syscallarg(uid_t) euid; 711 syscallarg(uid_t) suid; 712 } */ *uap = v; 713 struct linux_sys_setresuid_args ua; 714 715 SCARG(&ua, ruid) = (SCARG(uap, ruid) == -1) ? -1 : SCARG(uap, ruid); 716 SCARG(&ua, euid) = (SCARG(uap, euid) == -1) ? -1 : SCARG(uap, euid); 717 SCARG(&ua, suid) = (SCARG(uap, suid) == -1) ? -1 : SCARG(uap, suid); 718 719 return linux_sys_setresuid(l, &ua, retval); 720 } 721 722 int 723 linux32_sys_setresgid(l, v, retval) 724 struct lwp *l; 725 void *v; 726 register_t *retval; 727 { 728 struct linux32_sys_setresgid_args /* { 729 syscallarg(gid_t) rgid; 730 syscallarg(gid_t) egid; 731 syscallarg(gid_t) sgid; 732 } */ *uap = v; 733 struct linux_sys_setresgid_args ua; 734 735 SCARG(&ua, rgid) = (SCARG(uap, rgid) == -1) ? -1 : SCARG(uap, rgid); 736 SCARG(&ua, egid) = (SCARG(uap, egid) == -1) ? -1 : SCARG(uap, egid); 737 SCARG(&ua, sgid) = (SCARG(uap, sgid) == -1) ? -1 : SCARG(uap, sgid); 738 739 return linux_sys_setresgid(l, &ua, retval); 740 } 741