1 /* $NetBSD: linux32_unistd.c,v 1.16 2007/12/15 14:08:16 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.16 2007/12/15 14:08:16 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(struct lwp *l, void *v, register_t *retval) 77 { 78 struct linux32_sys_brk_args /* { 79 syscallarg(netbsd32_charp) nsize; 80 } */ *uap = v; 81 struct linux_sys_brk_args ua; 82 83 NETBSD32TOP_UAP(nsize, char); 84 return linux_sys_brk(l, &ua, retval); 85 } 86 87 int 88 linux32_sys_llseek(struct lwp *l, void *v, register_t *retval) 89 { 90 struct linux32_sys_llseek_args /* { 91 syscallcarg(int) fd; 92 syscallarg(u_int32_t) ohigh; 93 syscallarg(u_int32_t) olow; 94 syscallarg(netbsd32_caddr_t) res; 95 syscallcarg(int) whence; 96 } */ *uap = v; 97 struct linux_sys_llseek_args ua; 98 99 NETBSD32TO64_UAP(fd); 100 NETBSD32TO64_UAP(ohigh); 101 NETBSD32TO64_UAP(olow); 102 NETBSD32TOP_UAP(res, char); 103 NETBSD32TO64_UAP(whence); 104 105 return linux_sys_llseek(l, &ua, retval); 106 } 107 108 int 109 linux32_sys_select(struct lwp *l, void *v, register_t *retval) 110 { 111 struct linux32_sys_select_args /* { 112 syscallarg(int) nfds; 113 syscallarg(netbsd32_fd_setp_t) readfds; 114 syscallarg(netbsd32_fd_setp_t) writefds; 115 syscallarg(netbsd32_fd_setp_t) exceptfds; 116 syscallarg(netbsd32_timevalp_t) timeout; 117 } */ *uap = v; 118 119 return linux32_select1(l, retval, SCARG(uap, nfds), 120 SCARG_P32(uap, readfds), 121 SCARG_P32(uap, writefds), 122 SCARG_P32(uap, exceptfds), 123 SCARG_P32(uap, timeout)); 124 } 125 126 int 127 linux32_sys_oldselect(struct lwp *l, void *v, register_t *retval) 128 { 129 struct linux32_sys_oldselect_args /* { 130 syscallarg(linux32_oldselectp_t) lsp; 131 } */ *uap = v; 132 struct linux32_oldselect lsp32; 133 int error; 134 135 if ((error = copyin(SCARG_P32(uap, lsp), &lsp32, sizeof(lsp32))) != 0) 136 return error; 137 138 return linux32_select1(l, retval, lsp32.nfds, 139 NETBSD32PTR64(lsp32.readfds), NETBSD32PTR64(lsp32.writefds), 140 NETBSD32PTR64(lsp32.exceptfds), NETBSD32PTR64(lsp32.timeout)); 141 } 142 143 static int 144 linux32_select1(l, retval, nfds, readfds, writefds, exceptfds, timeout) 145 struct lwp *l; 146 register_t *retval; 147 int nfds; 148 fd_set *readfds, *writefds, *exceptfds; 149 struct timeval *timeout; 150 { 151 struct timeval tv0, tv1, utv, *tv = NULL; 152 struct netbsd32_timeval utv32; 153 int error; 154 155 timerclear(&utv); /* XXX GCC4 */ 156 157 /* 158 * Store current time for computation of the amount of 159 * time left. 160 */ 161 if (timeout) { 162 if ((error = copyin(timeout, &utv32, sizeof(utv32)))) 163 return error; 164 165 netbsd32_to_timeval(&utv32, &utv); 166 167 if (itimerfix(&utv)) { 168 /* 169 * The timeval was invalid. Convert it to something 170 * valid that will act as it does under Linux. 171 */ 172 utv.tv_sec += utv.tv_usec / 1000000; 173 utv.tv_usec %= 1000000; 174 if (utv.tv_usec < 0) { 175 utv.tv_sec -= 1; 176 utv.tv_usec += 1000000; 177 } 178 if (utv.tv_sec < 0) 179 timerclear(&utv); 180 } 181 microtime(&tv0); 182 tv = &utv; 183 } 184 185 error = selcommon(l, retval, nfds, 186 readfds, writefds, exceptfds, tv, NULL); 187 188 if (error) { 189 /* 190 * See fs/select.c in the Linux kernel. Without this, 191 * Maelstrom doesn't work. 192 */ 193 if (error == ERESTART) 194 error = EINTR; 195 return error; 196 } 197 198 if (timeout) { 199 if (*retval) { 200 /* 201 * Compute how much time was left of the timeout, 202 * by subtracting the current time and the time 203 * before we started the call, and subtracting 204 * that result from the user-supplied value. 205 */ 206 microtime(&tv1); 207 timersub(&tv1, &tv0, &tv1); 208 timersub(&utv, &tv1, &utv); 209 if (utv.tv_sec < 0) 210 timerclear(&utv); 211 } else { 212 timerclear(&utv); 213 } 214 215 netbsd32_from_timeval(&utv, &utv32); 216 217 if ((error = copyout(&utv32, timeout, sizeof(utv32)))) 218 return error; 219 } 220 221 return 0; 222 } 223 224 int 225 linux32_sys_pipe(struct lwp *l, void *v, register_t *retval) 226 { 227 struct linux32_sys_pipe_args /* { 228 syscallarg(netbsd32_intp) fd; 229 } */ *uap = v; 230 int error; 231 int pfds[2]; 232 233 if ((error = sys_pipe(l, 0, retval))) 234 return error; 235 236 pfds[0] = (int)retval[0]; 237 pfds[1] = (int)retval[1]; 238 239 if ((error = copyout(pfds, SCARG_P32(uap, fd), 2 * sizeof (int))) != 0) 240 return error; 241 242 retval[0] = 0; 243 retval[1] = 0; 244 245 return 0; 246 } 247 248 249 int 250 linux32_sys_unlink(struct lwp *l, void *v, register_t *retval) 251 { 252 struct linux32_sys_unlink_args /* { 253 syscallarg(const netbsd32_charp) path; 254 } */ *uap = v; 255 struct linux_sys_unlink_args ua; 256 257 NETBSD32TOP_UAP(path, const char); 258 259 return linux_sys_unlink(l, &ua, retval); 260 } 261 262 int 263 linux32_sys_creat(struct lwp *l, void *v, register_t *retval) 264 { 265 struct linux32_sys_creat_args /* { 266 syscallarg(const netbsd32_charp) path; 267 syscallarg(int) mode; 268 } */ *uap = v; 269 struct sys_open_args ua; 270 271 NETBSD32TOP_UAP(path, const char); 272 SCARG(&ua, flags) = O_CREAT | O_TRUNC | O_WRONLY; 273 NETBSD32TO64_UAP(mode); 274 275 return sys_open(l, &ua, retval); 276 } 277 278 int 279 linux32_sys_mknod(struct lwp *l, void *v, register_t *retval) 280 { 281 struct linux32_sys_mknod_args /* { 282 syscallarg(const netbsd32_charp) path; 283 syscallarg(int) mode; 284 syscallarg(int) dev; 285 } */ *uap = v; 286 struct linux_sys_mknod_args ua; 287 288 NETBSD32TOP_UAP(path, const char); 289 NETBSD32TO64_UAP(mode); 290 NETBSD32TO64_UAP(dev); 291 292 return linux_sys_mknod(l, &ua, retval); 293 } 294 295 int 296 linux32_sys_chown16(struct lwp *l, void *v, register_t *retval) 297 { 298 struct linux32_sys_chown16_args /* { 299 syscallarg(const netbsd32_charp) path; 300 syscallarg(int) uid; 301 syscallarg(int) gid; 302 } */ *uap = v; 303 struct sys___posix_chown_args ua; 304 305 NETBSD32TOP_UAP(path, const char); 306 307 if ((linux32_uid_t)SCARG(uap, uid) == (linux32_uid_t)-1) 308 SCARG(&ua, uid) = (uid_t)-1; 309 else 310 SCARG(&ua, uid) = SCARG(uap, uid); 311 312 if ((linux32_gid_t)SCARG(uap, gid) == (linux32_gid_t)-1) 313 SCARG(&ua, gid) = (gid_t)-1; 314 else 315 SCARG(&ua, gid) = SCARG(uap, gid); 316 317 return sys___posix_chown(l, &ua, retval); 318 } 319 320 int 321 linux32_sys_lchown16(struct lwp *l, void *v, register_t *retval) 322 { 323 struct linux32_sys_lchown16_args /* { 324 syscallarg(const netbsd32_charp) path; 325 syscallarg(int) uid; 326 syscallarg(int) gid; 327 } */ *uap = v; 328 struct sys___posix_lchown_args ua; 329 330 NETBSD32TOP_UAP(path, const char); 331 332 if ((linux32_uid_t)SCARG(uap, uid) == (linux32_uid_t)-1) 333 SCARG(&ua, uid) = (uid_t)-1; 334 else 335 SCARG(&ua, uid) = SCARG(uap, uid); 336 337 if ((linux32_gid_t)SCARG(uap, gid) == (linux32_gid_t)-1) 338 SCARG(&ua, gid) = (gid_t)-1; 339 else 340 SCARG(&ua, gid) = SCARG(uap, gid); 341 342 return sys___posix_lchown(l, &ua, retval); 343 } 344 345 int 346 linux32_sys_break(struct lwp *l, void *v, register_t *retval) 347 { 348 #if 0 349 struct linux32_sys_break_args /* { 350 syscallarg(const netbsd32_charp) nsize; 351 } */ *uap = v; 352 #endif 353 354 return ENOSYS; 355 } 356 357 int 358 linux32_sys_rename(struct lwp *l, void *v, register_t *retval) 359 { 360 struct linux32_sys_rename_args /* { 361 syscallarg(const netbsd32_charp) from; 362 syscallarg(const netbsd32_charp) to; 363 } */ *uap = v; 364 struct sys_rename_args ua; 365 366 NETBSD32TOP_UAP(from, const char); 367 NETBSD32TOP_UAP(to, const char); 368 369 return sys___posix_rename(l, &ua, retval); 370 } 371 372 int 373 linux32_sys_getgroups16(struct lwp *l, void *v, register_t *retval) 374 { 375 struct linux32_sys_getgroups16_args /* { 376 syscallarg(int) gidsetsize; 377 syscallarg(linux32_gidp_t) gidset; 378 } */ *uap = v; 379 struct linux_sys_getgroups16_args ua; 380 381 NETBSD32TO64_UAP(gidsetsize); 382 NETBSD32TOP_UAP(gidset, linux_gid_t); 383 384 return linux_sys_getgroups16(l, &ua, retval); 385 } 386 387 int 388 linux32_sys_setgroups16(struct lwp *l, void *v, register_t *retval) 389 { 390 struct linux32_sys_setgroups16_args /* { 391 syscallarg(int) gidsetsize; 392 syscallarg(linux32_gidp_t) gidset; 393 } */ *uap = v; 394 struct linux_sys_setgroups16_args ua; 395 396 NETBSD32TO64_UAP(gidsetsize); 397 NETBSD32TOP_UAP(gidset, linux_gid_t); 398 399 return linux_sys_setgroups16(l, &ua, retval); 400 } 401 402 int 403 linux32_sys_swapon(struct lwp *l, void *v, register_t *retval) 404 { 405 struct linux32_sys_swapon_args /* { 406 syscallarg(const netbsd32_charp) name; 407 } */ *uap = v; 408 struct sys_swapctl_args ua; 409 410 SCARG(&ua, cmd) = SWAP_ON; 411 SCARG(&ua, arg) = SCARG_P32(uap, name); 412 SCARG(&ua, misc) = 0; /* priority */ 413 return (sys_swapctl(l, &ua, retval)); 414 } 415 416 int 417 linux32_sys_swapoff(struct lwp *l, void *v, register_t *retval) 418 { 419 struct linux32_sys_swapoff_args /* { 420 syscallarg(const netbsd32_charp) path; 421 } */ *uap = v; 422 struct sys_swapctl_args ua; 423 424 SCARG(&ua, cmd) = SWAP_OFF; 425 SCARG(&ua, arg) = SCARG_P32(uap, path); 426 SCARG(&ua, misc) = 0; /* priority */ 427 return (sys_swapctl(l, &ua, retval)); 428 } 429 430 431 int 432 linux32_sys_reboot(struct lwp *l, void *v, register_t *retval) 433 { 434 struct linux32_sys_reboot_args /* { 435 syscallarg(int) magic1; 436 syscallarg(int) magic2; 437 syscallarg(int) cmd; 438 syscallarg(netbsd32_voidp) arg; 439 } */ *uap = v; 440 struct linux_sys_reboot_args ua; 441 442 NETBSD32TO64_UAP(magic1); 443 NETBSD32TO64_UAP(magic2); 444 NETBSD32TO64_UAP(cmd); 445 NETBSD32TOP_UAP(arg, void); 446 447 return linux_sys_reboot(l, &ua, retval); 448 } 449 450 int 451 linux32_sys_truncate(struct lwp *l, void *v, register_t *retval) 452 { 453 struct linux32_sys_truncate_args /* { 454 syscallarg(const netbsd32_charp) path; 455 syscallarg(netbsd32_charp) buf; 456 syscallarg(int) count; 457 } */ *uap = v; 458 struct compat_43_sys_truncate_args ua; 459 460 NETBSD32TOP_UAP(path, const char); 461 NETBSD32TO64_UAP(length); 462 463 return compat_43_sys_truncate(l, &ua, retval); 464 } 465 466 int 467 linux32_sys_fchown16(struct lwp *l, void *v, register_t *retval) 468 { 469 struct linux32_sys_fchown16_args /* { 470 syscallarg(int) fd; 471 syscallarg(int) uid; 472 syscallarg(int) gid; 473 } */ *uap = v; 474 struct sys___posix_fchown_args ua; 475 476 SCARG(&ua, fd) = SCARG(uap, fd); 477 478 if ((linux32_uid_t)SCARG(uap, uid) == (linux32_uid_t)-1) 479 SCARG(&ua, uid) = (uid_t)-1; 480 else 481 SCARG(&ua, uid) = SCARG(uap, uid); 482 483 if ((linux32_gid_t)SCARG(uap, gid) == (linux32_gid_t)-1) 484 SCARG(&ua, gid) = (gid_t)-1; 485 else 486 SCARG(&ua, gid) = SCARG(uap, gid); 487 488 return sys___posix_fchown(l, &ua, retval); 489 } 490 491 int 492 linux32_sys_setresuid(struct lwp *l, void *v, register_t *retval) 493 { 494 struct linux32_sys_setresuid_args /* { 495 syscallarg(uid_t) ruid; 496 syscallarg(uid_t) euid; 497 syscallarg(uid_t) suid; 498 } */ *uap = v; 499 struct linux_sys_setresuid_args ua; 500 501 SCARG(&ua, ruid) = (SCARG(uap, ruid) == -1) ? -1 : SCARG(uap, ruid); 502 SCARG(&ua, euid) = (SCARG(uap, euid) == -1) ? -1 : SCARG(uap, euid); 503 SCARG(&ua, suid) = (SCARG(uap, suid) == -1) ? -1 : SCARG(uap, suid); 504 505 return linux_sys_setresuid(l, &ua, retval); 506 } 507 508 int 509 linux32_sys_setresgid(struct lwp *l, void *v, register_t *retval) 510 { 511 struct linux32_sys_setresgid_args /* { 512 syscallarg(gid_t) rgid; 513 syscallarg(gid_t) egid; 514 syscallarg(gid_t) sgid; 515 } */ *uap = v; 516 struct linux_sys_setresgid_args ua; 517 518 SCARG(&ua, rgid) = (SCARG(uap, rgid) == -1) ? -1 : SCARG(uap, rgid); 519 SCARG(&ua, egid) = (SCARG(uap, egid) == -1) ? -1 : SCARG(uap, egid); 520 SCARG(&ua, sgid) = (SCARG(uap, sgid) == -1) ? -1 : SCARG(uap, sgid); 521 522 return linux_sys_setresgid(l, &ua, retval); 523 } 524 525 int 526 linux32_sys_nice(struct lwp *l, void *v, register_t *retval) 527 { 528 struct linux32_sys_nice_args /* { 529 syscallarg(int) incr; 530 } */ *uap = v; 531 struct netbsd32_setpriority_args bsa; 532 533 SCARG(&bsa, which) = PRIO_PROCESS; 534 SCARG(&bsa, who) = 0; 535 SCARG(&bsa, prio) = SCARG(uap, incr); 536 537 return netbsd32_setpriority(l, &bsa, retval); 538 } 539 540 int 541 linux32_sys_alarm(struct lwp *l, void *v, register_t *retval) 542 { 543 struct linux32_sys_alarm_args /* { 544 syscallarg(unsigned int) secs; 545 } */ *uap = v; 546 struct linux_sys_alarm_args ua; 547 548 NETBSD32TO64_UAP(secs); 549 550 return linux_sys_alarm(l, &ua, retval); 551 } 552 553 int 554 linux32_sys_fdatasync(struct lwp *l, void *v, register_t *retval) 555 { 556 struct linux32_sys_fdatasync_args /* { 557 syscallarg(int) fd; 558 } */ *uap = v; 559 struct linux_sys_fdatasync_args ua; 560 561 NETBSD32TO64_UAP(fd); 562 563 return linux_sys_fdatasync(l, &ua, retval); 564 } 565 566 int 567 linux32_sys_setfsuid(struct lwp *l, void *v, register_t *retval) 568 { 569 struct linux32_sys_setfsuid_args /* { 570 syscallarg(uid_t) uid; 571 } */ *uap = v; 572 struct linux_sys_setfsuid_args ua; 573 574 NETBSD32TO64_UAP(uid); 575 576 return linux_sys_setfsuid(l, &ua, retval); 577 } 578 579 int 580 linux32_sys_setreuid16(struct lwp *l, void *v, register_t *retval) 581 { 582 struct linux32_sys_setreuid16_args /* { 583 syscallarg(int) ruid; 584 syscallarg(int) euid; 585 } */ *uap = v; 586 struct sys_setreuid_args bsa; 587 588 if ((linux32_uid_t)SCARG(uap, ruid) == (linux32_uid_t)-1) 589 SCARG(&bsa, ruid) = (uid_t)-1; 590 else 591 SCARG(&bsa, ruid) = SCARG(uap, ruid); 592 if ((linux32_uid_t)SCARG(uap, euid) == (linux32_uid_t)-1) 593 SCARG(&bsa, euid) = (uid_t)-1; 594 else 595 SCARG(&bsa, euid) = SCARG(uap, euid); 596 597 return sys_setreuid(l, &bsa, retval); 598 } 599 600 int 601 linux32_sys_setregid16(struct lwp *l, void *v, register_t *retval) 602 { 603 struct linux32_sys_setregid16_args /* { 604 syscallarg(int) rgid; 605 syscallarg(int) egid; 606 } */ *uap = v; 607 struct sys_setregid_args bsa; 608 609 if ((linux32_gid_t)SCARG(uap, rgid) == (linux32_gid_t)-1) 610 SCARG(&bsa, rgid) = (gid_t)-1; 611 else 612 SCARG(&bsa, rgid) = SCARG(uap, rgid); 613 if ((linux32_gid_t)SCARG(uap, egid) == (linux32_gid_t)-1) 614 SCARG(&bsa, egid) = (gid_t)-1; 615 else 616 SCARG(&bsa, egid) = SCARG(uap, egid); 617 618 return sys_setregid(l, &bsa, retval); 619 } 620 621 int 622 linux32_sys_setresuid16(struct lwp *l, void *v, register_t *retval) 623 { 624 struct linux32_sys_setresuid16_args /* { 625 syscallarg(uid_t) ruid; 626 syscallarg(uid_t) euid; 627 syscallarg(uid_t) suid; 628 } */ *uap = v; 629 struct linux32_sys_setresuid_args lsa; 630 631 if ((linux32_uid_t)SCARG(uap, ruid) == (linux32_uid_t)-1) 632 SCARG(&lsa, ruid) = (uid_t)-1; 633 else 634 SCARG(&lsa, ruid) = SCARG(uap, ruid); 635 if ((linux32_uid_t)SCARG(uap, euid) == (linux32_uid_t)-1) 636 SCARG(&lsa, euid) = (uid_t)-1; 637 else 638 SCARG(&lsa, euid) = SCARG(uap, euid); 639 if ((linux32_uid_t)SCARG(uap, suid) == (linux32_uid_t)-1) 640 SCARG(&lsa, suid) = (uid_t)-1; 641 else 642 SCARG(&lsa, suid) = SCARG(uap, euid); 643 644 return linux32_sys_setresuid(l, &lsa, retval); 645 } 646 647 int 648 linux32_sys_setresgid16(struct lwp *l, void *v, register_t *retval) 649 { 650 struct linux32_sys_setresgid16_args /* { 651 syscallarg(gid_t) rgid; 652 syscallarg(gid_t) egid; 653 syscallarg(gid_t) sgid; 654 } */ *uap = v; 655 struct linux32_sys_setresgid_args lsa; 656 657 if ((linux32_gid_t)SCARG(uap, rgid) == (linux32_gid_t)-1) 658 SCARG(&lsa, rgid) = (gid_t)-1; 659 else 660 SCARG(&lsa, rgid) = SCARG(uap, rgid); 661 if ((linux32_gid_t)SCARG(uap, egid) == (linux32_gid_t)-1) 662 SCARG(&lsa, egid) = (gid_t)-1; 663 else 664 SCARG(&lsa, egid) = SCARG(uap, egid); 665 if ((linux32_gid_t)SCARG(uap, sgid) == (linux32_gid_t)-1) 666 SCARG(&lsa, sgid) = (gid_t)-1; 667 else 668 SCARG(&lsa, sgid) = SCARG(uap, sgid); 669 670 return linux32_sys_setresgid(l, &lsa, retval); 671 } 672