freebsd32_misc.c revision 174381
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 174381 2007-12-06 23:35:29Z jhb $");
29118031Sobrien
30104738Speter#include "opt_compat.h"
31104738Speter
32100384Speter#include <sys/param.h>
33100384Speter#include <sys/systm.h>
34100384Speter#include <sys/bus.h>
35162954Sphk#include <sys/clock.h>
36100384Speter#include <sys/exec.h>
37100384Speter#include <sys/fcntl.h>
38100384Speter#include <sys/filedesc.h>
39123746Speter#include <sys/namei.h>
40100384Speter#include <sys/imgact.h>
41100384Speter#include <sys/kernel.h>
42161343Sjkim#include <sys/limits.h>
43100384Speter#include <sys/lock.h>
44100384Speter#include <sys/malloc.h>
45100384Speter#include <sys/file.h>		/* Must come after sys/malloc.h */
46151909Sps#include <sys/mbuf.h>
47100384Speter#include <sys/mman.h>
48100384Speter#include <sys/module.h>
49100384Speter#include <sys/mount.h>
50100384Speter#include <sys/mutex.h>
51100384Speter#include <sys/proc.h>
52100384Speter#include <sys/reboot.h>
53100384Speter#include <sys/resource.h>
54100384Speter#include <sys/resourcevar.h>
55100384Speter#include <sys/selinfo.h>
56146950Sps#include <sys/eventvar.h>	/* Must come after sys/selinfo.h */
57100384Speter#include <sys/pipe.h>		/* Must come after sys/selinfo.h */
58100384Speter#include <sys/signal.h>
59100384Speter#include <sys/signalvar.h>
60100384Speter#include <sys/socket.h>
61100384Speter#include <sys/socketvar.h>
62100384Speter#include <sys/stat.h>
63150883Sjhb#include <sys/syscall.h>
64113859Sjhb#include <sys/syscallsubr.h>
65100384Speter#include <sys/sysctl.h>
66100384Speter#include <sys/sysent.h>
67100384Speter#include <sys/sysproto.h>
68162551Sdavidxu#include <sys/thr.h>
69100384Speter#include <sys/unistd.h>
70162551Sdavidxu#include <sys/ucontext.h>
71100384Speter#include <sys/vnode.h>
72127140Sjhb#include <sys/wait.h>
73157285Sps#include <sys/ipc.h>
74174381Sjhb#include <sys/msg.h>
75174381Sjhb#include <sys/sem.h>
76157285Sps#include <sys/shm.h>
77100384Speter
78100384Speter#include <vm/vm.h>
79100384Speter#include <vm/vm_kern.h>
80100384Speter#include <vm/vm_param.h>
81100384Speter#include <vm/pmap.h>
82100384Speter#include <vm/vm_map.h>
83100384Speter#include <vm/vm_object.h>
84100384Speter#include <vm/vm_extern.h>
85100384Speter
86151582Sps#include <machine/cpu.h>
87151582Sps
88119333Speter#include <compat/freebsd32/freebsd32_util.h>
89119333Speter#include <compat/freebsd32/freebsd32.h>
90174380Sjhb#include <compat/freebsd32/freebsd32_ipc.h>
91163018Sdavidxu#include <compat/freebsd32/freebsd32_signal.h>
92119333Speter#include <compat/freebsd32/freebsd32_proto.h>
93100384Speter
94121719SpeterCTASSERT(sizeof(struct timeval32) == 8);
95121719SpeterCTASSERT(sizeof(struct timespec32) == 8);
96174377SjhbCTASSERT(sizeof(struct itimerval32) == 16);
97121719SpeterCTASSERT(sizeof(struct statfs32) == 256);
98121719SpeterCTASSERT(sizeof(struct rusage32) == 72);
99174377SjhbCTASSERT(sizeof(struct sigaltstack32) == 12);
100174377SjhbCTASSERT(sizeof(struct kevent32) == 20);
101174377SjhbCTASSERT(sizeof(struct iovec32) == 8);
102174377SjhbCTASSERT(sizeof(struct msghdr32) == 28);
103174377SjhbCTASSERT(sizeof(struct stat32) == 96);
104174377SjhbCTASSERT(sizeof(struct sigaction32) == 24);
105121719Speter
106174377Sjhbstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
107174377Sjhbstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
108174377Sjhb
109100384Speterint
110119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
111100384Speter{
112127140Sjhb	int error, status;
113127140Sjhb	struct rusage32 ru32;
114136152Sjhb	struct rusage ru, *rup;
115100384Speter
116136152Sjhb	if (uap->rusage != NULL)
117136152Sjhb		rup = &ru;
118136152Sjhb	else
119136152Sjhb		rup = NULL;
120136152Sjhb	error = kern_wait(td, uap->pid, &status, uap->options, rup);
121100384Speter	if (error)
122100384Speter		return (error);
123127140Sjhb	if (uap->status != NULL)
124127140Sjhb		error = copyout(&status, uap->status, sizeof(status));
125127140Sjhb	if (uap->rusage != NULL && error == 0) {
126100384Speter		TV_CP(ru, ru32, ru_utime);
127100384Speter		TV_CP(ru, ru32, ru_stime);
128100384Speter		CP(ru, ru32, ru_maxrss);
129100384Speter		CP(ru, ru32, ru_ixrss);
130100384Speter		CP(ru, ru32, ru_idrss);
131100384Speter		CP(ru, ru32, ru_isrss);
132100384Speter		CP(ru, ru32, ru_minflt);
133100384Speter		CP(ru, ru32, ru_majflt);
134100384Speter		CP(ru, ru32, ru_nswap);
135100384Speter		CP(ru, ru32, ru_inblock);
136100384Speter		CP(ru, ru32, ru_oublock);
137100384Speter		CP(ru, ru32, ru_msgsnd);
138100384Speter		CP(ru, ru32, ru_msgrcv);
139100384Speter		CP(ru, ru32, ru_nsignals);
140100384Speter		CP(ru, ru32, ru_nvcsw);
141100384Speter		CP(ru, ru32, ru_nivcsw);
142127140Sjhb		error = copyout(&ru32, uap->rusage, sizeof(ru32));
143100384Speter	}
144100384Speter	return (error);
145100384Speter}
146100384Speter
147128597Smarcel#ifdef COMPAT_FREEBSD4
148174377Sjhbstatic int
149100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out)
150100384Speter{
151174377Sjhb	int error;
152172003Sjhb
153174377Sjhb	error = statfs_scale_blocks(in, INT32_MAX);
154174377Sjhb	if (error)
155174377Sjhb		return (error);
156156266Sps	bzero(out, sizeof(*out));
157100384Speter	CP(*in, *out, f_bsize);
158172003Sjhb	out->f_iosize = MIN(in->f_iosize, INT32_MAX);
159100384Speter	CP(*in, *out, f_blocks);
160100384Speter	CP(*in, *out, f_bfree);
161100384Speter	CP(*in, *out, f_bavail);
162172003Sjhb	out->f_files = MIN(in->f_files, INT32_MAX);
163174377Sjhb	if (in->f_ffree < 0)
164174377Sjhb		out->f_ffree = MAX(in->f_ffree, INT32_MIN);
165174377Sjhb	else
166174377Sjhb		out->f_ffree = MIN(in->f_ffree, INT32_MAX);
167100384Speter	CP(*in, *out, f_fsid);
168100384Speter	CP(*in, *out, f_owner);
169100384Speter	CP(*in, *out, f_type);
170100384Speter	CP(*in, *out, f_flags);
171174377Sjhb	CP(*in, *out, f_syncwrites);
172174377Sjhb	CP(*in, *out, f_asyncwrites);
173156266Sps	strlcpy(out->f_fstypename,
174156266Sps	      in->f_fstypename, MFSNAMELEN);
175156266Sps	strlcpy(out->f_mntonname,
176156266Sps	      in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
177174377Sjhb	CP(*in, *out, f_syncreads);
178174377Sjhb	CP(*in, *out, f_asyncreads);
179156266Sps	strlcpy(out->f_mntfromname,
180156266Sps	      in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
181174377Sjhb	return (0);
182100384Speter}
183128597Smarcel#endif
184100384Speter
185128597Smarcel#ifdef COMPAT_FREEBSD4
186100384Speterint
187128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
188100384Speter{
189147178Spjd	struct statfs *buf, *sp;
190147178Spjd	struct statfs32 stat32;
191147178Spjd	size_t count, size;
192100384Speter	int error;
193100384Speter
194147178Spjd	count = uap->bufsize / sizeof(struct statfs32);
195147178Spjd	size = count * sizeof(struct statfs);
196147302Spjd	error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
197147302Spjd	if (size > 0) {
198100384Speter		count = td->td_retval[0];
199147178Spjd		sp = buf;
200147178Spjd		while (count > 0 && error == 0) {
201174377Sjhb			error = copy_statfs(sp, &stat32);
202174377Sjhb			if (error)
203174377Sjhb				break;
204147178Spjd			error = copyout(&stat32, uap->buf, sizeof(stat32));
205147178Spjd			sp++;
206147178Spjd			uap->buf++;
207147178Spjd			count--;
208100384Speter		}
209147178Spjd		free(buf, M_TEMP);
210100384Speter	}
211100384Speter	return (error);
212100384Speter}
213128597Smarcel#endif
214100384Speter
215100384Speterint
216119333Speterfreebsd32_sigaltstack(struct thread *td,
217119333Speter		      struct freebsd32_sigaltstack_args *uap)
218100384Speter{
219113859Sjhb	struct sigaltstack32 s32;
220113859Sjhb	struct sigaltstack ss, oss, *ssp;
221100384Speter	int error;
222100384Speter
223113859Sjhb	if (uap->ss != NULL) {
224113859Sjhb		error = copyin(uap->ss, &s32, sizeof(s32));
225100384Speter		if (error)
226100384Speter			return (error);
227113859Sjhb		PTRIN_CP(s32, ss, ss_sp);
228113859Sjhb		CP(s32, ss, ss_size);
229113859Sjhb		CP(s32, ss, ss_flags);
230113859Sjhb		ssp = &ss;
231113859Sjhb	} else
232113859Sjhb		ssp = NULL;
233113859Sjhb	error = kern_sigaltstack(td, ssp, &oss);
234113859Sjhb	if (error == 0 && uap->oss != NULL) {
235113859Sjhb		PTROUT_CP(oss, s32, ss_sp);
236113859Sjhb		CP(oss, s32, ss_size);
237113859Sjhb		CP(oss, s32, ss_flags);
238113859Sjhb		error = copyout(&s32, uap->oss, sizeof(s32));
239100384Speter	}
240100384Speter	return (error);
241100384Speter}
242100384Speter
243142059Sjhb/*
244142059Sjhb * Custom version of exec_copyin_args() so that we can translate
245142059Sjhb * the pointers.
246142059Sjhb */
247142059Sjhbstatic int
248142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname,
249142059Sjhb    enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
250100384Speter{
251142059Sjhb	char *argp, *envp;
252142059Sjhb	u_int32_t *p32, arg;
253142059Sjhb	size_t length;
254100384Speter	int error;
255100384Speter
256142059Sjhb	bzero(args, sizeof(*args));
257142059Sjhb	if (argv == NULL)
258142059Sjhb		return (EFAULT);
259100384Speter
260142059Sjhb	/*
261142059Sjhb	 * Allocate temporary demand zeroed space for argument and
262142059Sjhb	 *	environment strings
263142059Sjhb	 */
264147588Sjhb	args->buf = (char *) kmem_alloc_wait(exec_map,
265147588Sjhb	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
266142059Sjhb	if (args->buf == NULL)
267142059Sjhb		return (ENOMEM);
268142059Sjhb	args->begin_argv = args->buf;
269142059Sjhb	args->endp = args->begin_argv;
270142059Sjhb	args->stringspace = ARG_MAX;
271142059Sjhb
272142059Sjhb	args->fname = args->buf + ARG_MAX;
273142059Sjhb
274142059Sjhb	/*
275142059Sjhb	 * Copy the file name.
276142059Sjhb	 */
277142059Sjhb	error = (segflg == UIO_SYSSPACE) ?
278142059Sjhb	    copystr(fname, args->fname, PATH_MAX, &length) :
279142059Sjhb	    copyinstr(fname, args->fname, PATH_MAX, &length);
280142059Sjhb	if (error != 0)
281156440Sups		goto err_exit;
282142059Sjhb
283142059Sjhb	/*
284142059Sjhb	 * extract arguments first
285142059Sjhb	 */
286142059Sjhb	p32 = argv;
287142059Sjhb	for (;;) {
288142059Sjhb		error = copyin(p32++, &arg, sizeof(arg));
289142059Sjhb		if (error)
290156440Sups			goto err_exit;
291142059Sjhb		if (arg == 0)
292142059Sjhb			break;
293142059Sjhb		argp = PTRIN(arg);
294142059Sjhb		error = copyinstr(argp, args->endp, args->stringspace, &length);
295142059Sjhb		if (error) {
296142059Sjhb			if (error == ENAMETOOLONG)
297156440Sups				error = E2BIG;
298156440Sups			goto err_exit;
299142059Sjhb		}
300142059Sjhb		args->stringspace -= length;
301142059Sjhb		args->endp += length;
302142059Sjhb		args->argc++;
303100384Speter	}
304142059Sjhb
305142059Sjhb	args->begin_envv = args->endp;
306142059Sjhb
307142059Sjhb	/*
308142059Sjhb	 * extract environment strings
309142059Sjhb	 */
310142059Sjhb	if (envv) {
311142059Sjhb		p32 = envv;
312142059Sjhb		for (;;) {
313100384Speter			error = copyin(p32++, &arg, sizeof(arg));
314100384Speter			if (error)
315156440Sups				goto err_exit;
316142059Sjhb			if (arg == 0)
317142059Sjhb				break;
318142059Sjhb			envp = PTRIN(arg);
319142059Sjhb			error = copyinstr(envp, args->endp, args->stringspace,
320142059Sjhb			    &length);
321142059Sjhb			if (error) {
322142059Sjhb				if (error == ENAMETOOLONG)
323156440Sups					error = E2BIG;
324156440Sups				goto err_exit;
325142059Sjhb			}
326142059Sjhb			args->stringspace -= length;
327142059Sjhb			args->endp += length;
328142059Sjhb			args->envc++;
329142059Sjhb		}
330100384Speter	}
331100384Speter
332142059Sjhb	return (0);
333156440Sups
334156440Supserr_exit:
335156440Sups	kmem_free_wakeup(exec_map, (vm_offset_t)args->buf,
336156440Sups	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
337156440Sups	args->buf = NULL;
338156440Sups	return (error);
339100384Speter}
340100384Speter
341142059Sjhbint
342142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
343142059Sjhb{
344142059Sjhb	struct image_args eargs;
345142059Sjhb	int error;
346142059Sjhb
347142059Sjhb	error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
348142059Sjhb	    uap->argv, uap->envv);
349142059Sjhb	if (error == 0)
350142059Sjhb		error = kern_execve(td, &eargs, NULL);
351142059Sjhb	return (error);
352142059Sjhb}
353142059Sjhb
354114987Speter#ifdef __ia64__
355100384Speterstatic int
356119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
357119333Speter		       int prot, int fd, off_t pos)
358100384Speter{
359100384Speter	vm_map_t map;
360100384Speter	vm_map_entry_t entry;
361100384Speter	int rv;
362100384Speter
363100384Speter	map = &td->td_proc->p_vmspace->vm_map;
364100384Speter	if (fd != -1)
365100384Speter		prot |= VM_PROT_WRITE;
366100384Speter
367100384Speter	if (vm_map_lookup_entry(map, start, &entry)) {
368100384Speter		if ((entry->protection & prot) != prot) {
369100384Speter			rv = vm_map_protect(map,
370100384Speter					    trunc_page(start),
371100384Speter					    round_page(end),
372100384Speter					    entry->protection | prot,
373100384Speter					    FALSE);
374100384Speter			if (rv != KERN_SUCCESS)
375100384Speter				return (EINVAL);
376100384Speter		}
377100384Speter	} else {
378100384Speter		vm_offset_t addr = trunc_page(start);
379100384Speter		rv = vm_map_find(map, 0, 0,
380100384Speter				 &addr, PAGE_SIZE, FALSE, prot,
381100384Speter				 VM_PROT_ALL, 0);
382100384Speter		if (rv != KERN_SUCCESS)
383100384Speter			return (EINVAL);
384100384Speter	}
385100384Speter
386100384Speter	if (fd != -1) {
387100384Speter		struct pread_args r;
388107849Salfred		r.fd = fd;
389107849Salfred		r.buf = (void *) start;
390107849Salfred		r.nbyte = end - start;
391107849Salfred		r.offset = pos;
392100384Speter		return (pread(td, &r));
393100384Speter	} else {
394100384Speter		while (start < end) {
395100384Speter			subyte((void *) start, 0);
396100384Speter			start++;
397100384Speter		}
398100384Speter		return (0);
399100384Speter	}
400100384Speter}
401114987Speter#endif
402100384Speter
403100384Speterint
404119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
405100384Speter{
406100384Speter	struct mmap_args ap;
407107849Salfred	vm_offset_t addr = (vm_offset_t) uap->addr;
408107849Salfred	vm_size_t len	 = uap->len;
409107849Salfred	int prot	 = uap->prot;
410107849Salfred	int flags	 = uap->flags;
411107849Salfred	int fd		 = uap->fd;
412107849Salfred	off_t pos	 = (uap->poslo
413107849Salfred			    | ((off_t)uap->poshi << 32));
414114987Speter#ifdef __ia64__
415100384Speter	vm_size_t pageoff;
416100384Speter	int error;
417100384Speter
418100384Speter	/*
419100384Speter	 * Attempt to handle page size hassles.
420100384Speter	 */
421100384Speter	pageoff = (pos & PAGE_MASK);
422100384Speter	if (flags & MAP_FIXED) {
423100384Speter		vm_offset_t start, end;
424100384Speter		start = addr;
425100384Speter		end = addr + len;
426100384Speter
427100384Speter		if (start != trunc_page(start)) {
428119333Speter			error = freebsd32_mmap_partial(td, start,
429119333Speter						       round_page(start), prot,
430119333Speter						       fd, pos);
431100384Speter			if (fd != -1)
432100384Speter				pos += round_page(start) - start;
433100384Speter			start = round_page(start);
434100384Speter		}
435100384Speter		if (end != round_page(end)) {
436100384Speter			vm_offset_t t = trunc_page(end);
437119333Speter			error = freebsd32_mmap_partial(td, t, end,
438100384Speter						  prot, fd,
439100384Speter						  pos + t - start);
440100384Speter			end = trunc_page(end);
441100384Speter		}
442100384Speter		if (end > start && fd != -1 && (pos & PAGE_MASK)) {
443100384Speter			/*
444100384Speter			 * We can't map this region at all. The specified
445100384Speter			 * address doesn't have the same alignment as the file
446100384Speter			 * position. Fake the mapping by simply reading the
447100384Speter			 * entire region into memory. First we need to make
448100384Speter			 * sure the region exists.
449100384Speter			 */
450100384Speter			vm_map_t map;
451100384Speter			struct pread_args r;
452100384Speter			int rv;
453100384Speter
454100384Speter			prot |= VM_PROT_WRITE;
455100384Speter			map = &td->td_proc->p_vmspace->vm_map;
456100384Speter			rv = vm_map_remove(map, start, end);
457169181Salc			if (rv != KERN_SUCCESS)
458100384Speter				return (EINVAL);
459100384Speter			rv = vm_map_find(map, 0, 0,
460100384Speter					 &start, end - start, FALSE,
461100384Speter					 prot, VM_PROT_ALL, 0);
462100384Speter			if (rv != KERN_SUCCESS)
463100384Speter				return (EINVAL);
464107849Salfred			r.fd = fd;
465107849Salfred			r.buf = (void *) start;
466107849Salfred			r.nbyte = end - start;
467107849Salfred			r.offset = pos;
468100384Speter			error = pread(td, &r);
469100384Speter			if (error)
470100384Speter				return (error);
471100384Speter
472100384Speter			td->td_retval[0] = addr;
473100384Speter			return (0);
474100384Speter		}
475100384Speter		if (end == start) {
476100384Speter			/*
477100384Speter			 * After dealing with the ragged ends, there
478100384Speter			 * might be none left.
479100384Speter			 */
480100384Speter			td->td_retval[0] = addr;
481100384Speter			return (0);
482100384Speter		}
483100384Speter		addr = start;
484100384Speter		len = end - start;
485100384Speter	}
486114987Speter#endif
487100384Speter
488107849Salfred	ap.addr = (void *) addr;
489107849Salfred	ap.len = len;
490107849Salfred	ap.prot = prot;
491107849Salfred	ap.flags = flags;
492107849Salfred	ap.fd = fd;
493107849Salfred	ap.pos = pos;
494100384Speter
495100384Speter	return (mmap(td, &ap));
496100384Speter}
497100384Speter
498171215Speter#ifdef COMPAT_FREEBSD6
499171215Speterint
500171215Speterfreebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *uap)
501171215Speter{
502171215Speter	struct freebsd32_mmap_args ap;
503171215Speter
504171215Speter	ap.addr = uap->addr;
505171215Speter	ap.len = uap->len;
506171215Speter	ap.prot = uap->prot;
507171215Speter	ap.flags = uap->flags;
508171215Speter	ap.fd = uap->fd;
509171215Speter	ap.poslo = uap->poslo;
510171215Speter	ap.poshi = uap->poshi;
511171215Speter
512171215Speter	return (freebsd32_mmap(td, &ap));
513171215Speter}
514171215Speter#endif
515171215Speter
516100384Speterint
517119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
518100384Speter{
519142059Sjhb	struct itimerval itv, oitv, *itvp;
520142059Sjhb	struct itimerval32 i32;
521100384Speter	int error;
522100384Speter
523142059Sjhb	if (uap->itv != NULL) {
524142059Sjhb		error = copyin(uap->itv, &i32, sizeof(i32));
525100384Speter		if (error)
526100384Speter			return (error);
527142059Sjhb		TV_CP(i32, itv, it_interval);
528142059Sjhb		TV_CP(i32, itv, it_value);
529142059Sjhb		itvp = &itv;
530142059Sjhb	} else
531142059Sjhb		itvp = NULL;
532142059Sjhb	error = kern_setitimer(td, uap->which, itvp, &oitv);
533142059Sjhb	if (error || uap->oitv == NULL)
534100384Speter		return (error);
535142059Sjhb	TV_CP(oitv, i32, it_interval);
536142059Sjhb	TV_CP(oitv, i32, it_value);
537142059Sjhb	return (copyout(&i32, uap->oitv, sizeof(i32)));
538100384Speter}
539100384Speter
540100384Speterint
541125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
542125171Speter{
543142059Sjhb	struct itimerval itv;
544142059Sjhb	struct itimerval32 i32;
545125171Speter	int error;
546125171Speter
547142059Sjhb	error = kern_getitimer(td, uap->which, &itv);
548142059Sjhb	if (error || uap->itv == NULL)
549125171Speter		return (error);
550142059Sjhb	TV_CP(itv, i32, it_interval);
551142059Sjhb	TV_CP(itv, i32, it_value);
552142059Sjhb	return (copyout(&i32, uap->itv, sizeof(i32)));
553125171Speter}
554125171Speter
555125171Speterint
556119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
557100384Speter{
558142059Sjhb	struct timeval32 tv32;
559142059Sjhb	struct timeval tv, *tvp;
560100384Speter	int error;
561100384Speter
562142059Sjhb	if (uap->tv != NULL) {
563142059Sjhb		error = copyin(uap->tv, &tv32, sizeof(tv32));
564100384Speter		if (error)
565100384Speter			return (error);
566142059Sjhb		CP(tv32, tv, tv_sec);
567142059Sjhb		CP(tv32, tv, tv_usec);
568142059Sjhb		tvp = &tv;
569142059Sjhb	} else
570142059Sjhb		tvp = NULL;
571100384Speter	/*
572100384Speter	 * XXX big-endian needs to convert the fd_sets too.
573142059Sjhb	 * XXX Do pointers need PTRIN()?
574100384Speter	 */
575142059Sjhb	return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp));
576100384Speter}
577100384Speter
578146950Sps/*
579146950Sps * Copy 'count' items into the destination list pointed to by uap->eventlist.
580146950Sps */
581146950Spsstatic int
582146950Spsfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
583146950Sps{
584146950Sps	struct freebsd32_kevent_args *uap;
585146950Sps	struct kevent32	ks32[KQ_NEVENTS];
586146950Sps	int i, error = 0;
587146950Sps
588146950Sps	KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
589146950Sps	uap = (struct freebsd32_kevent_args *)arg;
590146950Sps
591146950Sps	for (i = 0; i < count; i++) {
592146950Sps		CP(kevp[i], ks32[i], ident);
593146950Sps		CP(kevp[i], ks32[i], filter);
594146950Sps		CP(kevp[i], ks32[i], flags);
595146950Sps		CP(kevp[i], ks32[i], fflags);
596146950Sps		CP(kevp[i], ks32[i], data);
597146950Sps		PTROUT_CP(kevp[i], ks32[i], udata);
598146950Sps	}
599146950Sps	error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
600146950Sps	if (error == 0)
601146950Sps		uap->eventlist += count;
602146950Sps	return (error);
603146950Sps}
604146950Sps
605146950Sps/*
606146950Sps * Copy 'count' items from the list pointed to by uap->changelist.
607146950Sps */
608146950Spsstatic int
609146950Spsfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
610146950Sps{
611146950Sps	struct freebsd32_kevent_args *uap;
612146950Sps	struct kevent32	ks32[KQ_NEVENTS];
613146950Sps	int i, error = 0;
614146950Sps
615146950Sps	KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
616146950Sps	uap = (struct freebsd32_kevent_args *)arg;
617146950Sps
618146950Sps	error = copyin(uap->changelist, ks32, count * sizeof *ks32);
619146950Sps	if (error)
620146950Sps		goto done;
621146950Sps	uap->changelist += count;
622146950Sps
623146950Sps	for (i = 0; i < count; i++) {
624146950Sps		CP(ks32[i], kevp[i], ident);
625146950Sps		CP(ks32[i], kevp[i], filter);
626146950Sps		CP(ks32[i], kevp[i], flags);
627146950Sps		CP(ks32[i], kevp[i], fflags);
628146950Sps		CP(ks32[i], kevp[i], data);
629146950Sps		PTRIN_CP(ks32[i], kevp[i], udata);
630146950Sps	}
631146950Spsdone:
632146950Sps	return (error);
633146950Sps}
634146950Sps
635100384Speterint
636119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
637114987Speter{
638114987Speter	struct timespec32 ts32;
639142934Sps	struct timespec ts, *tsp;
640146950Sps	struct kevent_copyops k_ops = { uap,
641146950Sps					freebsd32_kevent_copyout,
642146950Sps					freebsd32_kevent_copyin};
643146950Sps	int error;
644114987Speter
645114987Speter
646114987Speter	if (uap->timeout) {
647114987Speter		error = copyin(uap->timeout, &ts32, sizeof(ts32));
648114987Speter		if (error)
649114987Speter			return (error);
650114987Speter		CP(ts32, ts, tv_sec);
651114987Speter		CP(ts32, ts, tv_nsec);
652142934Sps		tsp = &ts;
653142934Sps	} else
654142934Sps		tsp = NULL;
655146950Sps	error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
656146950Sps	    &k_ops, tsp);
657142934Sps	return (error);
658114987Speter}
659114987Speter
660114987Speterint
661119333Speterfreebsd32_gettimeofday(struct thread *td,
662119333Speter		       struct freebsd32_gettimeofday_args *uap)
663100384Speter{
664123425Speter	struct timeval atv;
665123425Speter	struct timeval32 atv32;
666123425Speter	struct timezone rtz;
667123425Speter	int error = 0;
668100384Speter
669123425Speter	if (uap->tp) {
670123425Speter		microtime(&atv);
671123425Speter		CP(atv, atv32, tv_sec);
672123425Speter		CP(atv, atv32, tv_usec);
673123425Speter		error = copyout(&atv32, uap->tp, sizeof (atv32));
674100384Speter	}
675123425Speter	if (error == 0 && uap->tzp != NULL) {
676123425Speter		rtz.tz_minuteswest = tz_minuteswest;
677123425Speter		rtz.tz_dsttime = tz_dsttime;
678123425Speter		error = copyout(&rtz, uap->tzp, sizeof (rtz));
679100384Speter	}
680100384Speter	return (error);
681100384Speter}
682100384Speter
683100384Speterint
684119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
685100384Speter{
686136152Sjhb	struct rusage32 s32;
687136152Sjhb	struct rusage s;
688100384Speter	int error;
689100384Speter
690136152Sjhb	error = kern_getrusage(td, uap->who, &s);
691100384Speter	if (error)
692100384Speter		return (error);
693136152Sjhb	if (uap->rusage != NULL) {
694100384Speter		TV_CP(s, s32, ru_utime);
695100384Speter		TV_CP(s, s32, ru_stime);
696100384Speter		CP(s, s32, ru_maxrss);
697100384Speter		CP(s, s32, ru_ixrss);
698100384Speter		CP(s, s32, ru_idrss);
699100384Speter		CP(s, s32, ru_isrss);
700100384Speter		CP(s, s32, ru_minflt);
701100384Speter		CP(s, s32, ru_majflt);
702100384Speter		CP(s, s32, ru_nswap);
703100384Speter		CP(s, s32, ru_inblock);
704100384Speter		CP(s, s32, ru_oublock);
705100384Speter		CP(s, s32, ru_msgsnd);
706100384Speter		CP(s, s32, ru_msgrcv);
707100384Speter		CP(s, s32, ru_nsignals);
708100384Speter		CP(s, s32, ru_nvcsw);
709100384Speter		CP(s, s32, ru_nivcsw);
710136152Sjhb		error = copyout(&s32, uap->rusage, sizeof(s32));
711100384Speter	}
712100384Speter	return (error);
713100384Speter}
714100384Speter
715144450Sjhbstatic int
716144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
717100384Speter{
718144450Sjhb	struct iovec32 iov32;
719144450Sjhb	struct iovec *iov;
720144450Sjhb	struct uio *uio;
721144450Sjhb	u_int iovlen;
722144450Sjhb	int error, i;
723100384Speter
724144450Sjhb	*uiop = NULL;
725144450Sjhb	if (iovcnt > UIO_MAXIOV)
726100384Speter		return (EINVAL);
727144450Sjhb	iovlen = iovcnt * sizeof(struct iovec);
728144450Sjhb	uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
729144450Sjhb	iov = (struct iovec *)(uio + 1);
730144450Sjhb	for (i = 0; i < iovcnt; i++) {
731144450Sjhb		error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
732144450Sjhb		if (error) {
733144450Sjhb			free(uio, M_IOV);
734144450Sjhb			return (error);
735144450Sjhb		}
736144450Sjhb		iov[i].iov_base = PTRIN(iov32.iov_base);
737144450Sjhb		iov[i].iov_len = iov32.iov_len;
738100384Speter	}
739144450Sjhb	uio->uio_iov = iov;
740144450Sjhb	uio->uio_iovcnt = iovcnt;
741144450Sjhb	uio->uio_segflg = UIO_USERSPACE;
742144450Sjhb	uio->uio_offset = -1;
743144450Sjhb	uio->uio_resid = 0;
744144450Sjhb	for (i = 0; i < iovcnt; i++) {
745144450Sjhb		if (iov->iov_len > INT_MAX - uio->uio_resid) {
746144450Sjhb			free(uio, M_IOV);
747144450Sjhb			return (EINVAL);
748144450Sjhb		}
749144450Sjhb		uio->uio_resid += iov->iov_len;
750144450Sjhb		iov++;
751144450Sjhb	}
752144450Sjhb	*uiop = uio;
753144450Sjhb	return (0);
754144450Sjhb}
755100384Speter
756144450Sjhbint
757144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
758144450Sjhb{
759144450Sjhb	struct uio *auio;
760144450Sjhb	int error;
761100384Speter
762144450Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
763144450Sjhb	if (error)
764144450Sjhb		return (error);
765144450Sjhb	error = kern_readv(td, uap->fd, auio);
766144450Sjhb	free(auio, M_IOV);
767100384Speter	return (error);
768100384Speter}
769100384Speter
770100384Speterint
771119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
772100384Speter{
773144450Sjhb	struct uio *auio;
774144450Sjhb	int error;
775100384Speter
776144450Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
777144450Sjhb	if (error)
778144450Sjhb		return (error);
779144450Sjhb	error = kern_writev(td, uap->fd, auio);
780144450Sjhb	free(auio, M_IOV);
781100384Speter	return (error);
782100384Speter}
783100384Speter
784100384Speterint
785147813Sjhbfreebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
786147813Sjhb{
787147813Sjhb	struct uio *auio;
788147813Sjhb	int error;
789147813Sjhb
790147813Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
791147813Sjhb	if (error)
792147813Sjhb		return (error);
793147813Sjhb	error = kern_preadv(td, uap->fd, auio, uap->offset);
794147813Sjhb	free(auio, M_IOV);
795147813Sjhb	return (error);
796147813Sjhb}
797147813Sjhb
798147813Sjhbint
799147813Sjhbfreebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
800147813Sjhb{
801147813Sjhb	struct uio *auio;
802147813Sjhb	int error;
803147813Sjhb
804147813Sjhb	error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
805147813Sjhb	if (error)
806147813Sjhb		return (error);
807147813Sjhb	error = kern_pwritev(td, uap->fd, auio, uap->offset);
808147813Sjhb	free(auio, M_IOV);
809147813Sjhb	return (error);
810147813Sjhb}
811147813Sjhb
812151359Spsstatic int
813151909Spsfreebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
814151359Sps    int error)
815151359Sps{
816151359Sps	struct iovec32 iov32;
817151909Sps	struct iovec *iov;
818151909Sps	u_int iovlen;
819151359Sps	int i;
820151359Sps
821151909Sps	*iovp = NULL;
822151359Sps	if (iovcnt > UIO_MAXIOV)
823151359Sps		return (error);
824151359Sps	iovlen = iovcnt * sizeof(struct iovec);
825151909Sps	iov = malloc(iovlen, M_IOV, M_WAITOK);
826151359Sps	for (i = 0; i < iovcnt; i++) {
827151909Sps		error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
828151359Sps		if (error) {
829151909Sps			free(iov, M_IOV);
830151359Sps			return (error);
831151359Sps		}
832151909Sps		iov[i].iov_base = PTRIN(iov32.iov_base);
833151909Sps		iov[i].iov_len = iov32.iov_len;
834151359Sps	}
835151909Sps	*iovp = iov;
836151359Sps	return (0);
837151359Sps}
838151359Sps
839151359Spsstatic int
840151359Spsfreebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg)
841151359Sps{
842151359Sps	struct msghdr32 m32;
843151359Sps	int error;
844151359Sps
845151359Sps	error = copyin(msg32, &m32, sizeof(m32));
846151359Sps	if (error)
847151359Sps		return (error);
848151359Sps	msg->msg_name = PTRIN(m32.msg_name);
849151359Sps	msg->msg_namelen = m32.msg_namelen;
850151359Sps	msg->msg_iov = PTRIN(m32.msg_iov);
851151359Sps	msg->msg_iovlen = m32.msg_iovlen;
852151359Sps	msg->msg_control = PTRIN(m32.msg_control);
853151359Sps	msg->msg_controllen = m32.msg_controllen;
854151359Sps	msg->msg_flags = m32.msg_flags;
855151909Sps	return (0);
856151359Sps}
857151359Sps
858151359Spsstatic int
859151359Spsfreebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
860151359Sps{
861151359Sps	struct msghdr32 m32;
862151359Sps	int error;
863151359Sps
864151359Sps	m32.msg_name = PTROUT(msg->msg_name);
865151359Sps	m32.msg_namelen = msg->msg_namelen;
866151359Sps	m32.msg_iov = PTROUT(msg->msg_iov);
867151359Sps	m32.msg_iovlen = msg->msg_iovlen;
868151359Sps	m32.msg_control = PTROUT(msg->msg_control);
869151359Sps	m32.msg_controllen = msg->msg_controllen;
870151359Sps	m32.msg_flags = msg->msg_flags;
871151359Sps	error = copyout(&m32, msg32, sizeof(m32));
872151359Sps	return (error);
873151359Sps}
874151359Sps
875151909Sps#define FREEBSD32_ALIGNBYTES	(sizeof(int) - 1)
876151909Sps#define FREEBSD32_ALIGN(p)	\
877151909Sps	(((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES)
878151909Sps#define	FREEBSD32_CMSG_SPACE(l)	\
879151909Sps	(FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l))
880151909Sps
881151909Sps#define	FREEBSD32_CMSG_DATA(cmsg)	((unsigned char *)(cmsg) + \
882151909Sps				 FREEBSD32_ALIGN(sizeof(struct cmsghdr)))
883151909Spsstatic int
884151909Spsfreebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
885151909Sps{
886151909Sps	struct cmsghdr *cm;
887151909Sps	void *data;
888151909Sps	socklen_t clen, datalen;
889151909Sps	int error;
890151909Sps	caddr_t ctlbuf;
891151909Sps	int len, maxlen, copylen;
892151909Sps	struct mbuf *m;
893151909Sps	error = 0;
894151909Sps
895151909Sps	len    = msg->msg_controllen;
896151909Sps	maxlen = msg->msg_controllen;
897151909Sps	msg->msg_controllen = 0;
898151909Sps
899151909Sps	m = control;
900151909Sps	ctlbuf = msg->msg_control;
901151909Sps
902151909Sps	while (m && len > 0) {
903151909Sps		cm = mtod(m, struct cmsghdr *);
904151909Sps		clen = m->m_len;
905151909Sps
906151909Sps		while (cm != NULL) {
907151909Sps
908151909Sps			if (sizeof(struct cmsghdr) > clen ||
909151909Sps			    cm->cmsg_len > clen) {
910151909Sps				error = EINVAL;
911151909Sps				break;
912151909Sps			}
913151909Sps
914151909Sps			data   = CMSG_DATA(cm);
915151909Sps			datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
916151909Sps
917151909Sps			/* Adjust message length */
918151909Sps			cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) +
919151909Sps			    datalen;
920151909Sps
921151909Sps
922151909Sps			/* Copy cmsghdr */
923151909Sps			copylen = sizeof(struct cmsghdr);
924151909Sps			if (len < copylen) {
925151909Sps				msg->msg_flags |= MSG_CTRUNC;
926151909Sps				copylen = len;
927151909Sps			}
928151909Sps
929151909Sps			error = copyout(cm,ctlbuf,copylen);
930151909Sps			if (error)
931151909Sps				goto exit;
932151909Sps
933151909Sps			ctlbuf += FREEBSD32_ALIGN(copylen);
934151909Sps			len    -= FREEBSD32_ALIGN(copylen);
935151909Sps
936151909Sps			if (len <= 0)
937151909Sps				break;
938151909Sps
939151909Sps			/* Copy data */
940151909Sps			copylen = datalen;
941151909Sps			if (len < copylen) {
942151909Sps				msg->msg_flags |= MSG_CTRUNC;
943151909Sps				copylen = len;
944151909Sps			}
945151909Sps
946151909Sps			error = copyout(data,ctlbuf,copylen);
947151909Sps			if (error)
948151909Sps				goto exit;
949151909Sps
950151909Sps			ctlbuf += FREEBSD32_ALIGN(copylen);
951151909Sps			len    -= FREEBSD32_ALIGN(copylen);
952151909Sps
953151909Sps			if (CMSG_SPACE(datalen) < clen) {
954151909Sps				clen -= CMSG_SPACE(datalen);
955151909Sps				cm = (struct cmsghdr *)
956151909Sps					((caddr_t)cm + CMSG_SPACE(datalen));
957151909Sps			} else {
958151909Sps				clen = 0;
959151909Sps				cm = NULL;
960151909Sps			}
961151909Sps		}
962151909Sps		m = m->m_next;
963151909Sps	}
964151909Sps
965151909Sps	msg->msg_controllen = (len <= 0) ? maxlen :  ctlbuf - (caddr_t)msg->msg_control;
966151909Sps
967151909Spsexit:
968151909Sps	return (error);
969151909Sps
970151909Sps}
971151909Sps
972147813Sjhbint
973151359Spsfreebsd32_recvmsg(td, uap)
974151359Sps	struct thread *td;
975151359Sps	struct freebsd32_recvmsg_args /* {
976151359Sps		int	s;
977151359Sps		struct	msghdr32 *msg;
978151359Sps		int	flags;
979151359Sps	} */ *uap;
980151359Sps{
981151359Sps	struct msghdr msg;
982151359Sps	struct msghdr32 m32;
983151359Sps	struct iovec *uiov, *iov;
984151909Sps	struct mbuf *control = NULL;
985151909Sps	struct mbuf **controlp;
986151909Sps
987151359Sps	int error;
988151359Sps	error = copyin(uap->msg, &m32, sizeof(m32));
989151359Sps	if (error)
990151359Sps		return (error);
991151359Sps	error = freebsd32_copyinmsghdr(uap->msg, &msg);
992151359Sps	if (error)
993151359Sps		return (error);
994160246Sjhb	error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
995160246Sjhb	    EMSGSIZE);
996151359Sps	if (error)
997151359Sps		return (error);
998151359Sps	msg.msg_flags = uap->flags;
999151359Sps	uiov = msg.msg_iov;
1000151359Sps	msg.msg_iov = iov;
1001151909Sps
1002151909Sps	controlp = (msg.msg_control != NULL) ?  &control : NULL;
1003160249Sjhb	error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
1004151359Sps	if (error == 0) {
1005151359Sps		msg.msg_iov = uiov;
1006151909Sps
1007151909Sps		if (control != NULL)
1008151909Sps			error = freebsd32_copy_msg_out(&msg, control);
1009151909Sps
1010151909Sps		if (error == 0)
1011151909Sps			error = freebsd32_copyoutmsghdr(&msg, uap->msg);
1012151359Sps	}
1013151359Sps	free(iov, M_IOV);
1014151909Sps
1015151909Sps	if (control != NULL)
1016151909Sps		m_freem(control);
1017151909Sps
1018151359Sps	return (error);
1019151359Sps}
1020151359Sps
1021151909Sps
1022151909Spsstatic int
1023151909Spsfreebsd32_convert_msg_in(struct mbuf **controlp)
1024151909Sps{
1025151909Sps	struct mbuf *control = *controlp;
1026151909Sps	struct cmsghdr *cm = mtod(control, struct cmsghdr *);
1027151909Sps	void *data;
1028151909Sps	socklen_t clen = control->m_len, datalen;
1029151909Sps	int error;
1030151909Sps
1031151909Sps	error = 0;
1032151909Sps	*controlp = NULL;
1033151909Sps
1034151909Sps	while (cm != NULL) {
1035151909Sps		if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) {
1036151909Sps			error = EINVAL;
1037151909Sps			break;
1038151909Sps		}
1039151909Sps
1040151909Sps		data = FREEBSD32_CMSG_DATA(cm);
1041151909Sps		datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1042151909Sps
1043151909Sps		*controlp = sbcreatecontrol(data, datalen, cm->cmsg_type,
1044151909Sps		    cm->cmsg_level);
1045151909Sps		controlp = &(*controlp)->m_next;
1046151909Sps
1047151909Sps		if (FREEBSD32_CMSG_SPACE(datalen) < clen) {
1048151909Sps			clen -= FREEBSD32_CMSG_SPACE(datalen);
1049151909Sps			cm = (struct cmsghdr *)
1050151909Sps				((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen));
1051151909Sps		} else {
1052151909Sps			clen = 0;
1053151909Sps			cm = NULL;
1054151909Sps		}
1055151909Sps	}
1056151909Sps
1057151909Sps	m_freem(control);
1058151909Sps	return (error);
1059151909Sps}
1060151909Sps
1061151909Sps
1062151359Spsint
1063151359Spsfreebsd32_sendmsg(struct thread *td,
1064151359Sps		  struct freebsd32_sendmsg_args *uap)
1065151359Sps{
1066151359Sps	struct msghdr msg;
1067151359Sps	struct msghdr32 m32;
1068151359Sps	struct iovec *iov;
1069151909Sps	struct mbuf *control = NULL;
1070151909Sps	struct sockaddr *to = NULL;
1071151359Sps	int error;
1072151359Sps
1073151359Sps	error = copyin(uap->msg, &m32, sizeof(m32));
1074151359Sps	if (error)
1075151359Sps		return (error);
1076151359Sps	error = freebsd32_copyinmsghdr(uap->msg, &msg);
1077151359Sps	if (error)
1078151359Sps		return (error);
1079160246Sjhb	error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
1080160246Sjhb	    EMSGSIZE);
1081151359Sps	if (error)
1082151359Sps		return (error);
1083151359Sps	msg.msg_iov = iov;
1084151909Sps	if (msg.msg_name != NULL) {
1085151909Sps		error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
1086151909Sps		if (error) {
1087151909Sps			to = NULL;
1088151909Sps			goto out;
1089151909Sps		}
1090151909Sps		msg.msg_name = to;
1091151909Sps	}
1092151909Sps
1093151909Sps	if (msg.msg_control) {
1094151909Sps		if (msg.msg_controllen < sizeof(struct cmsghdr)) {
1095151909Sps			error = EINVAL;
1096151909Sps			goto out;
1097151909Sps		}
1098151909Sps
1099151909Sps		error = sockargs(&control, msg.msg_control,
1100151909Sps		    msg.msg_controllen, MT_CONTROL);
1101151909Sps		if (error)
1102151909Sps			goto out;
1103151909Sps
1104151909Sps		error = freebsd32_convert_msg_in(&control);
1105151909Sps		if (error)
1106151909Sps			goto out;
1107151909Sps	}
1108151909Sps
1109151909Sps	error = kern_sendit(td, uap->s, &msg, uap->flags, control,
1110151909Sps	    UIO_USERSPACE);
1111151909Sps
1112151909Spsout:
1113151359Sps	free(iov, M_IOV);
1114151909Sps	if (to)
1115151909Sps		free(to, M_SONAME);
1116151359Sps	return (error);
1117151359Sps}
1118151359Sps
1119151359Spsint
1120151359Spsfreebsd32_recvfrom(struct thread *td,
1121151359Sps		   struct freebsd32_recvfrom_args *uap)
1122151359Sps{
1123151359Sps	struct msghdr msg;
1124151359Sps	struct iovec aiov;
1125151359Sps	int error;
1126151359Sps
1127151359Sps	if (uap->fromlenaddr) {
1128160246Sjhb		error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen,
1129160246Sjhb		    sizeof(msg.msg_namelen));
1130151359Sps		if (error)
1131151359Sps			return (error);
1132151359Sps	} else {
1133151359Sps		msg.msg_namelen = 0;
1134151359Sps	}
1135151359Sps
1136160246Sjhb	msg.msg_name = PTRIN(uap->from);
1137151359Sps	msg.msg_iov = &aiov;
1138151359Sps	msg.msg_iovlen = 1;
1139160246Sjhb	aiov.iov_base = PTRIN(uap->buf);
1140151359Sps	aiov.iov_len = uap->len;
1141160246Sjhb	msg.msg_control = NULL;
1142151359Sps	msg.msg_flags = uap->flags;
1143160249Sjhb	error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL);
1144160249Sjhb	if (error == 0 && uap->fromlenaddr)
1145160249Sjhb		error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr),
1146160249Sjhb		    sizeof (msg.msg_namelen));
1147151359Sps	return (error);
1148151359Sps}
1149151359Sps
1150151359Spsint
1151119333Speterfreebsd32_settimeofday(struct thread *td,
1152119333Speter		       struct freebsd32_settimeofday_args *uap)
1153100384Speter{
1154144450Sjhb	struct timeval32 tv32;
1155144450Sjhb	struct timeval tv, *tvp;
1156144450Sjhb	struct timezone tz, *tzp;
1157100384Speter	int error;
1158100384Speter
1159144450Sjhb	if (uap->tv) {
1160144450Sjhb		error = copyin(uap->tv, &tv32, sizeof(tv32));
1161100384Speter		if (error)
1162100384Speter			return (error);
1163144450Sjhb		CP(tv32, tv, tv_sec);
1164144450Sjhb		CP(tv32, tv, tv_usec);
1165144450Sjhb		tvp = &tv;
1166144450Sjhb	} else
1167144450Sjhb		tvp = NULL;
1168144450Sjhb	if (uap->tzp) {
1169144450Sjhb		error = copyin(uap->tzp, &tz, sizeof(tz));
1170100384Speter		if (error)
1171100384Speter			return (error);
1172144450Sjhb		tzp = &tz;
1173144450Sjhb	} else
1174144450Sjhb		tzp = NULL;
1175144450Sjhb	return (kern_settimeofday(td, tvp, tzp));
1176100384Speter}
1177100384Speter
1178100384Speterint
1179119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
1180100384Speter{
1181142059Sjhb	struct timeval32 s32[2];
1182142059Sjhb	struct timeval s[2], *sp;
1183100384Speter	int error;
1184100384Speter
1185142059Sjhb	if (uap->tptr != NULL) {
1186142059Sjhb		error = copyin(uap->tptr, s32, sizeof(s32));
1187100384Speter		if (error)
1188100384Speter			return (error);
1189100384Speter		CP(s32[0], s[0], tv_sec);
1190100384Speter		CP(s32[0], s[0], tv_usec);
1191100384Speter		CP(s32[1], s[1], tv_sec);
1192100384Speter		CP(s32[1], s[1], tv_usec);
1193142059Sjhb		sp = s;
1194142059Sjhb	} else
1195142059Sjhb		sp = NULL;
1196142059Sjhb	return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1197100384Speter}
1198100384Speter
1199100384Speterint
1200154586Sambriskofreebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
1201154586Sambrisko{
1202154586Sambrisko	struct timeval32 s32[2];
1203154586Sambrisko	struct timeval s[2], *sp;
1204154586Sambrisko	int error;
1205154586Sambrisko
1206154586Sambrisko	if (uap->tptr != NULL) {
1207154586Sambrisko		error = copyin(uap->tptr, s32, sizeof(s32));
1208154586Sambrisko		if (error)
1209154586Sambrisko			return (error);
1210154586Sambrisko		CP(s32[0], s[0], tv_sec);
1211154586Sambrisko		CP(s32[0], s[0], tv_usec);
1212154586Sambrisko		CP(s32[1], s[1], tv_sec);
1213154586Sambrisko		CP(s32[1], s[1], tv_usec);
1214154586Sambrisko		sp = s;
1215154586Sambrisko	} else
1216154586Sambrisko		sp = NULL;
1217154586Sambrisko	return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
1218154586Sambrisko}
1219154586Sambrisko
1220154586Sambriskoint
1221153247Sambriskofreebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
1222153247Sambrisko{
1223153247Sambrisko	struct timeval32 s32[2];
1224153247Sambrisko	struct timeval s[2], *sp;
1225153247Sambrisko	int error;
1226153247Sambrisko
1227153247Sambrisko	if (uap->tptr != NULL) {
1228153247Sambrisko		error = copyin(uap->tptr, s32, sizeof(s32));
1229153247Sambrisko		if (error)
1230153247Sambrisko			return (error);
1231153247Sambrisko		CP(s32[0], s[0], tv_sec);
1232153247Sambrisko		CP(s32[0], s[0], tv_usec);
1233153247Sambrisko		CP(s32[1], s[1], tv_sec);
1234153247Sambrisko		CP(s32[1], s[1], tv_usec);
1235153247Sambrisko		sp = s;
1236153247Sambrisko	} else
1237153247Sambrisko		sp = NULL;
1238153247Sambrisko	return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
1239153247Sambrisko}
1240153247Sambrisko
1241153247Sambrisko
1242153247Sambriskoint
1243119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
1244100384Speter{
1245144450Sjhb	struct timeval32 tv32;
1246144450Sjhb	struct timeval delta, olddelta, *deltap;
1247100384Speter	int error;
1248100384Speter
1249144450Sjhb	if (uap->delta) {
1250144450Sjhb		error = copyin(uap->delta, &tv32, sizeof(tv32));
1251100384Speter		if (error)
1252100384Speter			return (error);
1253144450Sjhb		CP(tv32, delta, tv_sec);
1254144450Sjhb		CP(tv32, delta, tv_usec);
1255144450Sjhb		deltap = &delta;
1256144450Sjhb	} else
1257144450Sjhb		deltap = NULL;
1258144450Sjhb	error = kern_adjtime(td, deltap, &olddelta);
1259144450Sjhb	if (uap->olddelta && error == 0) {
1260144450Sjhb		CP(olddelta, tv32, tv_sec);
1261144450Sjhb		CP(olddelta, tv32, tv_usec);
1262144450Sjhb		error = copyout(&tv32, uap->olddelta, sizeof(tv32));
1263100384Speter	}
1264100384Speter	return (error);
1265100384Speter}
1266100384Speter
1267128597Smarcel#ifdef COMPAT_FREEBSD4
1268100384Speterint
1269128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
1270100384Speter{
1271142059Sjhb	struct statfs32 s32;
1272142059Sjhb	struct statfs s;
1273100384Speter	int error;
1274100384Speter
1275142059Sjhb	error = kern_statfs(td, uap->path, UIO_USERSPACE, &s);
1276100384Speter	if (error)
1277100384Speter		return (error);
1278174377Sjhb	error = copy_statfs(&s, &s32);
1279174377Sjhb	if (error)
1280174377Sjhb		return (error);
1281142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
1282100384Speter}
1283128597Smarcel#endif
1284100384Speter
1285128597Smarcel#ifdef COMPAT_FREEBSD4
1286100384Speterint
1287128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
1288100384Speter{
1289142059Sjhb	struct statfs32 s32;
1290142059Sjhb	struct statfs s;
1291100384Speter	int error;
1292100384Speter
1293142059Sjhb	error = kern_fstatfs(td, uap->fd, &s);
1294100384Speter	if (error)
1295100384Speter		return (error);
1296174377Sjhb	error = copy_statfs(&s, &s32);
1297174377Sjhb	if (error)
1298174377Sjhb		return (error);
1299142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
1300100384Speter}
1301128597Smarcel#endif
1302100384Speter
1303128597Smarcel#ifdef COMPAT_FREEBSD4
1304100384Speterint
1305128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
1306128260Speter{
1307142059Sjhb	struct statfs32 s32;
1308142059Sjhb	struct statfs s;
1309142059Sjhb	fhandle_t fh;
1310128260Speter	int error;
1311128260Speter
1312142059Sjhb	if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
1313142059Sjhb		return (error);
1314142059Sjhb	error = kern_fhstatfs(td, fh, &s);
1315128260Speter	if (error)
1316128260Speter		return (error);
1317174377Sjhb	error = copy_statfs(&s, &s32);
1318174377Sjhb	if (error)
1319174377Sjhb		return (error);
1320142059Sjhb	return (copyout(&s32, uap->buf, sizeof(s32)));
1321128260Speter}
1322128597Smarcel#endif
1323128260Speter
1324174381Sjhbstatic void
1325174381Sjhbfreebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip)
1326174381Sjhb{
1327174381Sjhb
1328174381Sjhb	CP(*ip32, *ip, cuid);
1329174381Sjhb	CP(*ip32, *ip, cgid);
1330174381Sjhb	CP(*ip32, *ip, uid);
1331174381Sjhb	CP(*ip32, *ip, gid);
1332174381Sjhb	CP(*ip32, *ip, mode);
1333174381Sjhb	CP(*ip32, *ip, seq);
1334174381Sjhb	CP(*ip32, *ip, key);
1335174381Sjhb}
1336174381Sjhb
1337174381Sjhbstatic void
1338174381Sjhbfreebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32)
1339174381Sjhb{
1340174381Sjhb
1341174381Sjhb	CP(*ip, *ip32, cuid);
1342174381Sjhb	CP(*ip, *ip32, cgid);
1343174381Sjhb	CP(*ip, *ip32, uid);
1344174381Sjhb	CP(*ip, *ip32, gid);
1345174381Sjhb	CP(*ip, *ip32, mode);
1346174381Sjhb	CP(*ip, *ip32, seq);
1347174381Sjhb	CP(*ip, *ip32, key);
1348174381Sjhb}
1349174381Sjhb
1350128260Speterint
1351119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
1352100384Speter{
1353174381Sjhb
1354174381Sjhb	switch (uap->which) {
1355174381Sjhb	case 0:
1356174381Sjhb		return (freebsd32_semctl(td,
1357174381Sjhb		    (struct freebsd32_semctl_args *)&uap->a2));
1358174381Sjhb	default:
1359174381Sjhb		return (semsys(td, (struct semsys_args *)uap));
1360174381Sjhb	}
1361100384Speter}
1362100384Speter
1363100384Speterint
1364174381Sjhbfreebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap)
1365174381Sjhb{
1366174381Sjhb	struct semid_ds32 dsbuf32;
1367174381Sjhb	struct semid_ds dsbuf;
1368174381Sjhb	union semun semun;
1369174381Sjhb	union semun32 arg;
1370174381Sjhb	register_t rval;
1371174381Sjhb	int error;
1372174381Sjhb
1373174381Sjhb	switch (uap->cmd) {
1374174381Sjhb	case SEM_STAT:
1375174381Sjhb	case IPC_SET:
1376174381Sjhb	case IPC_STAT:
1377174381Sjhb	case GETALL:
1378174381Sjhb	case SETVAL:
1379174381Sjhb	case SETALL:
1380174381Sjhb		error = copyin(uap->arg, &arg, sizeof(arg));
1381174381Sjhb		if (error)
1382174381Sjhb			return (error);
1383174381Sjhb		break;
1384174381Sjhb	}
1385174381Sjhb
1386174381Sjhb	switch (uap->cmd) {
1387174381Sjhb	case SEM_STAT:
1388174381Sjhb	case IPC_STAT:
1389174381Sjhb		semun.buf = &dsbuf;
1390174381Sjhb		break;
1391174381Sjhb	case IPC_SET:
1392174381Sjhb		error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
1393174381Sjhb		if (error)
1394174381Sjhb			return (error);
1395174381Sjhb		freebsd32_ipcperm_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
1396174381Sjhb		PTRIN_CP(dsbuf32, dsbuf, sem_base);
1397174381Sjhb		CP(dsbuf32, dsbuf, sem_nsems);
1398174381Sjhb		CP(dsbuf32, dsbuf, sem_otime);
1399174381Sjhb		CP(dsbuf32, dsbuf, sem_pad1);
1400174381Sjhb		CP(dsbuf32, dsbuf, sem_ctime);
1401174381Sjhb		CP(dsbuf32, dsbuf, sem_pad2);
1402174381Sjhb		CP(dsbuf32, dsbuf, sem_pad3[0]);
1403174381Sjhb		CP(dsbuf32, dsbuf, sem_pad3[1]);
1404174381Sjhb		CP(dsbuf32, dsbuf, sem_pad3[2]);
1405174381Sjhb		CP(dsbuf32, dsbuf, sem_pad3[3]);
1406174381Sjhb		semun.buf = &dsbuf;
1407174381Sjhb		break;
1408174381Sjhb	case GETALL:
1409174381Sjhb	case SETALL:
1410174381Sjhb		semun.array = PTRIN(arg.array);
1411174381Sjhb		break;
1412174381Sjhb	case SETVAL:
1413174381Sjhb		semun.val = arg.val;
1414174381Sjhb		break;
1415174381Sjhb	}
1416174381Sjhb
1417174381Sjhb	error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
1418174381Sjhb	    &rval);
1419174381Sjhb	if (error)
1420174381Sjhb		return (error);
1421174381Sjhb
1422174381Sjhb	switch (uap->cmd) {
1423174381Sjhb	case SEM_STAT:
1424174381Sjhb	case IPC_STAT:
1425174381Sjhb		freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
1426174381Sjhb		PTROUT_CP(dsbuf, dsbuf32, sem_base);
1427174381Sjhb		CP(dsbuf, dsbuf32, sem_nsems);
1428174381Sjhb		CP(dsbuf, dsbuf32, sem_otime);
1429174381Sjhb		CP(dsbuf, dsbuf32, sem_pad1);
1430174381Sjhb		CP(dsbuf, dsbuf32, sem_ctime);
1431174381Sjhb		CP(dsbuf, dsbuf32, sem_pad2);
1432174381Sjhb		CP(dsbuf, dsbuf32, sem_pad3[0]);
1433174381Sjhb		CP(dsbuf, dsbuf32, sem_pad3[1]);
1434174381Sjhb		CP(dsbuf, dsbuf32, sem_pad3[2]);
1435174381Sjhb		CP(dsbuf, dsbuf32, sem_pad3[3]);
1436174381Sjhb		error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
1437174381Sjhb		break;
1438174381Sjhb	}
1439174381Sjhb
1440174381Sjhb	if (error == 0)
1441174381Sjhb		td->td_retval[0] = rval;
1442174381Sjhb	return (error);
1443174381Sjhb}
1444174381Sjhb
1445174381Sjhbint
1446119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
1447100384Speter{
1448174381Sjhb
1449165405Sjkim	switch (uap->which) {
1450174381Sjhb	case 0:
1451174381Sjhb		return (freebsd32_msgctl(td,
1452174381Sjhb		    (struct freebsd32_msgctl_args *)&uap->a2));
1453165405Sjkim	case 2:
1454165405Sjkim		return (freebsd32_msgsnd(td,
1455165405Sjkim		    (struct freebsd32_msgsnd_args *)&uap->a2));
1456165405Sjkim	case 3:
1457165405Sjkim		return (freebsd32_msgrcv(td,
1458165405Sjkim		    (struct freebsd32_msgrcv_args *)&uap->a2));
1459165405Sjkim	default:
1460174381Sjhb		return (msgsys(td, (struct msgsys_args *)uap));
1461165405Sjkim	}
1462100384Speter}
1463100384Speter
1464100384Speterint
1465174381Sjhbfreebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap)
1466174381Sjhb{
1467174381Sjhb	struct msqid_ds msqbuf;
1468174381Sjhb	struct msqid_ds32 msqbuf32;
1469174381Sjhb	int error;
1470174381Sjhb
1471174381Sjhb	if (uap->cmd == IPC_SET) {
1472174381Sjhb		error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
1473174381Sjhb		if (error)
1474174381Sjhb			return (error);
1475174381Sjhb		freebsd32_ipcperm_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
1476174381Sjhb		PTRIN_CP(msqbuf32, msqbuf, msg_first);
1477174381Sjhb		PTRIN_CP(msqbuf32, msqbuf, msg_last);
1478174381Sjhb		CP(msqbuf32, msqbuf, msg_cbytes);
1479174381Sjhb		CP(msqbuf32, msqbuf, msg_qnum);
1480174381Sjhb		CP(msqbuf32, msqbuf, msg_qbytes);
1481174381Sjhb		CP(msqbuf32, msqbuf, msg_lspid);
1482174381Sjhb		CP(msqbuf32, msqbuf, msg_lrpid);
1483174381Sjhb		CP(msqbuf32, msqbuf, msg_stime);
1484174381Sjhb		CP(msqbuf32, msqbuf, msg_pad1);
1485174381Sjhb		CP(msqbuf32, msqbuf, msg_rtime);
1486174381Sjhb		CP(msqbuf32, msqbuf, msg_pad2);
1487174381Sjhb		CP(msqbuf32, msqbuf, msg_ctime);
1488174381Sjhb		CP(msqbuf32, msqbuf, msg_pad3);
1489174381Sjhb		CP(msqbuf32, msqbuf, msg_pad4[0]);
1490174381Sjhb		CP(msqbuf32, msqbuf, msg_pad4[1]);
1491174381Sjhb		CP(msqbuf32, msqbuf, msg_pad4[2]);
1492174381Sjhb		CP(msqbuf32, msqbuf, msg_pad4[3]);
1493174381Sjhb	}
1494174381Sjhb	error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
1495174381Sjhb	if (error)
1496174381Sjhb		return (error);
1497174381Sjhb	if (uap->cmd == IPC_STAT) {
1498174381Sjhb		freebsd32_ipcperm_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
1499174381Sjhb		PTROUT_CP(msqbuf, msqbuf32, msg_first);
1500174381Sjhb		PTROUT_CP(msqbuf, msqbuf32, msg_last);
1501174381Sjhb		CP(msqbuf, msqbuf32, msg_cbytes);
1502174381Sjhb		CP(msqbuf, msqbuf32, msg_qnum);
1503174381Sjhb		CP(msqbuf, msqbuf32, msg_qbytes);
1504174381Sjhb		CP(msqbuf, msqbuf32, msg_lspid);
1505174381Sjhb		CP(msqbuf, msqbuf32, msg_lrpid);
1506174381Sjhb		CP(msqbuf, msqbuf32, msg_stime);
1507174381Sjhb		CP(msqbuf, msqbuf32, msg_pad1);
1508174381Sjhb		CP(msqbuf, msqbuf32, msg_rtime);
1509174381Sjhb		CP(msqbuf, msqbuf32, msg_pad2);
1510174381Sjhb		CP(msqbuf, msqbuf32, msg_ctime);
1511174381Sjhb		CP(msqbuf, msqbuf32, msg_pad3);
1512174381Sjhb		CP(msqbuf, msqbuf32, msg_pad4[0]);
1513174381Sjhb		CP(msqbuf, msqbuf32, msg_pad4[1]);
1514174381Sjhb		CP(msqbuf, msqbuf32, msg_pad4[2]);
1515174381Sjhb		CP(msqbuf, msqbuf32, msg_pad4[3]);
1516174381Sjhb		error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
1517174381Sjhb	}
1518174381Sjhb	return (error);
1519174381Sjhb}
1520174381Sjhb
1521174381Sjhbint
1522165405Sjkimfreebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
1523165405Sjkim{
1524165405Sjkim	const void *msgp;
1525165405Sjkim	long mtype;
1526165405Sjkim	int32_t mtype32;
1527165405Sjkim	int error;
1528165405Sjkim
1529165405Sjkim	msgp = PTRIN(uap->msgp);
1530165405Sjkim	if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
1531165405Sjkim		return (error);
1532165405Sjkim	mtype = mtype32;
1533165405Sjkim	return (kern_msgsnd(td, uap->msqid,
1534165405Sjkim	    (const char *)msgp + sizeof(mtype32),
1535165405Sjkim	    uap->msgsz, uap->msgflg, mtype));
1536165405Sjkim}
1537165405Sjkim
1538165405Sjkimint
1539165405Sjkimfreebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
1540165405Sjkim{
1541165405Sjkim	void *msgp;
1542165405Sjkim	long mtype;
1543165405Sjkim	int32_t mtype32;
1544165405Sjkim	int error;
1545165405Sjkim
1546165405Sjkim	msgp = PTRIN(uap->msgp);
1547165405Sjkim	if ((error = kern_msgrcv(td, uap->msqid,
1548165405Sjkim	    (char *)msgp + sizeof(mtype32), uap->msgsz,
1549165405Sjkim	    uap->msgtyp, uap->msgflg, &mtype)) != 0)
1550165405Sjkim		return (error);
1551165405Sjkim	mtype32 = (int32_t)mtype;
1552165405Sjkim	return (copyout(&mtype32, msgp, sizeof(mtype32)));
1553165405Sjkim}
1554165405Sjkim
1555165405Sjkimint
1556119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
1557100384Speter{
1558157285Sps
1559157285Sps	switch (uap->which) {
1560157285Sps	case 0:	{	/* shmat */
1561157285Sps		struct shmat_args ap;
1562157285Sps
1563157285Sps		ap.shmid = uap->a2;
1564157285Sps		ap.shmaddr = PTRIN(uap->a3);
1565157285Sps		ap.shmflg = uap->a4;
1566157285Sps		return (sysent[SYS_shmat].sy_call(td, &ap));
1567157285Sps	}
1568157285Sps	case 2: {	/* shmdt */
1569157285Sps		struct shmdt_args ap;
1570157285Sps
1571157285Sps		ap.shmaddr = PTRIN(uap->a2);
1572157285Sps		return (sysent[SYS_shmdt].sy_call(td, &ap));
1573157285Sps	}
1574157285Sps	case 3: {	/* shmget */
1575157285Sps		struct shmget_args ap;
1576157285Sps
1577157285Sps		ap.key = uap->a2;
1578157285Sps		ap.size = uap->a3;
1579157285Sps		ap.shmflg = uap->a4;
1580157285Sps		return (sysent[SYS_shmget].sy_call(td, &ap));
1581157285Sps	}
1582157285Sps	case 4: {	/* shmctl */
1583157285Sps		struct freebsd32_shmctl_args ap;
1584157285Sps
1585157285Sps		ap.shmid = uap->a2;
1586157285Sps		ap.cmd = uap->a3;
1587157285Sps		ap.buf = PTRIN(uap->a4);
1588157285Sps		return (freebsd32_shmctl(td, &ap));
1589157285Sps	}
1590157285Sps	case 1:		/* oshmctl */
1591157285Sps	default:
1592157285Sps		return (EINVAL);
1593157285Sps	}
1594100384Speter}
1595100384Speter
1596100384Speterint
1597157285Spsfreebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
1598157285Sps{
1599157285Sps	int error = 0;
1600157285Sps	union {
1601157285Sps		struct shmid_ds shmid_ds;
1602157285Sps		struct shm_info shm_info;
1603157285Sps		struct shminfo shminfo;
1604157285Sps	} u;
1605157285Sps	union {
1606157285Sps		struct shmid_ds32 shmid_ds32;
1607157285Sps		struct shm_info32 shm_info32;
1608157285Sps		struct shminfo32 shminfo32;
1609157285Sps	} u32;
1610157285Sps	size_t sz;
1611157285Sps
1612157285Sps	if (uap->cmd == IPC_SET) {
1613157285Sps		if ((error = copyin(uap->buf, &u32.shmid_ds32,
1614157285Sps		    sizeof(u32.shmid_ds32))))
1615157285Sps			goto done;
1616174381Sjhb		freebsd32_ipcperm_in(&u32.shmid_ds32.shm_perm,
1617174381Sjhb		    &u.shmid_ds.shm_perm);
1618157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
1619157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
1620157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
1621157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
1622157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
1623157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
1624157285Sps		CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
1625157285Sps		PTRIN_CP(u32.shmid_ds32, u.shmid_ds, shm_internal);
1626157285Sps	}
1627157285Sps
1628157285Sps	error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
1629157285Sps	if (error)
1630157285Sps		goto done;
1631157285Sps
1632157285Sps	/* Cases in which we need to copyout */
1633157285Sps	switch (uap->cmd) {
1634157285Sps	case IPC_INFO:
1635157285Sps		CP(u.shminfo, u32.shminfo32, shmmax);
1636157285Sps		CP(u.shminfo, u32.shminfo32, shmmin);
1637157285Sps		CP(u.shminfo, u32.shminfo32, shmmni);
1638157285Sps		CP(u.shminfo, u32.shminfo32, shmseg);
1639157285Sps		CP(u.shminfo, u32.shminfo32, shmall);
1640157285Sps		error = copyout(&u32.shminfo32, uap->buf,
1641157285Sps		    sizeof(u32.shminfo32));
1642157285Sps		break;
1643157285Sps	case SHM_INFO:
1644157285Sps		CP(u.shm_info, u32.shm_info32, used_ids);
1645157285Sps		CP(u.shm_info, u32.shm_info32, shm_rss);
1646157285Sps		CP(u.shm_info, u32.shm_info32, shm_tot);
1647157285Sps		CP(u.shm_info, u32.shm_info32, shm_swp);
1648157285Sps		CP(u.shm_info, u32.shm_info32, swap_attempts);
1649157285Sps		CP(u.shm_info, u32.shm_info32, swap_successes);
1650157285Sps		error = copyout(&u32.shm_info32, uap->buf,
1651157285Sps		    sizeof(u32.shm_info32));
1652157285Sps		break;
1653157285Sps	case SHM_STAT:
1654157285Sps	case IPC_STAT:
1655174381Sjhb		freebsd32_ipcperm_out(&u.shmid_ds.shm_perm,
1656174381Sjhb		    &u32.shmid_ds32.shm_perm);
1657157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
1658157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
1659157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
1660157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
1661157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
1662157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
1663157285Sps		CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
1664157285Sps		PTROUT_CP(u.shmid_ds, u32.shmid_ds32, shm_internal);
1665157285Sps		error = copyout(&u32.shmid_ds32, uap->buf,
1666157285Sps		    sizeof(u32.shmid_ds32));
1667157285Sps		break;
1668157285Sps	}
1669157285Sps
1670157285Spsdone:
1671157285Sps	if (error) {
1672157285Sps		/* Invalidate the return value */
1673157285Sps		td->td_retval[0] = -1;
1674157285Sps	}
1675157285Sps	return (error);
1676157285Sps}
1677157285Sps
1678157285Spsint
1679119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
1680100384Speter{
1681100384Speter	struct pread_args ap;
1682100384Speter
1683107849Salfred	ap.fd = uap->fd;
1684107849Salfred	ap.buf = uap->buf;
1685107849Salfred	ap.nbyte = uap->nbyte;
1686119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1687100384Speter	return (pread(td, &ap));
1688100384Speter}
1689100384Speter
1690100384Speterint
1691119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
1692100384Speter{
1693100384Speter	struct pwrite_args ap;
1694100384Speter
1695107849Salfred	ap.fd = uap->fd;
1696107849Salfred	ap.buf = uap->buf;
1697107849Salfred	ap.nbyte = uap->nbyte;
1698119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1699100384Speter	return (pwrite(td, &ap));
1700100384Speter}
1701100384Speter
1702100384Speterint
1703119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
1704100384Speter{
1705100384Speter	int error;
1706100384Speter	struct lseek_args ap;
1707100384Speter	off_t pos;
1708100384Speter
1709107849Salfred	ap.fd = uap->fd;
1710119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1711107849Salfred	ap.whence = uap->whence;
1712100384Speter	error = lseek(td, &ap);
1713100384Speter	/* Expand the quad return into two parts for eax and edx */
1714100384Speter	pos = *(off_t *)(td->td_retval);
1715100384Speter	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
1716100384Speter	td->td_retval[1] = pos >> 32;		/* %edx */
1717100384Speter	return error;
1718100384Speter}
1719100384Speter
1720100384Speterint
1721119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
1722100384Speter{
1723100384Speter	struct truncate_args ap;
1724100384Speter
1725107849Salfred	ap.path = uap->path;
1726119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1727100384Speter	return (truncate(td, &ap));
1728100384Speter}
1729100384Speter
1730100384Speterint
1731119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
1732100384Speter{
1733100384Speter	struct ftruncate_args ap;
1734100384Speter
1735107849Salfred	ap.fd = uap->fd;
1736119333Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1737100384Speter	return (ftruncate(td, &ap));
1738100384Speter}
1739100384Speter
1740171215Speter#ifdef COMPAT_FREEBSD6
1741171215Speter/* versions with the 'int pad' argument */
1742171215Speterint
1743171215Speterfreebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap)
1744171215Speter{
1745171215Speter	struct pread_args ap;
1746171215Speter
1747171215Speter	ap.fd = uap->fd;
1748171215Speter	ap.buf = uap->buf;
1749171215Speter	ap.nbyte = uap->nbyte;
1750171215Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1751171215Speter	return (pread(td, &ap));
1752171215Speter}
1753171215Speter
1754171215Speterint
1755171215Speterfreebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap)
1756171215Speter{
1757171215Speter	struct pwrite_args ap;
1758171215Speter
1759171215Speter	ap.fd = uap->fd;
1760171215Speter	ap.buf = uap->buf;
1761171215Speter	ap.nbyte = uap->nbyte;
1762171215Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1763171215Speter	return (pwrite(td, &ap));
1764171215Speter}
1765171215Speter
1766171215Speterint
1767171215Speterfreebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap)
1768171215Speter{
1769171215Speter	int error;
1770171215Speter	struct lseek_args ap;
1771171215Speter	off_t pos;
1772171215Speter
1773171215Speter	ap.fd = uap->fd;
1774171215Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1775171215Speter	ap.whence = uap->whence;
1776171215Speter	error = lseek(td, &ap);
1777171215Speter	/* Expand the quad return into two parts for eax and edx */
1778171215Speter	pos = *(off_t *)(td->td_retval);
1779171215Speter	td->td_retval[0] = pos & 0xffffffff;	/* %eax */
1780171215Speter	td->td_retval[1] = pos >> 32;		/* %edx */
1781171215Speter	return error;
1782171215Speter}
1783171215Speter
1784171215Speterint
1785171215Speterfreebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap)
1786171215Speter{
1787171215Speter	struct truncate_args ap;
1788171215Speter
1789171215Speter	ap.path = uap->path;
1790171215Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1791171215Speter	return (truncate(td, &ap));
1792171215Speter}
1793171215Speter
1794171215Speterint
1795171215Speterfreebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap)
1796171215Speter{
1797171215Speter	struct ftruncate_args ap;
1798171215Speter
1799171215Speter	ap.fd = uap->fd;
1800171215Speter	ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
1801171215Speter	return (ftruncate(td, &ap));
1802171215Speter}
1803171215Speter#endif /* COMPAT_FREEBSD6 */
1804171215Speter
1805156114Spsstruct sf_hdtr32 {
1806156114Sps	uint32_t headers;
1807156114Sps	int hdr_cnt;
1808156114Sps	uint32_t trailers;
1809156114Sps	int trl_cnt;
1810156114Sps};
1811156114Sps
1812156114Spsstatic int
1813156114Spsfreebsd32_do_sendfile(struct thread *td,
1814156114Sps    struct freebsd32_sendfile_args *uap, int compat)
1815104738Speter{
1816156114Sps	struct sendfile_args ap;
1817156114Sps	struct sf_hdtr32 hdtr32;
1818156114Sps	struct sf_hdtr hdtr;
1819156114Sps	struct uio *hdr_uio, *trl_uio;
1820156114Sps	struct iovec32 *iov32;
1821156114Sps	int error;
1822104738Speter
1823156114Sps	hdr_uio = trl_uio = NULL;
1824156114Sps
1825107849Salfred	ap.fd = uap->fd;
1826107849Salfred	ap.s = uap->s;
1827119333Speter	ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
1828156114Sps	ap.nbytes = uap->nbytes;
1829156114Sps	ap.hdtr = (struct sf_hdtr *)uap->hdtr;		/* XXX not used */
1830156114Sps	ap.sbytes = uap->sbytes;
1831107849Salfred	ap.flags = uap->flags;
1832156114Sps
1833156114Sps	if (uap->hdtr != NULL) {
1834156114Sps		error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
1835156114Sps		if (error)
1836156114Sps			goto out;
1837156114Sps		PTRIN_CP(hdtr32, hdtr, headers);
1838156114Sps		CP(hdtr32, hdtr, hdr_cnt);
1839156114Sps		PTRIN_CP(hdtr32, hdtr, trailers);
1840156114Sps		CP(hdtr32, hdtr, trl_cnt);
1841156114Sps
1842156114Sps		if (hdtr.headers != NULL) {
1843160246Sjhb			iov32 = PTRIN(hdtr32.headers);
1844156114Sps			error = freebsd32_copyinuio(iov32,
1845156114Sps			    hdtr32.hdr_cnt, &hdr_uio);
1846156114Sps			if (error)
1847156114Sps				goto out;
1848156114Sps		}
1849156114Sps		if (hdtr.trailers != NULL) {
1850160246Sjhb			iov32 = PTRIN(hdtr32.trailers);
1851156114Sps			error = freebsd32_copyinuio(iov32,
1852156114Sps			    hdtr32.trl_cnt, &trl_uio);
1853156114Sps			if (error)
1854156114Sps				goto out;
1855156114Sps		}
1856156114Sps	}
1857156114Sps
1858156114Sps	error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat);
1859156114Spsout:
1860156114Sps	if (hdr_uio)
1861156114Sps		free(hdr_uio, M_IOV);
1862156114Sps	if (trl_uio)
1863156114Sps		free(trl_uio, M_IOV);
1864156114Sps	return (error);
1865104738Speter}
1866156114Sps
1867156114Sps#ifdef COMPAT_FREEBSD4
1868156114Spsint
1869156114Spsfreebsd4_freebsd32_sendfile(struct thread *td,
1870156114Sps    struct freebsd4_freebsd32_sendfile_args *uap)
1871156114Sps{
1872156114Sps	return (freebsd32_do_sendfile(td,
1873156114Sps	    (struct freebsd32_sendfile_args *)uap, 1));
1874156114Sps}
1875104738Speter#endif
1876104738Speter
1877104738Speterint
1878119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
1879100384Speter{
1880100384Speter
1881156114Sps	return (freebsd32_do_sendfile(td, uap, 0));
1882100384Speter}
1883100384Speter
1884100384Speterstatic void
1885100384Spetercopy_stat( struct stat *in, struct stat32 *out)
1886100384Speter{
1887100384Speter	CP(*in, *out, st_dev);
1888100384Speter	CP(*in, *out, st_ino);
1889100384Speter	CP(*in, *out, st_mode);
1890100384Speter	CP(*in, *out, st_nlink);
1891100384Speter	CP(*in, *out, st_uid);
1892100384Speter	CP(*in, *out, st_gid);
1893100384Speter	CP(*in, *out, st_rdev);
1894100384Speter	TS_CP(*in, *out, st_atimespec);
1895100384Speter	TS_CP(*in, *out, st_mtimespec);
1896100384Speter	TS_CP(*in, *out, st_ctimespec);
1897100384Speter	CP(*in, *out, st_size);
1898100384Speter	CP(*in, *out, st_blocks);
1899100384Speter	CP(*in, *out, st_blksize);
1900100384Speter	CP(*in, *out, st_flags);
1901100384Speter	CP(*in, *out, st_gen);
1902100384Speter}
1903100384Speter
1904100384Speterint
1905119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
1906100384Speter{
1907123746Speter	struct stat sb;
1908123746Speter	struct stat32 sb32;
1909100384Speter	int error;
1910100384Speter
1911142059Sjhb	error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
1912100384Speter	if (error)
1913100384Speter		return (error);
1914123746Speter	copy_stat(&sb, &sb32);
1915123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1916100384Speter	return (error);
1917100384Speter}
1918100384Speter
1919100384Speterint
1920119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
1921100384Speter{
1922123746Speter	struct stat ub;
1923123746Speter	struct stat32 ub32;
1924100384Speter	int error;
1925100384Speter
1926142059Sjhb	error = kern_fstat(td, uap->fd, &ub);
1927100384Speter	if (error)
1928100384Speter		return (error);
1929123746Speter	copy_stat(&ub, &ub32);
1930123746Speter	error = copyout(&ub32, uap->ub, sizeof(ub32));
1931100384Speter	return (error);
1932100384Speter}
1933100384Speter
1934100384Speterint
1935119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
1936100384Speter{
1937123746Speter	struct stat sb;
1938123746Speter	struct stat32 sb32;
1939142059Sjhb	int error;
1940100384Speter
1941142059Sjhb	error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
1942100384Speter	if (error)
1943100384Speter		return (error);
1944123746Speter	copy_stat(&sb, &sb32);
1945123746Speter	error = copyout(&sb32, uap->ub, sizeof (sb32));
1946100384Speter	return (error);
1947100384Speter}
1948100384Speter
1949100384Speter/*
1950100384Speter * MPSAFE
1951100384Speter */
1952100384Speterint
1953119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
1954100384Speter{
1955100384Speter	int error, name[CTL_MAXNAME];
1956100384Speter	size_t j, oldlen;
1957100384Speter
1958100384Speter	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
1959100384Speter		return (EINVAL);
1960136404Speter 	error = copyin(uap->name, name, uap->namelen * sizeof(int));
1961100384Speter 	if (error)
1962100384Speter		return (error);
1963100384Speter	mtx_lock(&Giant);
1964100384Speter	if (uap->oldlenp)
1965100384Speter		oldlen = fuword32(uap->oldlenp);
1966100384Speter	else
1967100384Speter		oldlen = 0;
1968100384Speter	error = userland_sysctl(td, name, uap->namelen,
1969100384Speter		uap->old, &oldlen, 1,
1970136404Speter		uap->new, uap->newlen, &j, SCTL_MASK32);
1971100384Speter	if (error && error != ENOMEM)
1972100384Speter		goto done2;
1973136404Speter	if (uap->oldlenp)
1974100384Speter		suword32(uap->oldlenp, j);
1975100384Speterdone2:
1976100384Speter	mtx_unlock(&Giant);
1977100384Speter	return (error);
1978100384Speter}
1979100384Speter
1980100384Speterint
1981119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
1982100384Speter{
1983113859Sjhb	struct sigaction32 s32;
1984113859Sjhb	struct sigaction sa, osa, *sap;
1985100384Speter	int error;
1986100384Speter
1987113859Sjhb	if (uap->act) {
1988113859Sjhb		error = copyin(uap->act, &s32, sizeof(s32));
1989100384Speter		if (error)
1990100384Speter			return (error);
1991113859Sjhb		sa.sa_handler = PTRIN(s32.sa_u);
1992113859Sjhb		CP(s32, sa, sa_flags);
1993113859Sjhb		CP(s32, sa, sa_mask);
1994113859Sjhb		sap = &sa;
1995113859Sjhb	} else
1996113859Sjhb		sap = NULL;
1997113859Sjhb	error = kern_sigaction(td, uap->sig, sap, &osa, 0);
1998146583Sps	if (error == 0 && uap->oact != NULL) {
1999113859Sjhb		s32.sa_u = PTROUT(osa.sa_handler);
2000113859Sjhb		CP(osa, s32, sa_flags);
2001113859Sjhb		CP(osa, s32, sa_mask);
2002113859Sjhb		error = copyout(&s32, uap->oact, sizeof(s32));
2003100384Speter	}
2004100384Speter	return (error);
2005100384Speter}
2006100384Speter
2007114987Speter#ifdef COMPAT_FREEBSD4
2008114987Speterint
2009119333Speterfreebsd4_freebsd32_sigaction(struct thread *td,
2010119333Speter			     struct freebsd4_freebsd32_sigaction_args *uap)
2011114987Speter{
2012114987Speter	struct sigaction32 s32;
2013114987Speter	struct sigaction sa, osa, *sap;
2014114987Speter	int error;
2015114987Speter
2016114987Speter	if (uap->act) {
2017114987Speter		error = copyin(uap->act, &s32, sizeof(s32));
2018114987Speter		if (error)
2019114987Speter			return (error);
2020114987Speter		sa.sa_handler = PTRIN(s32.sa_u);
2021114987Speter		CP(s32, sa, sa_flags);
2022114987Speter		CP(s32, sa, sa_mask);
2023114987Speter		sap = &sa;
2024114987Speter	} else
2025114987Speter		sap = NULL;
2026114987Speter	error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
2027146583Sps	if (error == 0 && uap->oact != NULL) {
2028114987Speter		s32.sa_u = PTROUT(osa.sa_handler);
2029114987Speter		CP(osa, s32, sa_flags);
2030114987Speter		CP(osa, s32, sa_mask);
2031114987Speter		error = copyout(&s32, uap->oact, sizeof(s32));
2032114987Speter	}
2033114987Speter	return (error);
2034114987Speter}
2035114987Speter#endif
2036114987Speter
2037151582Sps#ifdef COMPAT_43
2038151720Speterstruct osigaction32 {
2039151582Sps	u_int32_t	sa_u;
2040151582Sps	osigset_t	sa_mask;
2041151582Sps	int		sa_flags;
2042151582Sps};
2043151582Sps
2044151582Sps#define	ONSIG	32
2045151582Sps
2046140481Spsint
2047151720Speterofreebsd32_sigaction(struct thread *td,
2048151720Speter			     struct ofreebsd32_sigaction_args *uap)
2049151582Sps{
2050151720Speter	struct osigaction32 s32;
2051151582Sps	struct sigaction sa, osa, *sap;
2052151582Sps	int error;
2053151582Sps
2054151582Sps	if (uap->signum <= 0 || uap->signum >= ONSIG)
2055151582Sps		return (EINVAL);
2056151582Sps
2057151582Sps	if (uap->nsa) {
2058151582Sps		error = copyin(uap->nsa, &s32, sizeof(s32));
2059151582Sps		if (error)
2060151582Sps			return (error);
2061151582Sps		sa.sa_handler = PTRIN(s32.sa_u);
2062151582Sps		CP(s32, sa, sa_flags);
2063151582Sps		OSIG2SIG(s32.sa_mask, sa.sa_mask);
2064151582Sps		sap = &sa;
2065151582Sps	} else
2066151582Sps		sap = NULL;
2067151582Sps	error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2068151582Sps	if (error == 0 && uap->osa != NULL) {
2069151582Sps		s32.sa_u = PTROUT(osa.sa_handler);
2070151582Sps		CP(osa, s32, sa_flags);
2071151582Sps		SIG2OSIG(osa.sa_mask, s32.sa_mask);
2072151582Sps		error = copyout(&s32, uap->osa, sizeof(s32));
2073151582Sps	}
2074151582Sps	return (error);
2075151582Sps}
2076151582Sps
2077151582Spsint
2078151720Speterofreebsd32_sigprocmask(struct thread *td,
2079151720Speter			       struct ofreebsd32_sigprocmask_args *uap)
2080151582Sps{
2081151582Sps	sigset_t set, oset;
2082151582Sps	int error;
2083151582Sps
2084151582Sps	OSIG2SIG(uap->mask, set);
2085151582Sps	error = kern_sigprocmask(td, uap->how, &set, &oset, 1);
2086151582Sps	SIG2OSIG(oset, td->td_retval[0]);
2087151582Sps	return (error);
2088151582Sps}
2089151582Sps
2090151582Spsint
2091151720Speterofreebsd32_sigpending(struct thread *td,
2092151720Speter			      struct ofreebsd32_sigpending_args *uap)
2093151582Sps{
2094151582Sps	struct proc *p = td->td_proc;
2095151582Sps	sigset_t siglist;
2096151582Sps
2097151582Sps	PROC_LOCK(p);
2098151582Sps	siglist = p->p_siglist;
2099151582Sps	SIGSETOR(siglist, td->td_siglist);
2100151582Sps	PROC_UNLOCK(p);
2101151582Sps	SIG2OSIG(siglist, td->td_retval[0]);
2102151582Sps	return (0);
2103151582Sps}
2104151582Sps
2105151582Spsstruct sigvec32 {
2106151582Sps	u_int32_t	sv_handler;
2107151582Sps	int		sv_mask;
2108151582Sps	int		sv_flags;
2109151582Sps};
2110151582Sps
2111151582Spsint
2112151720Speterofreebsd32_sigvec(struct thread *td,
2113151720Speter			  struct ofreebsd32_sigvec_args *uap)
2114151582Sps{
2115151582Sps	struct sigvec32 vec;
2116151582Sps	struct sigaction sa, osa, *sap;
2117151582Sps	int error;
2118151582Sps
2119151582Sps	if (uap->signum <= 0 || uap->signum >= ONSIG)
2120151582Sps		return (EINVAL);
2121151582Sps
2122151582Sps	if (uap->nsv) {
2123151582Sps		error = copyin(uap->nsv, &vec, sizeof(vec));
2124151582Sps		if (error)
2125151582Sps			return (error);
2126151582Sps		sa.sa_handler = PTRIN(vec.sv_handler);
2127151582Sps		OSIG2SIG(vec.sv_mask, sa.sa_mask);
2128151582Sps		sa.sa_flags = vec.sv_flags;
2129151582Sps		sa.sa_flags ^= SA_RESTART;
2130151582Sps		sap = &sa;
2131151582Sps	} else
2132151582Sps		sap = NULL;
2133151582Sps	error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
2134151582Sps	if (error == 0 && uap->osv != NULL) {
2135151582Sps		vec.sv_handler = PTROUT(osa.sa_handler);
2136151582Sps		SIG2OSIG(osa.sa_mask, vec.sv_mask);
2137151582Sps		vec.sv_flags = osa.sa_flags;
2138151582Sps		vec.sv_flags &= ~SA_NOCLDWAIT;
2139151582Sps		vec.sv_flags ^= SA_RESTART;
2140151582Sps		error = copyout(&vec, uap->osv, sizeof(vec));
2141151582Sps	}
2142151582Sps	return (error);
2143151582Sps}
2144151582Sps
2145151582Spsint
2146151720Speterofreebsd32_sigblock(struct thread *td,
2147151720Speter			    struct ofreebsd32_sigblock_args *uap)
2148151582Sps{
2149151582Sps	struct proc *p = td->td_proc;
2150151582Sps	sigset_t set;
2151151582Sps
2152151582Sps	OSIG2SIG(uap->mask, set);
2153151582Sps	SIG_CANTMASK(set);
2154151582Sps	PROC_LOCK(p);
2155151582Sps	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
2156151582Sps	SIGSETOR(td->td_sigmask, set);
2157151582Sps	PROC_UNLOCK(p);
2158151582Sps	return (0);
2159151582Sps}
2160151582Sps
2161151582Spsint
2162151720Speterofreebsd32_sigsetmask(struct thread *td,
2163151720Speter			      struct ofreebsd32_sigsetmask_args *uap)
2164151582Sps{
2165151582Sps	struct proc *p = td->td_proc;
2166151582Sps	sigset_t set;
2167151582Sps
2168151582Sps	OSIG2SIG(uap->mask, set);
2169151582Sps	SIG_CANTMASK(set);
2170151582Sps	PROC_LOCK(p);
2171151582Sps	SIG2OSIG(td->td_sigmask, td->td_retval[0]);
2172151582Sps	SIGSETLO(td->td_sigmask, set);
2173151582Sps	signotify(td);
2174151582Sps	PROC_UNLOCK(p);
2175151582Sps	return (0);
2176151582Sps}
2177151582Sps
2178151582Spsint
2179151720Speterofreebsd32_sigsuspend(struct thread *td,
2180151720Speter			      struct ofreebsd32_sigsuspend_args *uap)
2181151582Sps{
2182151582Sps	struct proc *p = td->td_proc;
2183151582Sps	sigset_t mask;
2184151582Sps
2185151582Sps	PROC_LOCK(p);
2186151582Sps	td->td_oldsigmask = td->td_sigmask;
2187151582Sps	td->td_pflags |= TDP_OLDMASK;
2188151582Sps	OSIG2SIG(uap->mask, mask);
2189151582Sps	SIG_CANTMASK(mask);
2190151582Sps	SIGSETLO(td->td_sigmask, mask);
2191151582Sps	signotify(td);
2192151582Sps	while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0)
2193151582Sps		/* void */;
2194151582Sps	PROC_UNLOCK(p);
2195151582Sps	/* always return EINTR rather than ERESTART... */
2196151582Sps	return (EINTR);
2197151582Sps}
2198151582Sps
2199151582Spsstruct sigstack32 {
2200151582Sps	u_int32_t	ss_sp;
2201151582Sps	int		ss_onstack;
2202151582Sps};
2203151582Sps
2204151582Spsint
2205151720Speterofreebsd32_sigstack(struct thread *td,
2206151720Speter			    struct ofreebsd32_sigstack_args *uap)
2207151582Sps{
2208151582Sps	struct sigstack32 s32;
2209151582Sps	struct sigstack nss, oss;
2210170870Smjacob	int error = 0, unss;
2211151582Sps
2212151582Sps	if (uap->nss != NULL) {
2213151582Sps		error = copyin(uap->nss, &s32, sizeof(s32));
2214151582Sps		if (error)
2215151582Sps			return (error);
2216151582Sps		nss.ss_sp = PTRIN(s32.ss_sp);
2217151582Sps		CP(s32, nss, ss_onstack);
2218170870Smjacob		unss = 1;
2219170870Smjacob	} else {
2220170870Smjacob		unss = 0;
2221151582Sps	}
2222151582Sps	oss.ss_sp = td->td_sigstk.ss_sp;
2223151582Sps	oss.ss_onstack = sigonstack(cpu_getstack(td));
2224170870Smjacob	if (unss) {
2225151582Sps		td->td_sigstk.ss_sp = nss.ss_sp;
2226151582Sps		td->td_sigstk.ss_size = 0;
2227170870Smjacob		td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK);
2228151582Sps		td->td_pflags |= TDP_ALTSTACK;
2229151582Sps	}
2230151582Sps	if (uap->oss != NULL) {
2231151582Sps		s32.ss_sp = PTROUT(oss.ss_sp);
2232151582Sps		CP(oss, s32, ss_onstack);
2233151582Sps		error = copyout(&s32, uap->oss, sizeof(s32));
2234151582Sps	}
2235151582Sps	return (error);
2236151582Sps}
2237151582Sps#endif
2238151582Sps
2239151582Spsint
2240140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
2241140481Sps{
2242140481Sps	struct timespec32 rmt32, rqt32;
2243140481Sps	struct timespec rmt, rqt;
2244140481Sps	int error;
2245140481Sps
2246151355Sps	error = copyin(uap->rqtp, &rqt32, sizeof(rqt32));
2247140481Sps	if (error)
2248140481Sps		return (error);
2249140481Sps
2250140481Sps	CP(rqt32, rqt, tv_sec);
2251140481Sps	CP(rqt32, rqt, tv_nsec);
2252140481Sps
2253140481Sps	if (uap->rmtp &&
2254140481Sps	    !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
2255140481Sps		return (EFAULT);
2256140481Sps	error = kern_nanosleep(td, &rqt, &rmt);
2257140481Sps	if (error && uap->rmtp) {
2258140481Sps		int error2;
2259140481Sps
2260140481Sps		CP(rmt, rmt32, tv_sec);
2261140481Sps		CP(rmt, rmt32, tv_nsec);
2262140481Sps
2263151355Sps		error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32));
2264140481Sps		if (error2)
2265140481Sps			error = error2;
2266140481Sps	}
2267140481Sps	return (error);
2268140481Sps}
2269140481Sps
2270151357Spsint
2271151357Spsfreebsd32_clock_gettime(struct thread *td,
2272151357Sps			struct freebsd32_clock_gettime_args *uap)
2273151357Sps{
2274151357Sps	struct timespec	ats;
2275151357Sps	struct timespec32 ats32;
2276151357Sps	int error;
2277151357Sps
2278151357Sps	error = kern_clock_gettime(td, uap->clock_id, &ats);
2279151357Sps	if (error == 0) {
2280151357Sps		CP(ats, ats32, tv_sec);
2281151357Sps		CP(ats, ats32, tv_nsec);
2282151357Sps		error = copyout(&ats32, uap->tp, sizeof(ats32));
2283151357Sps	}
2284151357Sps	return (error);
2285151357Sps}
2286151357Sps
2287151357Spsint
2288151357Spsfreebsd32_clock_settime(struct thread *td,
2289151357Sps			struct freebsd32_clock_settime_args *uap)
2290151357Sps{
2291151357Sps	struct timespec	ats;
2292151357Sps	struct timespec32 ats32;
2293151357Sps	int error;
2294151357Sps
2295151357Sps	error = copyin(uap->tp, &ats32, sizeof(ats32));
2296151357Sps	if (error)
2297151357Sps		return (error);
2298151357Sps	CP(ats32, ats, tv_sec);
2299151357Sps	CP(ats32, ats, tv_nsec);
2300151357Sps
2301151357Sps	return (kern_clock_settime(td, uap->clock_id, &ats));
2302151357Sps}
2303151357Sps
2304151357Spsint
2305151357Spsfreebsd32_clock_getres(struct thread *td,
2306151357Sps		       struct freebsd32_clock_getres_args *uap)
2307151357Sps{
2308151357Sps	struct timespec	ts;
2309151357Sps	struct timespec32 ts32;
2310151357Sps	int error;
2311151357Sps
2312151357Sps	if (uap->tp == NULL)
2313151357Sps		return (0);
2314151357Sps	error = kern_clock_getres(td, uap->clock_id, &ts);
2315151357Sps	if (error == 0) {
2316151357Sps		CP(ts, ts32, tv_sec);
2317151357Sps		CP(ts, ts32, tv_nsec);
2318151357Sps		error = copyout(&ts32, uap->tp, sizeof(ts32));
2319151357Sps	}
2320151357Sps	return (error);
2321151357Sps}
2322151357Sps
2323162551Sdavidxuint
2324162551Sdavidxufreebsd32_thr_new(struct thread *td,
2325162551Sdavidxu		  struct freebsd32_thr_new_args *uap)
2326162551Sdavidxu{
2327162551Sdavidxu	struct thr_param32 param32;
2328162551Sdavidxu	struct thr_param param;
2329162551Sdavidxu	int error;
2330162551Sdavidxu
2331162551Sdavidxu	if (uap->param_size < 0 ||
2332162551Sdavidxu	    uap->param_size > sizeof(struct thr_param32))
2333162551Sdavidxu		return (EINVAL);
2334162551Sdavidxu	bzero(&param, sizeof(struct thr_param));
2335162551Sdavidxu	bzero(&param32, sizeof(struct thr_param32));
2336162551Sdavidxu	error = copyin(uap->param, &param32, uap->param_size);
2337162551Sdavidxu	if (error != 0)
2338162551Sdavidxu		return (error);
2339162551Sdavidxu	param.start_func = PTRIN(param32.start_func);
2340162551Sdavidxu	param.arg = PTRIN(param32.arg);
2341162551Sdavidxu	param.stack_base = PTRIN(param32.stack_base);
2342162551Sdavidxu	param.stack_size = param32.stack_size;
2343162551Sdavidxu	param.tls_base = PTRIN(param32.tls_base);
2344162551Sdavidxu	param.tls_size = param32.tls_size;
2345162551Sdavidxu	param.child_tid = PTRIN(param32.child_tid);
2346162551Sdavidxu	param.parent_tid = PTRIN(param32.parent_tid);
2347162551Sdavidxu	param.flags = param32.flags;
2348162551Sdavidxu	param.rtp = PTRIN(param32.rtp);
2349162551Sdavidxu	param.spare[0] = PTRIN(param32.spare[0]);
2350162551Sdavidxu	param.spare[1] = PTRIN(param32.spare[1]);
2351162551Sdavidxu	param.spare[2] = PTRIN(param32.spare[2]);
2352162551Sdavidxu
2353162551Sdavidxu	return (kern_thr_new(td, &param));
2354162551Sdavidxu}
2355162551Sdavidxu
2356162551Sdavidxuint
2357162551Sdavidxufreebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
2358162551Sdavidxu{
2359162551Sdavidxu	struct timespec32 ts32;
2360162551Sdavidxu	struct timespec ts, *tsp;
2361162551Sdavidxu	int error;
2362162551Sdavidxu
2363162551Sdavidxu	error = 0;
2364162551Sdavidxu	tsp = NULL;
2365162551Sdavidxu	if (uap->timeout != NULL) {
2366162551Sdavidxu		error = copyin((const void *)uap->timeout, (void *)&ts32,
2367162551Sdavidxu		    sizeof(struct timespec32));
2368162551Sdavidxu		if (error != 0)
2369162551Sdavidxu			return (error);
2370162551Sdavidxu		ts.tv_sec = ts32.tv_sec;
2371162551Sdavidxu		ts.tv_nsec = ts32.tv_nsec;
2372162551Sdavidxu		tsp = &ts;
2373162551Sdavidxu	}
2374162551Sdavidxu	return (kern_thr_suspend(td, tsp));
2375162551Sdavidxu}
2376162551Sdavidxu
2377163018Sdavidxuvoid
2378163018Sdavidxusiginfo_to_siginfo32(siginfo_t *src, struct siginfo32 *dst)
2379163018Sdavidxu{
2380163018Sdavidxu	bzero(dst, sizeof(*dst));
2381163018Sdavidxu	dst->si_signo = src->si_signo;
2382163018Sdavidxu	dst->si_errno = src->si_errno;
2383163018Sdavidxu	dst->si_code = src->si_code;
2384163018Sdavidxu	dst->si_pid = src->si_pid;
2385163018Sdavidxu	dst->si_uid = src->si_uid;
2386163018Sdavidxu	dst->si_status = src->si_status;
2387163018Sdavidxu	dst->si_addr = dst->si_addr;
2388163018Sdavidxu	dst->si_value.sigval_int = src->si_value.sival_int;
2389163018Sdavidxu	dst->si_timerid = src->si_timerid;
2390163018Sdavidxu	dst->si_overrun = src->si_overrun;
2391163018Sdavidxu}
2392163018Sdavidxu
2393163018Sdavidxuint
2394163018Sdavidxufreebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
2395163018Sdavidxu{
2396163018Sdavidxu	struct timespec32 ts32;
2397163018Sdavidxu	struct timespec ts;
2398163018Sdavidxu	struct timespec *timeout;
2399163018Sdavidxu	sigset_t set;
2400163018Sdavidxu	ksiginfo_t ksi;
2401163018Sdavidxu	struct siginfo32 si32;
2402163018Sdavidxu	int error;
2403163018Sdavidxu
2404163018Sdavidxu	if (uap->timeout) {
2405163018Sdavidxu		error = copyin(uap->timeout, &ts32, sizeof(ts32));
2406163018Sdavidxu		if (error)
2407163018Sdavidxu			return (error);
2408163018Sdavidxu		ts.tv_sec = ts32.tv_sec;
2409163018Sdavidxu		ts.tv_nsec = ts32.tv_nsec;
2410163018Sdavidxu		timeout = &ts;
2411163018Sdavidxu	} else
2412163018Sdavidxu		timeout = NULL;
2413163018Sdavidxu
2414163018Sdavidxu	error = copyin(uap->set, &set, sizeof(set));
2415163018Sdavidxu	if (error)
2416163018Sdavidxu		return (error);
2417163018Sdavidxu
2418163018Sdavidxu	error = kern_sigtimedwait(td, set, &ksi, timeout);
2419163018Sdavidxu	if (error)
2420163018Sdavidxu		return (error);
2421163018Sdavidxu
2422163018Sdavidxu	if (uap->info) {
2423163018Sdavidxu		siginfo_to_siginfo32(&ksi.ksi_info, &si32);
2424163018Sdavidxu		error = copyout(&si32, uap->info, sizeof(struct siginfo32));
2425163018Sdavidxu	}
2426163018Sdavidxu
2427163018Sdavidxu	if (error == 0)
2428163018Sdavidxu		td->td_retval[0] = ksi.ksi_signo;
2429163018Sdavidxu	return (error);
2430163018Sdavidxu}
2431163018Sdavidxu
2432163018Sdavidxu/*
2433163018Sdavidxu * MPSAFE
2434163018Sdavidxu */
2435163018Sdavidxuint
2436163018Sdavidxufreebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
2437163018Sdavidxu{
2438163018Sdavidxu	ksiginfo_t ksi;
2439163018Sdavidxu	struct siginfo32 si32;
2440163018Sdavidxu	sigset_t set;
2441163018Sdavidxu	int error;
2442163018Sdavidxu
2443163018Sdavidxu	error = copyin(uap->set, &set, sizeof(set));
2444163018Sdavidxu	if (error)
2445163018Sdavidxu		return (error);
2446163018Sdavidxu
2447163018Sdavidxu	error = kern_sigtimedwait(td, set, &ksi, NULL);
2448163018Sdavidxu	if (error)
2449163018Sdavidxu		return (error);
2450163018Sdavidxu
2451163018Sdavidxu	if (uap->info) {
2452163018Sdavidxu		siginfo_to_siginfo32(&ksi.ksi_info, &si32);
2453163018Sdavidxu		error = copyout(&si32, uap->info, sizeof(struct siginfo32));
2454163018Sdavidxu	}
2455163018Sdavidxu	if (error == 0)
2456163018Sdavidxu		td->td_retval[0] = ksi.ksi_signo;
2457163018Sdavidxu	return (error);
2458163018Sdavidxu}
2459163018Sdavidxu
2460100384Speter#if 0
2461100384Speter
2462100384Speterint
2463119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
2464100384Speter{
2465100384Speter	int error;
2466100384Speter	struct yyy32 *p32, s32;
2467100384Speter	struct yyy *p = NULL, s;
2468100384Speter
2469147654Sjhb	if (uap->zzz) {
2470147654Sjhb		error = copyin(uap->zzz, &s32, sizeof(s32));
2471100384Speter		if (error)
2472100384Speter			return (error);
2473100384Speter		/* translate in */
2474147654Sjhb		p = &s;
2475100384Speter	}
2476147654Sjhb	error = kern_xxx(td, p);
2477100384Speter	if (error)
2478100384Speter		return (error);
2479147654Sjhb	if (uap->zzz) {
2480100384Speter		/* translate out */
2481100384Speter		error = copyout(&s32, p32, sizeof(s32));
2482100384Speter	}
2483100384Speter	return (error);
2484100384Speter}
2485100384Speter
2486100384Speter#endif
2487