freebsd32_misc.c revision 151720
1100384Speter/*-
2100384Speter * Copyright (c) 2002 Doug Rabson
3100384Speter * All rights reserved.
4100384Speter *
5100384Speter * Redistribution and use in source and binary forms, with or without
6100384Speter * modification, are permitted provided that the following conditions
7100384Speter * are met:
8100384Speter * 1. Redistributions of source code must retain the above copyright
9100384Speter *    notice, this list of conditions and the following disclaimer.
10100384Speter * 2. Redistributions in binary form must reproduce the above copyright
11100384Speter *    notice, this list of conditions and the following disclaimer in the
12100384Speter *    documentation and/or other materials provided with the distribution.
13100384Speter *
14100384Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15100384Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16100384Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17100384Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18100384Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19100384Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20100384Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21100384Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22100384Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23100384Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24100384Speter * SUCH DAMAGE.
25100384Speter */
26100384Speter
27118031Sobrien#include <sys/cdefs.h>
28118031Sobrien__FBSDID("$FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 151720 2005-10-26 22:19:51Z peter $");
29118031Sobrien
30104738Speter#include "opt_compat.h"
31104738Speter
32100384Speter#include <sys/param.h>
33100384Speter#include <sys/systm.h>
34100384Speter#include <sys/bus.h>
35100384Speter#include <sys/exec.h>
36100384Speter#include <sys/fcntl.h>
37100384Speter#include <sys/filedesc.h>
38123746Speter#include <sys/namei.h>
39100384Speter#include <sys/imgact.h>
40100384Speter#include <sys/kernel.h>
41100384Speter#include <sys/lock.h>
42100384Speter#include <sys/malloc.h>
43100384Speter#include <sys/file.h>		/* Must come after sys/malloc.h */
44100384Speter#include <sys/mman.h>
45100384Speter#include <sys/module.h>
46100384Speter#include <sys/mount.h>
47100384Speter#include <sys/mutex.h>
48100384Speter#include <sys/namei.h>
49100384Speter#include <sys/param.h>
50100384Speter#include <sys/proc.h>
51100384Speter#include <sys/reboot.h>
52100384Speter#include <sys/resource.h>
53100384Speter#include <sys/resourcevar.h>
54100384Speter#include <sys/selinfo.h>
55146950Sps#include <sys/eventvar.h>	/* Must come after sys/selinfo.h */
56100384Speter#include <sys/pipe.h>		/* Must come after sys/selinfo.h */
57100384Speter#include <sys/signal.h>
58100384Speter#include <sys/signalvar.h>
59100384Speter#include <sys/socket.h>
60100384Speter#include <sys/socketvar.h>
61100384Speter#include <sys/stat.h>
62150883Sjhb#include <sys/syscall.h>
63113859Sjhb#include <sys/syscallsubr.h>
64100384Speter#include <sys/sysctl.h>
65100384Speter#include <sys/sysent.h>
66100384Speter#include <sys/sysproto.h>
67100384Speter#include <sys/systm.h>
68100384Speter#include <sys/unistd.h>
69100384Speter#include <sys/vnode.h>
70127140Sjhb#include <sys/wait.h>
71100384Speter
72100384Speter#include <vm/vm.h>
73100384Speter#include <vm/vm_kern.h>
74100384Speter#include <vm/vm_param.h>
75100384Speter#include <vm/pmap.h>
76100384Speter#include <vm/vm_map.h>
77100384Speter#include <vm/vm_object.h>
78100384Speter#include <vm/vm_extern.h>
79100384Speter
80151582Sps#include <machine/cpu.h>
81151582Sps
82119333Speter#include <compat/freebsd32/freebsd32_util.h>
83119333Speter#include <compat/freebsd32/freebsd32.h>
84119333Speter#include <compat/freebsd32/freebsd32_proto.h>
85100384Speter
86121719SpeterCTASSERT(sizeof(struct timeval32) == 8);
87121719SpeterCTASSERT(sizeof(struct timespec32) == 8);
88121719SpeterCTASSERT(sizeof(struct statfs32) == 256);
89121719SpeterCTASSERT(sizeof(struct rusage32) == 72);
90121719Speter
91100384Speterint
92119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
93100384Speter{
94127140Sjhb	int error, status;
95127140Sjhb	struct rusage32 ru32;
96136152Sjhb	struct rusage ru, *rup;
97100384Speter
98136152Sjhb	if (uap->rusage != NULL)
99136152Sjhb		rup = &ru;
100136152Sjhb	else
101136152Sjhb		rup = NULL;
102136152Sjhb	error = kern_wait(td, uap->pid, &status, uap->options, rup);
103100384Speter	if (error)
104100384Speter		return (error);
105127140Sjhb	if (uap->status != NULL)
106127140Sjhb		error = copyout(&status, uap->status, sizeof(status));
107127140Sjhb	if (uap->rusage != NULL && error == 0) {
108100384Speter		TV_CP(ru, ru32, ru_utime);
109100384Speter		TV_CP(ru, ru32, ru_stime);
110100384Speter		CP(ru, ru32, ru_maxrss);
111100384Speter		CP(ru, ru32, ru_ixrss);
112100384Speter		CP(ru, ru32, ru_idrss);
113100384Speter		CP(ru, ru32, ru_isrss);
114100384Speter		CP(ru, ru32, ru_minflt);
115100384Speter		CP(ru, ru32, ru_majflt);
116100384Speter		CP(ru, ru32, ru_nswap);
117100384Speter		CP(ru, ru32, ru_inblock);
118100384Speter		CP(ru, ru32, ru_oublock);
119100384Speter		CP(ru, ru32, ru_msgsnd);
120100384Speter		CP(ru, ru32, ru_msgrcv);
121100384Speter		CP(ru, ru32, ru_nsignals);
122100384Speter		CP(ru, ru32, ru_nvcsw);
123100384Speter		CP(ru, ru32, ru_nivcsw);
124127140Sjhb		error = copyout(&ru32, uap->rusage, sizeof(ru32));
125100384Speter	}
126100384Speter	return (error);
127100384Speter}
128100384Speter
129128597Smarcel#ifdef COMPAT_FREEBSD4
130100384Speterstatic void
131100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out)
132100384Speter{
133100384Speter	CP(*in, *out, f_bsize);
134100384Speter	CP(*in, *out, f_iosize);
135100384Speter	CP(*in, *out, f_blocks);
136100384Speter	CP(*in, *out, f_bfree);
137100384Speter	CP(*in, *out, f_bavail);
138100384Speter	CP(*in, *out, f_files);
139100384Speter	CP(*in, *out, f_ffree);
140100384Speter	CP(*in, *out, f_fsid);
141100384Speter	CP(*in, *out, f_owner);
142100384Speter	CP(*in, *out, f_type);
143100384Speter	CP(*in, *out, f_flags);
144100384Speter	CP(*in, *out, f_flags);
145100384Speter	CP(*in, *out, f_syncwrites);
146100384Speter	CP(*in, *out, f_asyncwrites);
147100384Speter	bcopy(in->f_fstypename,
148100384Speter	      out->f_fstypename, MFSNAMELEN);
149100384Speter	bcopy(in->f_mntonname,
150128260Speter	      out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
151100384Speter	CP(*in, *out, f_syncreads);
152100384Speter	CP(*in, *out, f_asyncreads);
153100384Speter	bcopy(in->f_mntfromname,
154128260Speter	      out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
155100384Speter}
156128597Smarcel#endif
157100384Speter
158128597Smarcel#ifdef COMPAT_FREEBSD4
159100384Speterint
160128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
161100384Speter{
162147178Spjd	struct statfs *buf, *sp;
163147178Spjd	struct statfs32 stat32;
164147178Spjd	size_t count, size;
165100384Speter	int error;
166100384Speter
167147178Spjd	count = uap->bufsize / sizeof(struct statfs32);
168147178Spjd	size = count * sizeof(struct statfs);
169147302Spjd	error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
170147302Spjd	if (size > 0) {
171100384Speter		count = td->td_retval[0];
172147178Spjd		sp = buf;
173147178Spjd		while (count > 0 && error == 0) {
174147178Spjd			copy_statfs(sp, &stat32);
175147178Spjd			error = copyout(&stat32, uap->buf, sizeof(stat32));
176147178Spjd			sp++;
177147178Spjd			uap->buf++;
178147178Spjd			count--;
179100384Speter		}
180147178Spjd		free(buf, M_TEMP);
181100384Speter	}
182100384Speter	return (error);
183100384Speter}
184128597Smarcel#endif
185100384Speter
186100384Speterstruct sigaltstack32 {
187100384Speter	u_int32_t	ss_sp;
188100384Speter	u_int32_t	ss_size;
189100384Speter	int		ss_flags;
190100384Speter};
191100384Speter
192121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12);
193121719Speter
194100384Speterint
195119333Speterfreebsd32_sigaltstack(struct thread *td,
196119333Speter		      struct freebsd32_sigaltstack_args *uap)
197100384Speter{
198113859Sjhb	struct sigaltstack32 s32;
199113859Sjhb	struct sigaltstack ss, oss, *ssp;
200100384Speter	int error;
201100384Speter
202113859Sjhb	if (uap->ss != NULL) {
203113859Sjhb		error = copyin(uap->ss, &s32, sizeof(s32));
204100384Speter		if (error)
205100384Speter			return (error);
206113859Sjhb		PTRIN_CP(s32, ss, ss_sp);
207113859Sjhb		CP(s32, ss, ss_size);
208113859Sjhb		CP(s32, ss, ss_flags);
209113859Sjhb		ssp = &ss;
210113859Sjhb	} else
211113859Sjhb		ssp = NULL;
212113859Sjhb	error = kern_sigaltstack(td, ssp, &oss);
213113859Sjhb	if (error == 0 && uap->oss != NULL) {
214113859Sjhb		PTROUT_CP(oss, s32, ss_sp);
215113859Sjhb		CP(oss, s32, ss_size);
216113859Sjhb		CP(oss, s32, ss_flags);
217113859Sjhb		error = copyout(&s32, uap->oss, sizeof(s32));
218100384Speter	}
219100384Speter	return (error);
220100384Speter}
221100384Speter
222142059Sjhb/*
223142059Sjhb * Custom version of exec_copyin_args() so that we can translate
224142059Sjhb * the pointers.
225142059Sjhb */
226142059Sjhbstatic int
227142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname,
228142059Sjhb    enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
229100384Speter{
230142059Sjhb	char *argp, *envp;
231142059Sjhb	u_int32_t *p32, arg;
232142059Sjhb	size_t length;
233100384Speter	int error;
234100384Speter
235142059Sjhb	bzero(args, sizeof(*args));
236142059Sjhb	if (argv == NULL)
237142059Sjhb		return (EFAULT);
238100384Speter
239142059Sjhb	/*
240142059Sjhb	 * Allocate temporary demand zeroed space for argument and
241142059Sjhb	 *	environment strings
242142059Sjhb	 */
243147588Sjhb	args->buf = (char *) kmem_alloc_wait(exec_map,
244147588Sjhb	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
245142059Sjhb	if (args->buf == NULL)
246142059Sjhb		return (ENOMEM);
247142059Sjhb	args->begin_argv = args->buf;
248142059Sjhb	args->endp = args->begin_argv;
249142059Sjhb	args->stringspace = ARG_MAX;
250142059Sjhb
251142059Sjhb	args->fname = args->buf + ARG_MAX;
252142059Sjhb
253142059Sjhb	/*
254142059Sjhb	 * Copy the file name.
255142059Sjhb	 */
256142059Sjhb	error = (segflg == UIO_SYSSPACE) ?
257142059Sjhb	    copystr(fname, args->fname, PATH_MAX, &length) :
258142059Sjhb	    copyinstr(fname, args->fname, PATH_MAX, &length);
259142059Sjhb	if (error != 0)
260142059Sjhb		return (error);
261142059Sjhb
262142059Sjhb	/*
263142059Sjhb	 * extract arguments first
264142059Sjhb	 */
265142059Sjhb	p32 = argv;
266142059Sjhb	for (;;) {
267142059Sjhb		error = copyin(p32++, &arg, sizeof(arg));
268142059Sjhb		if (error)
269142059Sjhb			return (error);
270142059Sjhb		if (arg == 0)
271142059Sjhb			break;
272142059Sjhb		argp = PTRIN(arg);
273142059Sjhb		error = copyinstr(argp, args->endp, args->stringspace, &length);
274142059Sjhb		if (error) {
275142059Sjhb			if (error == ENAMETOOLONG)
276142059Sjhb				return (E2BIG);
277142059Sjhb			else
278142059Sjhb				return (error);
279142059Sjhb		}
280142059Sjhb		args->stringspace -= length;
281142059Sjhb		args->endp += length;
282142059Sjhb		args->argc++;
283100384Speter	}
284142059Sjhb
285142059Sjhb	args->begin_envv = args->endp;
286142059Sjhb
287142059Sjhb	/*
288142059Sjhb	 * extract environment strings
289142059Sjhb	 */
290142059Sjhb	if (envv) {
291142059Sjhb		p32 = envv;
292142059Sjhb		for (;;) {
293100384Speter			error = copyin(p32++, &arg, sizeof(arg));
294100384Speter			if (error)
295142059Sjhb				return (error);
296142059Sjhb			if (arg == 0)
297142059Sjhb				break;
298142059Sjhb			envp = PTRIN(arg);
299142059Sjhb			error = copyinstr(envp, args->endp, args->stringspace,
300142059Sjhb			    &length);
301142059Sjhb			if (error) {
302142059Sjhb				if (error == ENAMETOOLONG)
303142059Sjhb					return (E2BIG);
304142059Sjhb				else
305142059Sjhb					return (error);
306142059Sjhb			}
307142059Sjhb			args->stringspace -= length;
308142059Sjhb			args->endp += length;
309142059Sjhb			args->envc++;
310142059Sjhb		}
311100384Speter	}
312100384Speter
313142059Sjhb	return (0);
314100384Speter}
315100384Speter
316142059Sjhbint
317142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
318142059Sjhb{
319142059Sjhb	struct image_args eargs;
320142059Sjhb	int error;
321142059Sjhb
322142059Sjhb	error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
323142059Sjhb	    uap->argv, uap->envv);
324142059Sjhb	if (error == 0)
325142059Sjhb		error = kern_execve(td, &eargs, NULL);
326142059Sjhb	exec_free_args(&eargs);
327142059Sjhb	return (error);
328142059Sjhb}
329142059Sjhb
330114987Speter#ifdef __ia64__
331100384Speterstatic int
332119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
333119333Speter		       int prot, int fd, off_t pos)
334100384Speter{
335100384Speter	vm_map_t map;
336100384Speter	vm_map_entry_t entry;
337100384Speter	int rv;
338100384Speter
339100384Speter	map = &td->td_proc->p_vmspace->vm_map;
340100384Speter	if (fd != -1)
341100384Speter		prot |= VM_PROT_WRITE;
342100384Speter
343100384Speter	if (vm_map_lookup_entry(map, start, &entry)) {
344100384Speter		if ((entry->protection & prot) != prot) {
345100384Speter			rv = vm_map_protect(map,
346100384Speter					    trunc_page(start),
347100384Speter					    round_page(end),
348100384Speter					    entry->protection | prot,
349100384Speter					    FALSE);
350100384Speter			if (rv != KERN_SUCCESS)
351100384Speter				return (EINVAL);
352100384Speter		}
353100384Speter	} else {
354100384Speter		vm_offset_t addr = trunc_page(start);
355100384Speter		rv = vm_map_find(map, 0, 0,
356100384Speter				 &addr, PAGE_SIZE, FALSE, prot,
357100384Speter				 VM_PROT_ALL, 0);
358100384Speter		if (rv != KERN_SUCCESS)
359100384Speter			return (EINVAL);
360100384Speter	}
361100384Speter
362100384Speter	if (fd != -1) {
363100384Speter		struct pread_args r;
364107849Salfred		r.fd = fd;
365107849Salfred		r.buf = (void *) start;
366107849Salfred		r.nbyte = end - start;
367107849Salfred		r.offset = pos;
368100384Speter		return (pread(td, &r));
369100384Speter	} else {
370100384Speter		while (start < end) {
371100384Speter			subyte((void *) start, 0);
372100384Speter			start++;
373100384Speter		}
374100384Speter		return (0);
375100384Speter	}
376100384Speter}
377114987Speter#endif
378100384Speter
379100384Speterint
380119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
381100384Speter{
382100384Speter	struct mmap_args ap;
383107849Salfred	vm_offset_t addr = (vm_offset_t) uap->addr;
384107849Salfred	vm_size_t len	 = uap->len;
385107849Salfred	int prot	 = uap->prot;
386107849Salfred	int flags	 = uap->flags;
387107849Salfred	int fd		 = uap->fd;
388107849Salfred	off_t pos	 = (uap->poslo
389107849Salfred			    | ((off_t)uap->poshi << 32));
390114987Speter#ifdef __ia64__
391100384Speter	vm_size_t pageoff;
392100384Speter	int error;
393100384Speter
394100384Speter	/*
395100384Speter	 * Attempt to handle page size hassles.
396100384Speter	 */
397100384Speter	pageoff = (pos & PAGE_MASK);
398100384Speter	if (flags & MAP_FIXED) {
399100384Speter		vm_offset_t start, end;
400100384Speter		start = addr;
401100384Speter		end = addr + len;
402100384Speter
403147964Sjhb		mtx_lock(&Giant);
404100384Speter		if (start != trunc_page(start)) {
405119333Speter			error = freebsd32_mmap_partial(td, start,
406119333Speter						       round_page(start), prot,
407119333Speter						       fd, pos);
408100384Speter			if (fd != -1)
409100384Speter				pos += round_page(start) - start;
410100384Speter			start = round_page(start);
411100384Speter		}
412100384Speter		if (end != round_page(end)) {
413100384Speter			vm_offset_t t = trunc_page(end);
414119333Speter			error = freebsd32_mmap_partial(td, t, end,
415100384Speter						  prot, fd,
416100384Speter						  pos + t - start);
417100384Speter			end = trunc_page(end);
418100384Speter		}
419100384Speter		if (end > start && fd != -1 && (pos & PAGE_MASK)) {
420100384Speter			/*
421100384Speter			 * We can't map this region at all. The specified
422100384Speter			 * address doesn't have the same alignment as the file
423100384Speter			 * position. Fake the mapping by simply reading the
424100384Speter			 * entire region into memory. First we need to make
425100384Speter			 * sure the region exists.
426100384Speter			 */
427100384Speter			vm_map_t map;
428100384Speter			struct pread_args r;
429100384Speter			int rv;
430100384Speter
431100384Speter			prot |= VM_PROT_WRITE;
432100384Speter			map = &td->td_proc->p_vmspace->vm_map;
433100384Speter			rv = vm_map_remove(map, start, end);
434147964Sjhb			if (rv != KERN_SUCCESS) {
435147964Sjhb				mtx_unlock(&Giant);
436100384Speter				return (EINVAL);
437147964Sjhb			}
438100384Speter			rv = vm_map_find(map, 0, 0,
439100384Speter					 &start, end - start, FALSE,
440100384Speter					 prot, VM_PROT_ALL, 0);
441147964Sjhb			mtx_unlock(&Giant);
442100384Speter			if (rv != KERN_SUCCESS)
443100384Speter				return (EINVAL);
444107849Salfred			r.fd = fd;
445107849Salfred			r.buf = (void *) start;
446107849Salfred			r.nbyte = end - start;
447107849Salfred			r.offset = pos;
448100384Speter			error = pread(td, &r);
449100384Speter			if (error)
450100384Speter				return (error);
451100384Speter
452100384Speter			td->td_retval[0] = addr;
453100384Speter			return (0);
454100384Speter		}
455147964Sjhb		mtx_unlock(&Giant);
456100384Speter		if (end == start) {
457100384Speter			/*
458100384Speter			 * After dealing with the ragged ends, there
459100384Speter			 * might be none left.
460100384Speter			 */
461100384Speter			td->td_retval[0] = addr;
462100384Speter			return (0);
463100384Speter		}
464100384Speter		addr = start;
465100384Speter		len = end - start;
466100384Speter	}
467114987Speter#endif
468100384Speter
469107849Salfred	ap.addr = (void *) addr;
470107849Salfred	ap.len = len;
471107849Salfred	ap.prot = prot;
472107849Salfred	ap.flags = flags;
473107849Salfred	ap.fd = fd;
474107849Salfred	ap.pos = pos;
475100384Speter
476100384Speter	return (mmap(td, &ap));
477100384Speter}
478100384Speter
479100384Speterstruct itimerval32 {
480100384Speter	struct timeval32 it_interval;
481100384Speter	struct timeval32 it_value;
482100384Speter};
483100384Speter
484121719SpeterCTASSERT(sizeof(struct itimerval32) == 16);
485121719Speter
486100384Speterint
487119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
488100384Speter{
489142059Sjhb	struct itimerval itv, oitv, *itvp;
490142059Sjhb	struct itimerval32 i32;
491100384Speter	int error;
492100384Speter
493142059Sjhb	if (uap->itv != NULL) {
494142059Sjhb		error = copyin(uap->itv, &i32, sizeof(i32));
495100384Speter		if (error)
496100384Speter			return (error);
497142059Sjhb		TV_CP(i32, itv, it_interval);
498142059Sjhb		TV_CP(i32, itv, it_value);
499142059Sjhb		itvp = &itv;
500142059Sjhb	} else
501142059Sjhb		itvp = NULL;
502142059Sjhb	error = kern_setitimer(td, uap->which, itvp, &oitv);
503142059Sjhb	if (error || uap->oitv == NULL)
504100384Speter		return (error);
505142059Sjhb	TV_CP(oitv, i32, it_interval);
506142059Sjhb	TV_CP(oitv, i32, it_value);
507142059Sjhb	return (copyout(&i32, uap->oitv, sizeof(i32)));
508100384Speter}
509100384Speter
510100384Speterint
511125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
512125171Speter{
513142059Sjhb	struct itimerval itv;
514142059Sjhb	struct itimerval32 i32;
515125171Speter	int error;
516125171Speter
517142059Sjhb	error = kern_getitimer(td, uap->which, &itv);
518142059Sjhb	if (error || uap->itv == NULL)
519125171Speter		return (error);
520142059Sjhb	TV_CP(itv, i32, it_interval);
521142059Sjhb	TV_CP(itv, i32, it_value);
522142059Sjhb	return (copyout(&i32, uap->itv, sizeof(i32)));
523125171Speter}
524125171Speter
525125171Speterint
526119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
527100384Speter{
528142059Sjhb	struct timeval32 tv32;
529142059Sjhb	struct timeval tv, *tvp;
530100384Speter	int error;
531100384Speter
532142059Sjhb	if (uap->tv != NULL) {
533142059Sjhb		error = copyin(uap->tv, &tv32, sizeof(tv32));
534100384Speter		if (error)
535100384Speter			return (error);
536142059Sjhb		CP(tv32, tv, tv_sec);
537142059Sjhb		CP(tv32, tv, tv_usec);
538142059Sjhb		tvp = &tv;
539142059Sjhb	} else
540142059Sjhb		tvp = NULL;
541100384Speter	/*
542100384Speter	 * XXX big-endian needs to convert the fd_sets too.
543142059Sjhb	 * XXX Do pointers need PTRIN()?
544100384Speter	 */
545142059Sjhb	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp));
546100384Speter}
547100384Speter
548114987Speterstruct kevent32 {
549114987Speter	u_int32_t	ident;		/* identifier for this event */
550114987Speter	short		filter;		/* filter for event */
551114987Speter	u_short		flags;
552114987Speter	u_int		fflags;
553114987Speter	int32_t		data;
554114987Speter	u_int32_t	udata;		/* opaque user data identifier */
555114987Speter};
556114987Speter
557121719SpeterCTASSERT(sizeof(struct kevent32) == 20);
558146950Spsstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
559146950Spsstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
560121719Speter
561146950Sps/*
562146950Sps * Copy 'count' items into the destination list pointed to by uap->eventlist.
563146950Sps */
564146950Spsstatic int
565146950Spsfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
566146950Sps{
567146950Sps	struct freebsd32_kevent_args *uap;
568146950Sps	struct kevent32	ks32[KQ_NEVENTS];
569146950Sps	int i, error = 0;
570146950Sps
571146950Sps	KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
572146950Sps	uap = (struct freebsd32_kevent_args *)arg;
573146950Sps
574146950Sps	for (i = 0; i < count; i++) {
575146950Sps		CP(kevp[i], ks32[i], ident);
576146950Sps		CP(kevp[i], ks32[i], filter);
577146950Sps		CP(kevp[i], ks32[i], flags);
578146950Sps		CP(kevp[i], ks32[i], fflags);
579146950Sps		CP(kevp[i], ks32[i], data);
580146950Sps		PTROUT_CP(kevp[i], ks32[i], udata);
581146950Sps	}
582146950Sps	error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
583146950Sps	if (error == 0)
584146950Sps		uap->eventlist += count;
585146950Sps	return (error);
586146950Sps}
587146950Sps
588146950Sps/*
589146950Sps * Copy 'count' items from the list pointed to by uap->changelist.
590146950Sps */
591146950Spsstatic int
592146950Spsfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
593146950Sps{
594146950Sps	struct freebsd32_kevent_args *uap;
595146950Sps	struct kevent32	ks32[KQ_NEVENTS];
596146950Sps	int i, error = 0;
597146950Sps
598146950Sps	KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
599146950Sps	uap = (struct freebsd32_kevent_args *)arg;
600146950Sps
601146950Sps	error = copyin(uap->changelist, ks32, count * sizeof *ks32);
602146950Sps	if (error)
603146950Sps		goto done;
604146950Sps	uap->changelist += count;
605146950Sps
606146950Sps	for (i = 0; i < count; i++) {
607146950Sps		CP(ks32[i], kevp[i], ident);
608146950Sps		CP(ks32[i], kevp[i], filter);
609146950Sps		CP(ks32[i], kevp[i], flags);
610146950Sps		CP(ks32[i], kevp[i], fflags);
611146950Sps		CP(ks32[i], kevp[i], data);
612146950Sps		PTRIN_CP(ks32[i], kevp[i], udata);
613146950Sps	}
614146950Spsdone:
615146950Sps	return (error);
616146950Sps}
617146950Sps
618100384Speterint
619119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
620114987Speter{
621114987Speter	struct timespec32 ts32;
622142934Sps	struct timespec ts, *tsp;
623146950Sps	struct kevent_copyops k_ops = { uap,
624146950Sps					freebsd32_kevent_copyout,
625146950Sps					freebsd32_kevent_copyin};
626146950Sps	int error;
627114987Speter
628114987Speter
629114987Speter	if (uap->timeout) {
630114987Speter		error = copyin(uap->timeout, &ts32, sizeof(ts32));
631114987Speter		if (error)
632114987Speter			return (error);
633114987Speter		CP(ts32, ts, tv_sec);
634114987Speter		CP(ts32, ts, tv_nsec);
635142934Sps		tsp = &ts;
636142934Sps	} else
637142934Sps		tsp = NULL;
638146950Sps	error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
639146950Sps	    &k_ops, tsp);
640142934Sps	return (error);
641114987Speter}
642114987Speter
643114987Speterint
644119333Speterfreebsd32_gettimeofday(struct thread *td,
645119333Speter		       struct freebsd32_gettimeofday_args *uap)
646100384Speter{
647123425Speter	struct timeval atv;
648123425Speter	struct timeval32 atv32;
649123425Speter	struct timezone rtz;
650123425Speter	int error = 0;
651100384Speter
652123425Speter	if (uap->tp) {
653123425Speter		microtime(&atv);
654123425Speter		CP(atv, atv32, tv_sec);
655123425Speter		CP(atv, atv32, tv_usec);
656123425Speter		error = copyout(&atv32, uap->tp, sizeof (atv32));
657100384Speter	}
658123425Speter	if (error == 0 && uap->tzp != NULL) {
659123425Speter		rtz.tz_minuteswest = tz_minuteswest;
660123425Speter		rtz.tz_dsttime = tz_dsttime;
661123425Speter		error = copyout(&rtz, uap->tzp, sizeof (rtz));
662100384Speter	}
663100384Speter	return (error);
664100384Speter}
665100384Speter
666100384Speterint
667119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
668100384Speter{
669136152Sjhb	struct rusage32 s32;
670136152Sjhb	struct rusage s;
671100384Speter	int error;
672100384Speter
673136152Sjhb	error = kern_getrusage(td, uap->who, &s);
674100384Speter	if (error)
675100384Speter		return (error);
676136152Sjhb	if (uap->rusage != NULL) {
677100384Speter		TV_CP(s, s32, ru_utime);
678100384Speter		TV_CP(s, s32, ru_stime);
679100384Speter		CP(s, s32, ru_maxrss);
680100384Speter		CP(s, s32, ru_ixrss);
681100384Speter		CP(s, s32, ru_idrss);
682100384Speter		CP(s, s32, ru_isrss);
683100384Speter		CP(s, s32, ru_minflt);
684100384Speter		CP(s, s32, ru_majflt);
685100384Speter		CP(s, s32, ru_nswap);
686100384Speter		CP(s, s32, ru_inblock);
687100384Speter		CP(s, s32, ru_oublock);
688100384Speter		CP(s, s32, ru_msgsnd);
689100384Speter		CP(s, s32, ru_msgrcv);
690100384Speter		CP(s, s32, ru_nsignals);
691100384Speter		CP(s, s32, ru_nvcsw);
692100384Speter		CP(s, s32, ru_nivcsw);
693136152Sjhb		error = copyout(&s32, uap->rusage, sizeof(s32));
694100384Speter	}
695100384Speter	return (error);
696100384Speter}
697100384Speter
698100384Speterstruct iovec32 {
699100384Speter	u_int32_t iov_base;
700100384Speter	int	iov_len;
701100384Speter};
702100384Speter
703121719SpeterCTASSERT(sizeof(struct iovec32) == 8);
704121719Speter
705144450Sjhbstatic int
706144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
707100384Speter{
708144450Sjhb	struct iovec32 iov32;
709144450Sjhb	struct iovec *iov;
710144450Sjhb	struct uio *uio;
711144450Sjhb	u_int iovlen;
712144450Sjhb	int error, i;
713100384Speter
714144450Sjhb	*uiop = NULL;
715144450Sjhb	if (iovcnt > UIO_MAXIOV)
716100384Speter		return (EINVAL);
717144450Sjhb	iovlen = iovcnt * sizeof(struct iovec);
718144450Sjhb	uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
719144450Sjhb	iov = (struct iovec *)(uio + 1);
720144450Sjhb	for (i = 0; i < iovcnt; i++) {
721144450Sjhb		error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
722144450Sjhb		if (error) {
723144450Sjhb			free(uio, M_IOV);
724144450Sjhb			return (error);
725144450Sjhb		}
726144450Sjhb		iov[i].iov_base = PTRIN(iov32.iov_base);
727144450Sjhb		iov[i].iov_len = iov32.iov_len;
728100384Speter	}
729144450Sjhb	uio->uio_iov = iov;
730144450Sjhb	uio->uio_iovcnt = iovcnt;
731144450Sjhb	uio->uio_segflg = UIO_USERSPACE;
732144450Sjhb	uio->uio_offset = -1;
733144450Sjhb	uio->uio_resid = 0;
734144450Sjhb	for (i = 0; i < iovcnt; i++) {
735144450Sjhb		if (iov->iov_len > INT_MAX - uio->uio_resid) {
736144450Sjhb			free(uio, M_IOV);
737144450Sjhb			return (EINVAL);
738144450Sjhb		}
739144450Sjhb		uio->uio_resid += iov->iov_len;
740144450Sjhb		iov++;
741144450Sjhb	}
742144450Sjhb	*uiop = uio;
743144450Sjhb	return (0);
744144450Sjhb}
745100384Speter
746144450Sjhbint
747144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
748144450Sjhb{
749144450Sjhb	struct uio *auio;
750144450Sjhb	int error;
751100384Speter
752144450Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
753144450Sjhb	if (error)
754144450Sjhb		return (error);
755144450Sjhb	error = kern_readv(td, uap->fd, auio);
756144450Sjhb	free(auio, M_IOV);
757100384Speter	return (error);
758100384Speter}
759100384Speter
760100384Speterint
761119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
762100384Speter{
763144450Sjhb	struct uio *auio;
764144450Sjhb	int error;
765100384Speter
766144450Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
767144450Sjhb	if (error)
768144450Sjhb		return (error);
769144450Sjhb	error = kern_writev(td, uap->fd, auio);
770144450Sjhb	free(auio, M_IOV);
771100384Speter	return (error);
772100384Speter}
773100384Speter
774100384Speterint
775147813Sjhbfreebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
776147813Sjhb{
777147813Sjhb	struct uio *auio;
778147813Sjhb	int error;
779147813Sjhb
780147813Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
781147813Sjhb	if (error)
782147813Sjhb		return (error);
783147813Sjhb	error = kern_preadv(td, uap->fd, auio, uap->offset);
784147813Sjhb	free(auio, M_IOV);
785147813Sjhb	return (error);
786147813Sjhb}
787147813Sjhb
788147813Sjhbint
789147813Sjhbfreebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
790147813Sjhb{
791147813Sjhb	struct uio *auio;
792147813Sjhb	int error;
793147813Sjhb
794147813Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
795147813Sjhb	if (error)
796147813Sjhb		return (error);
797147813Sjhb	error = kern_pwritev(td, uap->fd, auio, uap->offset);
798147813Sjhb	free(auio, M_IOV);
799147813Sjhb	return (error);
800147813Sjhb}
801147813Sjhb
802151359Spsstatic int
803151359Spsfreebsd32_copyiniov(struct iovec32 *iovp, u_int iovcnt, struct iovec **iov,
804151359Sps    int error)
805151359Sps{
806151359Sps	struct iovec32 iov32;
807151359Sps	int i;
808151359Sps
809151359Sps	u_int iovlen;
810151359Sps
811151359Sps	*iov = NULL;
812151359Sps	if (iovcnt > UIO_MAXIOV)
813151359Sps		return (error);
814151359Sps	iovlen = iovcnt * sizeof(struct iovec);
815151359Sps	*iov = malloc(iovlen, M_IOV, M_WAITOK);
816151359Sps	for (i = 0; i < iovcnt; i++) {
817151359Sps		error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
818151359Sps		if (error) {
819151359Sps			free(*iov, M_IOV);
820151359Sps			*iov = NULL;
821151359Sps			return (error);
822151359Sps		}
823151359Sps		iov[i]->iov_base = PTRIN(iov32.iov_base);
824151359Sps		iov[i]->iov_len = iov32.iov_len;
825151359Sps	}
826151359Sps	return (0);
827151359Sps}
828151359Sps
829151359Spsstruct msghdr32 {
830151359Sps	u_int32_t	 msg_name;
831151359Sps	socklen_t	 msg_namelen;
832151359Sps	u_int32_t	 msg_iov;
833151359Sps	int		 msg_iovlen;
834151359Sps	u_int32_t	 msg_control;
835151359Sps	socklen_t	 msg_controllen;
836151359Sps	int		 msg_flags;
837151359Sps};
838151359SpsCTASSERT(sizeof(struct msghdr32) == 28);
839151359Sps
840151359Spsstatic int
841151359Spsfreebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg)
842151359Sps{
843151359Sps	struct msghdr32 m32;
844151359Sps	int error;
845151359Sps
846151359Sps	error = copyin(msg32, &m32, sizeof(m32));
847151359Sps	if (error)
848151359Sps		return (error);
849151359Sps	msg->msg_name = PTRIN(m32.msg_name);
850151359Sps	msg->msg_namelen = m32.msg_namelen;
851151359Sps	msg->msg_iov = PTRIN(m32.msg_iov);
852151359Sps	msg->msg_iovlen = m32.msg_iovlen;
853151359Sps	msg->msg_control = PTRIN(m32.msg_control);
854151359Sps	msg->msg_controllen = m32.msg_controllen;
855151359Sps	msg->msg_flags = m32.msg_flags;
856151359Sps	return (freebsd32_copyiniov((struct iovec32 *)(uintptr_t)m32.msg_iov, m32.msg_iovlen, &msg->msg_iov,
857151359Sps	    EMSGSIZE));
858151359Sps}
859151359Sps
860151359Spsstatic int
861151359Spsfreebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
862151359Sps{
863151359Sps	struct msghdr32 m32;
864151359Sps	int error;
865151359Sps
866151359Sps	m32.msg_name = PTROUT(msg->msg_name);
867151359Sps	m32.msg_namelen = msg->msg_namelen;
868151359Sps	m32.msg_iov = PTROUT(msg->msg_iov);
869151359Sps	m32.msg_iovlen = msg->msg_iovlen;
870151359Sps	m32.msg_control = PTROUT(msg->msg_control);
871151359Sps	m32.msg_controllen = msg->msg_controllen;
872151359Sps	m32.msg_flags = msg->msg_flags;
873151359Sps	error = copyout(&m32, msg32, sizeof(m32));
874151359Sps	return (error);
875151359Sps}
876151359Sps
877147813Sjhbint
878151359Spsfreebsd32_recvmsg(td, uap)
879151359Sps	struct thread *td;
880151359Sps	struct freebsd32_recvmsg_args /* {
881151359Sps		int	s;
882151359Sps		struct	msghdr32 *msg;
883151359Sps		int	flags;
884151359Sps	} */ *uap;
885151359Sps{
886151359Sps	struct msghdr msg;
887151359Sps	struct msghdr32 m32;
888151359Sps	struct iovec *uiov, *iov;
889151359Sps	int error;
890151359Sps
891151359Sps	error = copyin(uap->msg, &m32, sizeof(m32));
892151359Sps	if (error)
893151359Sps		return (error);
894151359Sps	error = freebsd32_copyinmsghdr(uap->msg, &msg);
895151359Sps	if (error)
896151359Sps		return (error);
897151359Sps	error = freebsd32_copyiniov((struct iovec32 *)(uintptr_t)m32.msg_iov,
898151359Sps	    m32.msg_iovlen, &iov, EMSGSIZE);
899151359Sps	if (error)
900151359Sps		return (error);
901151359Sps	msg.msg_flags = uap->flags;
902151359Sps	uiov = msg.msg_iov;
903151359Sps	msg.msg_iov = iov;
904151359Sps	error = kern_recvit(td, uap->s, &msg, NULL, UIO_SYSSPACE);
905151359Sps	if (error == 0) {
906151359Sps		msg.msg_iov = uiov;
907151359Sps		error = freebsd32_copyoutmsghdr(&msg, uap->msg);
908151359Sps	}
909151359Sps	free(iov, M_IOV);
910151359Sps	free(uiov, M_IOV);
911151359Sps	return (error);
912151359Sps}
913151359Sps
914151359Spsint
915151359Spsfreebsd32_sendmsg(struct thread *td,
916151359Sps		  struct freebsd32_sendmsg_args *uap)
917151359Sps{
918151359Sps	struct msghdr msg;
919151359Sps	struct msghdr32 m32;
920151359Sps	struct iovec *iov;
921151359Sps	int error;
922151359Sps
923151359Sps	error = copyin(uap->msg, &m32, sizeof(m32));
924151359Sps	if (error)
925151359Sps		return (error);
926151359Sps	error = freebsd32_copyinmsghdr(uap->msg, &msg);
927151359Sps	if (error)
928151359Sps		return (error);
929151359Sps	error = freebsd32_copyiniov((struct iovec32 *)(uintptr_t)m32.msg_iov,
930151359Sps	    m32.msg_iovlen, &iov, EMSGSIZE);
931151359Sps	if (error)
932151359Sps		return (error);
933151359Sps	msg.msg_iov = iov;
934151359Sps	error = kern_sendit(td, uap->s, &msg, uap->flags, NULL, UIO_SYSSPACE);
935151359Sps	free(iov, M_IOV);
936151359Sps	return (error);
937151359Sps}
938151359Sps
939151359Spsint
940151359Spsfreebsd32_recvfrom(struct thread *td,
941151359Sps		   struct freebsd32_recvfrom_args *uap)
942151359Sps{
943151359Sps	struct msghdr msg;
944151359Sps	struct iovec aiov;
945151359Sps	int error;
946151359Sps
947151359Sps	if (uap->fromlenaddr) {
948151359Sps		error = copyin((void *)(uintptr_t)uap->fromlenaddr,
949151359Sps		    &msg.msg_namelen, sizeof(msg.msg_namelen));
950151359Sps		if (error)
951151359Sps			return (error);
952151359Sps	} else {
953151359Sps		msg.msg_namelen = 0;
954151359Sps	}
955151359Sps
956151359Sps	msg.msg_name = (void *)(uintptr_t)uap->from;
957151359Sps	msg.msg_iov = &aiov;
958151359Sps	msg.msg_iovlen = 1;
959151359Sps	aiov.iov_base = (void *)(uintptr_t)uap->buf;
960151359Sps	aiov.iov_len = uap->len;
961151359Sps	msg.msg_control = 0;
962151359Sps	msg.msg_flags = uap->flags;
963151359Sps	error = kern_recvit(td, uap->s, &msg, (void *)(uintptr_t)uap->fromlenaddr, UIO_USERSPACE);
964151359Sps	return (error);
965151359Sps}
966151359Sps
967151359Spsint
968119333Speterfreebsd32_settimeofday(struct thread *td,
969119333Speter		       struct freebsd32_settimeofday_args *uap)
970100384Speter{
971144450Sjhb	struct timeval32 tv32;
972144450Sjhb	struct timeval tv, *tvp;
973144450Sjhb	struct timezone tz, *tzp;
974100384Speter	int error;
975100384Speter
976144450Sjhb	if (uap->tv) {
977144450Sjhb		error = copyin(uap->tv, &tv32, sizeof(tv32));
978100384Speter		if (error)
979100384Speter			return (error);
980144450Sjhb		CP(tv32, tv, tv_sec);
981144450Sjhb		CP(tv32, tv, tv_usec);
982144450Sjhb		tvp = &tv;
983144450Sjhb	} else
984144450Sjhb		tvp = NULL;
985144450Sjhb	if (uap->tzp) {
986144450Sjhb		error = copyin(uap->tzp, &tz, sizeof(tz));
987100384Speter		if (error)
988100384Speter			return (error);
989144450Sjhb		tzp = &tz;
990144450Sjhb	} else
991144450Sjhb		tzp = NULL;
992144450Sjhb	return (kern_settimeofday(td, tvp, tzp));
993100384Speter}
994100384Speter
995100384Speterint
996119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
997100384Speter{
998142059Sjhb	struct timeval32 s32[2];
999142059Sjhb	struct timeval s[2], *sp;
1000100384Speter	int error;
1001100384Speter
1002142059Sjhb	if (uap->tptr != NULL) {
1003142059Sjhb		error = copyin(uap->tptr, s32, sizeof(s32));
1004100384Speter		if (error)
1005100384Speter			return (error);
1006100384Speter		CP(s32[0], s[0], tv_sec);
1007100384Speter		CP(s32[0], s[0], tv_usec);
1008100384Speter		CP(s32[1], s[1], tv_sec);
1009100384Speter		CP(s32[1], s[1], tv_usec);
1010142059Sjhb		sp = s;
1011142059Sjhb	} else
1012142059Sjhb		sp = NULL;
1013142059Sjhb	return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1014100384Speter}
1015100384Speter
1016100384Speterint
1017119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
1018100384Speter{
1019144450Sjhb	struct timeval32 tv32;
1020144450Sjhb	struct timeval delta, olddelta, *deltap;
1021100384Speter	int error;
1022100384Speter
1023144450Sjhb	if (uap->delta) {
1024144450Sjhb		error = copyin(uap->delta, &tv32, sizeof(tv32));
1025100384Speter		if (error)
1026100384Speter			return (error);
1027144450Sjhb		CP(tv32, delta, tv_sec);
1028144450Sjhb		CP(tv32, delta, tv_usec);
1029144450Sjhb		deltap = &delta;
1030144450Sjhb	} else
1031144450Sjhb		deltap = NULL;
1032144450Sjhb	error = kern_adjtime(td, deltap, &olddelta);
1033144450Sjhb	if (uap->olddelta && error == 0) {
1034144450Sjhb		CP(olddelta, tv32, tv_sec);
1035144450Sjhb		CP(olddelta, tv32, tv_usec);
1036144450Sjhb		error = copyout(&tv32, uap->olddelta, sizeof(tv32));
1037100384Speter	}
1038100384Speter	return (error);
1039100384Speter}
1040100384Speter
1041128597Smarcel#ifdef COMPAT_FREEBSD4
1042100384Speterint
1043128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
1044100384Speter{
1045142059Sjhb	struct statfs32 s32;
1046142059Sjhb	struct statfs s;
1047100384Speter	int error;
1048100384Speter
1049142059Sjhb	error = kern_statfs(td, uap->path, UIO_USERSPACE, &s);
1050100384Speter	if (error)
1051100384Speter		return (error);
1052142059Sjhb	copy_statfs(&s, &s32);
1053142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
1054100384Speter}
1055128597Smarcel#endif
1056100384Speter
1057128597Smarcel#ifdef COMPAT_FREEBSD4
1058100384Speterint
1059128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
1060100384Speter{
1061142059Sjhb	struct statfs32 s32;
1062142059Sjhb	struct statfs s;
1063100384Speter	int error;
1064100384Speter
1065142059Sjhb	error = kern_fstatfs(td, uap->fd, &s);
1066100384Speter	if (error)
1067100384Speter		return (error);
1068142059Sjhb	copy_statfs(&s, &s32);
1069142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
1070100384Speter}
1071128597Smarcel#endif
1072100384Speter
1073128597Smarcel#ifdef COMPAT_FREEBSD4
1074100384Speterint
1075128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
1076128260Speter{
1077142059Sjhb	struct statfs32 s32;
1078142059Sjhb	struct statfs s;
1079142059Sjhb	fhandle_t fh;
1080128260Speter	int error;
1081128260Speter
1082142059Sjhb	if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
1083142059Sjhb		return (error);
1084142059Sjhb	error = kern_fhstatfs(td, fh, &s);
1085128260Speter	if (error)
1086128260Speter		return (error);
1087142059Sjhb	copy_statfs(&s, &s32);
1088142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
1089128260Speter}
1090128597Smarcel#endif
1091128260Speter
1092128260Speterint
1093119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
1094100384Speter{
1095100384Speter	/*
1096100384Speter	 * Vector through to semsys if it is loaded.
1097100384Speter	 */
1098150883Sjhb	return sysent[SYS_semsys].sy_call(td, uap);
1099100384Speter}
1100100384Speter
1101100384Speterint
1102119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
1103100384Speter{
1104100384Speter	/*
1105100384Speter	 * Vector through to msgsys if it is loaded.
1106100384Speter	 */
1107150883Sjhb	return sysent[SYS_msgsys].sy_call(td, uap);
1108100384Speter}
1109100384Speter
1110100384Speterint
1111119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
1112100384Speter{
1113100384Speter	/*
1114100384Speter	 * Vector through to shmsys if it is loaded.
1115100384Speter	 */
1116150883Sjhb	return sysent[SYS_shmsys].sy_call(td, uap);
1117100384Speter}
1118100384Speter
1119100384Speterint
1120119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
1121100384Speter{
1122100384Speter	struct pread_args ap;
1123100384Speter
1124107849Salfred	ap.fd = uap->fd;
1125107849Salfred	ap.buf = uap->buf;
1126107849Salfred	ap.nbyte = uap->nbyte;
1127119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1128100384Speter	return (pread(td, &ap));
1129100384Speter}
1130100384Speter
1131100384Speterint
1132119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
1133100384Speter{
1134100384Speter	struct pwrite_args ap;
1135100384Speter
1136107849Salfred	ap.fd = uap->fd;
1137107849Salfred	ap.buf = uap->buf;
1138107849Salfred	ap.nbyte = uap->nbyte;
1139119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1140100384Speter	return (pwrite(td, &ap));
1141100384Speter}
1142100384Speter
1143100384Speterint
1144119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
1145100384Speter{
1146100384Speter	int error;
1147100384Speter	struct lseek_args ap;
1148100384Speter	off_t pos;
1149100384Speter
1150107849Salfred	ap.fd = uap->fd;
1151119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1152107849Salfred	ap.whence = uap->whence;
1153100384Speter	error = lseek(td, &ap);
1154100384Speter	/* Expand the quad return into two parts for eax and edx */
1155100384Speter	pos = *(off_t *)(td->td_retval);
1156100384Speter	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
1157100384Speter	td->td_retval[1] = pos >> 32;		/* %edx */
1158100384Speter	return error;
1159100384Speter}
1160100384Speter
1161100384Speterint
1162119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
1163100384Speter{
1164100384Speter	struct truncate_args ap;
1165100384Speter
1166107849Salfred	ap.path = uap->path;
1167119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1168100384Speter	return (truncate(td, &ap));
1169100384Speter}
1170100384Speter
1171100384Speterint
1172119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
1173100384Speter{
1174100384Speter	struct ftruncate_args ap;
1175100384Speter
1176107849Salfred	ap.fd = uap->fd;
1177119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1178100384Speter	return (ftruncate(td, &ap));
1179100384Speter}
1180100384Speter
1181104738Speter#ifdef COMPAT_FREEBSD4
1182100384Speterint
1183119333Speterfreebsd4_freebsd32_sendfile(struct thread *td,
1184119333Speter    struct freebsd4_freebsd32_sendfile_args *uap)
1185104738Speter{
1186104738Speter	struct freebsd4_sendfile_args ap;
1187104738Speter
1188107849Salfred	ap.fd = uap->fd;
1189107849Salfred	ap.s = uap->s;
1190119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1191107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
1192107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
1193107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
1194107849Salfred	ap.flags = uap->flags;
1195104738Speter	return (freebsd4_sendfile(td, &ap));
1196104738Speter}
1197104738Speter#endif
1198104738Speter
1199104738Speterint
1200119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
1201100384Speter{
1202100384Speter	struct sendfile_args ap;
1203100384Speter
1204107849Salfred	ap.fd = uap->fd;
1205107849Salfred	ap.s = uap->s;
1206119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1207107849Salfred	ap.nbytes = uap->nbytes;	/* XXX check */
1208107849Salfred	ap.hdtr = uap->hdtr;		/* XXX check */
1209107849Salfred	ap.sbytes = uap->sbytes;	/* XXX FIXME!! */
1210107849Salfred	ap.flags = uap->flags;
1211100384Speter	return (sendfile(td, &ap));
1212100384Speter}
1213100384Speter
1214100384Speterstruct stat32 {
1215130640Sphk	dev_t	st_dev;
1216100384Speter	ino_t	st_ino;
1217100384Speter	mode_t	st_mode;
1218100384Speter	nlink_t	st_nlink;
1219100384Speter	uid_t	st_uid;
1220100384Speter	gid_t	st_gid;
1221130640Sphk	dev_t	st_rdev;
1222100384Speter	struct timespec32 st_atimespec;
1223100384Speter	struct timespec32 st_mtimespec;
1224100384Speter	struct timespec32 st_ctimespec;
1225100384Speter	off_t	st_size;
1226100384Speter	int64_t	st_blocks;
1227100384Speter	u_int32_t st_blksize;
1228100384Speter	u_int32_t st_flags;
1229100384Speter	u_int32_t st_gen;
1230121719Speter	struct timespec32 st_birthtimespec;
1231121719Speter	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1232121719Speter	unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
1233100384Speter};
1234100384Speter
1235121719Speter
1236121719SpeterCTASSERT(sizeof(struct stat32) == 96);
1237121719Speter
1238100384Speterstatic void
1239100384Spetercopy_stat( struct stat *in, struct stat32 *out)
1240100384Speter{
1241100384Speter	CP(*in, *out, st_dev);
1242100384Speter	CP(*in, *out, st_ino);
1243100384Speter	CP(*in, *out, st_mode);
1244100384Speter	CP(*in, *out, st_nlink);
1245100384Speter	CP(*in, *out, st_uid);
1246100384Speter	CP(*in, *out, st_gid);
1247100384Speter	CP(*in, *out, st_rdev);
1248100384Speter	TS_CP(*in, *out, st_atimespec);
1249100384Speter	TS_CP(*in, *out, st_mtimespec);
1250100384Speter	TS_CP(*in, *out, st_ctimespec);
1251100384Speter	CP(*in, *out, st_size);
1252100384Speter	CP(*in, *out, st_blocks);
1253100384Speter	CP(*in, *out, st_blksize);
1254100384Speter	CP(*in, *out, st_flags);
1255100384Speter	CP(*in, *out, st_gen);
1256100384Speter}
1257100384Speter
1258100384Speterint
1259119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
1260100384Speter{
1261123746Speter	struct stat sb;
1262123746Speter	struct stat32 sb32;
1263100384Speter	int error;
1264100384Speter
1265142059Sjhb	error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
1266100384Speter	if (error)
1267100384Speter		return (error);
1268123746Speter	copy_stat(&sb, &sb32);
1269123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1270100384Speter	return (error);
1271100384Speter}
1272100384Speter
1273100384Speterint
1274119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1275100384Speter{
1276123746Speter	struct stat ub;
1277123746Speter	struct stat32 ub32;
1278100384Speter	int error;
1279100384Speter
1280142059Sjhb	error = kern_fstat(td, uap->fd, &ub);
1281100384Speter	if (error)
1282100384Speter		return (error);
1283123746Speter	copy_stat(&ub, &ub32);
1284123746Speter	error = copyout(&ub32, uap->ub, sizeof(ub32));
1285100384Speter	return (error);
1286100384Speter}
1287100384Speter
1288100384Speterint
1289119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
1290100384Speter{
1291123746Speter	struct stat sb;
1292123746Speter	struct stat32 sb32;
1293142059Sjhb	int error;
1294100384Speter
1295142059Sjhb	error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
1296100384Speter	if (error)
1297100384Speter		return (error);
1298123746Speter	copy_stat(&sb, &sb32);
1299123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1300100384Speter	return (error);
1301100384Speter}
1302100384Speter
1303100384Speter/*
1304100384Speter * MPSAFE
1305100384Speter */
1306100384Speterint
1307119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
1308100384Speter{
1309100384Speter	int error, name[CTL_MAXNAME];
1310100384Speter	size_t j, oldlen;
1311100384Speter
1312100384Speter	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1313100384Speter		return (EINVAL);
1314136404Speter 	error = copyin(uap->name, name, uap->namelen * sizeof(int));
1315100384Speter 	if (error)
1316100384Speter		return (error);
1317100384Speter	mtx_lock(&Giant);
1318100384Speter	if (uap->oldlenp)
1319100384Speter		oldlen = fuword32(uap->oldlenp);
1320100384Speter	else
1321100384Speter		oldlen = 0;
1322100384Speter	error = userland_sysctl(td, name, uap->namelen,
1323100384Speter		uap->old, &oldlen, 1,
1324136404Speter		uap->new, uap->newlen, &j, SCTL_MASK32);
1325100384Speter	if (error && error != ENOMEM)
1326100384Speter		goto done2;
1327136404Speter	if (uap->oldlenp)
1328100384Speter		suword32(uap->oldlenp, j);
1329100384Speterdone2:
1330100384Speter	mtx_unlock(&Giant);
1331100384Speter	return (error);
1332100384Speter}
1333100384Speter
1334100384Speterstruct sigaction32 {
1335100384Speter	u_int32_t	sa_u;
1336100384Speter	int		sa_flags;
1337100384Speter	sigset_t	sa_mask;
1338100384Speter};
1339100384Speter
1340121719SpeterCTASSERT(sizeof(struct sigaction32) == 24);
1341121719Speter
1342100384Speterint
1343119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
1344100384Speter{
1345113859Sjhb	struct sigaction32 s32;
1346113859Sjhb	struct sigaction sa, osa, *sap;
1347100384Speter	int error;
1348100384Speter
1349113859Sjhb	if (uap->act) {
1350113859Sjhb		error = copyin(uap->act, &s32, sizeof(s32));
1351100384Speter		if (error)
1352100384Speter			return (error);
1353113859Sjhb		sa.sa_handler = PTRIN(s32.sa_u);
1354113859Sjhb		CP(s32, sa, sa_flags);
1355113859Sjhb		CP(s32, sa, sa_mask);
1356113859Sjhb		sap = &sa;
1357113859Sjhb	} else
1358113859Sjhb		sap = NULL;
1359113859Sjhb	error = kern_sigaction(td, uap->sig, sap, &osa, 0);
1360146583Sps	if (error == 0 && uap->oact != NULL) {
1361113859Sjhb		s32.sa_u = PTROUT(osa.sa_handler);
1362113859Sjhb		CP(osa, s32, sa_flags);
1363113859Sjhb		CP(osa, s32, sa_mask);
1364113859Sjhb		error = copyout(&s32, uap->oact, sizeof(s32));
1365100384Speter	}
1366100384Speter	return (error);
1367100384Speter}
1368100384Speter
1369114987Speter#ifdef COMPAT_FREEBSD4
1370114987Speterint
1371119333Speterfreebsd4_freebsd32_sigaction(struct thread *td,
1372119333Speter			     struct freebsd4_freebsd32_sigaction_args *uap)
1373114987Speter{
1374114987Speter	struct sigaction32 s32;
1375114987Speter	struct sigaction sa, osa, *sap;
1376114987Speter	int error;
1377114987Speter
1378114987Speter	if (uap->act) {
1379114987Speter		error = copyin(uap->act, &s32, sizeof(s32));
1380114987Speter		if (error)
1381114987Speter			return (error);
1382114987Speter		sa.sa_handler = PTRIN(s32.sa_u);
1383114987Speter		CP(s32, sa, sa_flags);
1384114987Speter		CP(s32, sa, sa_mask);
1385114987Speter		sap = &sa;
1386114987Speter	} else
1387114987Speter		sap = NULL;
1388114987Speter	error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
1389146583Sps	if (error == 0 && uap->oact != NULL) {
1390114987Speter		s32.sa_u = PTROUT(osa.sa_handler);
1391114987Speter		CP(osa, s32, sa_flags);
1392114987Speter		CP(osa, s32, sa_mask);
1393114987Speter		error = copyout(&s32, uap->oact, sizeof(s32));
1394114987Speter	}
1395114987Speter	return (error);
1396114987Speter}
1397114987Speter#endif
1398114987Speter
1399151582Sps#ifdef COMPAT_43
1400151720Speterstruct osigaction32 {
1401151582Sps	u_int32_t	sa_u;
1402151582Sps	osigset_t	sa_mask;
1403151582Sps	int		sa_flags;
1404151582Sps};
1405151582Sps
1406151582Sps#define	ONSIG	32
1407151582Sps
1408140481Spsint
1409151720Speterofreebsd32_sigaction(struct thread *td,
1410151720Speter			     struct ofreebsd32_sigaction_args *uap)
1411151582Sps{
1412151720Speter	struct osigaction32 s32;
1413151582Sps	struct sigaction sa, osa, *sap;
1414151582Sps	int error;
1415151582Sps
1416151582Sps	if (uap->signum <= 0 || uap->signum >= ONSIG)
1417151582Sps		return (EINVAL);
1418151582Sps
1419151582Sps	if (uap->nsa) {
1420151582Sps		error = copyin(uap->nsa, &s32, sizeof(s32));
1421151582Sps		if (error)
1422151582Sps			return (error);
1423151582Sps		sa.sa_handler = PTRIN(s32.sa_u);
1424151582Sps		CP(s32, sa, sa_flags);
1425151582Sps		OSIG2SIG(s32.sa_mask, sa.sa_mask);
1426151582Sps		sap = &sa;
1427151582Sps	} else
1428151582Sps		sap = NULL;
1429151582Sps	error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
1430151582Sps	if (error == 0 && uap->osa != NULL) {
1431151582Sps		s32.sa_u = PTROUT(osa.sa_handler);
1432151582Sps		CP(osa, s32, sa_flags);
1433151582Sps		SIG2OSIG(osa.sa_mask, s32.sa_mask);
1434151582Sps		error = copyout(&s32, uap->osa, sizeof(s32));
1435151582Sps	}
1436151582Sps	return (error);
1437151582Sps}
1438151582Sps
1439151582Spsint
1440151720Speterofreebsd32_sigprocmask(struct thread *td,
1441151720Speter			       struct ofreebsd32_sigprocmask_args *uap)
1442151582Sps{
1443151582Sps	sigset_t set, oset;
1444151582Sps	int error;
1445151582Sps
1446151582Sps	OSIG2SIG(uap->mask, set);
1447151582Sps	error = kern_sigprocmask(td, uap->how, &set, &oset, 1);
1448151582Sps	SIG2OSIG(oset, td->td_retval[0]);
1449151582Sps	return (error);
1450151582Sps}
1451151582Sps
1452151582Spsint
1453151720Speterofreebsd32_sigpending(struct thread *td,
1454151720Speter			      struct ofreebsd32_sigpending_args *uap)
1455151582Sps{
1456151582Sps	struct proc *p = td->td_proc;
1457151582Sps	sigset_t siglist;
1458151582Sps
1459151582Sps	PROC_LOCK(p);
1460151582Sps	siglist = p->p_siglist;
1461151582Sps	SIGSETOR(siglist, td->td_siglist);
1462151582Sps	PROC_UNLOCK(p);
1463151582Sps	SIG2OSIG(siglist, td->td_retval[0]);
1464151582Sps	return (0);
1465151582Sps}
1466151582Sps
1467151582Spsstruct sigvec32 {
1468151582Sps	u_int32_t	sv_handler;
1469151582Sps	int		sv_mask;
1470151582Sps	int		sv_flags;
1471151582Sps};
1472151582Sps
1473151582Spsint
1474151720Speterofreebsd32_sigvec(struct thread *td,
1475151720Speter			  struct ofreebsd32_sigvec_args *uap)
1476151582Sps{
1477151582Sps	struct sigvec32 vec;
1478151582Sps	struct sigaction sa, osa, *sap;
1479151582Sps	int error;
1480151582Sps
1481151582Sps	if (uap->signum <= 0 || uap->signum >= ONSIG)
1482151582Sps		return (EINVAL);
1483151582Sps
1484151582Sps	if (uap->nsv) {
1485151582Sps		error = copyin(uap->nsv, &vec, sizeof(vec));
1486151582Sps		if (error)
1487151582Sps			return (error);
1488151582Sps		sa.sa_handler = PTRIN(vec.sv_handler);
1489151582Sps		OSIG2SIG(vec.sv_mask, sa.sa_mask);
1490151582Sps		sa.sa_flags = vec.sv_flags;
1491151582Sps		sa.sa_flags ^= SA_RESTART;
1492151582Sps		sap = &sa;
1493151582Sps	} else
1494151582Sps		sap = NULL;
1495151582Sps	error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
1496151582Sps	if (error == 0 && uap->osv != NULL) {
1497151582Sps		vec.sv_handler = PTROUT(osa.sa_handler);
1498151582Sps		SIG2OSIG(osa.sa_mask, vec.sv_mask);
1499151582Sps		vec.sv_flags = osa.sa_flags;
1500151582Sps		vec.sv_flags &= ~SA_NOCLDWAIT;
1501151582Sps		vec.sv_flags ^= SA_RESTART;
1502151582Sps		error = copyout(&vec, uap->osv, sizeof(vec));
1503151582Sps	}
1504151582Sps	return (error);
1505151582Sps}
1506151582Sps
1507151582Spsint
1508151720Speterofreebsd32_sigblock(struct thread *td,
1509151720Speter			    struct ofreebsd32_sigblock_args *uap)
1510151582Sps{
1511151582Sps	struct proc *p = td->td_proc;
1512151582Sps	sigset_t set;
1513151582Sps
1514151582Sps	OSIG2SIG(uap->mask, set);
1515151582Sps	SIG_CANTMASK(set);
1516151582Sps	PROC_LOCK(p);
1517151582Sps	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
1518151582Sps	SIGSETOR(td->td_sigmask, set);
1519151582Sps	PROC_UNLOCK(p);
1520151582Sps	return (0);
1521151582Sps}
1522151582Sps
1523151582Spsint
1524151720Speterofreebsd32_sigsetmask(struct thread *td,
1525151720Speter			      struct ofreebsd32_sigsetmask_args *uap)
1526151582Sps{
1527151582Sps	struct proc *p = td->td_proc;
1528151582Sps	sigset_t set;
1529151582Sps
1530151582Sps	OSIG2SIG(uap->mask, set);
1531151582Sps	SIG_CANTMASK(set);
1532151582Sps	PROC_LOCK(p);
1533151582Sps	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
1534151582Sps	SIGSETLO(td->td_sigmask, set);
1535151582Sps	signotify(td);
1536151582Sps	PROC_UNLOCK(p);
1537151582Sps	return (0);
1538151582Sps}
1539151582Sps
1540151582Spsint
1541151720Speterofreebsd32_sigsuspend(struct thread *td,
1542151720Speter			      struct ofreebsd32_sigsuspend_args *uap)
1543151582Sps{
1544151582Sps	struct proc *p = td->td_proc;
1545151582Sps	sigset_t mask;
1546151582Sps
1547151582Sps	PROC_LOCK(p);
1548151582Sps	td->td_oldsigmask = td->td_sigmask;
1549151582Sps	td->td_pflags |= TDP_OLDMASK;
1550151582Sps	OSIG2SIG(uap->mask, mask);
1551151582Sps	SIG_CANTMASK(mask);
1552151582Sps	SIGSETLO(td->td_sigmask, mask);
1553151582Sps	signotify(td);
1554151582Sps	while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0)
1555151582Sps		/* void */;
1556151582Sps	PROC_UNLOCK(p);
1557151582Sps	/* always return EINTR rather than ERESTART... */
1558151582Sps	return (EINTR);
1559151582Sps}
1560151582Sps
1561151582Spsstruct sigstack32 {
1562151582Sps	u_int32_t	ss_sp;
1563151582Sps	int		ss_onstack;
1564151582Sps};
1565151582Sps
1566151582Spsint
1567151720Speterofreebsd32_sigstack(struct thread *td,
1568151720Speter			    struct ofreebsd32_sigstack_args *uap)
1569151582Sps{
1570151582Sps	struct sigstack32 s32;
1571151582Sps	struct sigstack nss, oss;
1572151582Sps	int error = 0;
1573151582Sps
1574151582Sps	if (uap->nss != NULL) {
1575151582Sps		error = copyin(uap->nss, &s32, sizeof(s32));
1576151582Sps		if (error)
1577151582Sps			return (error);
1578151582Sps		nss.ss_sp = PTRIN(s32.ss_sp);
1579151582Sps		CP(s32, nss, ss_onstack);
1580151582Sps	}
1581151582Sps	oss.ss_sp = td->td_sigstk.ss_sp;
1582151582Sps	oss.ss_onstack = sigonstack(cpu_getstack(td));
1583151582Sps	if (uap->nss != NULL) {
1584151582Sps		td->td_sigstk.ss_sp = nss.ss_sp;
1585151582Sps		td->td_sigstk.ss_size = 0;
1586151582Sps		td->td_sigstk.ss_flags |= nss.ss_onstack & SS_ONSTACK;
1587151582Sps		td->td_pflags |= TDP_ALTSTACK;
1588151582Sps	}
1589151582Sps	if (uap->oss != NULL) {
1590151582Sps		s32.ss_sp = PTROUT(oss.ss_sp);
1591151582Sps		CP(oss, s32, ss_onstack);
1592151582Sps		error = copyout(&s32, uap->oss, sizeof(s32));
1593151582Sps	}
1594151582Sps	return (error);
1595151582Sps}
1596151582Sps#endif
1597151582Sps
1598151582Spsint
1599140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
1600140481Sps{
1601140481Sps	struct timespec32 rmt32, rqt32;
1602140481Sps	struct timespec rmt, rqt;
1603140481Sps	int error;
1604140481Sps
1605151355Sps	error = copyin(uap->rqtp, &rqt32, sizeof(rqt32));
1606140481Sps	if (error)
1607140481Sps		return (error);
1608140481Sps
1609140481Sps	CP(rqt32, rqt, tv_sec);
1610140481Sps	CP(rqt32, rqt, tv_nsec);
1611140481Sps
1612140481Sps	if (uap->rmtp &&
1613140481Sps	    !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
1614140481Sps		return (EFAULT);
1615140481Sps	error = kern_nanosleep(td, &rqt, &rmt);
1616140481Sps	if (error && uap->rmtp) {
1617140481Sps		int error2;
1618140481Sps
1619140481Sps		CP(rmt, rmt32, tv_sec);
1620140481Sps		CP(rmt, rmt32, tv_nsec);
1621140481Sps
1622151355Sps		error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32));
1623140481Sps		if (error2)
1624140481Sps			error = error2;
1625140481Sps	}
1626140481Sps	return (error);
1627140481Sps}
1628140481Sps
1629151357Spsint
1630151357Spsfreebsd32_clock_gettime(struct thread *td,
1631151357Sps			struct freebsd32_clock_gettime_args *uap)
1632151357Sps{
1633151357Sps	struct timespec	ats;
1634151357Sps	struct timespec32 ats32;
1635151357Sps	int error;
1636151357Sps
1637151357Sps	error = kern_clock_gettime(td, uap->clock_id, &ats);
1638151357Sps	if (error == 0) {
1639151357Sps		CP(ats, ats32, tv_sec);
1640151357Sps		CP(ats, ats32, tv_nsec);
1641151357Sps		error = copyout(&ats32, uap->tp, sizeof(ats32));
1642151357Sps	}
1643151357Sps	return (error);
1644151357Sps}
1645151357Sps
1646151357Spsint
1647151357Spsfreebsd32_clock_settime(struct thread *td,
1648151357Sps			struct freebsd32_clock_settime_args *uap)
1649151357Sps{
1650151357Sps	struct timespec	ats;
1651151357Sps	struct timespec32 ats32;
1652151357Sps	int error;
1653151357Sps
1654151357Sps	error = copyin(uap->tp, &ats32, sizeof(ats32));
1655151357Sps	if (error)
1656151357Sps		return (error);
1657151357Sps	CP(ats32, ats, tv_sec);
1658151357Sps	CP(ats32, ats, tv_nsec);
1659151357Sps
1660151357Sps	return (kern_clock_settime(td, uap->clock_id, &ats));
1661151357Sps}
1662151357Sps
1663151357Spsint
1664151357Spsfreebsd32_clock_getres(struct thread *td,
1665151357Sps		       struct freebsd32_clock_getres_args *uap)
1666151357Sps{
1667151357Sps	struct timespec	ts;
1668151357Sps	struct timespec32 ts32;
1669151357Sps	int error;
1670151357Sps
1671151357Sps	if (uap->tp == NULL)
1672151357Sps		return (0);
1673151357Sps	error = kern_clock_getres(td, uap->clock_id, &ts);
1674151357Sps	if (error == 0) {
1675151357Sps		CP(ts, ts32, tv_sec);
1676151357Sps		CP(ts, ts32, tv_nsec);
1677151357Sps		error = copyout(&ts32, uap->tp, sizeof(ts32));
1678151357Sps	}
1679151357Sps	return (error);
1680151357Sps}
1681151357Sps
1682100384Speter#if 0
1683100384Speter
1684100384Speterint
1685119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
1686100384Speter{
1687100384Speter	int error;
1688100384Speter	struct yyy32 *p32, s32;
1689100384Speter	struct yyy *p = NULL, s;
1690100384Speter
1691147654Sjhb	if (uap->zzz) {
1692147654Sjhb		error = copyin(uap->zzz, &s32, sizeof(s32));
1693100384Speter		if (error)
1694100384Speter			return (error);
1695100384Speter		/* translate in */
1696147654Sjhb		p = &s;
1697100384Speter	}
1698147654Sjhb	error = kern_xxx(td, p);
1699100384Speter	if (error)
1700100384Speter		return (error);
1701147654Sjhb	if (uap->zzz) {
1702100384Speter		/* translate out */
1703100384Speter		error = copyout(&s32, p32, sizeof(s32));
1704100384Speter	}
1705100384Speter	return (error);
1706100384Speter}
1707100384Speter
1708100384Speter#endif
1709