1 /**	$MirOS: src/sys/compat/linux/linux_misc.c,v 1.5 2008/11/08 23:04:11 tg Exp $ */
2 /*	$OpenBSD: linux_misc.c,v 1.58 2005/02/17 18:07:36 jfb Exp $	*/
3 /*	$NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $	*/
4 
5 /*-
6  * Copyright (c) 2004
7  *	Thorsten "mirabilos" Glaser <tg@mirbsd.org>
8  * Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc.
9  * All rights reserved.
10  *
11  * This code is derived from software contributed to The NetBSD Foundation
12  * by Frank van der Linden and Eric Haszlakiewicz; by Jason R. Thorpe
13  * of the Numerical Aerospace Simulation Facility, NASA Ames Research Center.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  * 3. All advertising materials mentioning features or use of this software
24  *    must display the following acknowledgement:
25  *	This product includes software developed by the NetBSD
26  *	Foundation, Inc. and its contributors.
27  * 4. Neither the name of The NetBSD Foundation nor the names of its
28  *    contributors may be used to endorse or promote products derived
29  *    from this software without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
32  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
33  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
34  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
35  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
39  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGE.
42  */
43 
44 /*
45  * Linux compatibility module. Try to deal with various Linux system calls.
46  */
47 
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/namei.h>
51 #include <sys/proc.h>
52 #include <sys/dirent.h>
53 #include <sys/file.h>
54 #include <sys/stat.h>
55 #include <sys/filedesc.h>
56 #include <sys/ioctl.h>
57 #include <sys/kernel.h>
58 #include <sys/malloc.h>
59 #include <sys/mbuf.h>
60 #include <sys/mman.h>
61 #include <sys/mount.h>
62 #include <sys/ptrace.h>
63 #include <sys/resource.h>
64 #include <sys/resourcevar.h>
65 #include <sys/signal.h>
66 #include <sys/signalvar.h>
67 #include <sys/socket.h>
68 #include <sys/time.h>
69 #include <sys/times.h>
70 #include <sys/vnode.h>
71 #include <sys/uio.h>
72 #include <sys/wait.h>
73 #include <sys/utsname.h>
74 #include <sys/unistd.h>
75 
76 #include <sys/syscallargs.h>
77 
78 #include <uvm/uvm_extern.h>
79 
80 #include <compat/linux/linux_types.h>
81 #include <compat/linux/linux_fcntl.h>
82 #include <compat/linux/linux_misc.h>
83 #include <compat/linux/linux_mmap.h>
84 #include <compat/linux/linux_sched.h>
85 #include <compat/linux/linux_signal.h>
86 #include <compat/linux/linux_syscallargs.h>
87 #include <compat/linux/linux_util.h>
88 #include <compat/linux/linux_dirent.h>
89 #include <compat/linux/linux_emuldata.h>
90 #include <compat/linux/linux_ptrace.h>
91 
92 #include <compat/common/compat_dir.h>
93 
94 const int linux_ptrace_request_map[] = {
95 	LINUX_PTRACE_TRACEME,	PT_TRACE_ME,
96 	LINUX_PTRACE_PEEKTEXT,	PT_READ_I,
97 	LINUX_PTRACE_PEEKDATA,	PT_READ_D,
98 	LINUX_PTRACE_POKETEXT,	PT_WRITE_I,
99 	LINUX_PTRACE_POKEDATA,	PT_WRITE_D,
100 	LINUX_PTRACE_CONT,	PT_CONTINUE,
101 	LINUX_PTRACE_KILL,	PT_KILL,
102 	LINUX_PTRACE_ATTACH,	PT_ATTACH,
103 	LINUX_PTRACE_DETACH,	PT_DETACH,
104 #ifdef PT_STEP
105 	LINUX_PTRACE_SINGLESTEP,	PT_STEP,
106 #endif
107 	-1
108 };
109 
110 struct compat_time_sys_wait4_args {
111 	syscallarg(pid_t) pid;
112 	syscallarg(int *) status;
113 	syscallarg(int) options;
114 	syscallarg(struct rusage_compat *) rusage;
115 };
116 
117 extern char emul_uname[];
118 extern int compat_time_sys_wait4(struct proc *, void *, register_t *);
119 
120 /* linux_misc.c */
121 static void bsd_to_linux_statfs(struct statfs *, struct linux_statfs *);
122 int	linux_select1(struct proc *, register_t *, int, fd_set *,
123      fd_set *, fd_set *, struct timeval_compat *);
124 static int getdents_common(struct proc *, void *, register_t *, int);
125 static void linux_to_bsd_mmap_args(struct sys_mmap_args *,
126     const struct linux_sys_mmap2_args *);
127 
128 /*
129  * The information on a terminated (or stopped) process needs
130  * to be converted in order for Linux binaries to get a valid signal
131  * number out of it.
132  */
133 void
bsd_to_linux_wstat(status)134 bsd_to_linux_wstat(status)
135 	int *status;
136 {
137 
138 	if (WIFSIGNALED(*status))
139 		*status = (*status & ~0177) |
140 		    bsd_to_linux_sig[WTERMSIG(*status)];
141 	else if (WIFSTOPPED(*status))
142 		*status = (*status & ~0xff00) |
143 		    (bsd_to_linux_sig[WSTOPSIG(*status)] << 8);
144 }
145 
146 /*
147  * waitpid(2). Passed on to the OpenBSD call, surrounded by code to
148  * reserve some space for a OpenBSD-style wait status, and converting
149  * it to what Linux wants.
150  */
151 int
linux_sys_waitpid(p,v,retval)152 linux_sys_waitpid(p, v, retval)
153 	struct proc *p;
154 	void *v;
155 	register_t *retval;
156 {
157 	struct linux_sys_waitpid_args /* {
158 		syscallarg(int) pid;
159 		syscallarg(int *) status;
160 		syscallarg(int) options;
161 	} */ *uap = v;
162 	struct sys_wait4_args w4a;
163 	int error, *status, tstat;
164 	caddr_t sg;
165 
166 	if (SCARG(uap, status) != NULL) {
167 		sg = stackgap_init(p->p_emul);
168 		status = (int *) stackgap_alloc(&sg, sizeof status);
169 	} else
170 		status = NULL;
171 
172 	SCARG(&w4a, pid) = SCARG(uap, pid);
173 	SCARG(&w4a, status) = status;
174 	SCARG(&w4a, options) = SCARG(uap, options);
175 	SCARG(&w4a, rusage) = NULL;
176 
177 	if ((error = sys_wait4(p, &w4a, retval)))
178 		return error;
179 
180 	p->p_siglist &= ~sigmask(SIGCHLD);
181 
182 	if (status != NULL) {
183 		if ((error = copyin(status, &tstat, sizeof tstat)))
184 			return error;
185 
186 		bsd_to_linux_wstat(&tstat);
187 		return copyout(&tstat, SCARG(uap, status), sizeof tstat);
188 	}
189 
190 	return 0;
191 }
192 
193 /*
194  * This is very much the same as waitpid()
195  */
196 int
linux_sys_wait4(p,v,retval)197 linux_sys_wait4(p, v, retval)
198 	struct proc *p;
199 	void *v;
200 	register_t *retval;
201 {
202 	struct linux_sys_wait4_args /* {
203 		syscallarg(int) pid;
204 		syscallarg(int *) status;
205 		syscallarg(int) options;
206 		syscallarg(struct rusage_compat *) rusage;
207 	} */ *uap = v;
208 	struct compat_time_sys_wait4_args w4a;
209 	int error, *status, tstat, linux_options, options;
210 	caddr_t sg;
211 
212 	if (SCARG(uap, status) != NULL) {
213 		sg = stackgap_init(p->p_emul);
214 		status = (int *) stackgap_alloc(&sg, sizeof status);
215 	} else
216 		status = NULL;
217 
218 	linux_options = SCARG(uap, options);
219 	options = 0;
220 	if (linux_options &
221 	    ~(LINUX_WAIT4_WNOHANG|LINUX_WAIT4_WUNTRACED|LINUX_WAIT4_WCLONE))
222 		return (EINVAL);
223 
224 	if (linux_options & LINUX_WAIT4_WNOHANG)
225 		options |= WNOHANG;
226 	if (linux_options & LINUX_WAIT4_WUNTRACED)
227 		options |= WUNTRACED;
228 	if (linux_options & LINUX_WAIT4_WCLONE)
229 		options |= WALTSIG;
230 
231 	SCARG(&w4a, pid) = SCARG(uap, pid);
232 	SCARG(&w4a, status) = status;
233 	SCARG(&w4a, options) = options;
234 	SCARG(&w4a, rusage) = SCARG(uap, rusage);
235 
236 	if ((error = compat_time_sys_wait4(p, &w4a, retval)))
237 		return error;
238 
239 	p->p_siglist &= ~sigmask(SIGCHLD);
240 
241 	if (status != NULL) {
242 		if ((error = copyin(status, &tstat, sizeof tstat)))
243 			return error;
244 
245 		bsd_to_linux_wstat(&tstat);
246 		return copyout(&tstat, SCARG(uap, status), sizeof tstat);
247 	}
248 
249 	return 0;
250 }
251 
252 int
linux_sys_setresgid16(p,v,retval)253 linux_sys_setresgid16(p, v, retval)
254 	struct proc *p;
255 	void *v;
256 	register_t *retval;
257 {
258 	struct linux_sys_setresgid16_args /* {
259 		syscallarg(u_int16_t) rgid;
260 		syscallarg(u_int16_t) egid;
261 		syscallarg(u_int16_t) sgid;
262 	} */ *uap = v;
263 	struct sys_setresgid_args nuap;
264 	u_int16_t rgid, egid, sgid;
265 
266 	rgid = SCARG(uap, rgid);
267 	SCARG(&nuap, rgid) = (rgid == (u_int16_t)-1) ? (gid_t)-1 : rgid;
268 	egid = SCARG(uap, egid);
269 	SCARG(&nuap, egid) = (egid == (u_int16_t)-1) ? (gid_t)-1 : egid;
270 	sgid = SCARG(uap, sgid);
271 	SCARG(&nuap, sgid) = (sgid == (u_int16_t)-1) ? (gid_t)-1 : sgid;
272 
273 	return sys_setresgid(p, &nuap, retval);
274 }
275 
276 int
linux_sys_getresgid16(p,v,retval)277 linux_sys_getresgid16(p, v, retval)
278 	struct proc *p;
279 	void *v;
280 	register_t *retval;
281 {
282 	struct linux_sys_getresgid16_args /* {
283 		syscallarg(u_int16_t *) rgid;
284 		syscallarg(u_int16_t *) egid;
285 		syscallarg(u_int16_t *) sgid;
286 	} */ *uap = v;
287 	struct sys_getresgid_args nuap;
288 
289 	SCARG(&nuap, rgid) = (gid_t *)SCARG(uap, rgid);
290 	SCARG(&nuap, egid) = (gid_t *)SCARG(uap, egid);
291 	SCARG(&nuap, sgid) = (gid_t *)SCARG(uap, sgid);
292 
293 	return sys_getresgid(p, &nuap, retval);
294 }
295 
296 int
linux_sys_setresuid16(p,v,retval)297 linux_sys_setresuid16(p, v, retval)
298 	struct proc *p;
299 	void *v;
300 	register_t *retval;
301 {
302 	struct linux_sys_setresuid16_args /* {
303 		syscallarg(u_int16_t) ruid;
304 		syscallarg(u_int16_t) euid;
305 		syscallarg(u_int16_t) suid;
306 	} */ *uap = v;
307 	struct sys_setresuid_args nuap;
308 	u_int16_t ruid, euid, suid;
309 
310 	ruid = SCARG(uap, ruid);
311 	SCARG(&nuap, ruid) = (ruid == (u_int16_t)-1) ? (uid_t)-1 : ruid;
312 	euid = SCARG(uap, euid);
313 	SCARG(&nuap, euid) = (euid == (u_int16_t)-1) ? (uid_t)-1 : euid;
314 	suid = SCARG(uap, suid);
315 	SCARG(&nuap, suid) = (suid == (u_int16_t)-1) ? (uid_t)-1 : suid;
316 
317 	return sys_setresuid(p, &nuap, retval);
318 }
319 
320 int
linux_sys_getresuid16(p,v,retval)321 linux_sys_getresuid16(p, v, retval)
322 	struct proc *p;
323 	void *v;
324 	register_t *retval;
325 {
326 	struct linux_sys_getresuid16_args /* {
327 		syscallarg(u_int16_t *) ruid;
328 		syscallarg(u_int16_t *) euid;
329 		syscallarg(u_int16_t *) suid;
330 	} */ *uap = v;
331 	struct sys_getresuid_args nuap;
332 
333 	SCARG(&nuap, ruid) = (uid_t *)SCARG(uap, ruid);
334 	SCARG(&nuap, euid) = (uid_t *)SCARG(uap, euid);
335 	SCARG(&nuap, suid) = (uid_t *)SCARG(uap, suid);
336 
337 	return sys_getresuid(p, &nuap, retval);
338 }
339 
340 /*
341  * This is the old brk(2) call. I don't think anything in the Linux
342  * world uses this anymore
343  */
344 int
linux_sys_break(p,v,retval)345 linux_sys_break(p, v, retval)
346 	struct proc *p;
347 	void *v;
348 	register_t *retval;
349 {
350 #if 0
351 	struct linux_sys_brk_args /* {
352 		syscallarg(char *) nsize;
353 	} */ *uap = v;
354 #endif
355 
356 	return ENOSYS;
357 }
358 
359 /*
360  * Linux brk(2). The check if the new address is >= the old one is
361  * done in the kernel in Linux. OpenBSD does it in the library.
362  */
363 int
linux_sys_brk(p,v,retval)364 linux_sys_brk(p, v, retval)
365 	struct proc *p;
366 	void *v;
367 	register_t *retval;
368 {
369 	struct linux_sys_brk_args /* {
370 		syscallarg(char *) nsize;
371 	} */ *uap = v;
372 	char *nbrk = SCARG(uap, nsize);
373 	struct sys_obreak_args oba;
374 	struct vmspace *vm = p->p_vmspace;
375 	struct linux_emuldata *ed = (struct linux_emuldata*)p->p_emuldata;
376 
377 	SCARG(&oba, nsize) = nbrk;
378 
379 	if ((caddr_t) nbrk > vm->vm_daddr && sys_obreak(p, &oba, retval) == 0)
380 		ed->p_break = (char*)nbrk;
381 	else
382 		nbrk = ed->p_break;
383 
384 	retval[0] = (register_t)nbrk;
385 
386 	return 0;
387 }
388 
389 /*
390  * I wonder why Linux has gettimeofday() _and_ time().. Still, we
391  * need to deal with it.
392  */
393 int
linux_sys_time(p,v,retval)394 linux_sys_time(p, v, retval)
395 	struct proc *p;
396 	void *v;
397 	register_t *retval;
398 {
399 	struct linux_sys_time_args /* {
400 		linux_time_t *t;
401 	} */ *uap = v;
402 	struct timeval atv;
403 	linux_time_t tt;
404 	int error;
405 
406 	microtime(&atv);
407 
408 	tt = atv.tv_sec;
409 	if (SCARG(uap, t) && (error = copyout(&tt, SCARG(uap, t), sizeof tt)))
410 		return error;
411 
412 	retval[0] = tt;
413 	return 0;
414 }
415 
416 /*
417  * Convert BSD statfs structure to Linux statfs structure.
418  * The Linux structure has less fields, and it also wants
419  * the length of a name in a dir entry in a field, which
420  * we fake (probably the wrong way).
421  */
422 static void
bsd_to_linux_statfs(bsp,lsp)423 bsd_to_linux_statfs(bsp, lsp)
424 	struct statfs *bsp;
425 	struct linux_statfs *lsp;
426 {
427 
428 	/*
429 	 * Convert BSD filesystem names to Linux filesystem type numbers
430 	 * where possible.  Linux statfs uses a value of -1 to indicate
431 	 * an unsupported field.
432 	 */
433 	if (!strcmp(bsp->f_fstypename, MOUNT_FFS) ||
434 	    !strcmp(bsp->f_fstypename, MOUNT_MFS))
435 		lsp->l_ftype = 0x11954;
436 	else if (!strcmp(bsp->f_fstypename, MOUNT_NFS))
437 		lsp->l_ftype = 0x6969;
438 	else if (!strcmp(bsp->f_fstypename, MOUNT_MSDOS))
439 		lsp->l_ftype = 0x4d44;
440 	else if (!strcmp(bsp->f_fstypename, MOUNT_PROCFS))
441 		lsp->l_ftype = 0x9fa0;
442 	else if (!strcmp(bsp->f_fstypename, MOUNT_EXT2FS))
443 		lsp->l_ftype = 0xef53;
444 	else if (!strcmp(bsp->f_fstypename, MOUNT_CD9660))
445 		lsp->l_ftype = 0x9660;
446 	else if (!strcmp(bsp->f_fstypename, MOUNT_NCPFS))
447 		lsp->l_ftype = 0x6969;
448 	else
449 		lsp->l_ftype = -1;
450 
451 	lsp->l_fbsize = bsp->f_bsize;
452 	lsp->l_fblocks = bsp->f_blocks;
453 	lsp->l_fbfree = bsp->f_bfree;
454 	lsp->l_fbavail = bsp->f_bavail;
455 	lsp->l_ffiles = bsp->f_files;
456 	lsp->l_fffree = bsp->f_ffree;
457 	lsp->l_ffsid.val[0] = bsp->f_fsid.val[0];
458 	lsp->l_ffsid.val[1] = bsp->f_fsid.val[1];
459 	lsp->l_fnamelen = MAXNAMLEN;	/* XXX */
460 }
461 
462 /*
463  * Implement the fs stat functions. Straightforward.
464  */
465 int
linux_sys_statfs(p,v,retval)466 linux_sys_statfs(p, v, retval)
467 	struct proc *p;
468 	void *v;
469 	register_t *retval;
470 {
471 	struct linux_sys_statfs_args /* {
472 		syscallarg(char *) path;
473 		syscallarg(struct linux_statfs *) sp;
474 	} */ *uap = v;
475 	struct statfs btmp, *bsp;
476 	struct linux_statfs ltmp;
477 	struct sys_statfs_args bsa;
478 	caddr_t sg;
479 	int error;
480 
481 	sg = stackgap_init(p->p_emul);
482 	bsp = (struct statfs *) stackgap_alloc(&sg, sizeof (struct statfs));
483 
484 	LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
485 
486 	SCARG(&bsa, path) = SCARG(uap, path);
487 	SCARG(&bsa, buf) = bsp;
488 
489 	if ((error = sys_statfs(p, &bsa, retval)))
490 		return error;
491 
492 	if ((error = copyin((caddr_t) bsp, (caddr_t) &btmp, sizeof btmp)))
493 		return error;
494 
495 	bsd_to_linux_statfs(&btmp, &ltmp);
496 
497 	return copyout((caddr_t) &ltmp, (caddr_t) SCARG(uap, sp), sizeof ltmp);
498 }
499 
500 int
linux_sys_fstatfs(p,v,retval)501 linux_sys_fstatfs(p, v, retval)
502 	struct proc *p;
503 	void *v;
504 	register_t *retval;
505 {
506 	struct linux_sys_fstatfs_args /* {
507 		syscallarg(int) fd;
508 		syscallarg(struct linux_statfs *) sp;
509 	} */ *uap = v;
510 	struct statfs btmp, *bsp;
511 	struct linux_statfs ltmp;
512 	struct sys_fstatfs_args bsa;
513 	caddr_t sg;
514 	int error;
515 
516 	sg = stackgap_init(p->p_emul);
517 	bsp = (struct statfs *) stackgap_alloc(&sg, sizeof (struct statfs));
518 
519 	SCARG(&bsa, fd) = SCARG(uap, fd);
520 	SCARG(&bsa, buf) = bsp;
521 
522 	if ((error = sys_fstatfs(p, &bsa, retval)))
523 		return error;
524 
525 	if ((error = copyin((caddr_t) bsp, (caddr_t) &btmp, sizeof btmp)))
526 		return error;
527 
528 	bsd_to_linux_statfs(&btmp, &ltmp);
529 
530 	return copyout((caddr_t) &ltmp, (caddr_t) SCARG(uap, sp), sizeof ltmp);
531 }
532 
533 /*
534  * uname(). Just copy the info from the various strings stored in the
535  * kernel, and put it in the Linux utsname structure. That structure
536  * is almost the same as the OpenBSD one, only it has fields 65 characters
537  * long, and an extra domainname field.
538  */
539 int
linux_sys_uname(p,v,retval)540 linux_sys_uname(p, v, retval)
541 	struct proc *p;
542 	void *v;
543 	register_t *retval;
544 {
545 	struct linux_sys_uname_args /* {
546 		syscallarg(struct linux_utsname *) up;
547 	} */ *uap = v;
548 	extern char hostname[], machine[];
549 	struct linux_utsname luts;
550 	int len;
551 	char *cp;
552 
553 	strlcpy(luts.l_sysname, emul_uname, sizeof(luts.l_sysname));
554 	strlcpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
555 	strlcpy(luts.l_release, osrelease, sizeof(luts.l_release));
556 	strlcpy(luts.l_version, version, sizeof(luts.l_version));
557 	strlcpy(luts.l_machine, machine, sizeof(luts.l_machine));
558 	luts.l_domainname[0] = '\0';
559 
560 	/* This part taken from the uname() in libc */
561 	len = sizeof(luts.l_version);
562 	for (cp = luts.l_version; len--; ++cp)
563 		if (*cp == '\n' || *cp == '\t')
564 			*cp = (len > 1) ? ' ' : '\0';
565 
566 	return copyout(&luts, SCARG(uap, up), sizeof(luts));
567 }
568 
569 int
linux_sys_olduname(p,v,retval)570 linux_sys_olduname(p, v, retval)
571 	struct proc *p;
572 	void *v;
573 	register_t *retval;
574 {
575 	struct linux_sys_uname_args /* {
576 		syscallarg(struct linux_oldutsname *) up;
577 	} */ *uap = v;
578 	extern char hostname[], machine[];
579 	struct linux_oldutsname luts;
580 	int len;
581 	char *cp;
582 
583 	strlcpy(luts.l_sysname, emul_uname, sizeof(luts.l_sysname));
584 	strlcpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
585 	strlcpy(luts.l_release, osrelease, sizeof(luts.l_release));
586 	strlcpy(luts.l_version, version, sizeof(luts.l_version));
587 	strlcpy(luts.l_machine, machine, sizeof(luts.l_machine));
588 
589 	/* This part taken from the uname() in libc */
590 	len = sizeof(luts.l_version);
591 	for (cp = luts.l_version; len--; ++cp)
592 		if (*cp == '\n' || *cp == '\t')
593 			*cp = (len > 1) ? ' ' : '\0';
594 
595 	return copyout(&luts, SCARG(uap, up), sizeof(luts));
596 }
597 
598 int
linux_sys_oldolduname(p,v,retval)599 linux_sys_oldolduname(p, v, retval)
600 	struct proc *p;
601 	void *v;
602 	register_t *retval;
603 {
604 	struct linux_sys_uname_args /* {
605 		syscallarg(struct linux_oldoldutsname *) up;
606 	} */ *uap = v;
607 	extern char hostname[], machine[];
608 	struct linux_oldoldutsname luts;
609 	int len;
610 	char *cp;
611 
612 	strlcpy(luts.l_sysname, emul_uname, sizeof(luts.l_sysname));
613 	strlcpy(luts.l_nodename, hostname, sizeof(luts.l_nodename));
614 	strlcpy(luts.l_release, osrelease, sizeof(luts.l_release));
615 	strlcpy(luts.l_version, version, sizeof(luts.l_version));
616 	strlcpy(luts.l_machine, machine, sizeof(luts.l_machine));
617 
618 	/* This part taken from the uname() in libc */
619 	len = sizeof(luts.l_version);
620 	for (cp = luts.l_version; len--; ++cp)
621 		if (*cp == '\n' || *cp == '\t')
622 			*cp = (len > 1) ? ' ' : '\0';
623 
624 	return copyout(&luts, SCARG(uap, up), sizeof(luts));
625 }
626 
627 /*
628  * Linux wants to pass everything to a syscall in registers. However,
629  * mmap() has 6 of them. Oops: out of register error. They just pass
630  * everything in a structure.
631  */
632 int
linux_sys_mmap(p,v,retval)633 linux_sys_mmap(p, v, retval)
634 	struct proc *p;
635 	void *v;
636 	register_t *retval;
637 {
638 	struct linux_sys_mmap_args /* {
639 		syscallarg(struct linux_mmap *) lmp;
640 	} */ *uap = v;
641 	struct linux_mmap lmap;
642 	struct linux_sys_mmap2_args nlmap;
643 	struct sys_mmap_args cma;
644 	int error;
645 
646 	if ((error = copyin(SCARG(uap, lmp), &lmap, sizeof lmap)))
647 		return error;
648 
649 	if (lmap.lm_pos & PAGE_MASK)
650 		return EINVAL;
651 
652 	/* repackage into something sane */
653 	SCARG(&nlmap,addr) = (unsigned long)lmap.lm_addr;
654 	SCARG(&nlmap,len) = lmap.lm_len;
655 	SCARG(&nlmap,prot) = lmap.lm_prot;
656 	SCARG(&nlmap,flags) = lmap.lm_flags;
657 	SCARG(&nlmap,fd) = lmap.lm_fd;
658 	SCARG(&nlmap,offset) = (unsigned)lmap.lm_pos;
659 
660 	linux_to_bsd_mmap_args(&cma, &nlmap);
661 	SCARG(&cma, pos) = (off_t)SCARG(&nlmap, offset);
662 
663 	return sys_mmap(p, &cma, retval);
664 }
665 
666 /*
667  * Guts of most architectures' mmap64() implementations.  This shares
668  * its list of arguments with linux_sys_mmap().
669  *
670  * The difference in linux_sys_mmap2() is that "offset" is actually
671  * (offset / pagesize), not an absolute byte count.  This translation
672  * to pagesize offsets is done inside glibc between the mmap64() call
673  * point, and the actual syscall.
674  */
675 int
linux_sys_mmap2(p,v,retval)676 linux_sys_mmap2(p, v, retval)
677 	struct proc *p;
678 	void *v;
679 	register_t *retval;
680 {
681 	struct linux_sys_mmap2_args /* {
682 		syscallarg(unsigned long) addr;
683 		syscallarg(size_t) len;
684 		syscallarg(int) prot;
685 		syscallarg(int) flags;
686 		syscallarg(int) fd;
687 		syscallarg(linux_off_t) offset;
688 	} */ *uap = v;
689 	struct sys_mmap_args cma;
690 
691 	linux_to_bsd_mmap_args(&cma, uap);
692 	SCARG(&cma, pos) = ((off_t)SCARG(uap, offset)) << PAGE_SHIFT;
693 
694 	return sys_mmap(p, &cma, retval);
695 }
696 
697 static void
linux_to_bsd_mmap_args(cma,uap)698 linux_to_bsd_mmap_args(cma, uap)
699 	struct sys_mmap_args *cma;
700 	const struct linux_sys_mmap2_args *uap;
701 {
702 	int flags = MAP_TRYFIXED, fl = SCARG(uap, flags);
703 
704 	flags |= cvtto_bsd_mask(fl, LINUX_MAP_SHARED, MAP_SHARED);
705 	flags |= cvtto_bsd_mask(fl, LINUX_MAP_PRIVATE, MAP_PRIVATE);
706 	flags |= cvtto_bsd_mask(fl, LINUX_MAP_FIXED, MAP_FIXED);
707 	flags |= cvtto_bsd_mask(fl, LINUX_MAP_ANON, MAP_ANON);
708 	/* XXX XAX ERH: Any other flags here?  There are more defined... */
709 
710 	SCARG(cma, addr) = (void *)SCARG(uap, addr);
711 	SCARG(cma, len) = SCARG(uap, len);
712 	SCARG(cma, prot) = SCARG(uap, prot);
713 	if (SCARG(cma, prot) & VM_PROT_WRITE) /* XXX */
714 		SCARG(cma, prot) |= VM_PROT_READ;
715 	SCARG(cma, flags) = flags;
716 	SCARG(cma, fd) = flags & MAP_ANON ? -1 : SCARG(uap, fd);
717 	SCARG(cma, pad) = 0;
718 }
719 
720 int
linux_sys_mremap(p,v,retval)721 linux_sys_mremap(p, v, retval)
722 	struct proc *p;
723 	void *v;
724 	register_t *retval;
725 {
726 
727 	struct linux_sys_mremap_args /* {
728 		syscallarg(void *) old_address;
729 		syscallarg(size_t) old_size;
730 		syscallarg(size_t) new_size;
731 		syscallarg(u_long) flags;
732 	} */ *uap = v;
733 	struct sys_munmap_args mua;
734 	size_t old_size, new_size;
735 	int error;
736 
737 	old_size = round_page(SCARG(uap, old_size));
738 	new_size = round_page(SCARG(uap, new_size));
739 
740 	/*
741 	 * Growing mapped region.
742 	 */
743 	if (new_size > old_size) {
744 		/*
745 		 * XXX Implement me.  What we probably want to do is
746 		 * XXX dig out the guts of the old mapping, mmap that
747 		 * XXX object again with the new size, then munmap
748 		 * XXX the old mapping.
749 		 */
750 		*retval = 0;
751 		return (ENOMEM);
752 	}
753 	/*
754 	 * Shrinking mapped region.
755 	 */
756 	if (new_size < old_size) {
757 		SCARG(&mua, addr) = (caddr_t)SCARG(uap, old_address) + new_size;
758 		SCARG(&mua, len) = old_size - new_size;
759 		error = sys_munmap(p, &mua, retval);
760 		*retval = error ? 0 : (register_t)SCARG(uap, old_address);
761 		return (error);
762 	}
763 
764 	/*
765 	 * No change.
766 	 */
767 	*retval = (register_t)SCARG(uap, old_address);
768 	return (0);
769 
770 }
771 
772 /*
773  * This code is partly stolen from src/lib/libc/gen/times.c
774  * XXX - CLK_TCK isn't declared in /sys, just in <time.h>, done here
775  */
776 
777 #define CLK_TCK 100
778 #define	CONVTCK(r)	(r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
779 
780 int
linux_sys_times(p,v,retval)781 linux_sys_times(p, v, retval)
782 	struct proc *p;
783 	void *v;
784 	register_t *retval;
785 {
786 	struct linux_sys_times_args /* {
787 		syscallarg(struct times *) tms;
788 	} */ *uap = v;
789 	struct timeval t;
790 	struct linux_tms ltms;
791 	struct rusage ru;
792 	int error, s;
793 
794 	calcru(p, &ru.ru_utime, &ru.ru_stime, NULL);
795 	ltms.ltms_utime = CONVTCK(ru.ru_utime);
796 	ltms.ltms_stime = CONVTCK(ru.ru_stime);
797 
798 	ltms.ltms_cutime = CONVTCK(p->p_stats->p_cru.ru_utime);
799 	ltms.ltms_cstime = CONVTCK(p->p_stats->p_cru.ru_stime);
800 
801 	if ((error = copyout(&ltms, SCARG(uap, tms), sizeof ltms)))
802 		return error;
803 
804 	s = splclock();
805 	timersub(&time, &boottime, &t);
806 	splx(s);
807 
808 	retval[0] = ((linux_clock_t)(CONVTCK(t)));
809 	return 0;
810 }
811 
812 /*
813  * OpenBSD passes fd[0] in retval[0], and fd[1] in retval[1].
814  * Linux directly passes the pointer.
815  */
816 int
linux_sys_pipe(p,v,retval)817 linux_sys_pipe(p, v, retval)
818 	struct proc *p;
819 	void *v;
820 	register_t *retval;
821 {
822 	struct linux_sys_pipe_args /* {
823 		syscallarg(int *) pfds;
824 	} */ *uap = v;
825 	int error;
826 	int pfds[2];
827 #ifdef __i386__
828 	int reg_edx = retval[1];
829 #endif /* __i386__ */
830 
831 	if ((error = sys_opipe(p, 0, retval))) {
832 #ifdef __i386__
833 		retval[1] = reg_edx;
834 #endif /* __i386__ */
835 		return error;
836 	}
837 
838 	/* Assumes register_t is an int */
839 
840 	pfds[0] = retval[0];
841 	pfds[1] = retval[1];
842 	if ((error = copyout(pfds, SCARG(uap, pfds), 2 * sizeof (int)))) {
843 #ifdef __i386__
844 		retval[1] = reg_edx;
845 #endif /* __i386__ */
846 		fdrelease(p, retval[0]);
847 		fdrelease(p, retval[1]);
848 		return error;
849 	}
850 
851 	retval[0] = 0;
852 #ifdef __i386__
853 	retval[1] = reg_edx;
854 #endif /* __i386__ */
855 	return 0;
856 }
857 
858 /*
859  * Alarm. This is a libc call which uses setitimer(2) in OpenBSD.
860  * Fiddle with the timers to make it work.
861  */
862 int
linux_sys_alarm(p,v,retval)863 linux_sys_alarm(p, v, retval)
864 	struct proc *p;
865 	void *v;
866 	register_t *retval;
867 {
868 	struct linux_sys_alarm_args /* {
869 		syscallarg(unsigned int) secs;
870 	} */ *uap = v;
871 	int s;
872 	struct itimerval *itp, it;
873 	int timo;
874 
875 	itp = &p->p_realtimer;
876 	s = splclock();
877 	/*
878 	 * Clear any pending timer alarms.
879 	 */
880 
881 	timeout_del(&p->p_realit_to);
882 	timerclear(&itp->it_interval);
883 	if (timerisset(&itp->it_value) &&
884 	    timercmp(&itp->it_value, &time, >))
885 		timersub(&itp->it_value, &time, &itp->it_value);
886 	/*
887 	 * Return how many seconds were left (rounded up)
888 	 */
889 	retval[0] = itp->it_value.tv_sec;
890 	if (itp->it_value.tv_usec)
891 		retval[0]++;
892 
893 	/*
894 	 * alarm(0) just resets the timer.
895 	 */
896 	if (SCARG(uap, secs) == 0) {
897 		timerclear(&itp->it_value);
898 		splx(s);
899 		return 0;
900 	}
901 
902 	/*
903 	 * Check the new alarm time for sanity, and set it.
904 	 */
905 	timerclear(&it.it_interval);
906 	it.it_value.tv_sec = SCARG(uap, secs);
907 	it.it_value.tv_usec = 0;
908 	if (itimerfix(&it.it_value) || itimerfix(&it.it_interval)) {
909 		splx(s);
910 		return (EINVAL);
911 	}
912 
913 	if (timerisset(&it.it_value)) {
914 		timo = tvtohz(&it.it_value);
915 		if (timo <= 0)
916 			timo = 1;
917 		timeradd(&it.it_value, &time, &it.it_value);
918 		timeout_add(&p->p_realit_to, timo);
919 	}
920 	p->p_realtimer = it;
921 	splx(s);
922 
923 	return 0;
924 }
925 
926 /*
927  * utime(). Do conversion to things that utimes() understands,
928  * and pass it on.
929  */
930 int
linux_sys_utime(p,v,retval)931 linux_sys_utime(p, v, retval)
932 	struct proc *p;
933 	void *v;
934 	register_t *retval;
935 {
936 	struct linux_sys_utime_args /* {
937 		syscallarg(char *) path;
938 		syscallarg(struct linux_utimbuf *)times;
939 	} */ *uap = v;
940 	caddr_t sg;
941 	int error;
942 	struct sys_utimes_args ua;
943 	struct timeval tv[2], *tvp;
944 	struct linux_utimbuf lut;
945 
946 	sg = stackgap_init(p->p_emul);
947 	tvp = (struct timeval *) stackgap_alloc(&sg, sizeof(tv));
948 	LINUX_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
949 
950 	SCARG(&ua, path) = SCARG(uap, path);
951 
952 	if (SCARG(uap, times) != NULL) {
953 		if ((error = copyin(SCARG(uap, times), &lut, sizeof lut)))
954 			return error;
955 		tv[0].tv_usec = tv[1].tv_usec = 0;
956 		tv[0].tv_sec = lut.l_actime;
957 		tv[1].tv_sec = lut.l_modtime;
958 		if ((error = copyout(tv, tvp, sizeof tv)))
959 			return error;
960 		SCARG(&ua, tptr) = tvp;
961 	}
962 	else
963 		SCARG(&ua, tptr) = NULL;
964 
965 	return sys_utimes(p, &ua, retval);
966 }
967 
968 /*
969  * The old Linux readdir was only able to read one entry at a time,
970  * even though it had a 'count' argument. In fact, the emulation
971  * of the old call was better than the original, because it did handle
972  * the count arg properly. Don't bother with it anymore now, and use
973  * it to distinguish between old and new. The difference is that the
974  * newer one actually does multiple entries, and the reclen field
975  * really is the reclen, not the namelength.
976  */
977 int
linux_sys_readdir(p,v,retval)978 linux_sys_readdir(p, v, retval)
979 	struct proc *p;
980 	void *v;
981 	register_t *retval;
982 {
983 	struct linux_sys_readdir_args /* {
984 		syscallarg(int) fd;
985 		syscallarg(struct linux_dirent *) dent;
986 		syscallarg(unsigned int) count;
987 	} */ *uap = v;
988 
989 	SCARG(uap, count) = 1;
990 
991 	return linux_sys_getdents(p, uap, retval);
992 }
993 
994 /*
995  * Linux 'readdir' call. This code is mostly taken from the
996  * SunOS getdents call (see compat/sunos/sunos_misc.c), though
997  * an attempt has been made to keep it a little cleaner (failing
998  * miserably, because of the cruft needed if count 1 is passed).
999  *
1000  * The d_off field should contain the offset of the next valid entry,
1001  * but in Linux it has the offset of the entry itself. We emulate
1002  * that bug here.
1003  *
1004  * Read in BSD-style entries, convert them, and copy them out.
1005  *
1006  * Note that this doesn't handle union-mounted filesystems.
1007  */
1008 int linux_readdir_callback(void *, struct dirent *, off_t);
1009 
1010 struct linux_readdir_callback_args {
1011 	caddr_t outp;
1012 	int     resid;
1013 	int     oldcall;
1014 	int	is64bit;
1015 };
1016 
1017 int
linux_readdir_callback(arg,bdp,cookie)1018 linux_readdir_callback(arg, bdp, cookie)
1019 	void *arg;
1020 	struct dirent *bdp;
1021 	off_t cookie;
1022 {
1023 	struct linux_dirent64 idb64;
1024 	struct linux_dirent idb;
1025 	struct linux_readdir_callback_args *cb = arg;
1026 	int linux_reclen;
1027 	int error;
1028 
1029 	if (cb->oldcall == 2)
1030 		return (ENOMEM);
1031 
1032 	linux_reclen = (cb->is64bit) ?
1033 	     LINUX_RECLEN(&idb64, bdp->d_namlen) :
1034 	     LINUX_RECLEN(&idb, bdp->d_namlen);
1035 
1036 	if (cb->resid < linux_reclen)
1037 		return (ENOMEM);
1038 
1039 	if (cb->is64bit) {
1040 		idb64.d_ino = (linux_ino64_t)bdp->d_fileno;
1041 		idb64.d_off = (linux_off64_t)cookie;
1042 		idb64.d_reclen = (u_short)linux_reclen;
1043 		idb64.d_type = bdp->d_type;
1044 		strlcpy(idb64.d_name, bdp->d_name, sizeof(idb64.d_name));
1045 		error = copyout((caddr_t)&idb64, cb->outp, linux_reclen);
1046 	} else {
1047 		idb.d_ino = (linux_ino_t)bdp->d_fileno;
1048 		if (cb->oldcall) {
1049 			/*
1050 			 * The old readdir() call misuses the offset
1051 			 * and reclen fields.
1052 			 */
1053 			idb.d_off = (linux_off_t)linux_reclen;
1054 			idb.d_reclen = (u_short)bdp->d_namlen;
1055 		} else {
1056 			idb.d_off = (linux_off_t)cookie;
1057 			idb.d_reclen = (u_short)linux_reclen;
1058 		}
1059 		strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
1060 		error = copyout((caddr_t)&idb, cb->outp, linux_reclen);
1061 	}
1062 	if (error)
1063 		return (error);
1064 
1065 	/* advance output past Linux-shaped entry */
1066 	cb->outp += linux_reclen;
1067 	cb->resid -= linux_reclen;
1068 
1069 	if (cb->oldcall == 1)
1070 		++cb->oldcall;
1071 
1072 	return (0);
1073 }
1074 
1075 int
linux_sys_getdents64(p,v,retval)1076 linux_sys_getdents64(p, v, retval)
1077 	struct proc *p;
1078 	void *v;
1079 	register_t *retval;
1080 {
1081 	return getdents_common(p, v, retval, 1);
1082 }
1083 
1084 int
linux_sys_getdents(p,v,retval)1085 linux_sys_getdents(p, v, retval)
1086 	struct proc *p;
1087 	void *v;
1088 	register_t *retval;
1089 {
1090 	return getdents_common(p, v, retval, 0);
1091 }
1092 
1093 static int
getdents_common(p,v,retval,is64bit)1094 getdents_common(p, v, retval, is64bit)
1095 	struct proc *p;
1096 	void *v;
1097 	register_t *retval;
1098 	int is64bit;
1099 {
1100 	struct linux_sys_getdents_args /* {
1101 		syscallarg(int) fd;
1102 		syscallarg(void *) dirent;
1103 		syscallarg(unsigned) count;
1104 	} */ *uap = v;
1105 	struct linux_readdir_callback_args args;
1106 	struct file *fp;
1107 	int error;
1108 	int nbytes = SCARG(uap, count);
1109 
1110 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
1111 		return (error);
1112 
1113 	if (nbytes == 1) {	/* emulating old, broken behaviour */
1114 		/* readdir(2) case. Always struct dirent. */
1115 		if (is64bit) {
1116 			FRELE(fp);
1117 			return (EINVAL);
1118 		}
1119 		nbytes = sizeof(struct linux_dirent);
1120 		args.oldcall = 1;
1121 	} else {
1122 		args.oldcall = 0;
1123 	}
1124 
1125 	args.resid = nbytes;
1126 	args.outp = (caddr_t)SCARG(uap, dirent);
1127 	args.is64bit = is64bit;
1128 
1129 	if ((error = readdir_with_callback(fp, &fp->f_offset, nbytes,
1130 	    linux_readdir_callback, &args)) != 0)
1131 		goto exit;
1132 
1133 	*retval = nbytes - args.resid;
1134 
1135  exit:
1136 	FRELE(fp);
1137 	return (error);
1138 }
1139 
1140 /*
1141  * Not sure why the arguments to this older version of select() were put
1142  * into a structure, because there are 5, and that can all be handled
1143  * in registers on the i386 like Linux wants to.
1144  */
1145 int
linux_sys_oldselect(p,v,retval)1146 linux_sys_oldselect(p, v, retval)
1147 	struct proc *p;
1148 	void *v;
1149 	register_t *retval;
1150 {
1151 	struct linux_sys_oldselect_args /* {
1152 		syscallarg(struct linux_select *) lsp;
1153 	} */ *uap = v;
1154 	struct linux_select ls;
1155 	int error;
1156 
1157 	if ((error = copyin(SCARG(uap, lsp), &ls, sizeof(ls))))
1158 		return error;
1159 
1160 	return linux_select1(p, retval, ls.nfds, ls.readfds, ls.writefds,
1161 	    ls.exceptfds, ls.timeout);
1162 }
1163 
1164 /*
1165  * Even when just using registers to pass arguments to syscalls you can
1166  * have 5 of them on the i386. So this newer version of select() does
1167  * this.
1168  */
1169 int
linux_sys_select(p,v,retval)1170 linux_sys_select(p, v, retval)
1171 	struct proc *p;
1172 	void *v;
1173 	register_t *retval;
1174 {
1175 	struct linux_sys_select_args /* {
1176 		syscallarg(int) nfds;
1177 		syscallarg(fd_set *) readfds;
1178 		syscallarg(fd_set *) writefds;
1179 		syscallarg(fd_set *) exceptfds;
1180 		syscallarg(struct timeval_compat *) timeout;
1181 	} */ *uap = v;
1182 
1183 	return linux_select1(p, retval, SCARG(uap, nfds), SCARG(uap, readfds),
1184 	    SCARG(uap, writefds), SCARG(uap, exceptfds), SCARG(uap, timeout));
1185 }
1186 
1187 /*
1188  * Common code for the old and new versions of select(). A couple of
1189  * things are important:
1190  * 1) return the amount of time left in the 'timeout' parameter
1191  * 2) select never returns ERESTART on Linux, always return EINTR
1192  */
1193 int
linux_select1(p,retval,nfds,readfds,writefds,exceptfds,timeout)1194 linux_select1(p, retval, nfds, readfds, writefds, exceptfds, timeout)
1195 	struct proc *p;
1196 	register_t *retval;
1197 	int nfds;
1198 	fd_set *readfds, *writefds, *exceptfds;
1199 	struct timeval_compat *timeout;
1200 {
1201 	struct sys_select_args bsa;
1202 	struct timeval tv0, tv1, utv64, *tvp;
1203 	struct timeval_compat utv;
1204 	caddr_t sg;
1205 	int error;
1206 
1207 	sg = stackgap_init(p->p_emul);
1208 	tvp = stackgap_alloc(&sg, sizeof(utv64));
1209 
1210 	SCARG(&bsa, nd) = nfds;
1211 	SCARG(&bsa, in) = readfds;
1212 	SCARG(&bsa, ou) = writefds;
1213 	SCARG(&bsa, ex) = exceptfds;
1214 	SCARG(&bsa, tv) = NULL;
1215 
1216 	/*
1217 	 * Store current time for computation of the amount of
1218 	 * time left.
1219 	 */
1220 	if (timeout) {
1221 		if ((error = copyin(timeout, &utv, sizeof(utv))))
1222 			return error;
1223 		utv64.tv_sec = utv.tv_sec;
1224 		utv64.tv_usec = utv.tv_usec;
1225 		if (itimerfix(&utv64)) {
1226 			/*
1227 			 * The timeval was invalid.  Convert it to something
1228 			 * valid that will act as it does under Linux.
1229 			 */
1230 			utv64.tv_sec += utv64.tv_usec / 1000000;
1231 			utv64.tv_usec %= 1000000;
1232 			if (utv64.tv_usec < 0) {
1233 				utv64.tv_sec -= 1;
1234 				utv64.tv_usec += 1000000;
1235 			}
1236 			if (utv64.tv_sec < 0)
1237 				timerclear(&utv64);
1238 		}
1239 		if ((error = copyout(&utv64, tvp, sizeof(utv64))))
1240 			return error;
1241 		SCARG(&bsa, tv) = tvp;
1242 		microtime(&tv0);
1243 	}
1244 
1245 	error = sys_select(p, &bsa, retval);
1246 	if (error) {
1247 		/*
1248 		 * See fs/select.c in the Linux kernel.  Without this,
1249 		 * Maelstrom doesn't work.
1250 		 */
1251 		if (error == ERESTART)
1252 			error = EINTR;
1253 		return error;
1254 	}
1255 
1256 	if (timeout) {
1257 		if (*retval) {
1258 			/*
1259 			 * Compute how much time was left of the timeout,
1260 			 * by subtracting the current time and the time
1261 			 * before we started the call, and subtracting
1262 			 * that result from the user-supplied value.
1263 			 */
1264 			microtime(&tv1);
1265 			timersub(&tv1, &tv0, &tv1);
1266 			timersub(&utv64, &tv1, &utv64);
1267 			if (utv64.tv_sec < 0)
1268 				timerclear(&utv64);
1269 		} else
1270 			timerclear(&utv64);
1271 		utv.tv_sec = utv64.tv_sec;
1272 		utv.tv_usec = utv64.tv_usec;
1273 		if ((error = copyout(&utv, timeout, sizeof(utv))))
1274 			return error;
1275 	}
1276 
1277 	return 0;
1278 }
1279 
1280 /*
1281  * Get the process group of a certain process. Look it up
1282  * and return the value.
1283  */
1284 int
linux_sys_getpgid(p,v,retval)1285 linux_sys_getpgid(p, v, retval)
1286 	struct proc *p;
1287 	void *v;
1288 	register_t *retval;
1289 {
1290 	struct linux_sys_getpgid_args /* {
1291 		syscallarg(int) pid;
1292 	} */ *uap = v;
1293 	struct proc *targp;
1294 
1295 	if (SCARG(uap, pid) != 0 && SCARG(uap, pid) != p->p_pid) {
1296 		if ((targp = pfind(SCARG(uap, pid))) == 0)
1297 			return ESRCH;
1298 	}
1299 	else
1300 		targp = p;
1301 
1302 	retval[0] = targp->p_pgid;
1303 	return 0;
1304 }
1305 
1306 /*
1307  * Set the 'personality' (emulation mode) for the current process. Only
1308  * accept the Linux personality here (0). This call is needed because
1309  * the Linux ELF crt0 issues it in an ugly kludge to make sure that
1310  * ELF binaries run in Linux mode, not SVR4 mode.
1311  */
1312 int
linux_sys_personality(p,v,retval)1313 linux_sys_personality(p, v, retval)
1314 	struct proc *p;
1315 	void *v;
1316 	register_t *retval;
1317 {
1318 	struct linux_sys_personality_args /* {
1319 		syscallarg(int) per;
1320 	} */ *uap = v;
1321 
1322 	if (SCARG(uap, per) != 0)
1323 		return EINVAL;
1324 	retval[0] = 0;
1325 	return 0;
1326 }
1327 
1328 /*
1329  * The calls are here because of type conversions.
1330  */
1331 int
linux_sys_setreuid16(p,v,retval)1332 linux_sys_setreuid16(p, v, retval)
1333 	struct proc *p;
1334 	void *v;
1335 	register_t *retval;
1336 {
1337 	struct linux_sys_setreuid16_args /* {
1338 		syscallarg(int) ruid;
1339 		syscallarg(int) euid;
1340 	} */ *uap = v;
1341 	struct sys_setreuid_args bsa;
1342 
1343 	SCARG(&bsa, ruid) = ((linux_uid_t)SCARG(uap, ruid) == (linux_uid_t)-1) ?
1344 		(uid_t)-1 : SCARG(uap, ruid);
1345 	SCARG(&bsa, euid) = ((linux_uid_t)SCARG(uap, euid) == (linux_uid_t)-1) ?
1346 		(uid_t)-1 : SCARG(uap, euid);
1347 
1348 	return sys_setreuid(p, &bsa, retval);
1349 }
1350 
1351 int
linux_sys_setregid16(p,v,retval)1352 linux_sys_setregid16(p, v, retval)
1353 	struct proc *p;
1354 	void *v;
1355 	register_t *retval;
1356 {
1357 	struct linux_sys_setregid16_args /* {
1358 		syscallarg(int) rgid;
1359 		syscallarg(int) egid;
1360 	} */ *uap = v;
1361 	struct sys_setregid_args bsa;
1362 
1363 	SCARG(&bsa, rgid) = ((linux_gid_t)SCARG(uap, rgid) == (linux_gid_t)-1) ?
1364 		(uid_t)-1 : SCARG(uap, rgid);
1365 	SCARG(&bsa, egid) = ((linux_gid_t)SCARG(uap, egid) == (linux_gid_t)-1) ?
1366 		(uid_t)-1 : SCARG(uap, egid);
1367 
1368 	return sys_setregid(p, &bsa, retval);
1369 }
1370 
1371 int
linux_sys_getsid(p,v,retval)1372 linux_sys_getsid(p, v, retval)
1373 	struct proc *p;
1374 	void *v;
1375 	register_t *retval;
1376 {
1377 	struct linux_sys_getsid_args /* {
1378 		syscallarg(int) pid;
1379 	} */ *uap = v;
1380 	struct proc *p1;
1381 	pid_t pid;
1382 
1383 	pid = (pid_t)SCARG(uap, pid);
1384 
1385 	if (pid == 0) {
1386 		retval[0] = (int)p->p_session;	/* XXX Oh well */
1387 		return 0;
1388 	}
1389 
1390 	p1 = pfind((int)pid);
1391 	if (p1 == NULL)
1392 		return ESRCH;
1393 
1394 	retval[0] = (int)p1->p_session;
1395 	return 0;
1396 }
1397 
1398 int
linux_sys___sysctl(p,v,retval)1399 linux_sys___sysctl(p, v, retval)
1400 	struct proc *p;
1401 	void *v;
1402 	register_t *retval;
1403 {
1404 	struct linux_sys___sysctl_args /* {
1405 		syscallarg(struct linux___sysctl *) lsp;
1406 	} */ *uap = v;
1407 	struct linux___sysctl ls;
1408 	struct sys___sysctl_args bsa;
1409 	int error;
1410 
1411 	if ((error = copyin(SCARG(uap, lsp), &ls, sizeof ls)))
1412 		return error;
1413 	SCARG(&bsa, name) = ls.name;
1414 	SCARG(&bsa, namelen) = ls.namelen;
1415 	SCARG(&bsa, old) = ls.old;
1416 	SCARG(&bsa, oldlenp) = ls.oldlenp;
1417 	SCARG(&bsa, new) = ls.new;
1418 	SCARG(&bsa, newlen) = ls.newlen;
1419 
1420 	return sys___sysctl(p, &bsa, retval);
1421 }
1422 
1423 /*
1424  * We have nonexistent fsuid equal to uid.
1425  * If modification is requested, refuse.
1426  */
1427 int
linux_sys_setfsuid(p,v,retval)1428 linux_sys_setfsuid(p, v, retval)
1429 	 struct proc *p;
1430 	 void *v;
1431 	 register_t *retval;
1432 {
1433 	 struct linux_sys_setfsuid_args /* {
1434 		 syscallarg(uid_t) uid;
1435 	 } */ *uap = v;
1436 	 uid_t uid;
1437 
1438 	 uid = SCARG(uap, uid);
1439 	 if (p->p_cred->p_ruid != uid)
1440 		 return sys_nosys(p, v, retval);
1441 	 else
1442 		 return (0);
1443 }
1444 
1445 int
linux_sys_getfsuid(p,v,retval)1446 linux_sys_getfsuid(p, v, retval)
1447 	struct proc *p;
1448 	void *v;
1449 	register_t *retval;
1450 {
1451 	return sys_getuid(p, v, retval);
1452 }
1453 
1454 
1455 int
linux_sys_nice(p,v,retval)1456 linux_sys_nice(p, v, retval)
1457 	struct proc *p;
1458 	void *v;
1459 	register_t *retval;
1460 {
1461 	struct linux_sys_nice_args /* {
1462 		syscallarg(int) incr;
1463 	} */ *uap = v;
1464 	struct sys_setpriority_args bsa;
1465 
1466 	SCARG(&bsa, which) = PRIO_PROCESS;
1467 	SCARG(&bsa, who) = 0;
1468 	SCARG(&bsa, prio) = SCARG(uap, incr);
1469 	return sys_setpriority(p, &bsa, retval);
1470 }
1471 
1472 int
linux_sys_stime(p,v,retval)1473 linux_sys_stime(p, v, retval)
1474 	struct proc *p;
1475 	void *v;
1476 	register_t *retval;
1477 {
1478 	struct linux_sys_time_args /* {
1479 		linux_time_t *t;
1480 	} */ *uap = v;
1481 	struct timeval atv;
1482 	linux_time_t tt;
1483 	int error;
1484 
1485 	if ((error = suser(p, 0)) != 0)
1486 		return (error);
1487 
1488 	if ((error = copyin(SCARG(uap, t), &tt, sizeof(tt))) != 0)
1489 		return (error);
1490 
1491 	atv.tv_sec = tt;
1492 	atv.tv_usec = 0;
1493 
1494 	error = settime(&atv);
1495 
1496 	return (error);
1497 }
1498 
1499 int
linux_sys_getpid(p,v,retval)1500 linux_sys_getpid(p, v, retval)
1501 	struct proc *p;
1502 	void *v;
1503 	register_t *retval;
1504 {
1505 
1506 	*retval = p->p_pid;
1507 	return (0);
1508 }
1509 
1510 int
linux_sys_getuid(p,v,retval)1511 linux_sys_getuid(p, v, retval)
1512 	struct proc *p;
1513 	void *v;
1514 	register_t *retval;
1515 {
1516 
1517 	*retval = p->p_cred->p_ruid;
1518 	return (0);
1519 }
1520 
1521 int
linux_sys_getgid(p,v,retval)1522 linux_sys_getgid(p, v, retval)
1523 	struct proc *p;
1524 	void *v;
1525 	register_t *retval;
1526 {
1527 
1528 	*retval = p->p_cred->p_rgid;
1529 	return (0);
1530 }
1531 
1532 
1533 /*
1534  * sysinfo()
1535  */
1536 /* ARGSUSED */
1537 int
linux_sys_sysinfo(p,v,retval)1538 linux_sys_sysinfo(p, v, retval)
1539 	struct proc *p;
1540 	void *v;
1541 	register_t *retval;
1542 {
1543 	struct linux_sys_sysinfo_args /* {
1544 		syscallarg(struct linux_sysinfo *) sysinfo;
1545 	} */ *uap = v;
1546 	struct linux_sysinfo si;
1547 	struct loadavg *la;
1548 	extern int bufpages;
1549 
1550 
1551 	si.uptime = time.tv_sec - boottime.tv_sec;
1552 	la = &averunnable;
1553 	si.loads[0] = la->ldavg[0] * LINUX_SYSINFO_LOADS_SCALE / la->fscale;
1554 	si.loads[1] = la->ldavg[1] * LINUX_SYSINFO_LOADS_SCALE / la->fscale;
1555 	si.loads[2] = la->ldavg[2] * LINUX_SYSINFO_LOADS_SCALE / la->fscale;
1556 	si.totalram = ctob(physmem);
1557 	si.freeram = uvmexp.free * uvmexp.pagesize;
1558 	si.sharedram = 0;/* XXX */
1559 	si.bufferram = bufpages * PAGE_SIZE;
1560 	si.totalswap = uvmexp.swpages * PAGE_SIZE;
1561 	si.freeswap = (uvmexp.swpages - uvmexp.swpginuse) * PAGE_SIZE;
1562 	si.procs = nprocs;
1563 	/* The following are only present in newer Linux kernels. */
1564 	si.totalbig = 0;
1565 	si.freebig = 0;
1566 	si.mem_unit = 1;
1567 
1568 	return (copyout(&si, SCARG(uap, sysinfo), sizeof(si)));
1569 }
1570 
1571 int
linux_sys_ptrace(l,v,retval)1572 linux_sys_ptrace(l, v, retval)
1573 	struct proc *l;
1574 	void *v;
1575 	register_t *retval;
1576 {
1577 	struct linux_sys_ptrace_args /* {
1578 		i386, m68k, powerpc: T=int
1579 		alpha, amd64: T=long
1580 		syscallarg(T) request;
1581 		syscallarg(T) pid;
1582 		syscallarg(T) addr;
1583 		syscallarg(T) data;
1584 	} */ *uap = v;
1585 	const int *ptr;
1586 	int request;
1587 	int error;
1588 
1589 	ptr = linux_ptrace_request_map;
1590 	request = SCARG(uap, request);
1591 	while (*ptr != -1)
1592 		if (*ptr++ == request) {
1593 			struct sys_ptrace_args pta;
1594 
1595 			SCARG(&pta, req) = *ptr;
1596 			SCARG(&pta, pid) = SCARG(uap, pid);
1597 			SCARG(&pta, addr) = (caddr_t)SCARG(uap, addr);
1598 			SCARG(&pta, data) = SCARG(uap, data);
1599 
1600 			/*
1601 			 * Linux ptrace(PTRACE_CONT, pid, 0, 0) means actually
1602 			 * to continue where the process left off previously.
1603 			 * The same thing is achieved by addr == (caddr_t) 1
1604 			 * on NetBSD, so rewrite 'addr' appropriately.
1605 			 */
1606 			if (request == LINUX_PTRACE_CONT && SCARG(uap, addr)==0)
1607 				SCARG(&pta, addr) = (caddr_t) 1;
1608 
1609 			error = sys_ptrace(l, &pta, retval);
1610 			if (error)
1611 				return error;
1612 			switch (request) {
1613 			case LINUX_PTRACE_PEEKTEXT:
1614 			case LINUX_PTRACE_PEEKDATA:
1615 				error = copyout (retval,
1616 				    (caddr_t)SCARG(uap, data),
1617 				    sizeof *retval);
1618 				*retval = SCARG(uap, data);
1619 				break;
1620 			default:
1621 				break;
1622 			}
1623 			return error;
1624 		}
1625 		else
1626 			ptr++;
1627 
1628 	return LINUX_SYS_PTRACE_ARCH(l, uap, retval);
1629 }
1630