xref: /netbsd-src/sys/compat/linux32/common/linux32_unistd.c (revision 7fa608457b817eca6e0977b37f758ae064f3c99c)
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