netbsd32_netbsd.c revision 1.16 1 /* $NetBSD: netbsd32_netbsd.c,v 1.16 1999/07/20 21:54:05 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1998 Matthew R. Green
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 #include "opt_ktrace.h"
32 #include "opt_ntp.h"
33 #include "opt_compat_freebsd.h"
34 #include "opt_compat_linux.h"
35 #include "opt_compat_sunos.h"
36 #include "opt_compat_43.h"
37 #if defined(COMPAT_43) || defined(COMPAT_SUNOS) || defined(COMPAT_LINUX) || \
38 defined(COMPAT_FREEBSD)
39 #define COMPAT_OLDSOCK /* used by <sys/socket.h> */
40 #endif
41
42 #include "fs_lfs.h"
43 #include "fs_nfs.h"
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/ipc.h>
49 #include <sys/msg.h>
50 #include <sys/sem.h>
51 #include <sys/shm.h>
52 #include <sys/malloc.h>
53 #include <sys/mount.h>
54 #include <sys/socket.h>
55 #include <sys/sockio.h>
56 #include <sys/socketvar.h>
57 #include <sys/mbuf.h>
58 #include <sys/stat.h>
59 #include <sys/time.h>
60 #include <sys/timex.h>
61 #include <sys/signalvar.h>
62 #include <sys/wait.h>
63 #include <sys/ptrace.h>
64 #include <sys/ktrace.h>
65 #include <sys/trace.h>
66 #include <sys/resourcevar.h>
67 #include <sys/pool.h>
68 #include <sys/vnode.h>
69 #include <sys/file.h>
70 #include <sys/filedesc.h>
71 #include <sys/namei.h>
72
73 #include <vm/vm.h>
74 #include <sys/syscallargs.h>
75 #include <sys/proc.h>
76 #include <sys/sysctl.h>
77
78 #include <net/if.h>
79
80 #include <compat/netbsd32/netbsd32.h>
81 #include <compat/netbsd32/netbsd32_syscallargs.h>
82
83 #include <machine/frame.h>
84
85 static __inline void netbsd32_from_timeval __P((struct timeval *, struct netbsd32_timeval *));
86 static __inline void netbsd32_to_timeval __P((struct netbsd32_timeval *, struct timeval *));
87 static __inline void netbsd32_from_itimerval __P((struct itimerval *, struct netbsd32_itimerval *));
88 static __inline void netbsd32_to_itimerval __P((struct netbsd32_itimerval *, struct itimerval *));
89 static __inline void netbsd32_to_timespec __P((struct netbsd32_timespec *, struct timespec *));
90 static __inline void netbsd32_from_timespec __P((struct timespec *, struct netbsd32_timespec *));
91 static __inline void netbsd32_from_rusage __P((struct rusage *, struct netbsd32_rusage *));
92 static __inline void netbsd32_to_rusage __P((struct netbsd32_rusage *, struct rusage *));
93 static __inline int netbsd32_to_iovecin __P((struct netbsd32_iovec *, struct iovec *, int));
94 static __inline void netbsd32_to_msghdr __P((struct netbsd32_msghdr *, struct msghdr *));
95 static __inline void netbsd32_from_msghdr __P((struct netbsd32_msghdr *, struct msghdr *));
96 static __inline void netbsd32_from_statfs __P((struct statfs *, struct netbsd32_statfs *));
97 static __inline void netbsd32_from_timex __P((struct timex *, struct netbsd32_timex *));
98 static __inline void netbsd32_to_timex __P((struct netbsd32_timex *, struct timex *));
99 static __inline void netbsd32_from___stat13 __P((struct stat *, struct netbsd32_stat *));
100 static __inline void netbsd32_to_ipc_perm __P((struct netbsd32_ipc_perm *, struct ipc_perm *));
101 static __inline void netbsd32_from_ipc_perm __P((struct ipc_perm *, struct netbsd32_ipc_perm *));
102 static __inline void netbsd32_to_msg __P((struct netbsd32_msg *, struct msg *));
103 static __inline void netbsd32_from_msg __P((struct msg *, struct netbsd32_msg *));
104 static __inline void netbsd32_to_msqid_ds __P((struct netbsd32_msqid_ds *, struct msqid_ds *));
105 static __inline void netbsd32_from_msqid_ds __P((struct msqid_ds *, struct netbsd32_msqid_ds *));
106 static __inline void netbsd32_to_shmid_ds __P((struct netbsd32_shmid_ds *, struct shmid_ds *));
107 static __inline void netbsd32_from_shmid_ds __P((struct shmid_ds *, struct netbsd32_shmid_ds *));
108 static __inline void netbsd32_to_semid_ds __P((struct netbsd32_semid_ds *, struct semid_ds *));
109 static __inline void netbsd32_from_semid_ds __P((struct semid_ds *, struct netbsd32_semid_ds *));
110
111
112 static int recvit32 __P((struct proc *, int, struct netbsd32_msghdr *, struct iovec *, caddr_t,
113 register_t *));
114 static int dofilereadv32 __P((struct proc *, int, struct file *, struct netbsd32_iovec *,
115 int, off_t *, int, register_t *));
116 static int dofilewritev32 __P((struct proc *, int, struct file *, struct netbsd32_iovec *,
117 int, off_t *, int, register_t *));
118 static int change_utimes32 __P((struct vnode *, struct timeval *, struct proc *));
119
120 /* converters for structures that we need */
121 static __inline void
122 netbsd32_from_timeval(tv, tv32)
123 struct timeval *tv;
124 struct netbsd32_timeval *tv32;
125 {
126
127 tv32->tv_sec = (netbsd32_long)tv->tv_sec;
128 tv32->tv_usec = (netbsd32_long)tv->tv_usec;
129 }
130
131 static __inline void
132 netbsd32_to_timeval(tv32, tv)
133 struct netbsd32_timeval *tv32;
134 struct timeval *tv;
135 {
136
137 tv->tv_sec = (long)tv32->tv_sec;
138 tv->tv_usec = (long)tv32->tv_usec;
139 }
140
141 static __inline void
142 netbsd32_from_itimerval(itv, itv32)
143 struct itimerval *itv;
144 struct netbsd32_itimerval *itv32;
145 {
146
147 netbsd32_from_timeval(&itv->it_interval,
148 &itv32->it_interval);
149 netbsd32_from_timeval(&itv->it_value,
150 &itv32->it_value);
151 }
152
153 static __inline void
154 netbsd32_to_itimerval(itv32, itv)
155 struct netbsd32_itimerval *itv32;
156 struct itimerval *itv;
157 {
158
159 netbsd32_to_timeval(&itv32->it_interval, &itv->it_interval);
160 netbsd32_to_timeval(&itv32->it_value, &itv->it_value);
161 }
162
163 static __inline void
164 netbsd32_to_timespec(s32p, p)
165 struct netbsd32_timespec *s32p;
166 struct timespec *p;
167 {
168
169 p->tv_sec = s32p->tv_sec;
170 p->tv_nsec = (long)s32p->tv_nsec;
171 }
172
173 static __inline void
174 netbsd32_from_timespec(p, s32p)
175 struct timespec *p;
176 struct netbsd32_timespec *s32p;
177 {
178
179 s32p->tv_sec = p->tv_sec;
180 s32p->tv_nsec = (netbsd32_long)p->tv_nsec;
181 }
182
183 static __inline void
184 netbsd32_from_rusage(rup, ru32p)
185 struct rusage *rup;
186 struct netbsd32_rusage *ru32p;
187 {
188
189 netbsd32_from_timeval(&rup->ru_utime, &ru32p->ru_utime);
190 netbsd32_from_timeval(&rup->ru_stime, &ru32p->ru_stime);
191 #define C(var) ru32p->var = (netbsd32_long)rup->var
192 C(ru_maxrss);
193 C(ru_ixrss);
194 C(ru_idrss);
195 C(ru_isrss);
196 C(ru_minflt);
197 C(ru_majflt);
198 C(ru_nswap);
199 C(ru_inblock);
200 C(ru_oublock);
201 C(ru_msgsnd);
202 C(ru_msgrcv);
203 C(ru_nsignals);
204 C(ru_nvcsw);
205 C(ru_nivcsw);
206 #undef C
207 }
208
209 static __inline void
210 netbsd32_to_rusage(ru32p, rup)
211 struct netbsd32_rusage *ru32p;
212 struct rusage *rup;
213 {
214
215 netbsd32_to_timeval(&ru32p->ru_utime, &rup->ru_utime);
216 netbsd32_to_timeval(&ru32p->ru_stime, &rup->ru_stime);
217 #define C(var) rup->var = (long)ru32p->var
218 C(ru_maxrss);
219 C(ru_ixrss);
220 C(ru_idrss);
221 C(ru_isrss);
222 C(ru_minflt);
223 C(ru_majflt);
224 C(ru_nswap);
225 C(ru_inblock);
226 C(ru_oublock);
227 C(ru_msgsnd);
228 C(ru_msgrcv);
229 C(ru_nsignals);
230 C(ru_nvcsw);
231 C(ru_nivcsw);
232 #undef C
233 }
234
235 static __inline int
236 netbsd32_to_iovecin(iov32p, iovp, len)
237 struct netbsd32_iovec *iov32p;
238 struct iovec *iovp;
239 int len;
240 {
241 int i, error=0;
242 u_int32_t iov_base;
243 u_int32_t iov_len;
244 /*
245 * We could allocate an iov32p, do a copyin, and translate
246 * each field and then free it all up, or we could copyin
247 * each field separately. I'm doing the latter to reduce
248 * the number of MALLOC()s.
249 */
250 printf("converting iovec at %p len %lx to %p\n", iov32p, len, iovp);
251 for (i = 0; i < len; i++, iovp++, iov32p++) {
252 if ((error = copyin((caddr_t)&iov32p->iov_base, &iov_base, sizeof(iov_base))))
253 return (error);
254 if ((error = copyin((caddr_t)&iov32p->iov_len, &iov_len, sizeof(iov_len))))
255 return (error);
256 iovp->iov_base = (void *)(u_long)iov_base;
257 iovp->iov_len = (size_t)iov_len;
258 printf("iovec slot %d base %p len %lx\n", i, iovp->iov_base, iovp->iov_len);
259 }
260 }
261
262 /* msg_iov must be done separately */
263 static __inline void
264 netbsd32_to_msghdr(mhp32, mhp)
265 struct netbsd32_msghdr *mhp32;
266 struct msghdr *mhp;
267 {
268
269 mhp->msg_name = (caddr_t)(u_long)mhp32->msg_name;
270 mhp->msg_namelen = mhp32->msg_namelen;
271 mhp->msg_iovlen = (size_t)mhp32->msg_iovlen;
272 mhp->msg_control = (caddr_t)(u_long)mhp32->msg_control;
273 mhp->msg_controllen = mhp32->msg_controllen;
274 mhp->msg_flags = mhp32->msg_flags;
275 }
276
277 /* msg_iov must be done separately */
278 static __inline void
279 netbsd32_from_msghdr(mhp32, mhp)
280 struct netbsd32_msghdr *mhp32;
281 struct msghdr *mhp;
282 {
283
284 mhp32->msg_name = mhp32->msg_name;
285 mhp32->msg_namelen = mhp32->msg_namelen;
286 mhp32->msg_iovlen = mhp32->msg_iovlen;
287 mhp32->msg_control = mhp32->msg_control;
288 mhp32->msg_controllen = mhp->msg_controllen;
289 mhp32->msg_flags = mhp->msg_flags;
290 }
291
292 static __inline void
293 netbsd32_from_statfs(sbp, sb32p)
294 struct statfs *sbp;
295 struct netbsd32_statfs *sb32p;
296 {
297
298 sb32p->f_type = sbp->f_type;
299 sb32p->f_flags = sbp->f_flags;
300 sb32p->f_bsize = (netbsd32_long)sbp->f_bsize;
301 sb32p->f_iosize = (netbsd32_long)sbp->f_iosize;
302 sb32p->f_blocks = (netbsd32_long)sbp->f_blocks;
303 sb32p->f_bfree = (netbsd32_long)sbp->f_bfree;
304 sb32p->f_bavail = (netbsd32_long)sbp->f_bavail;
305 sb32p->f_files = (netbsd32_long)sbp->f_files;
306 sb32p->f_ffree = (netbsd32_long)sbp->f_ffree;
307 sb32p->f_fsid = sbp->f_fsid;
308 sb32p->f_owner = sbp->f_owner;
309 sb32p->f_spare[0] = 0;
310 sb32p->f_spare[1] = 0;
311 sb32p->f_spare[2] = 0;
312 sb32p->f_spare[3] = 0;
313 #if 1
314 /* May as well do the whole batch in one go */
315 memcpy(sb32p->f_fstypename, sbp->f_fstypename, MFSNAMELEN+MNAMELEN+MNAMELEN);
316 #else
317 /* If we want to be careful */
318 memcpy(sb32p->f_fstypename, sbp->f_fstypename, MFSNAMELEN);
319 memcpy(sb32p->f_mntonname, sbp->f_mntonname, MNAMELEN);
320 memcpy(sb32p->f_mntfromname, sbp->f_mntfromname, MNAMELEN);
321 #endif
322 }
323
324 static __inline void
325 netbsd32_from_timex(txp, tx32p)
326 struct timex *txp;
327 struct netbsd32_timex *tx32p;
328 {
329
330 tx32p->modes = txp->modes;
331 tx32p->offset = (netbsd32_long)txp->offset;
332 tx32p->freq = (netbsd32_long)txp->freq;
333 tx32p->maxerror = (netbsd32_long)txp->maxerror;
334 tx32p->esterror = (netbsd32_long)txp->esterror;
335 tx32p->status = txp->status;
336 tx32p->constant = (netbsd32_long)txp->constant;
337 tx32p->precision = (netbsd32_long)txp->precision;
338 tx32p->tolerance = (netbsd32_long)txp->tolerance;
339 tx32p->ppsfreq = (netbsd32_long)txp->ppsfreq;
340 tx32p->jitter = (netbsd32_long)txp->jitter;
341 tx32p->shift = txp->shift;
342 tx32p->stabil = (netbsd32_long)txp->stabil;
343 tx32p->jitcnt = (netbsd32_long)txp->jitcnt;
344 tx32p->calcnt = (netbsd32_long)txp->calcnt;
345 tx32p->errcnt = (netbsd32_long)txp->errcnt;
346 tx32p->stbcnt = (netbsd32_long)txp->stbcnt;
347 }
348
349 static __inline void
350 netbsd32_to_timex(tx32p, txp)
351 struct netbsd32_timex *tx32p;
352 struct timex *txp;
353 {
354
355 txp->modes = tx32p->modes;
356 txp->offset = (long)tx32p->offset;
357 txp->freq = (long)tx32p->freq;
358 txp->maxerror = (long)tx32p->maxerror;
359 txp->esterror = (long)tx32p->esterror;
360 txp->status = tx32p->status;
361 txp->constant = (long)tx32p->constant;
362 txp->precision = (long)tx32p->precision;
363 txp->tolerance = (long)tx32p->tolerance;
364 txp->ppsfreq = (long)tx32p->ppsfreq;
365 txp->jitter = (long)tx32p->jitter;
366 txp->shift = tx32p->shift;
367 txp->stabil = (long)tx32p->stabil;
368 txp->jitcnt = (long)tx32p->jitcnt;
369 txp->calcnt = (long)tx32p->calcnt;
370 txp->errcnt = (long)tx32p->errcnt;
371 txp->stbcnt = (long)tx32p->stbcnt;
372 }
373
374 static __inline void
375 netbsd32_from___stat13(sbp, sb32p)
376 struct stat *sbp;
377 struct netbsd32_stat *sb32p;
378 {
379 sb32p->st_dev = sbp->st_dev;
380 sb32p->st_ino = sbp->st_ino;
381 sb32p->st_mode = sbp->st_mode;
382 sb32p->st_nlink = sbp->st_nlink;
383 sb32p->st_uid = sbp->st_uid;
384 sb32p->st_gid = sbp->st_gid;
385 sb32p->st_rdev = sbp->st_rdev;
386 if (sbp->st_size < (quad_t)1 << 32)
387 sb32p->st_size = sbp->st_size;
388 else
389 sb32p->st_size = -2;
390 sb32p->st_atimespec.tv_sec = sbp->st_atimespec.tv_sec;
391 sb32p->st_atimespec.tv_nsec = (netbsd32_long)sbp->st_atimespec.tv_nsec;
392 sb32p->st_mtimespec.tv_sec = sbp->st_mtimespec.tv_sec;
393 sb32p->st_mtimespec.tv_nsec = (netbsd32_long)sbp->st_mtimespec.tv_nsec;
394 sb32p->st_ctimespec.tv_sec = sbp->st_ctimespec.tv_sec;
395 sb32p->st_ctimespec.tv_nsec = (netbsd32_long)sbp->st_ctimespec.tv_nsec;
396 sb32p->st_blksize = sbp->st_blksize;
397 sb32p->st_blocks = sbp->st_blocks;
398 sb32p->st_flags = sbp->st_flags;
399 sb32p->st_gen = sbp->st_gen;
400 }
401
402 static __inline void
403 netbsd32_to_ipc_perm(ip32p, ipp)
404 struct netbsd32_ipc_perm *ip32p;
405 struct ipc_perm *ipp;
406 {
407
408 ipp->cuid = ip32p->cuid;
409 ipp->cgid = ip32p->cgid;
410 ipp->uid = ip32p->uid;
411 ipp->gid = ip32p->gid;
412 ipp->mode = ip32p->mode;
413 ipp->seq = ip32p->seq;
414 ipp->key = (key_t)ip32p->key;
415 }
416
417 static __inline void
418 netbsd32_from_ipc_perm(ipp, ip32p)
419 struct ipc_perm *ipp;
420 struct netbsd32_ipc_perm *ip32p;
421 {
422
423 ip32p->cuid = ipp->cuid;
424 ip32p->cgid = ipp->cgid;
425 ip32p->uid = ipp->uid;
426 ip32p->gid = ipp->gid;
427 ip32p->mode = ipp->mode;
428 ip32p->seq = ipp->seq;
429 ip32p->key = (netbsd32_key_t)ipp->key;
430 }
431
432 static __inline void
433 netbsd32_to_msg(m32p, mp)
434 struct netbsd32_msg *m32p;
435 struct msg *mp;
436 {
437
438 mp->msg_next = (struct msg *)(u_long)m32p->msg_next;
439 mp->msg_type = (long)m32p->msg_type;
440 mp->msg_ts = m32p->msg_ts;
441 mp->msg_spot = m32p->msg_spot;
442 }
443
444 static __inline void
445 netbsd32_from_msg(mp, m32p)
446 struct msg *mp;
447 struct netbsd32_msg *m32p;
448 {
449
450 m32p->msg_next = (netbsd32_msgp_t)(u_long)mp->msg_next;
451 m32p->msg_type = (netbsd32_long)mp->msg_type;
452 m32p->msg_ts = mp->msg_ts;
453 m32p->msg_spot = mp->msg_spot;
454 }
455
456 static __inline void
457 netbsd32_to_msqid_ds(ds32p, dsp)
458 struct netbsd32_msqid_ds *ds32p;
459 struct msqid_ds *dsp;
460 {
461
462 netbsd32_to_ipc_perm(&ds32p->msg_perm, &dsp->msg_perm);
463 netbsd32_to_msg((struct netbsd32_msg *)(u_long)ds32p->msg_first, dsp->msg_first);
464 netbsd32_to_msg((struct netbsd32_msg *)(u_long)ds32p->msg_last, dsp->msg_last);
465 dsp->msg_cbytes = (u_long)ds32p->msg_cbytes;
466 dsp->msg_qnum = (u_long)ds32p->msg_qnum;
467 dsp->msg_qbytes = (u_long)ds32p->msg_qbytes;
468 dsp->msg_lspid = ds32p->msg_lspid;
469 dsp->msg_lrpid = ds32p->msg_lrpid;
470 dsp->msg_rtime = (time_t)ds32p->msg_rtime;
471 dsp->msg_stime = (time_t)ds32p->msg_stime;
472 dsp->msg_ctime = (time_t)ds32p->msg_ctime;
473 }
474
475 static __inline void
476 netbsd32_from_msqid_ds(dsp, ds32p)
477 struct msqid_ds *dsp;
478 struct netbsd32_msqid_ds *ds32p;
479 {
480
481 netbsd32_from_ipc_perm(&dsp->msg_perm, &ds32p->msg_perm);
482 netbsd32_from_msg(dsp->msg_first, (struct netbsd32_msg *)(u_long)ds32p->msg_first);
483 netbsd32_from_msg(dsp->msg_last, (struct netbsd32_msg *)(u_long)ds32p->msg_last);
484 ds32p->msg_cbytes = (netbsd32_u_long)dsp->msg_cbytes;
485 ds32p->msg_qnum = (netbsd32_u_long)dsp->msg_qnum;
486 ds32p->msg_qbytes = (netbsd32_u_long)dsp->msg_qbytes;
487 ds32p->msg_lspid = dsp->msg_lspid;
488 ds32p->msg_lrpid = dsp->msg_lrpid;
489 ds32p->msg_rtime = dsp->msg_rtime;
490 ds32p->msg_stime = dsp->msg_stime;
491 ds32p->msg_ctime = dsp->msg_ctime;
492 }
493
494 static __inline void
495 netbsd32_to_shmid_ds(ds32p, dsp)
496 struct netbsd32_shmid_ds *ds32p;
497 struct shmid_ds *dsp;
498 {
499
500 netbsd32_to_ipc_perm(&ds32p->shm_perm, &dsp->shm_perm);
501 dsp->shm_segsz = ds32p->shm_segsz;
502 dsp->shm_lpid = ds32p->shm_lpid;
503 dsp->shm_cpid = ds32p->shm_cpid;
504 dsp->shm_nattch = ds32p->shm_nattch;
505 dsp->shm_atime = (long)ds32p->shm_atime;
506 dsp->shm_dtime = (long)ds32p->shm_dtime;
507 dsp->shm_ctime = (long)ds32p->shm_ctime;
508 dsp->shm_internal = (void *)(u_long)ds32p->shm_internal;
509 }
510
511 static __inline void
512 netbsd32_from_shmid_ds(dsp, ds32p)
513 struct shmid_ds *dsp;
514 struct netbsd32_shmid_ds *ds32p;
515 {
516
517 netbsd32_from_ipc_perm(&dsp->shm_perm, &ds32p->shm_perm);
518 ds32p->shm_segsz = dsp->shm_segsz;
519 ds32p->shm_lpid = dsp->shm_lpid;
520 ds32p->shm_cpid = dsp->shm_cpid;
521 ds32p->shm_nattch = dsp->shm_nattch;
522 ds32p->shm_atime = (netbsd32_long)dsp->shm_atime;
523 ds32p->shm_dtime = (netbsd32_long)dsp->shm_dtime;
524 ds32p->shm_ctime = (netbsd32_long)dsp->shm_ctime;
525 ds32p->shm_internal = (netbsd32_voidp)(u_long)dsp->shm_internal;
526 }
527
528 static __inline void
529 netbsd32_to_semid_ds(s32dsp, dsp)
530 struct netbsd32_semid_ds *s32dsp;
531 struct semid_ds *dsp;
532 {
533
534 netbsd32_from_ipc_perm(&dsp->sem_perm, &s32dsp->sem_perm);
535 dsp->sem_base = (struct sem *)(u_long)s32dsp->sem_base;
536 dsp->sem_nsems = s32dsp->sem_nsems;
537 dsp->sem_otime = s32dsp->sem_otime;
538 dsp->sem_ctime = s32dsp->sem_ctime;
539 }
540
541 static __inline void
542 netbsd32_from_semid_ds(dsp, s32dsp)
543 struct semid_ds *dsp;
544 struct netbsd32_semid_ds *s32dsp;
545 {
546
547 netbsd32_to_ipc_perm(&s32dsp->sem_perm, &dsp->sem_perm);
548 s32dsp->sem_base = (netbsd32_semp_t)(u_long)dsp->sem_base;
549 s32dsp->sem_nsems = dsp->sem_nsems;
550 s32dsp->sem_otime = dsp->sem_otime;
551 s32dsp->sem_ctime = dsp->sem_ctime;
552 }
553
554 /*
555 * below are all the standard NetBSD system calls, in the 32bit
556 * environment, witht he necessary conversions to 64bit before
557 * calling the real syscall.
558 */
559
560
561 int
562 compat_netbsd32_exit(p, v, retval)
563 struct proc *p;
564 void *v;
565 register_t *retval;
566 {
567 struct compat_netbsd32_exit_args /* {
568 syscallarg(int) rval;
569 } */ *uap = v;
570 struct sys_exit_args ua;
571
572 NETBSD32TO64_UAP(rval);
573 sys_exit(p, &ua, retval);
574 }
575
576 int
577 compat_netbsd32_read(p, v, retval)
578 struct proc *p;
579 void *v;
580 register_t *retval;
581 {
582 struct compat_netbsd32_read_args /* {
583 syscallarg(int) fd;
584 syscallarg(netbsd32_voidp) buf;
585 syscallarg(netbsd32_size_t) nbyte;
586 } */ *uap = v;
587 struct sys_read_args ua;
588
589 NETBSD32TO64_UAP(fd);
590 NETBSD32TOP_UAP(buf, void *);
591 NETBSD32TOX_UAP(nbyte, size_t);
592 return sys_read(p, &ua, retval);
593 }
594
595 int
596 compat_netbsd32_write(p, v, retval)
597 struct proc *p;
598 void *v;
599 register_t *retval;
600 {
601 struct compat_netbsd32_write_args /* {
602 syscallarg(int) fd;
603 syscallarg(const netbsd32_voidp) buf;
604 syscallarg(netbsd32_size_t) nbyte;
605 } */ *uap = v;
606 struct sys_write_args ua;
607
608 NETBSD32TO64_UAP(fd);
609 NETBSD32TOP_UAP(buf, void *);
610 NETBSD32TOX_UAP(nbyte, size_t);
611 return sys_write(p, &ua, retval);
612 }
613
614 int
615 compat_netbsd32_close(p, v, retval)
616 struct proc *p;
617 void *v;
618 register_t *retval;
619 {
620 struct compat_netbsd32_close_args /* {
621 syscallarg(int) fd;
622 } */ *uap = v;
623 struct sys_close_args ua;
624
625 NETBSD32TO64_UAP(fd);
626 return sys_write(p, &ua, retval);
627 }
628
629 int
630 compat_netbsd32_open(p, v, retval)
631 struct proc *p;
632 void *v;
633 register_t *retval;
634 {
635 struct compat_netbsd32_open_args /* {
636 syscallarg(const netbsd32_charp) path;
637 syscallarg(int) flags;
638 syscallarg(mode_t) mode;
639 } */ *uap = v;
640 struct sys_open_args ua;
641 caddr_t sg;
642
643 NETBSD32TOP_UAP(path, const char);
644 NETBSD32TO64_UAP(flags);
645 NETBSD32TO64_UAP(mode);
646 sg = stackgap_init(p->p_emul);
647 NETBSD32_CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
648
649 return (sys_open(p, &ua, retval));
650 }
651
652 int
653 compat_netbsd32_wait4(q, v, retval)
654 struct proc *q;
655 void *v;
656 register_t *retval;
657 {
658 struct compat_netbsd32_wait4_args /* {
659 syscallarg(int) pid;
660 syscallarg(netbsd32_intp) status;
661 syscallarg(int) options;
662 syscallarg(netbsd32_rusagep_t) rusage;
663 } */ *uap = v;
664 struct netbsd32_rusage ru32;
665 register int nfound;
666 register struct proc *p, *t;
667 int status, error;
668
669 if (SCARG(uap, pid) == 0)
670 SCARG(uap, pid) = -q->p_pgid;
671 if (SCARG(uap, options) &~ (WUNTRACED|WNOHANG))
672 return (EINVAL);
673
674 loop:
675 nfound = 0;
676 for (p = q->p_children.lh_first; p != 0; p = p->p_sibling.le_next) {
677 if (SCARG(uap, pid) != WAIT_ANY &&
678 p->p_pid != SCARG(uap, pid) &&
679 p->p_pgid != -SCARG(uap, pid))
680 continue;
681 nfound++;
682 if (p->p_stat == SZOMB) {
683 retval[0] = p->p_pid;
684
685 if (SCARG(uap, status)) {
686 status = p->p_xstat; /* convert to int */
687 error = copyout((caddr_t)&status,
688 (caddr_t)(u_long)SCARG(uap, status),
689 sizeof(status));
690 if (error)
691 return (error);
692 }
693 if (SCARG(uap, rusage)) {
694 netbsd32_from_rusage(p->p_ru, &ru32);
695 if ((error = copyout((caddr_t)&ru32,
696 (caddr_t)(u_long)SCARG(uap, rusage),
697 sizeof(struct netbsd32_rusage))))
698 return (error);
699 }
700 /*
701 * If we got the child via ptrace(2) or procfs, and
702 * the parent is different (meaning the process was
703 * attached, rather than run as a child), then we need
704 * to give it back to the old parent, and send the
705 * parent a SIGCHLD. The rest of the cleanup will be
706 * done when the old parent waits on the child.
707 */
708 if ((p->p_flag & P_TRACED) &&
709 p->p_oppid != p->p_pptr->p_pid) {
710 t = pfind(p->p_oppid);
711 proc_reparent(p, t ? t : initproc);
712 p->p_oppid = 0;
713 p->p_flag &= ~(P_TRACED|P_WAITED|P_FSTRACE);
714 psignal(p->p_pptr, SIGCHLD);
715 wakeup((caddr_t)p->p_pptr);
716 return (0);
717 }
718 p->p_xstat = 0;
719 ruadd(&q->p_stats->p_cru, p->p_ru);
720 pool_put(&rusage_pool, p->p_ru);
721
722 /*
723 * Finally finished with old proc entry.
724 * Unlink it from its process group and free it.
725 */
726 leavepgrp(p);
727
728 LIST_REMOVE(p, p_list); /* off zombproc */
729
730 LIST_REMOVE(p, p_sibling);
731
732 /*
733 * Decrement the count of procs running with this uid.
734 */
735 (void)chgproccnt(p->p_cred->p_ruid, -1);
736
737 /*
738 * Free up credentials.
739 */
740 if (--p->p_cred->p_refcnt == 0) {
741 crfree(p->p_cred->pc_ucred);
742 pool_put(&pcred_pool, p->p_cred);
743 }
744
745 /*
746 * Release reference to text vnode
747 */
748 if (p->p_textvp)
749 vrele(p->p_textvp);
750
751 pool_put(&proc_pool, p);
752 nprocs--;
753 return (0);
754 }
755 if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
756 (p->p_flag & P_TRACED || SCARG(uap, options) & WUNTRACED)) {
757 p->p_flag |= P_WAITED;
758 retval[0] = p->p_pid;
759
760 if (SCARG(uap, status)) {
761 status = W_STOPCODE(p->p_xstat);
762 error = copyout((caddr_t)&status,
763 (caddr_t)(u_long)SCARG(uap, status),
764 sizeof(status));
765 } else
766 error = 0;
767 return (error);
768 }
769 }
770 if (nfound == 0)
771 return (ECHILD);
772 if (SCARG(uap, options) & WNOHANG) {
773 retval[0] = 0;
774 return (0);
775 }
776 if ((error = tsleep((caddr_t)q, PWAIT | PCATCH, "wait", 0)) != 0)
777 return (error);
778 goto loop;
779 }
780
781 int
782 compat_netbsd32_link(p, v, retval)
783 struct proc *p;
784 void *v;
785 register_t *retval;
786 {
787 struct compat_netbsd32_link_args /* {
788 syscallarg(const netbsd32_charp) path;
789 syscallarg(const netbsd32_charp) link;
790 } */ *uap = v;
791 struct sys_link_args ua;
792
793 NETBSD32TOP_UAP(path, const char);
794 NETBSD32TOP_UAP(link, const char);
795 return (sys_link(p, &ua, retval));
796 }
797
798 int
799 compat_netbsd32_unlink(p, v, retval)
800 struct proc *p;
801 void *v;
802 register_t *retval;
803 {
804 struct compat_netbsd32_unlink_args /* {
805 syscallarg(const netbsd32_charp) path;
806 } */ *uap = v;
807 struct sys_unlink_args ua;
808
809 NETBSD32TOP_UAP(path, const char);
810
811 return (sys_unlink(p, &ua, retval));
812 }
813
814 int
815 compat_netbsd32_chdir(p, v, retval)
816 struct proc *p;
817 void *v;
818 register_t *retval;
819 {
820 struct compat_netbsd32_chdir_args /* {
821 syscallarg(const netbsd32_charp) path;
822 } */ *uap = v;
823 struct sys_chdir_args ua;
824
825 NETBSD32TOP_UAP(path, const char);
826
827 return (sys_chdir(p, &ua, retval));
828 }
829
830 int
831 compat_netbsd32_fchdir(p, v, retval)
832 struct proc *p;
833 void *v;
834 register_t *retval;
835 {
836 struct compat_netbsd32_fchdir_args /* {
837 syscallarg(int) fd;
838 } */ *uap = v;
839 struct sys_fchdir_args ua;
840
841 NETBSD32TO64_UAP(fd);
842
843 return (sys_fchdir(p, &ua, retval));
844 }
845
846 int
847 compat_netbsd32_mknod(p, v, retval)
848 struct proc *p;
849 void *v;
850 register_t *retval;
851 {
852 struct compat_netbsd32_mknod_args /* {
853 syscallarg(const netbsd32_charp) path;
854 syscallarg(mode_t) mode;
855 syscallarg(dev_t) dev;
856 } */ *uap = v;
857 struct sys_mknod_args ua;
858
859 NETBSD32TOP_UAP(path, const char);
860 NETBSD32TO64_UAP(dev);
861 NETBSD32TO64_UAP(mode);
862
863 return (sys_mknod(p, &ua, retval));
864 }
865
866 int
867 compat_netbsd32_chmod(p, v, retval)
868 struct proc *p;
869 void *v;
870 register_t *retval;
871 {
872 struct compat_netbsd32_chmod_args /* {
873 syscallarg(const netbsd32_charp) path;
874 syscallarg(mode_t) mode;
875 } */ *uap = v;
876 struct sys_chmod_args ua;
877
878 NETBSD32TOP_UAP(path, const char);
879 NETBSD32TO64_UAP(mode);
880
881 return (sys_chmod(p, &ua, retval));
882 }
883
884 int
885 compat_netbsd32_chown(p, v, retval)
886 struct proc *p;
887 void *v;
888 register_t *retval;
889 {
890 struct compat_netbsd32_chown_args /* {
891 syscallarg(const netbsd32_charp) path;
892 syscallarg(uid_t) uid;
893 syscallarg(gid_t) gid;
894 } */ *uap = v;
895 struct sys_chown_args ua;
896
897 NETBSD32TOP_UAP(path, const char);
898 NETBSD32TO64_UAP(uid);
899 NETBSD32TO64_UAP(gid);
900
901 return (sys_chown(p, &ua, retval));
902 }
903
904 int
905 compat_netbsd32_break(p, v, retval)
906 struct proc *p;
907 void *v;
908 register_t *retval;
909 {
910 struct compat_netbsd32_break_args /* {
911 syscallarg(netbsd32_charp) nsize;
912 } */ *uap = v;
913 struct sys_obreak_args ua;
914
915 SCARG(&ua, nsize) = (char *)(u_long)SCARG(uap, nsize);
916 NETBSD32TOP_UAP(nsize, char);
917 return (sys_obreak(p, &ua, retval));
918 }
919
920 int
921 compat_netbsd32_getfsstat(p, v, retval)
922 struct proc *p;
923 void *v;
924 register_t *retval;
925 {
926 struct compat_netbsd32_getfsstat_args /* {
927 syscallarg(netbsd32_statfsp_t) buf;
928 syscallarg(netbsd32_long) bufsize;
929 syscallarg(int) flags;
930 } */ *uap = v;
931 struct sys_getfsstat_args ua;
932 struct statfs sb;
933 struct netbsd32_statfs *sb32p;
934 int error;
935
936 sb32p = (struct netbsd32_statfs *)(u_long)SCARG(uap, buf);
937 if (sb32p)
938 SCARG(&ua, buf) = &sb;
939 else
940 SCARG(&ua, buf) = NULL;
941 NETBSD32TOX_UAP(bufsize, long);
942 NETBSD32TO64_UAP(flags);
943 error = sys_getfsstat(p, &ua, retval);
944 if (error)
945 return (error);
946
947 if (sb32p) {
948 struct netbsd32_statfs sb32;
949 netbsd32_from_statfs(&sb, &sb32);
950 if (copyout(&sb32, sb32p, sizeof(sb32)))
951 return EFAULT;
952 }
953 return (0);
954 }
955
956 int
957 compat_netbsd32_mount(p, v, retval)
958 struct proc *p;
959 void *v;
960 register_t *retval;
961 {
962 struct compat_netbsd32_mount_args /* {
963 syscallarg(const netbsd32_charp) type;
964 syscallarg(const netbsd32_charp) path;
965 syscallarg(int) flags;
966 syscallarg(netbsd32_voidp) data;
967 } */ *uap = v;
968 struct sys_mount_args ua;
969
970 NETBSD32TOP_UAP(type, const char);
971 NETBSD32TOP_UAP(path, const char);
972 NETBSD32TO64_UAP(flags);
973 NETBSD32TOP_UAP(data, void);
974 return (sys_mount(p, &ua, retval));
975 }
976
977 int
978 compat_netbsd32_unmount(p, v, retval)
979 struct proc *p;
980 void *v;
981 register_t *retval;
982 {
983 struct compat_netbsd32_unmount_args /* {
984 syscallarg(const netbsd32_charp) path;
985 syscallarg(int) flags;
986 } */ *uap = v;
987 struct sys_unmount_args ua;
988
989 NETBSD32TOP_UAP(path, const char);
990 NETBSD32TO64_UAP(flags);
991 return (sys_unmount(p, &ua, retval));
992 }
993
994 int
995 compat_netbsd32_setuid(p, v, retval)
996 struct proc *p;
997 void *v;
998 register_t *retval;
999 {
1000 struct compat_netbsd32_setuid_args /* {
1001 syscallarg(uid_t) uid;
1002 } */ *uap = v;
1003 struct sys_setuid_args ua;
1004
1005 NETBSD32TO64_UAP(uid);
1006 return (sys_setuid(p, &ua, retval));
1007 }
1008
1009 int
1010 compat_netbsd32_ptrace(p, v, retval)
1011 struct proc *p;
1012 void *v;
1013 register_t *retval;
1014 {
1015 struct compat_netbsd32_ptrace_args /* {
1016 syscallarg(int) req;
1017 syscallarg(pid_t) pid;
1018 syscallarg(netbsd32_caddr_t) addr;
1019 syscallarg(int) data;
1020 } */ *uap = v;
1021 struct sys_ptrace_args ua;
1022
1023 NETBSD32TO64_UAP(req);
1024 NETBSD32TO64_UAP(pid);
1025 NETBSD32TOX64_UAP(addr, caddr_t);
1026 NETBSD32TO64_UAP(data);
1027 return (sys_ptrace(p, &ua, retval));
1028 }
1029
1030 int
1031 compat_netbsd32_recvmsg(p, v, retval)
1032 struct proc *p;
1033 void *v;
1034 register_t *retval;
1035 {
1036 struct compat_netbsd32_recvmsg_args /* {
1037 syscallarg(int) s;
1038 syscallarg(netbsd32_msghdrp_t) msg;
1039 syscallarg(int) flags;
1040 } */ *uap = v;
1041 struct netbsd32_msghdr msg;
1042 struct iovec aiov[UIO_SMALLIOV], *uiov, *iov;
1043 register int error;
1044
1045 error = copyin((caddr_t)(u_long)SCARG(uap, msg), (caddr_t)&msg,
1046 sizeof(msg));
1047 /* netbsd32_msghdr needs the iov pre-allocated */
1048 if (error)
1049 return (error);
1050 if ((u_int)msg.msg_iovlen > UIO_SMALLIOV) {
1051 if ((u_int)msg.msg_iovlen > IOV_MAX)
1052 return (EMSGSIZE);
1053 MALLOC(iov, struct iovec *,
1054 sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
1055 M_WAITOK);
1056 } else if ((u_int)msg.msg_iovlen > 0)
1057 iov = aiov;
1058 else
1059 return (EMSGSIZE);
1060 #ifdef COMPAT_OLDSOCK
1061 msg.msg_flags = SCARG(uap, flags) &~ MSG_COMPAT;
1062 #else
1063 msg.msg_flags = SCARG(uap, flags);
1064 #endif
1065 uiov = (struct iovec *)(u_long)msg.msg_iov;
1066 error = netbsd32_to_iovecin((struct netbsd32_iovec *)uiov,
1067 iov, msg.msg_iovlen);
1068 if (error)
1069 goto done;
1070 if ((error = recvit32(p, SCARG(uap, s), &msg, iov, (caddr_t)0, retval)) == 0) {
1071 error = copyout((caddr_t)&msg, (caddr_t)(u_long)SCARG(uap, msg),
1072 sizeof(msg));
1073 }
1074 done:
1075 if (iov != aiov)
1076 FREE(iov, M_IOV);
1077 return (error);
1078 }
1079
1080 int
1081 recvit32(p, s, mp, iov, namelenp, retsize)
1082 struct proc *p;
1083 int s;
1084 struct netbsd32_msghdr *mp;
1085 struct iovec *iov;
1086 caddr_t namelenp;
1087 register_t *retsize;
1088 {
1089 struct file *fp;
1090 struct uio auio;
1091 register int i;
1092 int len, error;
1093 struct mbuf *from = 0, *control = 0;
1094 struct socket *so;
1095 #ifdef KTRACE
1096 struct iovec *ktriov = NULL;
1097 #endif
1098
1099 /* getsock() will use the descriptor for us */
1100 if ((error = getsock(p->p_fd, s, &fp)) != 0)
1101 return (error);
1102 auio.uio_iov = (struct iovec *)(u_long)mp->msg_iov;
1103 auio.uio_iovcnt = mp->msg_iovlen;
1104 auio.uio_segflg = UIO_USERSPACE;
1105 auio.uio_rw = UIO_READ;
1106 auio.uio_procp = p;
1107 auio.uio_offset = 0; /* XXX */
1108 auio.uio_resid = 0;
1109 for (i = 0; i < mp->msg_iovlen; i++, iov++) {
1110 #if 0
1111 /* cannot happen iov_len is unsigned */
1112 if (iov->iov_len < 0) {
1113 error = EINVAL;
1114 goto out1;
1115 }
1116 #endif
1117 /*
1118 * Reads return ssize_t because -1 is returned on error.
1119 * Therefore we must restrict the length to SSIZE_MAX to
1120 * avoid garbage return values.
1121 */
1122 auio.uio_resid += iov->iov_len;
1123 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
1124 error = EINVAL;
1125 goto out1;
1126 }
1127 }
1128 #ifdef KTRACE
1129 if (KTRPOINT(p, KTR_GENIO)) {
1130 int iovlen = auio.uio_iovcnt * sizeof(struct iovec);
1131
1132 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
1133 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
1134 }
1135 #endif
1136 len = auio.uio_resid;
1137 so = (struct socket *)fp->f_data;
1138 error = (*so->so_receive)(so, &from, &auio, NULL,
1139 mp->msg_control ? &control : NULL, &mp->msg_flags);
1140 if (error) {
1141 if (auio.uio_resid != len && (error == ERESTART ||
1142 error == EINTR || error == EWOULDBLOCK))
1143 error = 0;
1144 }
1145 #ifdef KTRACE
1146 if (ktriov != NULL) {
1147 if (error == 0)
1148 ktrgenio(p->p_tracep, s, UIO_READ,
1149 ktriov, len - auio.uio_resid, error);
1150 FREE(ktriov, M_TEMP);
1151 }
1152 #endif
1153 if (error)
1154 goto out;
1155 *retsize = len - auio.uio_resid;
1156 if (mp->msg_name) {
1157 len = mp->msg_namelen;
1158 if (len <= 0 || from == 0)
1159 len = 0;
1160 else {
1161 #ifdef COMPAT_OLDSOCK
1162 if (mp->msg_flags & MSG_COMPAT)
1163 mtod(from, struct osockaddr *)->sa_family =
1164 mtod(from, struct sockaddr *)->sa_family;
1165 #endif
1166 if (len > from->m_len)
1167 len = from->m_len;
1168 /* else if len < from->m_len ??? */
1169 error = copyout(mtod(from, caddr_t),
1170 (caddr_t)(u_long)mp->msg_name, (unsigned)len);
1171 if (error)
1172 goto out;
1173 }
1174 mp->msg_namelen = len;
1175 if (namelenp &&
1176 (error = copyout((caddr_t)&len, namelenp, sizeof(int)))) {
1177 #ifdef COMPAT_OLDSOCK
1178 if (mp->msg_flags & MSG_COMPAT)
1179 error = 0; /* old recvfrom didn't check */
1180 else
1181 #endif
1182 goto out;
1183 }
1184 }
1185 if (mp->msg_control) {
1186 #ifdef COMPAT_OLDSOCK
1187 /*
1188 * We assume that old recvmsg calls won't receive access
1189 * rights and other control info, esp. as control info
1190 * is always optional and those options didn't exist in 4.3.
1191 * If we receive rights, trim the cmsghdr; anything else
1192 * is tossed.
1193 */
1194 if (control && mp->msg_flags & MSG_COMPAT) {
1195 if (mtod(control, struct cmsghdr *)->cmsg_level !=
1196 SOL_SOCKET ||
1197 mtod(control, struct cmsghdr *)->cmsg_type !=
1198 SCM_RIGHTS) {
1199 mp->msg_controllen = 0;
1200 goto out;
1201 }
1202 control->m_len -= sizeof(struct cmsghdr);
1203 control->m_data += sizeof(struct cmsghdr);
1204 }
1205 #endif
1206 len = mp->msg_controllen;
1207 if (len <= 0 || control == 0)
1208 len = 0;
1209 else {
1210 struct mbuf *m = control;
1211 caddr_t p = (caddr_t)(u_long)mp->msg_control;
1212
1213 do {
1214 i = m->m_len;
1215 if (len < i) {
1216 mp->msg_flags |= MSG_CTRUNC;
1217 i = len;
1218 }
1219 error = copyout(mtod(m, caddr_t), p,
1220 (unsigned)i);
1221 if (m->m_next)
1222 i = ALIGN(i);
1223 p += i;
1224 len -= i;
1225 if (error != 0 || len <= 0)
1226 break;
1227 } while ((m = m->m_next) != NULL);
1228 len = p - (caddr_t)(u_long)mp->msg_control;
1229 }
1230 mp->msg_controllen = len;
1231 }
1232 out:
1233 if (from)
1234 m_freem(from);
1235 if (control)
1236 m_freem(control);
1237 out1:
1238 FILE_UNUSE(fp);
1239 return (error);
1240 }
1241
1242
1243 int
1244 compat_netbsd32_sendmsg(p, v, retval)
1245 struct proc *p;
1246 void *v;
1247 register_t *retval;
1248 {
1249 struct compat_netbsd32_sendmsg_args /* {
1250 syscallarg(int) s;
1251 syscallarg(const netbsd32_msghdrp_t) msg;
1252 syscallarg(int) flags;
1253 } */ *uap = v;
1254 struct msghdr msg;
1255 struct netbsd32_msghdr msg32;
1256 struct iovec aiov[UIO_SMALLIOV], *iov;
1257 int error;
1258
1259 error = copyin((caddr_t)(u_long)SCARG(uap, msg),
1260 (caddr_t)&msg32, sizeof(msg32));
1261 if (error)
1262 return (error);
1263 netbsd32_to_msghdr(&msg32, &msg);
1264 if ((u_int)msg.msg_iovlen > UIO_SMALLIOV) {
1265 if ((u_int)msg.msg_iovlen > IOV_MAX)
1266 return (EMSGSIZE);
1267 MALLOC(iov, struct iovec *,
1268 sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV,
1269 M_WAITOK);
1270 } else if ((u_int)msg.msg_iovlen > 0)
1271 iov = aiov;
1272 else
1273 return (EMSGSIZE);
1274 error = netbsd32_to_iovecin((struct netbsd32_iovec *)msg.msg_iov,
1275 iov, msg.msg_iovlen);
1276 if (error)
1277 goto done;
1278 msg.msg_iov = iov;
1279 #ifdef COMPAT_OLDSOCK
1280 msg.msg_flags = 0;
1281 #endif
1282 /* Luckily we can use this directly */
1283 error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
1284 done:
1285 if (iov != aiov)
1286 FREE(iov, M_IOV);
1287 return (error);
1288 }
1289
1290 int
1291 compat_netbsd32_recvfrom(p, v, retval)
1292 struct proc *p;
1293 void *v;
1294 register_t *retval;
1295 {
1296 struct compat_netbsd32_recvfrom_args /* {
1297 syscallarg(int) s;
1298 syscallarg(netbsd32_voidp) buf;
1299 syscallarg(netbsd32_size_t) len;
1300 syscallarg(int) flags;
1301 syscallarg(netbsd32_sockaddrp_t) from;
1302 syscallarg(netbsd32_intp) fromlenaddr;
1303 } */ *uap = v;
1304 struct netbsd32_msghdr msg;
1305 struct iovec aiov;
1306 int error;
1307
1308 if (SCARG(uap, fromlenaddr)) {
1309 error = copyin((caddr_t)(u_long)SCARG(uap, fromlenaddr),
1310 (caddr_t)&msg.msg_namelen,
1311 sizeof(msg.msg_namelen));
1312 if (error)
1313 return (error);
1314 } else
1315 msg.msg_namelen = 0;
1316 msg.msg_name = SCARG(uap, from);
1317 msg.msg_iov = NULL; /* We can't store a real pointer here */
1318 msg.msg_iovlen = 1;
1319 aiov.iov_base = (caddr_t)(u_long)SCARG(uap, buf);
1320 aiov.iov_len = (u_long)SCARG(uap, len);
1321 msg.msg_control = 0;
1322 msg.msg_flags = SCARG(uap, flags);
1323 return (recvit32(p, SCARG(uap, s), &msg, &aiov,
1324 (caddr_t)(u_long)SCARG(uap, fromlenaddr), retval));
1325 }
1326
1327 int
1328 compat_netbsd32_sendto(p, v, retval)
1329 struct proc *p;
1330 void *v;
1331 register_t *retval;
1332 {
1333 struct compat_netbsd32_sendto_args /* {
1334 syscallarg(int) s;
1335 syscallarg(const netbsd32_voidp) buf;
1336 syscallarg(netbsd32_size_t) len;
1337 syscallarg(int) flags;
1338 syscallarg(const netbsd32_sockaddrp_t) to;
1339 syscallarg(int) tolen;
1340 } */ *uap = v;
1341 struct msghdr msg;
1342 struct iovec aiov;
1343
1344 msg.msg_name = (caddr_t)(u_long)SCARG(uap, to); /* XXX kills const */
1345 msg.msg_namelen = SCARG(uap, tolen);
1346 msg.msg_iov = &aiov;
1347 msg.msg_iovlen = 1;
1348 msg.msg_control = 0;
1349 #ifdef COMPAT_OLDSOCK
1350 msg.msg_flags = 0;
1351 #endif
1352 aiov.iov_base = (char *)(u_long)SCARG(uap, buf); /* XXX kills const */
1353 aiov.iov_len = SCARG(uap, len);
1354 return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval));
1355 }
1356
1357 int
1358 compat_netbsd32_accept(p, v, retval)
1359 struct proc *p;
1360 void *v;
1361 register_t *retval;
1362 {
1363 struct compat_netbsd32_accept_args /* {
1364 syscallarg(int) s;
1365 syscallarg(netbsd32_sockaddrp_t) name;
1366 syscallarg(netbsd32_intp) anamelen;
1367 } */ *uap = v;
1368 struct sys_accept_args ua;
1369
1370 NETBSD32TO64_UAP(s);
1371 NETBSD32TOP_UAP(name, struct sockaddr);
1372 NETBSD32TOP_UAP(anamelen, int);
1373 return (sys_accept(p, &ua, retval));
1374 }
1375
1376 int
1377 compat_netbsd32_getpeername(p, v, retval)
1378 struct proc *p;
1379 void *v;
1380 register_t *retval;
1381 {
1382 struct compat_netbsd32_getpeername_args /* {
1383 syscallarg(int) fdes;
1384 syscallarg(netbsd32_sockaddrp_t) asa;
1385 syscallarg(netbsd32_intp) alen;
1386 } */ *uap = v;
1387 struct sys_getpeername_args ua;
1388
1389 NETBSD32TO64_UAP(fdes);
1390 NETBSD32TOP_UAP(asa, struct sockaddr);
1391 NETBSD32TOP_UAP(alen, int);
1392 /* NB: do the protocol specific sockaddrs need to be converted? */
1393 return (sys_getpeername(p, &ua, retval));
1394 }
1395
1396 int
1397 compat_netbsd32_getsockname(p, v, retval)
1398 struct proc *p;
1399 void *v;
1400 register_t *retval;
1401 {
1402 struct compat_netbsd32_getsockname_args /* {
1403 syscallarg(int) fdes;
1404 syscallarg(netbsd32_sockaddrp_t) asa;
1405 syscallarg(netbsd32_intp) alen;
1406 } */ *uap = v;
1407 struct sys_getsockname_args ua;
1408
1409 NETBSD32TO64_UAP(fdes);
1410 NETBSD32TOP_UAP(asa, struct sockaddr);
1411 NETBSD32TOP_UAP(alen, int);
1412 return (sys_getsockname(p, &ua, retval));
1413 }
1414
1415 int
1416 compat_netbsd32_access(p, v, retval)
1417 struct proc *p;
1418 void *v;
1419 register_t *retval;
1420 {
1421 struct compat_netbsd32_access_args /* {
1422 syscallarg(const netbsd32_charp) path;
1423 syscallarg(int) flags;
1424 } */ *uap = v;
1425 struct sys_access_args ua;
1426 caddr_t sg;
1427
1428 NETBSD32TOP_UAP(path, const char);
1429 NETBSD32TO64_UAP(flags);
1430 sg = stackgap_init(p->p_emul);
1431 NETBSD32_CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
1432
1433 return (sys_access(p, &ua, retval));
1434 }
1435
1436 int
1437 compat_netbsd32_chflags(p, v, retval)
1438 struct proc *p;
1439 void *v;
1440 register_t *retval;
1441 {
1442 struct compat_netbsd32_chflags_args /* {
1443 syscallarg(const netbsd32_charp) path;
1444 syscallarg(netbsd32_u_long) flags;
1445 } */ *uap = v;
1446 struct sys_chflags_args ua;
1447
1448 NETBSD32TOP_UAP(path, const char);
1449 NETBSD32TO64_UAP(flags);
1450
1451 return (sys_chflags(p, &ua, retval));
1452 }
1453
1454 int
1455 compat_netbsd32_fchflags(p, v, retval)
1456 struct proc *p;
1457 void *v;
1458 register_t *retval;
1459 {
1460 struct compat_netbsd32_fchflags_args /* {
1461 syscallarg(int) fd;
1462 syscallarg(netbsd32_u_long) flags;
1463 } */ *uap = v;
1464 struct sys_fchflags_args ua;
1465
1466 NETBSD32TO64_UAP(fd);
1467 NETBSD32TO64_UAP(flags);
1468
1469 return (sys_fchflags(p, &ua, retval));
1470 }
1471
1472 int
1473 compat_netbsd32_kill(p, v, retval)
1474 struct proc *p;
1475 void *v;
1476 register_t *retval;
1477 {
1478 struct compat_netbsd32_kill_args /* {
1479 syscallarg(int) pid;
1480 syscallarg(int) signum;
1481 } */ *uap = v;
1482 struct sys_kill_args ua;
1483
1484 NETBSD32TO64_UAP(pid);
1485 NETBSD32TO64_UAP(signum);
1486
1487 return (sys_kill(p, &ua, retval));
1488 }
1489
1490 int
1491 compat_netbsd32_dup(p, v, retval)
1492 struct proc *p;
1493 void *v;
1494 register_t *retval;
1495 {
1496 struct compat_netbsd32_dup_args /* {
1497 syscallarg(int) fd;
1498 } */ *uap = v;
1499 struct sys_dup_args ua;
1500
1501 NETBSD32TO64_UAP(fd);
1502
1503 return (sys_dup(p, &ua, retval));
1504 }
1505
1506 int
1507 compat_netbsd32_profil(p, v, retval)
1508 struct proc *p;
1509 void *v;
1510 register_t *retval;
1511 {
1512 struct compat_netbsd32_profil_args /* {
1513 syscallarg(netbsd32_caddr_t) samples;
1514 syscallarg(netbsd32_size_t) size;
1515 syscallarg(netbsd32_u_long) offset;
1516 syscallarg(u_int) scale;
1517 } */ *uap = v;
1518 struct sys_profil_args ua;
1519
1520 NETBSD32TOX64_UAP(samples, caddr_t);
1521 NETBSD32TOX_UAP(size, size_t);
1522 NETBSD32TOX_UAP(offset, u_long);
1523 NETBSD32TO64_UAP(scale);
1524 return (sys_profil(p, &ua, retval));
1525 }
1526
1527 int
1528 compat_netbsd32_ktrace(p, v, retval)
1529 struct proc *p;
1530 void *v;
1531 register_t *retval;
1532 {
1533 struct compat_netbsd32_ktrace_args /* {
1534 syscallarg(const netbsd32_charp) fname;
1535 syscallarg(int) ops;
1536 syscallarg(int) facs;
1537 syscallarg(int) pid;
1538 } */ *uap = v;
1539 struct sys_ktrace_args ua;
1540
1541 NETBSD32TOP_UAP(fname, const char);
1542 NETBSD32TO64_UAP(ops);
1543 NETBSD32TO64_UAP(facs);
1544 NETBSD32TO64_UAP(pid);
1545 return (sys_ktrace(p, &ua, retval));
1546 }
1547
1548 int
1549 compat_netbsd32_sigaction(p, v, retval)
1550 struct proc *p;
1551 void *v;
1552 register_t *retval;
1553 {
1554 struct compat_netbsd32_sigaction_args /* {
1555 syscallarg(int) signum;
1556 syscallarg(const netbsd32_sigactionp_t) nsa;
1557 syscallarg(netbsd32_sigactionp_t) osa;
1558 } */ *uap = v;
1559 struct sigaction nsa, osa;
1560 struct netbsd32_sigaction *sa32p, sa32;
1561 int error;
1562
1563 if (SCARG(uap, nsa)) {
1564 sa32p = (struct netbsd32_sigaction *)(u_long)SCARG(uap, nsa);
1565 if (copyin(sa32p, &sa32, sizeof(sa32)))
1566 return EFAULT;
1567 nsa.sa_handler = (void *)(u_long)sa32.sa_handler;
1568 nsa.sa_mask = sa32.sa_mask;
1569 nsa.sa_flags = sa32.sa_flags;
1570 }
1571 error = sigaction1(p, SCARG(uap, signum),
1572 SCARG(uap, nsa) ? &nsa : 0,
1573 SCARG(uap, osa) ? &osa : 0);
1574
1575 if (error)
1576 return (error);
1577
1578 if (SCARG(uap, osa)) {
1579 sa32.sa_handler = (netbsd32_sigactionp_t)(u_long)osa.sa_handler;
1580 sa32.sa_mask = osa.sa_mask;
1581 sa32.sa_flags = osa.sa_flags;
1582 sa32p = (struct netbsd32_sigaction *)(u_long)SCARG(uap, osa);
1583 if (copyout(&sa32, sa32p, sizeof(sa32)))
1584 return EFAULT;
1585 }
1586
1587 return (0);
1588 }
1589
1590 int
1591 compat_netbsd32___getlogin(p, v, retval)
1592 struct proc *p;
1593 void *v;
1594 register_t *retval;
1595 {
1596 struct compat_netbsd32___getlogin_args /* {
1597 syscallarg(netbsd32_charp) namebuf;
1598 syscallarg(u_int) namelen;
1599 } */ *uap = v;
1600 struct sys___getlogin_args ua;
1601
1602 NETBSD32TOP_UAP(namebuf, char);
1603 NETBSD32TO64_UAP(namelen);
1604 return (sys___getlogin(p, &ua, retval));
1605 }
1606
1607 int
1608 compat_netbsd32_setlogin(p, v, retval)
1609 struct proc *p;
1610 void *v;
1611 register_t *retval;
1612 {
1613 struct compat_netbsd32_setlogin_args /* {
1614 syscallarg(const netbsd32_charp) namebuf;
1615 } */ *uap = v;
1616 struct sys_setlogin_args ua;
1617
1618 NETBSD32TOP_UAP(namebuf, char);
1619 return (sys_setlogin(p, &ua, retval));
1620 }
1621
1622 int
1623 compat_netbsd32_acct(p, v, retval)
1624 struct proc *p;
1625 void *v;
1626 register_t *retval;
1627 {
1628 struct compat_netbsd32_acct_args /* {
1629 syscallarg(const netbsd32_charp) path;
1630 } */ *uap = v;
1631 struct sys_acct_args ua;
1632
1633 NETBSD32TOP_UAP(path, const char);
1634 return (sys_acct(p, &ua, retval));
1635 }
1636
1637 int
1638 compat_netbsd32_revoke(p, v, retval)
1639 struct proc *p;
1640 void *v;
1641 register_t *retval;
1642 {
1643 struct compat_netbsd32_revoke_args /* {
1644 syscallarg(const netbsd32_charp) path;
1645 } */ *uap = v;
1646 struct sys_revoke_args ua;
1647 caddr_t sg;
1648
1649 NETBSD32TOP_UAP(path, const char);
1650 sg = stackgap_init(p->p_emul);
1651 NETBSD32_CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
1652
1653 return (sys_revoke(p, &ua, retval));
1654 }
1655
1656 int
1657 compat_netbsd32_symlink(p, v, retval)
1658 struct proc *p;
1659 void *v;
1660 register_t *retval;
1661 {
1662 struct compat_netbsd32_symlink_args /* {
1663 syscallarg(const netbsd32_charp) path;
1664 syscallarg(const netbsd32_charp) link;
1665 } */ *uap = v;
1666 struct sys_symlink_args ua;
1667
1668 NETBSD32TOP_UAP(path, const char);
1669 NETBSD32TOP_UAP(link, const char);
1670
1671 return (sys_symlink(p, &ua, retval));
1672 }
1673
1674 int
1675 compat_netbsd32_readlink(p, v, retval)
1676 struct proc *p;
1677 void *v;
1678 register_t *retval;
1679 {
1680 struct compat_netbsd32_readlink_args /* {
1681 syscallarg(const netbsd32_charp) path;
1682 syscallarg(netbsd32_charp) buf;
1683 syscallarg(netbsd32_size_t) count;
1684 } */ *uap = v;
1685 struct sys_readlink_args ua;
1686 caddr_t sg;
1687
1688 NETBSD32TOP_UAP(path, const char);
1689 NETBSD32TOP_UAP(buf, char);
1690 NETBSD32TOX_UAP(count, size_t);
1691 sg = stackgap_init(p->p_emul);
1692 NETBSD32_CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
1693
1694 return (sys_readlink(p, &ua, retval));
1695 }
1696
1697 int
1698 compat_netbsd32_execve(p, v, retval)
1699 struct proc *p;
1700 void *v;
1701 register_t *retval;
1702 {
1703 struct compat_netbsd32_execve_args /* {
1704 syscallarg(const netbsd32_charp) path;
1705 syscallarg(netbsd32_charpp) argp;
1706 syscallarg(netbsd32_charpp) envp;
1707 } */ *uap = v;
1708 struct sys_execve_args ua;
1709 caddr_t sg;
1710
1711 NETBSD32TOP_UAP(path, const char);
1712 NETBSD32TOP_UAP(argp, char *);
1713 NETBSD32TOP_UAP(envp, char *);
1714 sg = stackgap_init(p->p_emul);
1715 NETBSD32_CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
1716
1717 return (sys_execve(p, &ua, retval));
1718 }
1719
1720 int
1721 compat_netbsd32_umask(p, v, retval)
1722 struct proc *p;
1723 void *v;
1724 register_t *retval;
1725 {
1726 struct compat_netbsd32_umask_args /* {
1727 syscallarg(mode_t) newmask;
1728 } */ *uap = v;
1729 struct sys_umask_args ua;
1730
1731 NETBSD32TO64_UAP(newmask);
1732 return (sys_umask(p, &ua, retval));
1733 }
1734
1735 int
1736 compat_netbsd32_chroot(p, v, retval)
1737 struct proc *p;
1738 void *v;
1739 register_t *retval;
1740 {
1741 struct compat_netbsd32_chroot_args /* {
1742 syscallarg(const netbsd32_charp) path;
1743 } */ *uap = v;
1744 struct sys_chroot_args ua;
1745
1746 NETBSD32TOP_UAP(path, const char);
1747 return (sys_chroot(p, &ua, retval));
1748 }
1749
1750 int
1751 compat_netbsd32_sbrk(p, v, retval)
1752 struct proc *p;
1753 void *v;
1754 register_t *retval;
1755 {
1756 struct compat_netbsd32_sbrk_args /* {
1757 syscallarg(int) incr;
1758 } */ *uap = v;
1759 struct sys_sbrk_args ua;
1760
1761 NETBSD32TO64_UAP(incr);
1762 return (sys_sbrk(p, &ua, retval));
1763 }
1764
1765 int
1766 compat_netbsd32_sstk(p, v, retval)
1767 struct proc *p;
1768 void *v;
1769 register_t *retval;
1770 {
1771 struct compat_netbsd32_sstk_args /* {
1772 syscallarg(int) incr;
1773 } */ *uap = v;
1774 struct sys_sstk_args ua;
1775
1776 NETBSD32TO64_UAP(incr);
1777 return (sys_sstk(p, &ua, retval));
1778 }
1779
1780 int
1781 compat_netbsd32_munmap(p, v, retval)
1782 struct proc *p;
1783 void *v;
1784 register_t *retval;
1785 {
1786 struct compat_netbsd32_munmap_args /* {
1787 syscallarg(netbsd32_voidp) addr;
1788 syscallarg(netbsd32_size_t) len;
1789 } */ *uap = v;
1790 struct sys_munmap_args ua;
1791
1792 NETBSD32TOP_UAP(addr, void);
1793 NETBSD32TOX_UAP(len, size_t);
1794 return (sys_munmap(p, &ua, retval));
1795 }
1796
1797 int
1798 compat_netbsd32_mprotect(p, v, retval)
1799 struct proc *p;
1800 void *v;
1801 register_t *retval;
1802 {
1803 struct compat_netbsd32_mprotect_args /* {
1804 syscallarg(netbsd32_voidp) addr;
1805 syscallarg(netbsd32_size_t) len;
1806 syscallarg(int) prot;
1807 } */ *uap = v;
1808 struct sys_mprotect_args ua;
1809
1810 NETBSD32TOP_UAP(addr, void);
1811 NETBSD32TOX_UAP(len, size_t);
1812 NETBSD32TO64_UAP(prot);
1813 return (sys_mprotect(p, &ua, retval));
1814 }
1815
1816 int
1817 compat_netbsd32_madvise(p, v, retval)
1818 struct proc *p;
1819 void *v;
1820 register_t *retval;
1821 {
1822 struct compat_netbsd32_madvise_args /* {
1823 syscallarg(netbsd32_voidp) addr;
1824 syscallarg(netbsd32_size_t) len;
1825 syscallarg(int) behav;
1826 } */ *uap = v;
1827 struct sys_madvise_args ua;
1828
1829 NETBSD32TOP_UAP(addr, void);
1830 NETBSD32TOX_UAP(len, size_t);
1831 NETBSD32TO64_UAP(behav);
1832 return (sys_madvise(p, &ua, retval));
1833 }
1834
1835 int
1836 compat_netbsd32_mincore(p, v, retval)
1837 struct proc *p;
1838 void *v;
1839 register_t *retval;
1840 {
1841 struct compat_netbsd32_mincore_args /* {
1842 syscallarg(netbsd32_caddr_t) addr;
1843 syscallarg(netbsd32_size_t) len;
1844 syscallarg(netbsd32_charp) vec;
1845 } */ *uap = v;
1846 struct sys_mincore_args ua;
1847
1848 NETBSD32TOX64_UAP(addr, caddr_t);
1849 NETBSD32TOX_UAP(len, size_t);
1850 NETBSD32TOP_UAP(vec, char);
1851 return (sys_mincore(p, &ua, retval));
1852 }
1853
1854 int
1855 compat_netbsd32_getgroups(p, v, retval)
1856 struct proc *p;
1857 void *v;
1858 register_t *retval;
1859 {
1860 struct compat_netbsd32_getgroups_args /* {
1861 syscallarg(int) gidsetsize;
1862 syscallarg(netbsd32_gid_tp) gidset;
1863 } */ *uap = v;
1864 register struct pcred *pc = p->p_cred;
1865 register int ngrp;
1866 int error;
1867
1868 ngrp = SCARG(uap, gidsetsize);
1869 if (ngrp == 0) {
1870 *retval = pc->pc_ucred->cr_ngroups;
1871 return (0);
1872 }
1873 if (ngrp < pc->pc_ucred->cr_ngroups)
1874 return (EINVAL);
1875 ngrp = pc->pc_ucred->cr_ngroups;
1876 /* Should convert gid_t to netbsd32_gid_t, but they're the same */
1877 error = copyout((caddr_t)pc->pc_ucred->cr_groups,
1878 (caddr_t)(u_long)SCARG(uap, gidset),
1879 ngrp * sizeof(gid_t));
1880 if (error)
1881 return (error);
1882 *retval = ngrp;
1883 return (0);
1884 }
1885
1886 int
1887 compat_netbsd32_setgroups(p, v, retval)
1888 struct proc *p;
1889 void *v;
1890 register_t *retval;
1891 {
1892 struct compat_netbsd32_setgroups_args /* {
1893 syscallarg(int) gidsetsize;
1894 syscallarg(const netbsd32_gid_tp) gidset;
1895 } */ *uap = v;
1896 struct sys_setgroups_args ua;
1897
1898 NETBSD32TO64_UAP(gidsetsize);
1899 NETBSD32TOP_UAP(gidset, gid_t);
1900 return (sys_setgroups(p, &ua, retval));
1901 }
1902
1903 int
1904 compat_netbsd32_setpgid(p, v, retval)
1905 struct proc *p;
1906 void *v;
1907 register_t *retval;
1908 {
1909 struct compat_netbsd32_setpgid_args /* {
1910 syscallarg(int) pid;
1911 syscallarg(int) pgid;
1912 } */ *uap = v;
1913 struct sys_setpgid_args ua;
1914
1915 NETBSD32TO64_UAP(pid);
1916 NETBSD32TO64_UAP(pgid);
1917 return (sys_setpgid(p, &ua, retval));
1918 }
1919
1920 int
1921 compat_netbsd32_setitimer(p, v, retval)
1922 struct proc *p;
1923 void *v;
1924 register_t *retval;
1925 {
1926 struct compat_netbsd32_setitimer_args /* {
1927 syscallarg(int) which;
1928 syscallarg(const netbsd32_itimervalp_t) itv;
1929 syscallarg(netbsd32_itimervalp_t) oitv;
1930 } */ *uap = v;
1931 struct netbsd32_itimerval s32it, *itvp;
1932 int which = SCARG(uap, which);
1933 struct compat_netbsd32_getitimer_args getargs;
1934 struct itimerval aitv;
1935 int s, error;
1936
1937 if ((u_int)which > ITIMER_PROF)
1938 return (EINVAL);
1939 itvp = (struct netbsd32_itimerval *)(u_long)SCARG(uap, itv);
1940 if (itvp && (error = copyin(itvp, &s32it, sizeof(s32it))))
1941 return (error);
1942 netbsd32_to_itimerval(&s32it, &aitv);
1943 if (SCARG(uap, oitv) != NULL) {
1944 SCARG(&getargs, which) = which;
1945 SCARG(&getargs, itv) = SCARG(uap, oitv);
1946 if ((error = compat_netbsd32_getitimer(p, &getargs, retval)) != 0)
1947 return (error);
1948 }
1949 if (itvp == 0)
1950 return (0);
1951 if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval))
1952 return (EINVAL);
1953 s = splclock();
1954 if (which == ITIMER_REAL) {
1955 untimeout(realitexpire, p);
1956 if (timerisset(&aitv.it_value)) {
1957 timeradd(&aitv.it_value, &time, &aitv.it_value);
1958 timeout(realitexpire, p, hzto(&aitv.it_value));
1959 }
1960 p->p_realtimer = aitv;
1961 } else
1962 p->p_stats->p_timer[which] = aitv;
1963 splx(s);
1964 return (0);
1965 }
1966
1967 int
1968 compat_netbsd32_getitimer(p, v, retval)
1969 struct proc *p;
1970 void *v;
1971 register_t *retval;
1972 {
1973 struct compat_netbsd32_getitimer_args /* {
1974 syscallarg(int) which;
1975 syscallarg(netbsd32_itimervalp_t) itv;
1976 } */ *uap = v;
1977 int which = SCARG(uap, which);
1978 struct netbsd32_itimerval s32it;
1979 struct itimerval aitv;
1980 int s;
1981
1982 if ((u_int)which > ITIMER_PROF)
1983 return (EINVAL);
1984 s = splclock();
1985 if (which == ITIMER_REAL) {
1986 /*
1987 * Convert from absolute to relative time in .it_value
1988 * part of real time timer. If time for real time timer
1989 * has passed return 0, else return difference between
1990 * current time and time for the timer to go off.
1991 */
1992 aitv = p->p_realtimer;
1993 if (timerisset(&aitv.it_value)) {
1994 if (timercmp(&aitv.it_value, &time, <))
1995 timerclear(&aitv.it_value);
1996 else
1997 timersub(&aitv.it_value, &time, &aitv.it_value);
1998 }
1999 } else
2000 aitv = p->p_stats->p_timer[which];
2001 splx(s);
2002 netbsd32_from_itimerval(&aitv, &s32it);
2003 return (copyout(&s32it, (caddr_t)(u_long)SCARG(uap, itv), sizeof(s32it)));
2004 }
2005
2006 int
2007 compat_netbsd32_fcntl(p, v, retval)
2008 struct proc *p;
2009 void *v;
2010 register_t *retval;
2011 {
2012 struct compat_netbsd32_fcntl_args /* {
2013 syscallarg(int) fd;
2014 syscallarg(int) cmd;
2015 syscallarg(netbsd32_voidp) arg;
2016 } */ *uap = v;
2017 struct sys_fcntl_args ua;
2018
2019 NETBSD32TO64_UAP(fd);
2020 NETBSD32TO64_UAP(cmd);
2021 NETBSD32TOP_UAP(arg, void);
2022 /* XXXX we can do this 'cause flock doesn't change */
2023 return (sys_fcntl(p, &ua, retval));
2024 }
2025
2026 int
2027 compat_netbsd32_dup2(p, v, retval)
2028 struct proc *p;
2029 void *v;
2030 register_t *retval;
2031 {
2032 struct compat_netbsd32_dup2_args /* {
2033 syscallarg(int) from;
2034 syscallarg(int) to;
2035 } */ *uap = v;
2036 struct sys_dup2_args ua;
2037
2038 NETBSD32TO64_UAP(from);
2039 NETBSD32TO64_UAP(to);
2040 return (sys_dup2(p, &ua, retval));
2041 }
2042
2043 int
2044 compat_netbsd32_select(p, v, retval)
2045 struct proc *p;
2046 void *v;
2047 register_t *retval;
2048 {
2049 struct compat_netbsd32_select_args /* {
2050 syscallarg(int) nd;
2051 syscallarg(netbsd32_fd_setp_t) in;
2052 syscallarg(netbsd32_fd_setp_t) ou;
2053 syscallarg(netbsd32_fd_setp_t) ex;
2054 syscallarg(netbsd32_timevalp_t) tv;
2055 } */ *uap = v;
2056 /* This one must be done in-line 'cause of the timeval */
2057 struct netbsd32_timeval tv32;
2058 caddr_t bits;
2059 char smallbits[howmany(FD_SETSIZE, NFDBITS) * sizeof(fd_mask) * 6];
2060 struct timeval atv;
2061 int s, ncoll, error = 0, timo;
2062 size_t ni;
2063 extern int selwait, nselcoll;
2064 extern int selscan __P((struct proc *, fd_mask *, fd_mask *, int, register_t *));
2065
2066 if (SCARG(uap, nd) < 0)
2067 return (EINVAL);
2068 if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
2069 /* forgiving; slightly wrong */
2070 SCARG(uap, nd) = p->p_fd->fd_nfiles;
2071 }
2072 ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
2073 if (ni * 6 > sizeof(smallbits))
2074 bits = malloc(ni * 6, M_TEMP, M_WAITOK);
2075 else
2076 bits = smallbits;
2077
2078 #define getbits(name, x) \
2079 if (SCARG(uap, name)) { \
2080 error = copyin((caddr_t)(u_long)SCARG(uap, name), bits + ni * x, ni); \
2081 if (error) \
2082 goto done; \
2083 } else \
2084 memset(bits + ni * x, 0, ni);
2085 getbits(in, 0);
2086 getbits(ou, 1);
2087 getbits(ex, 2);
2088 #undef getbits
2089
2090 if (SCARG(uap, tv)) {
2091 error = copyin((caddr_t)(u_long)SCARG(uap, tv), (caddr_t)&tv32,
2092 sizeof(tv32));
2093 if (error)
2094 goto done;
2095 netbsd32_to_timeval(&tv32, &atv);
2096 if (itimerfix(&atv)) {
2097 error = EINVAL;
2098 goto done;
2099 }
2100 s = splclock();
2101 timeradd(&atv, &time, &atv);
2102 timo = hzto(&atv);
2103 /*
2104 * Avoid inadvertently sleeping forever.
2105 */
2106 if (timo == 0)
2107 timo = 1;
2108 splx(s);
2109 } else
2110 timo = 0;
2111 retry:
2112 ncoll = nselcoll;
2113 p->p_flag |= P_SELECT;
2114 error = selscan(p, (fd_mask *)(bits + ni * 0),
2115 (fd_mask *)(bits + ni * 3), SCARG(uap, nd), retval);
2116 if (error || *retval)
2117 goto done;
2118 s = splhigh();
2119 if (timo && timercmp(&time, &atv, >=)) {
2120 splx(s);
2121 goto done;
2122 }
2123 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
2124 splx(s);
2125 goto retry;
2126 }
2127 p->p_flag &= ~P_SELECT;
2128 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
2129 splx(s);
2130 if (error == 0)
2131 goto retry;
2132 done:
2133 p->p_flag &= ~P_SELECT;
2134 /* select is not restarted after signals... */
2135 if (error == ERESTART)
2136 error = EINTR;
2137 if (error == EWOULDBLOCK)
2138 error = 0;
2139 if (error == 0) {
2140 #define putbits(name, x) \
2141 if (SCARG(uap, name)) { \
2142 error = copyout(bits + ni * x, (caddr_t)(u_long)SCARG(uap, name), ni); \
2143 if (error) \
2144 goto out; \
2145 }
2146 putbits(in, 3);
2147 putbits(ou, 4);
2148 putbits(ex, 5);
2149 #undef putbits
2150 }
2151 out:
2152 if (ni * 6 > sizeof(smallbits))
2153 free(bits, M_TEMP);
2154 return (error);
2155 }
2156
2157 int
2158 compat_netbsd32_fsync(p, v, retval)
2159 struct proc *p;
2160 void *v;
2161 register_t *retval;
2162 {
2163 struct compat_netbsd32_fsync_args /* {
2164 syscallarg(int) fd;
2165 } */ *uap = v;
2166 struct sys_fsync_args ua;
2167
2168 NETBSD32TO64_UAP(fd);
2169 return (sys_fsync(p, &ua, retval));
2170 }
2171
2172 int
2173 compat_netbsd32_setpriority(p, v, retval)
2174 struct proc *p;
2175 void *v;
2176 register_t *retval;
2177 {
2178 struct compat_netbsd32_setpriority_args /* {
2179 syscallarg(int) which;
2180 syscallarg(int) who;
2181 syscallarg(int) prio;
2182 } */ *uap = v;
2183 struct sys_setpriority_args ua;
2184
2185 NETBSD32TO64_UAP(which);
2186 NETBSD32TO64_UAP(who);
2187 NETBSD32TO64_UAP(prio);
2188 return (sys_setpriority(p, &ua, retval));
2189 }
2190
2191 int
2192 compat_netbsd32_socket(p, v, retval)
2193 struct proc *p;
2194 void *v;
2195 register_t *retval;
2196 {
2197 struct compat_netbsd32_socket_args /* {
2198 syscallarg(int) domain;
2199 syscallarg(int) type;
2200 syscallarg(int) protocol;
2201 } */ *uap = v;
2202 struct sys_socket_args ua;
2203
2204 NETBSD32TO64_UAP(domain);
2205 NETBSD32TO64_UAP(type);
2206 NETBSD32TO64_UAP(protocol);
2207 return (sys_socket(p, &ua, retval));
2208 }
2209
2210 int
2211 compat_netbsd32_connect(p, v, retval)
2212 struct proc *p;
2213 void *v;
2214 register_t *retval;
2215 {
2216 struct compat_netbsd32_connect_args /* {
2217 syscallarg(int) s;
2218 syscallarg(const netbsd32_sockaddrp_t) name;
2219 syscallarg(int) namelen;
2220 } */ *uap = v;
2221 struct sys_connect_args ua;
2222
2223 NETBSD32TO64_UAP(s);
2224 NETBSD32TOP_UAP(name, struct sockaddr);
2225 NETBSD32TO64_UAP(namelen);
2226 return (sys_connect(p, &ua, retval));
2227 }
2228
2229 int
2230 compat_netbsd32_getpriority(p, v, retval)
2231 struct proc *p;
2232 void *v;
2233 register_t *retval;
2234 {
2235 struct compat_netbsd32_getpriority_args /* {
2236 syscallarg(int) which;
2237 syscallarg(int) who;
2238 } */ *uap = v;
2239 struct sys_getpriority_args ua;
2240
2241 NETBSD32TO64_UAP(which);
2242 NETBSD32TO64_UAP(who);
2243 return (sys_getpriority(p, &ua, retval));
2244 }
2245
2246 int
2247 compat_netbsd32_bind(p, v, retval)
2248 struct proc *p;
2249 void *v;
2250 register_t *retval;
2251 {
2252 struct compat_netbsd32_bind_args /* {
2253 syscallarg(int) s;
2254 syscallarg(const netbsd32_sockaddrp_t) name;
2255 syscallarg(int) namelen;
2256 } */ *uap = v;
2257 struct sys_bind_args ua;
2258
2259 NETBSD32TO64_UAP(s);
2260 NETBSD32TOP_UAP(name, struct sockaddr);
2261 NETBSD32TO64_UAP(namelen);
2262 return (sys_bind(p, &ua, retval));
2263 }
2264
2265 int
2266 compat_netbsd32_setsockopt(p, v, retval)
2267 struct proc *p;
2268 void *v;
2269 register_t *retval;
2270 {
2271 struct compat_netbsd32_setsockopt_args /* {
2272 syscallarg(int) s;
2273 syscallarg(int) level;
2274 syscallarg(int) name;
2275 syscallarg(const netbsd32_voidp) val;
2276 syscallarg(int) valsize;
2277 } */ *uap = v;
2278 struct sys_setsockopt_args ua;
2279
2280 NETBSD32TO64_UAP(s);
2281 NETBSD32TO64_UAP(level);
2282 NETBSD32TO64_UAP(name);
2283 NETBSD32TOP_UAP(val, void);
2284 NETBSD32TO64_UAP(valsize);
2285 /* may be more efficient to do this inline. */
2286 return (sys_setsockopt(p, &ua, retval));
2287 }
2288
2289 int
2290 compat_netbsd32_listen(p, v, retval)
2291 struct proc *p;
2292 void *v;
2293 register_t *retval;
2294 {
2295 struct compat_netbsd32_listen_args /* {
2296 syscallarg(int) s;
2297 syscallarg(int) backlog;
2298 } */ *uap = v;
2299 struct sys_listen_args ua;
2300
2301 NETBSD32TO64_UAP(s);
2302 NETBSD32TO64_UAP(backlog);
2303 return (sys_listen(p, &ua, retval));
2304 }
2305
2306 int
2307 compat_netbsd32_gettimeofday(p, v, retval)
2308 struct proc *p;
2309 void *v;
2310 register_t *retval;
2311 {
2312 struct compat_netbsd32_gettimeofday_args /* {
2313 syscallarg(netbsd32_timevalp_t) tp;
2314 syscallarg(netbsd32_timezonep_t) tzp;
2315 } */ *uap = v;
2316 struct timeval atv;
2317 struct netbsd32_timeval tv32;
2318 int error = 0;
2319 struct netbsd32_timezone tzfake;
2320
2321 if (SCARG(uap, tp)) {
2322 microtime(&atv);
2323 netbsd32_from_timeval(&atv, &tv32);
2324 error = copyout(&tv32, (caddr_t)(u_long)SCARG(uap, tp), sizeof(tv32));
2325 if (error)
2326 return (error);
2327 }
2328 if (SCARG(uap, tzp)) {
2329 /*
2330 * NetBSD has no kernel notion of time zone, so we just
2331 * fake up a timezone struct and return it if demanded.
2332 */
2333 tzfake.tz_minuteswest = 0;
2334 tzfake.tz_dsttime = 0;
2335 error = copyout(&tzfake, (caddr_t)(u_long)SCARG(uap, tzp), sizeof(tzfake));
2336 }
2337 return (error);
2338 }
2339
2340 static int settime __P((struct timeval *));
2341 /* This function is used by clock_settime and settimeofday */
2342 static int
2343 settime(tv)
2344 struct timeval *tv;
2345 {
2346 struct timeval delta;
2347 int s;
2348
2349 /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
2350 s = splclock();
2351 timersub(tv, &time, &delta);
2352 if ((delta.tv_sec < 0 || delta.tv_usec < 0) && securelevel > 1)
2353 return (EPERM);
2354 #ifdef notyet
2355 if ((delta.tv_sec < 86400) && securelevel > 0)
2356 return (EPERM);
2357 #endif
2358 time = *tv;
2359 (void) splsoftclock();
2360 timeradd(&boottime, &delta, &boottime);
2361 timeradd(&runtime, &delta, &runtime);
2362 # if defined(NFS) || defined(NFSSERVER)
2363 nqnfs_lease_updatetime(delta.tv_sec);
2364 # endif
2365 splx(s);
2366 resettodr();
2367 return (0);
2368 }
2369
2370
2371 int
2372 compat_netbsd32_settimeofday(p, v, retval)
2373 struct proc *p;
2374 void *v;
2375 register_t *retval;
2376 {
2377 struct compat_netbsd32_settimeofday_args /* {
2378 syscallarg(const netbsd32_timevalp_t) tv;
2379 syscallarg(const netbsd32_timezonep_t) tzp;
2380 } */ *uap = v;
2381 struct netbsd32_timeval atv32;
2382 struct timeval atv;
2383 struct netbsd32_timezone atz;
2384 int error;
2385
2386 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
2387 return (error);
2388 /* Verify all parameters before changing time. */
2389 if (SCARG(uap, tv) && (error = copyin((caddr_t)(u_long)SCARG(uap, tv),
2390 &atv32, sizeof(atv32))))
2391 return (error);
2392 netbsd32_to_timeval(&atv32, &atv);
2393 /* XXX since we don't use tz, probably no point in doing copyin. */
2394 if (SCARG(uap, tzp) && (error = copyin((caddr_t)(u_long)SCARG(uap, tzp),
2395 &atz, sizeof(atz))))
2396 return (error);
2397 if (SCARG(uap, tv))
2398 if ((error = settime(&atv)))
2399 return (error);
2400 /*
2401 * NetBSD has no kernel notion of time zone, and only an
2402 * obsolete program would try to set it, so we log a warning.
2403 */
2404 if (SCARG(uap, tzp))
2405 printf("pid %d attempted to set the "
2406 "(obsolete) kernel time zone\n", p->p_pid);
2407 return (0);
2408 }
2409
2410 int
2411 compat_netbsd32_fchown(p, v, retval)
2412 struct proc *p;
2413 void *v;
2414 register_t *retval;
2415 {
2416 struct compat_netbsd32_fchown_args /* {
2417 syscallarg(int) fd;
2418 syscallarg(uid_t) uid;
2419 syscallarg(gid_t) gid;
2420 } */ *uap = v;
2421 struct sys_fchown_args ua;
2422
2423 NETBSD32TO64_UAP(fd);
2424 NETBSD32TO64_UAP(uid);
2425 NETBSD32TO64_UAP(gid);
2426 return (sys_fchown(p, &ua, retval));
2427 }
2428
2429 int
2430 compat_netbsd32_fchmod(p, v, retval)
2431 struct proc *p;
2432 void *v;
2433 register_t *retval;
2434 {
2435 struct compat_netbsd32_fchmod_args /* {
2436 syscallarg(int) fd;
2437 syscallarg(mode_t) mode;
2438 } */ *uap = v;
2439 struct sys_fchmod_args ua;
2440
2441 NETBSD32TO64_UAP(fd);
2442 NETBSD32TO64_UAP(mode);
2443 return (sys_fchmod(p, &ua, retval));
2444 }
2445
2446 int
2447 compat_netbsd32_setreuid(p, v, retval)
2448 struct proc *p;
2449 void *v;
2450 register_t *retval;
2451 {
2452 struct compat_netbsd32_setreuid_args /* {
2453 syscallarg(uid_t) ruid;
2454 syscallarg(uid_t) euid;
2455 } */ *uap = v;
2456 struct sys_setreuid_args ua;
2457
2458 NETBSD32TO64_UAP(ruid);
2459 NETBSD32TO64_UAP(euid);
2460 return (sys_setreuid(p, &ua, retval));
2461 }
2462
2463 int
2464 compat_netbsd32_setregid(p, v, retval)
2465 struct proc *p;
2466 void *v;
2467 register_t *retval;
2468 {
2469 struct compat_netbsd32_setregid_args /* {
2470 syscallarg(gid_t) rgid;
2471 syscallarg(gid_t) egid;
2472 } */ *uap = v;
2473 struct sys_setregid_args ua;
2474
2475 NETBSD32TO64_UAP(rgid);
2476 NETBSD32TO64_UAP(egid);
2477 return (sys_setregid(p, &ua, retval));
2478 }
2479
2480 int
2481 compat_netbsd32_getrusage(p, v, retval)
2482 struct proc *p;
2483 void *v;
2484 register_t *retval;
2485 {
2486 struct compat_netbsd32_getrusage_args /* {
2487 syscallarg(int) who;
2488 syscallarg(netbsd32_rusagep_t) rusage;
2489 } */ *uap = v;
2490 struct rusage *rup;
2491 struct netbsd32_rusage ru;
2492
2493 switch (SCARG(uap, who)) {
2494
2495 case RUSAGE_SELF:
2496 rup = &p->p_stats->p_ru;
2497 calcru(p, &rup->ru_utime, &rup->ru_stime, NULL);
2498 break;
2499
2500 case RUSAGE_CHILDREN:
2501 rup = &p->p_stats->p_cru;
2502 break;
2503
2504 default:
2505 return (EINVAL);
2506 }
2507 netbsd32_from_rusage(rup, &ru);
2508 return (copyout(&ru, (caddr_t)(u_long)SCARG(uap, rusage), sizeof(ru)));
2509 }
2510
2511 int
2512 compat_netbsd32_getsockopt(p, v, retval)
2513 struct proc *p;
2514 void *v;
2515 register_t *retval;
2516 {
2517 struct compat_netbsd32_getsockopt_args /* {
2518 syscallarg(int) s;
2519 syscallarg(int) level;
2520 syscallarg(int) name;
2521 syscallarg(netbsd32_voidp) val;
2522 syscallarg(netbsd32_intp) avalsize;
2523 } */ *uap = v;
2524 struct sys_getsockopt_args ua;
2525
2526 NETBSD32TO64_UAP(s);
2527 NETBSD32TO64_UAP(level);
2528 NETBSD32TO64_UAP(name);
2529 NETBSD32TOP_UAP(val, void);
2530 NETBSD32TOP_UAP(avalsize, int);
2531 return (sys_getsockopt(p, &ua, retval));
2532 }
2533
2534 int
2535 compat_netbsd32_readv(p, v, retval)
2536 struct proc *p;
2537 void *v;
2538 register_t *retval;
2539 {
2540 struct compat_netbsd32_readv_args /* {
2541 syscallarg(int) fd;
2542 syscallarg(const netbsd32_iovecp_t) iovp;
2543 syscallarg(int) iovcnt;
2544 } */ *uap = v;
2545 int fd = SCARG(uap, fd);
2546 register struct file *fp;
2547 register struct filedesc *fdp = p->p_fd;
2548
2549 if ((u_int)fd >= fdp->fd_nfiles ||
2550 (fp = fdp->fd_ofiles[fd]) == NULL ||
2551 (fp->f_flag & FREAD) == 0)
2552 return (EBADF);
2553
2554 return (dofilereadv32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp),
2555 SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
2556 }
2557
2558 /* Damn thing copies in the iovec! */
2559 int
2560 dofilereadv32(p, fd, fp, iovp, iovcnt, offset, flags, retval)
2561 struct proc *p;
2562 int fd;
2563 struct file *fp;
2564 struct netbsd32_iovec *iovp;
2565 int iovcnt;
2566 off_t *offset;
2567 int flags;
2568 register_t *retval;
2569 {
2570 struct uio auio;
2571 register struct iovec *iov;
2572 struct iovec *needfree;
2573 struct iovec aiov[UIO_SMALLIOV];
2574 long i, cnt, error = 0;
2575 u_int iovlen;
2576 #ifdef KTRACE
2577 struct iovec *ktriov = NULL;
2578 #endif
2579
2580 /* note: can't use iovlen until iovcnt is validated */
2581 iovlen = iovcnt * sizeof(struct iovec);
2582 if ((u_int)iovcnt > UIO_SMALLIOV) {
2583 if ((u_int)iovcnt > IOV_MAX)
2584 return (EINVAL);
2585 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
2586 needfree = iov;
2587 } else if ((u_int)iovcnt > 0) {
2588 iov = aiov;
2589 needfree = NULL;
2590 } else
2591 return (EINVAL);
2592
2593 auio.uio_iov = iov;
2594 auio.uio_iovcnt = iovcnt;
2595 auio.uio_rw = UIO_READ;
2596 auio.uio_segflg = UIO_USERSPACE;
2597 auio.uio_procp = p;
2598 error = netbsd32_to_iovecin(iovp, iov, iovcnt);
2599 if (error)
2600 goto done;
2601 auio.uio_resid = 0;
2602 for (i = 0; i < iovcnt; i++) {
2603 auio.uio_resid += iov->iov_len;
2604 /*
2605 * Reads return ssize_t because -1 is returned on error.
2606 * Therefore we must restrict the length to SSIZE_MAX to
2607 * avoid garbage return values.
2608 */
2609 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
2610 error = EINVAL;
2611 goto done;
2612 }
2613 iov++;
2614 }
2615 #ifdef KTRACE
2616 /*
2617 * if tracing, save a copy of iovec
2618 */
2619 if (KTRPOINT(p, KTR_GENIO)) {
2620 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
2621 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
2622 }
2623 #endif
2624 cnt = auio.uio_resid;
2625 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags);
2626 if (error)
2627 if (auio.uio_resid != cnt && (error == ERESTART ||
2628 error == EINTR || error == EWOULDBLOCK))
2629 error = 0;
2630 cnt -= auio.uio_resid;
2631 #ifdef KTRACE
2632 if (KTRPOINT(p, KTR_GENIO))
2633 if (error == 0) {
2634 ktrgenio(p->p_tracep, fd, UIO_READ, ktriov, cnt,
2635 error);
2636 FREE(ktriov, M_TEMP);
2637 }
2638 #endif
2639 *retval = cnt;
2640 done:
2641 if (needfree)
2642 FREE(needfree, M_IOV);
2643 return (error);
2644 }
2645
2646
2647 int
2648 compat_netbsd32_writev(p, v, retval)
2649 struct proc *p;
2650 void *v;
2651 register_t *retval;
2652 {
2653 struct compat_netbsd32_writev_args /* {
2654 syscallarg(int) fd;
2655 syscallarg(const netbsd32_iovecp_t) iovp;
2656 syscallarg(int) iovcnt;
2657 } */ *uap = v;
2658 int fd = SCARG(uap, fd);
2659 register struct file *fp;
2660 register struct filedesc *fdp = p->p_fd;
2661
2662 if ((u_int)fd >= fdp->fd_nfiles ||
2663 (fp = fdp->fd_ofiles[fd]) == NULL ||
2664 (fp->f_flag & FWRITE) == 0)
2665 return (EBADF);
2666
2667 return (dofilewritev32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp),
2668 SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
2669 }
2670
2671 int
2672 dofilewritev32(p, fd, fp, iovp, iovcnt, offset, flags, retval)
2673 struct proc *p;
2674 int fd;
2675 struct file *fp;
2676 struct netbsd32_iovec *iovp;
2677 int iovcnt;
2678 off_t *offset;
2679 int flags;
2680 register_t *retval;
2681 {
2682 struct uio auio;
2683 register struct iovec *iov;
2684 struct iovec *needfree;
2685 struct iovec aiov[UIO_SMALLIOV];
2686 long i, cnt, error = 0;
2687 u_int iovlen;
2688 #ifdef KTRACE
2689 struct iovec *ktriov = NULL;
2690 #endif
2691
2692 /* note: can't use iovlen until iovcnt is validated */
2693 iovlen = iovcnt * sizeof(struct iovec);
2694 if ((u_int)iovcnt > UIO_SMALLIOV) {
2695 if ((u_int)iovcnt > IOV_MAX)
2696 return (EINVAL);
2697 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
2698 needfree = iov;
2699 } else if ((u_int)iovcnt > 0) {
2700 iov = aiov;
2701 needfree = NULL;
2702 } else
2703 return (EINVAL);
2704
2705 auio.uio_iov = iov;
2706 auio.uio_iovcnt = iovcnt;
2707 auio.uio_rw = UIO_WRITE;
2708 auio.uio_segflg = UIO_USERSPACE;
2709 auio.uio_procp = p;
2710 error = netbsd32_to_iovecin(iovp, iov, iovcnt);
2711 if (error)
2712 goto done;
2713 auio.uio_resid = 0;
2714 for (i = 0; i < iovcnt; i++) {
2715 auio.uio_resid += iov->iov_len;
2716 /*
2717 * Writes return ssize_t because -1 is returned on error.
2718 * Therefore we must restrict the length to SSIZE_MAX to
2719 * avoid garbage return values.
2720 */
2721 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
2722 error = EINVAL;
2723 goto done;
2724 }
2725 iov++;
2726 }
2727 #ifdef KTRACE
2728 /*
2729 * if tracing, save a copy of iovec
2730 */
2731 if (KTRPOINT(p, KTR_GENIO)) {
2732 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
2733 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
2734 }
2735 #endif
2736 cnt = auio.uio_resid;
2737 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags);
2738 if (error) {
2739 if (auio.uio_resid != cnt && (error == ERESTART ||
2740 error == EINTR || error == EWOULDBLOCK))
2741 error = 0;
2742 if (error == EPIPE)
2743 psignal(p, SIGPIPE);
2744 }
2745 cnt -= auio.uio_resid;
2746 #ifdef KTRACE
2747 if (KTRPOINT(p, KTR_GENIO))
2748 if (error == 0) {
2749 ktrgenio(p->p_tracep, fd, UIO_WRITE, ktriov, cnt,
2750 error);
2751 FREE(ktriov, M_TEMP);
2752 }
2753 #endif
2754 *retval = cnt;
2755 done:
2756 if (needfree)
2757 FREE(needfree, M_IOV);
2758 return (error);
2759 }
2760
2761
2762 int
2763 compat_netbsd32_rename(p, v, retval)
2764 struct proc *p;
2765 void *v;
2766 register_t *retval;
2767 {
2768 struct compat_netbsd32_rename_args /* {
2769 syscallarg(const netbsd32_charp) from;
2770 syscallarg(const netbsd32_charp) to;
2771 } */ *uap = v;
2772 struct sys_rename_args ua;
2773
2774 NETBSD32TOP_UAP(from, const char *);
2775 NETBSD32TOP_UAP(to, const char *)
2776
2777 return (sys_rename(p, &ua, retval));
2778 }
2779
2780 int
2781 compat_netbsd32_flock(p, v, retval)
2782 struct proc *p;
2783 void *v;
2784 register_t *retval;
2785 {
2786 struct compat_netbsd32_flock_args /* {
2787 syscallarg(int) fd;
2788 syscallarg(int) how;
2789 } */ *uap = v;
2790 struct sys_flock_args ua;
2791
2792 NETBSD32TO64_UAP(fd);
2793 NETBSD32TO64_UAP(how)
2794
2795 return (sys_flock(p, &ua, retval));
2796 }
2797
2798 int
2799 compat_netbsd32_mkfifo(p, v, retval)
2800 struct proc *p;
2801 void *v;
2802 register_t *retval;
2803 {
2804 struct compat_netbsd32_mkfifo_args /* {
2805 syscallarg(const netbsd32_charp) path;
2806 syscallarg(mode_t) mode;
2807 } */ *uap = v;
2808 struct sys_mkfifo_args ua;
2809
2810 NETBSD32TOP_UAP(path, const char)
2811 NETBSD32TO64_UAP(mode);
2812 return (sys_mkfifo(p, &ua, retval));
2813 }
2814
2815 int
2816 compat_netbsd32_shutdown(p, v, retval)
2817 struct proc *p;
2818 void *v;
2819 register_t *retval;
2820 {
2821 struct compat_netbsd32_shutdown_args /* {
2822 syscallarg(int) s;
2823 syscallarg(int) how;
2824 } */ *uap = v;
2825 struct sys_shutdown_args ua;
2826
2827 NETBSD32TO64_UAP(s)
2828 NETBSD32TO64_UAP(how);
2829 return (sys_shutdown(p, &ua, retval));
2830 }
2831
2832 int
2833 compat_netbsd32_socketpair(p, v, retval)
2834 struct proc *p;
2835 void *v;
2836 register_t *retval;
2837 {
2838 struct compat_netbsd32_socketpair_args /* {
2839 syscallarg(int) domain;
2840 syscallarg(int) type;
2841 syscallarg(int) protocol;
2842 syscallarg(netbsd32_intp) rsv;
2843 } */ *uap = v;
2844 struct sys_socketpair_args ua;
2845
2846 NETBSD32TO64_UAP(domain);
2847 NETBSD32TO64_UAP(type);
2848 NETBSD32TO64_UAP(protocol);
2849 NETBSD32TOP_UAP(rsv, int);
2850 /* Since we're just copying out two `int's we can do this */
2851 return (sys_socketpair(p, &ua, retval));
2852 }
2853
2854 int
2855 compat_netbsd32_mkdir(p, v, retval)
2856 struct proc *p;
2857 void *v;
2858 register_t *retval;
2859 {
2860 struct compat_netbsd32_mkdir_args /* {
2861 syscallarg(const netbsd32_charp) path;
2862 syscallarg(mode_t) mode;
2863 } */ *uap = v;
2864 struct sys_mkdir_args ua;
2865
2866 NETBSD32TOP_UAP(path, const char)
2867 NETBSD32TO64_UAP(mode);
2868 return (sys_mkdir(p, &ua, retval));
2869 }
2870
2871 int
2872 compat_netbsd32_rmdir(p, v, retval)
2873 struct proc *p;
2874 void *v;
2875 register_t *retval;
2876 {
2877 struct compat_netbsd32_rmdir_args /* {
2878 syscallarg(const netbsd32_charp) path;
2879 } */ *uap = v;
2880 struct sys_rmdir_args ua;
2881
2882 NETBSD32TOP_UAP(path, const char);
2883 return (sys_rmdir(p, &ua, retval));
2884 }
2885
2886 int
2887 compat_netbsd32_utimes(p, v, retval)
2888 struct proc *p;
2889 void *v;
2890 register_t *retval;
2891 {
2892 struct compat_netbsd32_utimes_args /* {
2893 syscallarg(const netbsd32_charp) path;
2894 syscallarg(const netbsd32_timevalp_t) tptr;
2895 } */ *uap = v;
2896 int error;
2897 struct nameidata nd;
2898
2899 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, (char *)(u_long)SCARG(uap, path), p);
2900 if ((error = namei(&nd)) != 0)
2901 return (error);
2902
2903 error = change_utimes32(nd.ni_vp, (struct timeval *)(u_long)SCARG(uap, tptr), p);
2904
2905 vrele(nd.ni_vp);
2906 return (error);
2907 }
2908
2909 /*
2910 * Common routine to set access and modification times given a vnode.
2911 */
2912 static int
2913 change_utimes32(vp, tptr, p)
2914 struct vnode *vp;
2915 struct timeval *tptr;
2916 struct proc *p;
2917 {
2918 struct netbsd32_timeval tv32[2];
2919 struct timeval tv[2];
2920 struct vattr vattr;
2921 int error;
2922
2923 VATTR_NULL(&vattr);
2924 if (tptr == NULL) {
2925 microtime(&tv[0]);
2926 tv[1] = tv[0];
2927 vattr.va_vaflags |= VA_UTIMES_NULL;
2928 } else {
2929 error = copyin(tptr, tv, sizeof(tv));
2930 if (error)
2931 return (error);
2932 }
2933 netbsd32_to_timeval(&tv32[0], &tv[0]);
2934 netbsd32_to_timeval(&tv32[1], &tv[1]);
2935 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
2936 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2937 vattr.va_atime.tv_sec = tv[0].tv_sec;
2938 vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
2939 vattr.va_mtime.tv_sec = tv[1].tv_sec;
2940 vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;
2941 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
2942 VOP_UNLOCK(vp, 0);
2943 return (error);
2944 }
2945
2946 int
2947 compat_netbsd32_adjtime(p, v, retval)
2948 struct proc *p;
2949 void *v;
2950 register_t *retval;
2951 {
2952 struct compat_netbsd32_adjtime_args /* {
2953 syscallarg(const netbsd32_timevalp_t) delta;
2954 syscallarg(netbsd32_timevalp_t) olddelta;
2955 } */ *uap = v;
2956 struct netbsd32_timeval atv;
2957 int32_t ndelta, ntickdelta, odelta;
2958 int s, error;
2959 extern long bigadj, timedelta;
2960 extern int tickdelta;
2961
2962 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
2963 return (error);
2964
2965 error = copyin((caddr_t)(u_long)SCARG(uap, delta), &atv, sizeof(struct timeval));
2966 if (error)
2967 return (error);
2968 /*
2969 * Compute the total correction and the rate at which to apply it.
2970 * Round the adjustment down to a whole multiple of the per-tick
2971 * delta, so that after some number of incremental changes in
2972 * hardclock(), tickdelta will become zero, lest the correction
2973 * overshoot and start taking us away from the desired final time.
2974 */
2975 ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
2976 if (ndelta > bigadj)
2977 ntickdelta = 10 * tickadj;
2978 else
2979 ntickdelta = tickadj;
2980 if (ndelta % ntickdelta)
2981 ndelta = ndelta / ntickdelta * ntickdelta;
2982
2983 /*
2984 * To make hardclock()'s job easier, make the per-tick delta negative
2985 * if we want time to run slower; then hardclock can simply compute
2986 * tick + tickdelta, and subtract tickdelta from timedelta.
2987 */
2988 if (ndelta < 0)
2989 ntickdelta = -ntickdelta;
2990 s = splclock();
2991 odelta = timedelta;
2992 timedelta = ndelta;
2993 tickdelta = ntickdelta;
2994 splx(s);
2995
2996 if (SCARG(uap, olddelta)) {
2997 atv.tv_sec = odelta / 1000000;
2998 atv.tv_usec = odelta % 1000000;
2999 (void) copyout(&atv, (caddr_t)(u_long)SCARG(uap, olddelta),
3000 sizeof(struct timeval));
3001 }
3002 return (0);
3003 }
3004
3005 int
3006 compat_netbsd32_quotactl(p, v, retval)
3007 struct proc *p;
3008 void *v;
3009 register_t *retval;
3010 {
3011 struct compat_netbsd32_quotactl_args /* {
3012 syscallarg(const netbsd32_charp) path;
3013 syscallarg(int) cmd;
3014 syscallarg(int) uid;
3015 syscallarg(netbsd32_caddr_t) arg;
3016 } */ *uap = v;
3017 struct sys_quotactl_args ua;
3018
3019 NETBSD32TOP_UAP(path, const char);
3020 NETBSD32TO64_UAP(cmd);
3021 NETBSD32TO64_UAP(uid);
3022 NETBSD32TOX64_UAP(arg, caddr_t);
3023 return (sys_quotactl(p, &ua, retval));
3024 }
3025
3026 #if defined(NFS) || defined(NFSSERVER)
3027 int
3028 compat_netbsd32_nfssvc(p, v, retval)
3029 struct proc *p;
3030 void *v;
3031 register_t *retval;
3032 {
3033 #if 0
3034 struct compat_netbsd32_nfssvc_args /* {
3035 syscallarg(int) flag;
3036 syscallarg(netbsd32_voidp) argp;
3037 } */ *uap = v;
3038 struct sys_nfssvc_args ua;
3039
3040 NETBSD32TO64_UAP(flag);
3041 NETBSD32TOP_UAP(argp, void);
3042 return (sys_nfssvc(p, &ua, retval));
3043 #else
3044 /* Why would we want to support a 32-bit nfsd? */
3045 return (ENOSYS);
3046 #endif
3047 }
3048 #endif
3049
3050 int
3051 compat_netbsd32_statfs(p, v, retval)
3052 struct proc *p;
3053 void *v;
3054 register_t *retval;
3055 {
3056 struct compat_netbsd32_statfs_args /* {
3057 syscallarg(const netbsd32_charp) path;
3058 syscallarg(netbsd32_statfsp_t) buf;
3059 } */ *uap = v;
3060 register struct mount *mp;
3061 register struct statfs *sp;
3062 struct netbsd32_statfs s32;
3063 int error;
3064 struct nameidata nd;
3065
3066 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, (char *)(u_long)SCARG(uap, path), p);
3067 if ((error = namei(&nd)) != 0)
3068 return (error);
3069 mp = nd.ni_vp->v_mount;
3070 sp = &mp->mnt_stat;
3071 vrele(nd.ni_vp);
3072 if ((error = VFS_STATFS(mp, sp, p)) != 0)
3073 return (error);
3074 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
3075 netbsd32_from_statfs(sp, &s32);
3076 return (copyout(&s32, (caddr_t)(u_long)SCARG(uap, buf), sizeof(s32)));
3077 }
3078
3079 int
3080 compat_netbsd32_fstatfs(p, v, retval)
3081 struct proc *p;
3082 void *v;
3083 register_t *retval;
3084 {
3085 struct compat_netbsd32_fstatfs_args /* {
3086 syscallarg(int) fd;
3087 syscallarg(netbsd32_statfsp_t) buf;
3088 } */ *uap = v;
3089 struct file *fp;
3090 register struct mount *mp;
3091 register struct statfs *sp;
3092 struct netbsd32_statfs s32;
3093 int error;
3094
3095 /* getvnode() will use the descriptor for us */
3096 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
3097 return (error);
3098 mp = ((struct vnode *)fp->f_data)->v_mount;
3099 sp = &mp->mnt_stat;
3100 if ((error = VFS_STATFS(mp, sp, p)) != 0)
3101 goto out;
3102 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
3103 netbsd32_from_statfs(sp, &s32);
3104 error = copyout(&s32, (caddr_t)(u_long)SCARG(uap, buf), sizeof(s32));
3105 out:
3106 FILE_UNUSE(fp);
3107 return (error);
3108 }
3109
3110 #if defined(NFS) || defined(NFSSERVER)
3111 int
3112 compat_netbsd32_getfh(p, v, retval)
3113 struct proc *p;
3114 void *v;
3115 register_t *retval;
3116 {
3117 struct compat_netbsd32_getfh_args /* {
3118 syscallarg(const netbsd32_charp) fname;
3119 syscallarg(netbsd32_fhandlep_t) fhp;
3120 } */ *uap = v;
3121 struct sys_getfh_args ua;
3122
3123 NETBSD32TOP_UAP(fname, const char);
3124 NETBSD32TOP_UAP(fhp, struct fhandle);
3125 /* Lucky for us a fhandlep_t doesn't change sizes */
3126 return (sys_getfh(p, &ua, retval));
3127 }
3128 #endif
3129
3130 int
3131 compat_netbsd32_sysarch(p, v, retval)
3132 struct proc *p;
3133 void *v;
3134 register_t *retval;
3135 {
3136 struct compat_netbsd32_sysarch_args /* {
3137 syscallarg(int) op;
3138 syscallarg(netbsd32_voidp) parms;
3139 } */ *uap = v;
3140
3141 switch (SCARG(uap, op)) {
3142 default:
3143 printf("(sparc64) compat_netbsd32_sysarch(%d)\n", SCARG(uap, op));
3144 return EINVAL;
3145 }
3146 }
3147
3148 int
3149 compat_netbsd32_pread(p, v, retval)
3150 struct proc *p;
3151 void *v;
3152 register_t *retval;
3153 {
3154 struct compat_netbsd32_pread_args /* {
3155 syscallarg(int) fd;
3156 syscallarg(netbsd32_voidp) buf;
3157 syscallarg(netbsd32_size_t) nbyte;
3158 syscallarg(int) pad;
3159 syscallarg(off_t) offset;
3160 } */ *uap = v;
3161 struct sys_pread_args ua;
3162 ssize_t rt;
3163 int error;
3164
3165 NETBSD32TO64_UAP(fd);
3166 NETBSD32TOP_UAP(buf, void);
3167 NETBSD32TOX_UAP(nbyte, size_t);
3168 NETBSD32TO64_UAP(pad);
3169 NETBSD32TO64_UAP(offset);
3170 error = sys_pread(p, &ua, (register_t *)&rt);
3171 *(netbsd32_ssize_t *)retval = rt;
3172 return (error);
3173 }
3174
3175 int
3176 compat_netbsd32_pwrite(p, v, retval)
3177 struct proc *p;
3178 void *v;
3179 register_t *retval;
3180 {
3181 struct compat_netbsd32_pwrite_args /* {
3182 syscallarg(int) fd;
3183 syscallarg(const netbsd32_voidp) buf;
3184 syscallarg(netbsd32_size_t) nbyte;
3185 syscallarg(int) pad;
3186 syscallarg(off_t) offset;
3187 } */ *uap = v;
3188 struct sys_pwrite_args ua;
3189 ssize_t rt;
3190 int error;
3191
3192 NETBSD32TO64_UAP(fd);
3193 NETBSD32TOP_UAP(buf, void);
3194 NETBSD32TOX_UAP(nbyte, size_t);
3195 NETBSD32TO64_UAP(pad);
3196 NETBSD32TO64_UAP(offset);
3197 error = sys_pwrite(p, &ua, (register_t *)&rt);
3198 *(netbsd32_ssize_t *)retval = rt;
3199 return (error);
3200 }
3201
3202 #ifdef NTP
3203 int
3204 compat_netbsd32_ntp_gettime(p, v, retval)
3205 struct proc *p;
3206 void *v;
3207 register_t *retval;
3208 {
3209 struct compat_netbsd32_ntp_gettime_args /* {
3210 syscallarg(netbsd32_ntptimevalp_t) ntvp;
3211 } */ *uap = v;
3212 struct netbsd32_ntptimeval ntv32;
3213 struct timeval atv;
3214 struct ntptimeval ntv;
3215 int error = 0;
3216 int s;
3217
3218 /* The following are NTP variables */
3219 extern long time_maxerror;
3220 extern long time_esterror;
3221 extern int time_status;
3222 extern int time_state; /* clock state */
3223 extern int time_status; /* clock status bits */
3224
3225 if (SCARG(uap, ntvp)) {
3226 s = splclock();
3227 #ifdef EXT_CLOCK
3228 /*
3229 * The microtime() external clock routine returns a
3230 * status code. If less than zero, we declare an error
3231 * in the clock status word and return the kernel
3232 * (software) time variable. While there are other
3233 * places that call microtime(), this is the only place
3234 * that matters from an application point of view.
3235 */
3236 if (microtime(&atv) < 0) {
3237 time_status |= STA_CLOCKERR;
3238 ntv.time = time;
3239 } else
3240 time_status &= ~STA_CLOCKERR;
3241 #else /* EXT_CLOCK */
3242 microtime(&atv);
3243 #endif /* EXT_CLOCK */
3244 ntv.time = atv;
3245 ntv.maxerror = time_maxerror;
3246 ntv.esterror = time_esterror;
3247 (void) splx(s);
3248
3249 netbsd32_from_timeval(&ntv.time, &ntv32.time);
3250 ntv32.maxerror = (netbsd32_long)ntv.maxerror;
3251 ntv32.esterror = (netbsd32_long)ntv.esterror;
3252 error = copyout((caddr_t)&ntv32, (caddr_t)(u_long)SCARG(uap, ntvp),
3253 sizeof(ntv32));
3254 }
3255 if (!error) {
3256
3257 /*
3258 * Status word error decode. If any of these conditions
3259 * occur, an error is returned, instead of the status
3260 * word. Most applications will care only about the fact
3261 * the system clock may not be trusted, not about the
3262 * details.
3263 *
3264 * Hardware or software error
3265 */
3266 if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
3267
3268 /*
3269 * PPS signal lost when either time or frequency
3270 * synchronization requested
3271 */
3272 (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
3273 !(time_status & STA_PPSSIGNAL)) ||
3274
3275 /*
3276 * PPS jitter exceeded when time synchronization
3277 * requested
3278 */
3279 (time_status & STA_PPSTIME &&
3280 time_status & STA_PPSJITTER) ||
3281
3282 /*
3283 * PPS wander exceeded or calibration error when
3284 * frequency synchronization requested
3285 */
3286 (time_status & STA_PPSFREQ &&
3287 time_status & (STA_PPSWANDER | STA_PPSERROR)))
3288 *retval = TIME_ERROR;
3289 else
3290 *retval = (register_t)time_state;
3291 }
3292 return(error);
3293 }
3294
3295 int
3296 compat_netbsd32_ntp_adjtime(p, v, retval)
3297 struct proc *p;
3298 void *v;
3299 register_t *retval;
3300 {
3301 struct compat_netbsd32_ntp_adjtime_args /* {
3302 syscallarg(netbsd32_timexp_t) tp;
3303 } */ *uap = v;
3304 struct netbsd32_timex ntv32;
3305 struct timex ntv;
3306 int error = 0;
3307 int modes;
3308 int s;
3309 extern long time_freq; /* frequency offset (scaled ppm) */
3310 extern long time_maxerror;
3311 extern long time_esterror;
3312 extern int time_state; /* clock state */
3313 extern int time_status; /* clock status bits */
3314 extern long time_constant; /* pll time constant */
3315 extern long time_offset; /* time offset (us) */
3316 extern long time_tolerance; /* frequency tolerance (scaled ppm) */
3317 extern long time_precision; /* clock precision (us) */
3318
3319 if ((error = copyin((caddr_t)(u_long)SCARG(uap, tp), (caddr_t)&ntv32,
3320 sizeof(ntv32))))
3321 return (error);
3322 netbsd32_to_timex(&ntv32, &ntv);
3323
3324 /*
3325 * Update selected clock variables - only the superuser can
3326 * change anything. Note that there is no error checking here on
3327 * the assumption the superuser should know what it is doing.
3328 */
3329 modes = ntv.modes;
3330 if (modes != 0 && (error = suser(p->p_ucred, &p->p_acflag)))
3331 return (error);
3332
3333 s = splclock();
3334 if (modes & MOD_FREQUENCY)
3335 #ifdef PPS_SYNC
3336 time_freq = ntv.freq - pps_freq;
3337 #else /* PPS_SYNC */
3338 time_freq = ntv.freq;
3339 #endif /* PPS_SYNC */
3340 if (modes & MOD_MAXERROR)
3341 time_maxerror = ntv.maxerror;
3342 if (modes & MOD_ESTERROR)
3343 time_esterror = ntv.esterror;
3344 if (modes & MOD_STATUS) {
3345 time_status &= STA_RONLY;
3346 time_status |= ntv.status & ~STA_RONLY;
3347 }
3348 if (modes & MOD_TIMECONST)
3349 time_constant = ntv.constant;
3350 if (modes & MOD_OFFSET)
3351 hardupdate(ntv.offset);
3352
3353 /*
3354 * Retrieve all clock variables
3355 */
3356 if (time_offset < 0)
3357 ntv.offset = -(-time_offset >> SHIFT_UPDATE);
3358 else
3359 ntv.offset = time_offset >> SHIFT_UPDATE;
3360 #ifdef PPS_SYNC
3361 ntv.freq = time_freq + pps_freq;
3362 #else /* PPS_SYNC */
3363 ntv.freq = time_freq;
3364 #endif /* PPS_SYNC */
3365 ntv.maxerror = time_maxerror;
3366 ntv.esterror = time_esterror;
3367 ntv.status = time_status;
3368 ntv.constant = time_constant;
3369 ntv.precision = time_precision;
3370 ntv.tolerance = time_tolerance;
3371 #ifdef PPS_SYNC
3372 ntv.shift = pps_shift;
3373 ntv.ppsfreq = pps_freq;
3374 ntv.jitter = pps_jitter >> PPS_AVG;
3375 ntv.stabil = pps_stabil;
3376 ntv.calcnt = pps_calcnt;
3377 ntv.errcnt = pps_errcnt;
3378 ntv.jitcnt = pps_jitcnt;
3379 ntv.stbcnt = pps_stbcnt;
3380 #endif /* PPS_SYNC */
3381 (void)splx(s);
3382
3383 netbsd32_from_timeval(&ntv, &ntv32);
3384 error = copyout((caddr_t)&ntv32, (caddr_t)SCARG(uap, tp), sizeof(ntv32));
3385 if (!error) {
3386
3387 /*
3388 * Status word error decode. See comments in
3389 * ntp_gettime() routine.
3390 */
3391 if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
3392 (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
3393 !(time_status & STA_PPSSIGNAL)) ||
3394 (time_status & STA_PPSTIME &&
3395 time_status & STA_PPSJITTER) ||
3396 (time_status & STA_PPSFREQ &&
3397 time_status & (STA_PPSWANDER | STA_PPSERROR)))
3398 *retval = TIME_ERROR;
3399 else
3400 *retval = (register_t)time_state;
3401 }
3402 return error;
3403 }
3404 #endif
3405
3406 int
3407 compat_netbsd32_setgid(p, v, retval)
3408 struct proc *p;
3409 void *v;
3410 register_t *retval;
3411 {
3412 struct compat_netbsd32_setgid_args /* {
3413 syscallarg(gid_t) gid;
3414 } */ *uap = v;
3415 struct sys_setgid_args ua;
3416
3417 NETBSD32TO64_UAP(gid);
3418 return (sys_setgid(p, v, retval));
3419 }
3420
3421 int
3422 compat_netbsd32_setegid(p, v, retval)
3423 struct proc *p;
3424 void *v;
3425 register_t *retval;
3426 {
3427 struct compat_netbsd32_setegid_args /* {
3428 syscallarg(gid_t) egid;
3429 } */ *uap = v;
3430 struct sys_setegid_args ua;
3431
3432 NETBSD32TO64_UAP(egid);
3433 return (sys_setegid(p, v, retval));
3434 }
3435
3436 int
3437 compat_netbsd32_seteuid(p, v, retval)
3438 struct proc *p;
3439 void *v;
3440 register_t *retval;
3441 {
3442 struct compat_netbsd32_seteuid_args /* {
3443 syscallarg(gid_t) euid;
3444 } */ *uap = v;
3445 struct sys_seteuid_args ua;
3446
3447 NETBSD32TO64_UAP(euid);
3448 return (sys_seteuid(p, v, retval));
3449 }
3450
3451 #ifdef LFS
3452 int
3453 compat_netbsd32_lfs_bmapv(p, v, retval)
3454 struct proc *p;
3455 void *v;
3456 register_t *retval;
3457 {
3458 #if 0
3459 struct compat_netbsd32_lfs_bmapv_args /* {
3460 syscallarg(netbsd32_fsid_tp_t) fsidp;
3461 syscallarg(netbsd32_block_infop_t) blkiov;
3462 syscallarg(int) blkcnt;
3463 } */ *uap = v;
3464 struct sys_lfs_bmapv_args ua;
3465
3466 NETBSD32TOP_UAP(fdidp, struct fsid);
3467 NETBSD32TO64_UAP(blkcnt);
3468 /* XXX finish me */
3469 #else
3470
3471 return (ENOSYS); /* XXX */
3472 #endif
3473 }
3474
3475 int
3476 compat_netbsd32_lfs_markv(p, v, retval)
3477 struct proc *p;
3478 void *v;
3479 register_t *retval;
3480 {
3481 struct compat_netbsd32_lfs_markv_args /* {
3482 syscallarg(netbsd32_fsid_tp_t) fsidp;
3483 syscallarg(netbsd32_block_infop_t) blkiov;
3484 syscallarg(int) blkcnt;
3485 } */ *uap = v;
3486
3487 return (ENOSYS); /* XXX */
3488 }
3489
3490 int
3491 compat_netbsd32_lfs_segclean(p, v, retval)
3492 struct proc *p;
3493 void *v;
3494 register_t *retval;
3495 {
3496 struct compat_netbsd32_lfs_segclean_args /* {
3497 syscallarg(netbsd32_fsid_tp_t) fsidp;
3498 syscallarg(netbsd32_u_long) segment;
3499 } */ *uap = v;
3500 return (ENOSYS); /* XXX */
3501 }
3502
3503 int
3504 compat_netbsd32_lfs_segwait(p, v, retval)
3505 struct proc *p;
3506 void *v;
3507 register_t *retval;
3508 {
3509 struct compat_netbsd32_lfs_segwait_args /* {
3510 syscallarg(netbsd32_fsid_tp_t) fsidp;
3511 syscallarg(netbsd32_timevalp_t) tv;
3512 } */ *uap = v;
3513 return (ENOSYS); /* XXX */
3514 }
3515 #endif
3516
3517 int
3518 compat_netbsd32_pathconf(p, v, retval)
3519 struct proc *p;
3520 void *v;
3521 register_t *retval;
3522 {
3523 struct compat_netbsd32_pathconf_args /* {
3524 syscallarg(int) fd;
3525 syscallarg(int) name;
3526 } */ *uap = v;
3527 struct sys_pathconf_args ua;
3528 long rt;
3529 int error;
3530
3531 NETBSD32TOP_UAP(path, const char);
3532 NETBSD32TO64_UAP(name);
3533 error = sys_pathconf(p, &ua, (register_t *)&rt);
3534 *(netbsd32_long *)retval = (netbsd32_long)rt;
3535 return (error);
3536 }
3537
3538 int
3539 compat_netbsd32_fpathconf(p, v, retval)
3540 struct proc *p;
3541 void *v;
3542 register_t *retval;
3543 {
3544 struct compat_netbsd32_fpathconf_args /* {
3545 syscallarg(int) fd;
3546 syscallarg(int) name;
3547 } */ *uap = v;
3548 struct sys_fpathconf_args ua;
3549 long rt;
3550 int error;
3551
3552 NETBSD32TO64_UAP(fd);
3553 NETBSD32TO64_UAP(name);
3554 error = sys_fpathconf(p, &ua, (register_t *)&rt);
3555 *(netbsd32_long *)retval = (netbsd32_long)rt;
3556 return (error);
3557 }
3558
3559 int
3560 compat_netbsd32_getrlimit(p, v, retval)
3561 struct proc *p;
3562 void *v;
3563 register_t *retval;
3564 {
3565 struct compat_netbsd32_getrlimit_args /* {
3566 syscallarg(int) which;
3567 syscallarg(netbsd32_rlimitp_t) rlp;
3568 } */ *uap = v;
3569 int which = SCARG(uap, which);
3570
3571 if ((u_int)which >= RLIM_NLIMITS)
3572 return (EINVAL);
3573 return (copyout(&p->p_rlimit[which], (caddr_t)(u_long)SCARG(uap, rlp),
3574 sizeof(struct rlimit)));
3575 }
3576
3577 int
3578 compat_netbsd32_setrlimit(p, v, retval)
3579 struct proc *p;
3580 void *v;
3581 register_t *retval;
3582 {
3583 struct compat_netbsd32_setrlimit_args /* {
3584 syscallarg(int) which;
3585 syscallarg(const netbsd32_rlimitp_t) rlp;
3586 } */ *uap = v;
3587 int which = SCARG(uap, which);
3588 struct rlimit alim;
3589 int error;
3590
3591 error = copyin((caddr_t)(u_long)SCARG(uap, rlp), &alim, sizeof(struct rlimit));
3592 if (error)
3593 return (error);
3594 return (dosetrlimit(p, which, &alim));
3595 }
3596
3597 int
3598 compat_netbsd32_mmap(p, v, retval)
3599 struct proc *p;
3600 void *v;
3601 register_t *retval;
3602 {
3603 struct compat_netbsd32_mmap_args /* {
3604 syscallarg(netbsd32_voidp) addr;
3605 syscallarg(netbsd32_size_t) len;
3606 syscallarg(int) prot;
3607 syscallarg(int) flags;
3608 syscallarg(int) fd;
3609 syscallarg(netbsd32_long) pad;
3610 syscallarg(off_t) pos;
3611 } */ *uap = v;
3612 struct sys_mmap_args ua;
3613 void *rt;
3614 int error;
3615
3616 NETBSD32TOP_UAP(addr, void);
3617 NETBSD32TOX_UAP(len, size_t);
3618 NETBSD32TO64_UAP(prot);
3619 NETBSD32TO64_UAP(flags);
3620 NETBSD32TO64_UAP(fd);
3621 NETBSD32TOX_UAP(pad, long);
3622 NETBSD32TOX_UAP(pos, off_t);
3623 error = sys_mmap(p, &ua, (register_t *)&rt);
3624 if ((long)rt > (long)UINT_MAX)
3625 printf("compat_netbsd32_mmap: retval out of range: 0x%qx",
3626 rt);
3627 *retval = (netbsd32_voidp)(u_long)rt;
3628 return (error);
3629 }
3630
3631 int
3632 compat_netbsd32_lseek(p, v, retval)
3633 struct proc *p;
3634 void *v;
3635 register_t *retval;
3636 {
3637 struct compat_netbsd32_lseek_args /* {
3638 syscallarg(int) fd;
3639 syscallarg(int) pad;
3640 syscallarg(off_t) offset;
3641 syscallarg(int) whence;
3642 } */ *uap = v;
3643 struct sys_lseek_args ua;
3644
3645 NETBSD32TO64_UAP(fd);
3646 NETBSD32TO64_UAP(pad);
3647 NETBSD32TO64_UAP(offset);
3648 NETBSD32TO64_UAP(whence);
3649 return (sys_lseek(p, &ua, retval));
3650 }
3651
3652 int
3653 compat_netbsd32_truncate(p, v, retval)
3654 struct proc *p;
3655 void *v;
3656 register_t *retval;
3657 {
3658 struct compat_netbsd32_truncate_args /* {
3659 syscallarg(const netbsd32_charp) path;
3660 syscallarg(int) pad;
3661 syscallarg(off_t) length;
3662 } */ *uap = v;
3663 struct sys_truncate_args ua;
3664
3665 NETBSD32TOP_UAP(path, const char);
3666 NETBSD32TO64_UAP(pad);
3667 NETBSD32TO64_UAP(length);
3668 return (sys_truncate(p, &ua, retval));
3669 }
3670
3671 int
3672 compat_netbsd32_ftruncate(p, v, retval)
3673 struct proc *p;
3674 void *v;
3675 register_t *retval;
3676 {
3677 struct compat_netbsd32_ftruncate_args /* {
3678 syscallarg(int) fd;
3679 syscallarg(int) pad;
3680 syscallarg(off_t) length;
3681 } */ *uap = v;
3682 struct sys_ftruncate_args ua;
3683
3684 NETBSD32TO64_UAP(fd);
3685 NETBSD32TO64_UAP(pad);
3686 NETBSD32TO64_UAP(length);
3687 return (sys_ftruncate(p, &ua, retval));
3688 }
3689
3690 int
3691 compat_netbsd32___sysctl(p, v, retval)
3692 struct proc *p;
3693 void *v;
3694 register_t *retval;
3695 {
3696 struct compat_netbsd32___sysctl_args /* {
3697 syscallarg(netbsd32_intp) name;
3698 syscallarg(u_int) namelen;
3699 syscallarg(netbsd32_voidp) old;
3700 syscallarg(netbsd32_size_tp) oldlenp;
3701 syscallarg(netbsd32_voidp) new;
3702 syscallarg(netbsd32_size_t) newlen;
3703 } */ *uap = v;
3704 int error, dolock = 1;
3705 netbsd32_size_t savelen = 0;
3706 size_t oldlen = 0;
3707 sysctlfn *fn;
3708 int name[CTL_MAXNAME];
3709
3710 /*
3711 * Some of these sysctl functions do their own copyin/copyout.
3712 * We need to disable or emulate the ones that need their
3713 * arguments converted.
3714 */
3715
3716 if (SCARG(uap, new) != NULL &&
3717 (error = suser(p->p_ucred, &p->p_acflag)))
3718 return (error);
3719 /*
3720 * all top-level sysctl names are non-terminal
3721 */
3722 if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
3723 return (EINVAL);
3724 error = copyin((caddr_t)(u_long)SCARG(uap, name), &name,
3725 SCARG(uap, namelen) * sizeof(int));
3726 if (error)
3727 return (error);
3728
3729 switch (name[0]) {
3730 case CTL_KERN:
3731 fn = kern_sysctl;
3732 if (name[2] != KERN_VNODE) /* XXX */
3733 dolock = 0;
3734 break;
3735 case CTL_HW:
3736 fn = hw_sysctl;
3737 break;
3738 case CTL_VM:
3739 fn = uvm_sysctl;
3740 break;
3741 case CTL_NET:
3742 fn = net_sysctl;
3743 break;
3744 case CTL_VFS:
3745 fn = vfs_sysctl;
3746 break;
3747 case CTL_MACHDEP:
3748 fn = cpu_sysctl;
3749 break;
3750 #ifdef DEBUG
3751 case CTL_DEBUG:
3752 fn = debug_sysctl;
3753 break;
3754 #endif
3755 #ifdef DDB
3756 case CTL_DDB:
3757 fn = ddb_sysctl;
3758 break;
3759 #endif
3760 default:
3761 return (EOPNOTSUPP);
3762 }
3763
3764 if (SCARG(uap, oldlenp) &&
3765 (error = copyin((caddr_t)(u_long)SCARG(uap, oldlenp), &savelen, sizeof(savelen))))
3766 return (error);
3767 if (SCARG(uap, old) != NULL) {
3768 if (!uvm_useracc((caddr_t)(u_long)SCARG(uap, old), savelen, B_WRITE))
3769 return (EFAULT);
3770 #if 0 /* XXXXXXXX */
3771 while (memlock.sl_lock) {
3772 memlock.sl_want = 1;
3773 sleep((caddr_t)&memlock, PRIBIO+1);
3774 memlock.sl_locked++;
3775 }
3776 memlock.sl_lock = 1;
3777 #endif /* XXXXXXXX */
3778 if (dolock) {
3779 /*
3780 * XXX Um, this is kind of evil. What should
3781 * XXX we be passing here?
3782 */
3783 if (uvm_vslock(p, SCARG(uap, old), savelen,
3784 VM_PROT_NONE) != KERN_SUCCESS) {
3785 #if 0 /* XXXXXXXX */
3786 memlock.sl_lock = 0;
3787 if (memlock.sl_want) {
3788 memlock.sl_want = 0;
3789 wakeup((caddr_t)&memlock);
3790 }
3791 #endif /* XXXXXXXX */
3792 return (EFAULT);
3793 }
3794 }
3795 oldlen = savelen;
3796 }
3797 error = (*fn)(name + 1, SCARG(uap, namelen) - 1, SCARG(uap, old),
3798 &oldlen, SCARG(uap, new), SCARG(uap, newlen), p);
3799 if (SCARG(uap, old) != NULL) {
3800 if (dolock)
3801 uvm_vsunlock(p, SCARG(uap, old), savelen);
3802 #if 0 /* XXXXXXXXXXX */
3803 memlock.sl_lock = 0;
3804 if (memlock.sl_want) {
3805 memlock.sl_want = 0;
3806 wakeup((caddr_t)&memlock);
3807 }
3808 #endif /* XXXXXXXXX */
3809 }
3810 savelen = oldlen;
3811 if (error)
3812 return (error);
3813 if (SCARG(uap, oldlenp))
3814 error = copyout(&savelen, (caddr_t)(u_long)SCARG(uap, oldlenp), sizeof(savelen));
3815 return (error);
3816 }
3817
3818 int
3819 compat_netbsd32_mlock(p, v, retval)
3820 struct proc *p;
3821 void *v;
3822 register_t *retval;
3823 {
3824 struct compat_netbsd32_mlock_args /* {
3825 syscallarg(const netbsd32_voidp) addr;
3826 syscallarg(netbsd32_size_t) len;
3827 } */ *uap = v;
3828 struct sys_mlock_args ua;
3829
3830 NETBSD32TOP_UAP(addr, const void);
3831 NETBSD32TO64_UAP(len);
3832 return (sys_mlock(p, &ua, retval));
3833 }
3834
3835 int
3836 compat_netbsd32_munlock(p, v, retval)
3837 struct proc *p;
3838 void *v;
3839 register_t *retval;
3840 {
3841 struct compat_netbsd32_munlock_args /* {
3842 syscallarg(const netbsd32_voidp) addr;
3843 syscallarg(netbsd32_size_t) len;
3844 } */ *uap = v;
3845 struct sys_munlock_args ua;
3846
3847 NETBSD32TOP_UAP(addr, const void);
3848 NETBSD32TO64_UAP(len);
3849 return (sys_munlock(p, &ua, retval));
3850 }
3851
3852 int
3853 compat_netbsd32_undelete(p, v, retval)
3854 struct proc *p;
3855 void *v;
3856 register_t *retval;
3857 {
3858 struct compat_netbsd32_undelete_args /* {
3859 syscallarg(const netbsd32_charp) path;
3860 } */ *uap = v;
3861 struct sys_undelete_args ua;
3862
3863 NETBSD32TOP_UAP(path, const char);
3864 return (sys_undelete(p, &ua, retval));
3865 }
3866
3867 int
3868 compat_netbsd32_futimes(p, v, retval)
3869 struct proc *p;
3870 void *v;
3871 register_t *retval;
3872 {
3873 struct compat_netbsd32_futimes_args /* {
3874 syscallarg(int) fd;
3875 syscallarg(const netbsd32_timevalp_t) tptr;
3876 } */ *uap = v;
3877 int error;
3878 struct file *fp;
3879
3880 /* getvnode() will use the descriptor for us */
3881 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
3882 return (error);
3883
3884 error = change_utimes32((struct vnode *)fp->f_data,
3885 (struct timeval *)(u_long)SCARG(uap, tptr), p);
3886 FILE_UNUSE(fp);
3887 return (error);
3888 }
3889
3890 int
3891 compat_netbsd32_getpgid(p, v, retval)
3892 struct proc *p;
3893 void *v;
3894 register_t *retval;
3895 {
3896 struct compat_netbsd32_getpgid_args /* {
3897 syscallarg(pid_t) pid;
3898 } */ *uap = v;
3899 struct sys_getpgid_args ua;
3900
3901 NETBSD32TO64_UAP(pid);
3902 return (sys_getpgid(p, &ua, retval));
3903 }
3904
3905 int
3906 compat_netbsd32_reboot(p, v, retval)
3907 struct proc *p;
3908 void *v;
3909 register_t *retval;
3910 {
3911 struct compat_netbsd32_reboot_args /* {
3912 syscallarg(int) opt;
3913 syscallarg(netbsd32_charp) bootstr;
3914 } */ *uap = v;
3915 struct sys_reboot_args ua;
3916
3917 NETBSD32TO64_UAP(opt);
3918 NETBSD32TOP_UAP(bootstr, char);
3919 return (sys_reboot(p, &ua, retval));
3920 }
3921
3922 int
3923 compat_netbsd32_poll(p, v, retval)
3924 struct proc *p;
3925 void *v;
3926 register_t *retval;
3927 {
3928 struct compat_netbsd32_poll_args /* {
3929 syscallarg(netbsd32_pollfdp_t) fds;
3930 syscallarg(u_int) nfds;
3931 syscallarg(int) timeout;
3932 } */ *uap = v;
3933 struct sys_poll_args ua;
3934
3935 NETBSD32TOP_UAP(fds, struct pollfd);
3936 NETBSD32TO64_UAP(nfds);
3937 NETBSD32TO64_UAP(timeout);
3938 return (sys_poll(p, &ua, retval));
3939 }
3940
3941 /*
3942 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3943 *
3944 * This is BSD. We won't support System V IPC.
3945 * Too much work.
3946 *
3947 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3948 */
3949 int
3950 compat_netbsd32___semctl(p, v, retval)
3951 struct proc *p;
3952 void *v;
3953 register_t *retval;
3954 {
3955 #if 0
3956 struct compat_netbsd32___semctl_args /* {
3957 syscallarg(int) semid;
3958 syscallarg(int) semnum;
3959 syscallarg(int) cmd;
3960 syscallarg(netbsd32_semunu_t) arg;
3961 } */ *uap = v;
3962 union netbsd32_semun sem32;
3963 int semid = SCARG(uap, semid);
3964 int semnum = SCARG(uap, semnum);
3965 int cmd = SCARG(uap, cmd);
3966 union netbsd32_semun *arg = (void*)(u_long)SCARG(uap, arg);
3967 union netbsd32_semun real_arg;
3968 struct ucred *cred = p->p_ucred;
3969 int i, rval, eval;
3970 struct netbsd32_semid_ds sbuf;
3971 register struct semid_ds *semaptr;
3972
3973 semlock(p);
3974
3975 semid = IPCID_TO_IX(semid);
3976 if (semid < 0 || semid >= seminfo.semmsl)
3977 return(EINVAL);
3978
3979 semaptr = &sema[semid];
3980 if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
3981 semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
3982 return(EINVAL);
3983
3984 eval = 0;
3985 rval = 0;
3986
3987 switch (cmd) {
3988 case IPC_RMID:
3989 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
3990 return(eval);
3991 semaptr->sem_perm.cuid = cred->cr_uid;
3992 semaptr->sem_perm.uid = cred->cr_uid;
3993 semtot -= semaptr->sem_nsems;
3994 for (i = semaptr->sem_base - sem; i < semtot; i++)
3995 sem[i] = sem[i + semaptr->sem_nsems];
3996 for (i = 0; i < seminfo.semmni; i++) {
3997 if ((sema[i].sem_perm.mode & SEM_ALLOC) &&
3998 sema[i].sem_base > semaptr->sem_base)
3999 sema[i].sem_base -= semaptr->sem_nsems;
4000 }
4001 semaptr->sem_perm.mode = 0;
4002 semundo_clear(semid, -1);
4003 wakeup((caddr_t)semaptr);
4004 break;
4005
4006 case IPC_SET:
4007 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)))
4008 return(eval);
4009 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4010 return(eval);
4011 if ((eval = copyin((caddr_t)(u_long)real_arg.buf, (caddr_t)&sbuf,
4012 sizeof(sbuf))) != 0)
4013 return(eval);
4014 semaptr->sem_perm.uid = sbuf.sem_perm.uid;
4015 semaptr->sem_perm.gid = sbuf.sem_perm.gid;
4016 semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
4017 (sbuf.sem_perm.mode & 0777);
4018 semaptr->sem_ctime = time.tv_sec;
4019 break;
4020
4021 case IPC_STAT:
4022 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4023 return(eval);
4024 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4025 return(eval);
4026 eval = copyout((caddr_t)semaptr, (caddr_t)(u_long)real_arg.buf,
4027 sizeof(struct semid_ds));
4028 break;
4029
4030 case GETNCNT:
4031 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4032 return(eval);
4033 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4034 return(EINVAL);
4035 rval = semaptr->sem_base[semnum].semncnt;
4036 break;
4037
4038 case GETPID:
4039 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4040 return(eval);
4041 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4042 return(EINVAL);
4043 rval = semaptr->sem_base[semnum].sempid;
4044 break;
4045
4046 case GETVAL:
4047 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4048 return(eval);
4049 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4050 return(EINVAL);
4051 rval = semaptr->sem_base[semnum].semval;
4052 break;
4053
4054 case GETALL:
4055 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4056 return(eval);
4057 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4058 return(eval);
4059 for (i = 0; i < semaptr->sem_nsems; i++) {
4060 eval = copyout((caddr_t)&semaptr->sem_base[i].semval,
4061 &real_arg.array[i], sizeof(real_arg.array[0]));
4062 if (eval != 0)
4063 break;
4064 }
4065 break;
4066
4067 case GETZCNT:
4068 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4069 return(eval);
4070 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4071 return(EINVAL);
4072 rval = semaptr->sem_base[semnum].semzcnt;
4073 break;
4074
4075 case SETVAL:
4076 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
4077 return(eval);
4078 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4079 return(EINVAL);
4080 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4081 return(eval);
4082 semaptr->sem_base[semnum].semval = real_arg.val;
4083 semundo_clear(semid, semnum);
4084 wakeup((caddr_t)semaptr);
4085 break;
4086
4087 case SETALL:
4088 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
4089 return(eval);
4090 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4091 return(eval);
4092 for (i = 0; i < semaptr->sem_nsems; i++) {
4093 eval = copyin(&real_arg.array[i],
4094 (caddr_t)&semaptr->sem_base[i].semval,
4095 sizeof(real_arg.array[0]));
4096 if (eval != 0)
4097 break;
4098 }
4099 semundo_clear(semid, -1);
4100 wakeup((caddr_t)semaptr);
4101 break;
4102
4103 default:
4104 return(EINVAL);
4105 }
4106
4107 if (eval == 0)
4108 *retval = rval;
4109 return(eval);
4110 #else
4111 return (ENOSYS);
4112 #endif
4113 }
4114
4115 int
4116 compat_netbsd32_semget(p, v, retval)
4117 struct proc *p;
4118 void *v;
4119 register_t *retval;
4120 {
4121 struct compat_netbsd32_semget_args /* {
4122 syscallarg(netbsd32_key_t) key;
4123 syscallarg(int) nsems;
4124 syscallarg(int) semflg;
4125 } */ *uap = v;
4126 struct sys_semget_args ua;
4127
4128 NETBSD32TOX_UAP(key, key_t);
4129 NETBSD32TO64_UAP(nsems);
4130 NETBSD32TO64_UAP(semflg);
4131 return (sys_semget(p, &ua, retval));
4132 }
4133
4134 int
4135 compat_netbsd32_semop(p, v, retval)
4136 struct proc *p;
4137 void *v;
4138 register_t *retval;
4139 {
4140 struct compat_netbsd32_semop_args /* {
4141 syscallarg(int) semid;
4142 syscallarg(netbsd32_sembufp_t) sops;
4143 syscallarg(netbsd32_size_t) nsops;
4144 } */ *uap = v;
4145 struct sys_semop_args ua;
4146
4147 NETBSD32TO64_UAP(semid);
4148 NETBSD32TOP_UAP(sops, struct sembuf);
4149 NETBSD32TOX_UAP(nsops, size_t);
4150 return (sys_semop(p, &ua, retval));
4151 }
4152
4153 int
4154 compat_netbsd32_semconfig(p, v, retval)
4155 struct proc *p;
4156 void *v;
4157 register_t *retval;
4158 {
4159 struct compat_netbsd32_semconfig_args /* {
4160 syscallarg(int) flag;
4161 } */ *uap = v;
4162 struct sys_semconfig_args ua;
4163
4164 NETBSD32TO64_UAP(flag);
4165 return (sys_semconfig(p, &ua, retval));
4166 }
4167
4168 int
4169 compat_netbsd32_msgctl(p, v, retval)
4170 struct proc *p;
4171 void *v;
4172 register_t *retval;
4173 {
4174 #if 0
4175 struct compat_netbsd32_msgctl_args /* {
4176 syscallarg(int) msqid;
4177 syscallarg(int) cmd;
4178 syscallarg(netbsd32_msqid_dsp_t) buf;
4179 } */ *uap = v;
4180 struct sys_msgctl_args ua;
4181 struct msqid_ds ds;
4182 struct netbsd32_msqid_ds *ds32p;
4183 int error;
4184
4185 NETBSD32TO64_UAP(msqid);
4186 NETBSD32TO64_UAP(cmd);
4187 ds32p = (struct netbsd32_msqid_ds *)(u_long)SCARG(uap, buf);
4188 if (ds32p) {
4189 SCARG(&ua, buf) = NULL;
4190 netbsd32_to_msqid_ds(ds32p, &ds);
4191 } else
4192 SCARG(&ua, buf) = NULL;
4193 error = sys_msgctl(p, &ua, retval);
4194 if (error)
4195 return (error);
4196
4197 if (ds32p)
4198 netbsd32_from_msqid_ds(&ds, ds32p);
4199 return (0);
4200 #else
4201 return (ENOSYS);
4202 #endif
4203 }
4204
4205 int
4206 compat_netbsd32_msgget(p, v, retval)
4207 struct proc *p;
4208 void *v;
4209 register_t *retval;
4210 {
4211 #if 0
4212 struct compat_netbsd32_msgget_args /* {
4213 syscallarg(netbsd32_key_t) key;
4214 syscallarg(int) msgflg;
4215 } */ *uap = v;
4216 struct sys_msgget_args ua;
4217
4218 NETBSD32TOX_UAP(key, key_t);
4219 NETBSD32TO64_UAP(msgflg);
4220 return (sys_msgget(p, &ua, retval));
4221 #else
4222 return (ENOSYS);
4223 #endif
4224 }
4225
4226 int
4227 compat_netbsd32_msgsnd(p, v, retval)
4228 struct proc *p;
4229 void *v;
4230 register_t *retval;
4231 {
4232 #if 0
4233 struct compat_netbsd32_msgsnd_args /* {
4234 syscallarg(int) msqid;
4235 syscallarg(const netbsd32_voidp) msgp;
4236 syscallarg(netbsd32_size_t) msgsz;
4237 syscallarg(int) msgflg;
4238 } */ *uap = v;
4239 struct sys_msgsnd_args ua;
4240
4241 NETBSD32TO64_UAP(msqid);
4242 NETBSD32TOP_UAP(msgp, void);
4243 NETBSD32TOX_UAP(msgsz, size_t);
4244 NETBSD32TO64_UAP(msgflg);
4245 return (sys_msgsnd(p, &ua, retval));
4246 #else
4247 return (ENOSYS);
4248 #endif
4249 }
4250
4251 int
4252 compat_netbsd32_msgrcv(p, v, retval)
4253 struct proc *p;
4254 void *v;
4255 register_t *retval;
4256 {
4257 #if 0
4258 struct compat_netbsd32_msgrcv_args /* {
4259 syscallarg(int) msqid;
4260 syscallarg(netbsd32_voidp) msgp;
4261 syscallarg(netbsd32_size_t) msgsz;
4262 syscallarg(netbsd32_long) msgtyp;
4263 syscallarg(int) msgflg;
4264 } */ *uap = v;
4265 struct sys_msgrcv_args ua;
4266 ssize_t rt;
4267 int error;
4268
4269 NETBSD32TO64_UAP(msqid);
4270 NETBSD32TOP_UAP(msgp, void);
4271 NETBSD32TOX_UAP(msgsz, size_t);
4272 NETBSD32TOX_UAP(msgtyp, long);
4273 NETBSD32TO64_UAP(msgflg);
4274 error = sys_msgrcv(p, &ua, (register_t *)&rt);
4275 *(netbsd32_ssize_t *)retval = rt;
4276 return (error);
4277 #else
4278 return (ENOSYS);
4279 #endif
4280 }
4281
4282 int
4283 compat_netbsd32_shmat(p, v, retval)
4284 struct proc *p;
4285 void *v;
4286 register_t *retval;
4287 {
4288 #if 0
4289 struct compat_netbsd32_shmat_args /* {
4290 syscallarg(int) shmid;
4291 syscallarg(const netbsd32_voidp) shmaddr;
4292 syscallarg(int) shmflg;
4293 } */ *uap = v;
4294 struct sys_shmat_args ua;
4295 void *rt;
4296 int error;
4297
4298 NETBSD32TO64_UAP(shmid);
4299 NETBSD32TOP_UAP(shmaddr, void);
4300 NETBSD32TO64_UAP(shmflg);
4301 error = sys_shmat(p, &ua, (register_t *)&rt);
4302 *retval = (netbsd32_voidp)(u_long)rt;
4303 return (error);
4304 #else
4305 return (ENOSYS);
4306 #endif
4307 }
4308
4309 int
4310 compat_netbsd32_shmctl(p, v, retval)
4311 struct proc *p;
4312 void *v;
4313 register_t *retval;
4314 {
4315 #if 0
4316 struct compat_netbsd32_shmctl_args /* {
4317 syscallarg(int) shmid;
4318 syscallarg(int) cmd;
4319 syscallarg(netbsd32_shmid_dsp_t) buf;
4320 } */ *uap = v;
4321 struct sys_shmctl_args ua;
4322 struct shmid_ds ds;
4323 struct netbsd32_shmid_ds *ds32p;
4324 int error;
4325
4326 NETBSD32TO64_UAP(shmid);
4327 NETBSD32TO64_UAP(cmd);
4328 ds32p = (struct netbsd32_shmid_ds *)(u_long)SCARG(uap, buf);
4329 if (ds32p) {
4330 SCARG(&ua, buf) = NULL;
4331 netbsd32_to_shmid_ds(ds32p, &ds);
4332 } else
4333 SCARG(&ua, buf) = NULL;
4334 error = sys_shmctl(p, &ua, retval);
4335 if (error)
4336 return (error);
4337
4338 if (ds32p)
4339 netbsd32_from_shmid_ds(&ds, ds32p);
4340 return (0);
4341 #else
4342 return (ENOSYS);
4343 #endif
4344 }
4345
4346 int
4347 compat_netbsd32_shmdt(p, v, retval)
4348 struct proc *p;
4349 void *v;
4350 register_t *retval;
4351 {
4352 #if 0
4353 struct compat_netbsd32_shmdt_args /* {
4354 syscallarg(const netbsd32_voidp) shmaddr;
4355 } */ *uap = v;
4356 struct sys_shmdt_args ua;
4357
4358 NETBSD32TOP_UAP(shmaddr, const char);
4359 return (sys_shmdt(p, &ua, retval));
4360 #else
4361 return (ENOSYS);
4362 #endif
4363 }
4364
4365 int
4366 compat_netbsd32_shmget(p, v, retval)
4367 struct proc *p;
4368 void *v;
4369 register_t *retval;
4370 {
4371 #if 0
4372 struct compat_netbsd32_shmget_args /* {
4373 syscallarg(netbsd32_key_t) key;
4374 syscallarg(netbsd32_size_t) size;
4375 syscallarg(int) shmflg;
4376 } */ *uap = v;
4377 struct sys_shmget_args ua;
4378
4379 NETBSD32TOX_UAP(key, key_t)
4380 NETBSD32TOX_UAP(size, size_t)
4381 NETBSD32TO64_UAP(shmflg);
4382 return (sys_shmget(p, &ua, retval));
4383 #else
4384 return (ENOSYS);
4385 #endif
4386 }
4387
4388 int
4389 compat_netbsd32_clock_gettime(p, v, retval)
4390 struct proc *p;
4391 void *v;
4392 register_t *retval;
4393 {
4394 struct compat_netbsd32_clock_gettime_args /* {
4395 syscallarg(netbsd32_clockid_t) clock_id;
4396 syscallarg(netbsd32_timespecp_t) tp;
4397 } */ *uap = v;
4398 clockid_t clock_id;
4399 struct timeval atv;
4400 struct timespec ats;
4401 struct netbsd32_timespec ts32;
4402
4403 clock_id = SCARG(uap, clock_id);
4404 if (clock_id != CLOCK_REALTIME)
4405 return (EINVAL);
4406
4407 microtime(&atv);
4408 TIMEVAL_TO_TIMESPEC(&atv,&ats);
4409 netbsd32_from_timespec(&ats, &ts32);
4410
4411 return copyout(&ts32, (caddr_t)(u_long)SCARG(uap, tp), sizeof(ts32));
4412 }
4413
4414 int
4415 compat_netbsd32_clock_settime(p, v, retval)
4416 struct proc *p;
4417 void *v;
4418 register_t *retval;
4419 {
4420 struct compat_netbsd32_clock_settime_args /* {
4421 syscallarg(netbsd32_clockid_t) clock_id;
4422 syscallarg(const netbsd32_timespecp_t) tp;
4423 } */ *uap = v;
4424 struct netbsd32_timespec ts32;
4425 clockid_t clock_id;
4426 struct timeval atv;
4427 struct timespec ats;
4428 int error;
4429
4430 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
4431 return (error);
4432
4433 clock_id = SCARG(uap, clock_id);
4434 if (clock_id != CLOCK_REALTIME)
4435 return (EINVAL);
4436
4437 if ((error = copyin((caddr_t)(u_long)SCARG(uap, tp), &ts32, sizeof(ts32))) != 0)
4438 return (error);
4439
4440 netbsd32_to_timespec(&ts32, &ats);
4441 TIMESPEC_TO_TIMEVAL(&atv,&ats);
4442 if ((error = settime(&atv)))
4443 return (error);
4444
4445 return 0;
4446 }
4447
4448 int
4449 compat_netbsd32_clock_getres(p, v, retval)
4450 struct proc *p;
4451 void *v;
4452 register_t *retval;
4453 {
4454 struct compat_netbsd32_clock_getres_args /* {
4455 syscallarg(netbsd32_clockid_t) clock_id;
4456 syscallarg(netbsd32_timespecp_t) tp;
4457 } */ *uap = v;
4458 struct netbsd32_timespec ts32;
4459 clockid_t clock_id;
4460 struct timespec ts;
4461 int error = 0;
4462
4463 clock_id = SCARG(uap, clock_id);
4464 if (clock_id != CLOCK_REALTIME)
4465 return (EINVAL);
4466
4467 if (SCARG(uap, tp)) {
4468 ts.tv_sec = 0;
4469 ts.tv_nsec = 1000000000 / hz;
4470
4471 netbsd32_from_timespec(&ts, &ts32);
4472 error = copyout(&ts, (caddr_t)(u_long)SCARG(uap, tp), sizeof(ts));
4473 }
4474
4475 return error;
4476 }
4477
4478 int
4479 compat_netbsd32_nanosleep(p, v, retval)
4480 struct proc *p;
4481 void *v;
4482 register_t *retval;
4483 {
4484 struct compat_netbsd32_nanosleep_args /* {
4485 syscallarg(const netbsd32_timespecp_t) rqtp;
4486 syscallarg(netbsd32_timespecp_t) rmtp;
4487 } */ *uap = v;
4488 static int nanowait;
4489 struct netbsd32_timespec ts32;
4490 struct timespec rqt;
4491 struct timespec rmt;
4492 struct timeval atv, utv;
4493 int error, s, timo;
4494
4495 error = copyin((caddr_t)(u_long)SCARG(uap, rqtp), (caddr_t)&ts32,
4496 sizeof(ts32));
4497 if (error)
4498 return (error);
4499
4500 netbsd32_to_timespec(&ts32, &rqt);
4501 TIMESPEC_TO_TIMEVAL(&atv,&rqt)
4502 if (itimerfix(&atv))
4503 return (EINVAL);
4504
4505 s = splclock();
4506 timeradd(&atv,&time,&atv);
4507 timo = hzto(&atv);
4508 /*
4509 * Avoid inadvertantly sleeping forever
4510 */
4511 if (timo == 0)
4512 timo = 1;
4513 splx(s);
4514
4515 error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo);
4516 if (error == ERESTART)
4517 error = EINTR;
4518 if (error == EWOULDBLOCK)
4519 error = 0;
4520
4521 if (SCARG(uap, rmtp)) {
4522 int error;
4523
4524 s = splclock();
4525 utv = time;
4526 splx(s);
4527
4528 timersub(&atv, &utv, &utv);
4529 if (utv.tv_sec < 0)
4530 timerclear(&utv);
4531
4532 TIMEVAL_TO_TIMESPEC(&utv,&rmt);
4533 netbsd32_from_timespec(&rmt, &ts32);
4534 error = copyout((caddr_t)&ts32, (caddr_t)(u_long)SCARG(uap,rmtp),
4535 sizeof(ts32));
4536 if (error)
4537 return (error);
4538 }
4539
4540 return error;
4541 }
4542
4543 int
4544 compat_netbsd32_fdatasync(p, v, retval)
4545 struct proc *p;
4546 void *v;
4547 register_t *retval;
4548 {
4549 struct compat_netbsd32_fdatasync_args /* {
4550 syscallarg(int) fd;
4551 } */ *uap = v;
4552 struct sys_fdatasync_args ua;
4553
4554 NETBSD32TO64_UAP(fd);
4555
4556 return (sys_fdatasync(p, &ua, retval));
4557 }
4558
4559 int
4560 compat_netbsd32___posix_rename(p, v, retval)
4561 struct proc *p;
4562 void *v;
4563 register_t *retval;
4564 {
4565 struct compat_netbsd32___posix_rename_args /* {
4566 syscallarg(const netbsd32_charp) from;
4567 syscallarg(const netbsd32_charp) to;
4568 } */ *uap = v;
4569 struct sys___posix_rename_args ua;
4570
4571 NETBSD32TOP_UAP(from, const char *);
4572 NETBSD32TOP_UAP(to, const char *);
4573
4574 return (sys___posix_rename(p, &ua, retval));
4575 }
4576
4577 int
4578 compat_netbsd32_swapctl(p, v, retval)
4579 struct proc *p;
4580 void *v;
4581 register_t *retval;
4582 {
4583 struct compat_netbsd32_swapctl_args /* {
4584 syscallarg(int) cmd;
4585 syscallarg(const netbsd32_voidp) arg;
4586 syscallarg(int) misc;
4587 } */ *uap = v;
4588 struct sys_swapctl_args ua;
4589
4590 NETBSD32TO64_UAP(cmd);
4591 NETBSD32TOP_UAP(arg, const void);
4592 NETBSD32TO64_UAP(misc);
4593 return (sys_swapctl(p, &ua, retval));
4594 }
4595
4596 int
4597 compat_netbsd32_getdents(p, v, retval)
4598 struct proc *p;
4599 void *v;
4600 register_t *retval;
4601 {
4602 struct compat_netbsd32_getdents_args /* {
4603 syscallarg(int) fd;
4604 syscallarg(netbsd32_charp) buf;
4605 syscallarg(netbsd32_size_t) count;
4606 } */ *uap = v;
4607 struct file *fp;
4608 int error, done;
4609
4610 /* getvnode() will use the descriptor for us */
4611 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
4612 return (error);
4613 if ((fp->f_flag & FREAD) == 0) {
4614 error = EBADF;
4615 goto out;
4616 }
4617 error = vn_readdir(fp, (caddr_t)(u_long)SCARG(uap, buf), UIO_USERSPACE,
4618 SCARG(uap, count), &done, p, 0, 0);
4619 *retval = done;
4620 out:
4621 FILE_UNUSE(fp);
4622 return (error);
4623 }
4624
4625
4626 int
4627 compat_netbsd32_minherit(p, v, retval)
4628 struct proc *p;
4629 void *v;
4630 register_t *retval;
4631 {
4632 struct compat_netbsd32_minherit_args /* {
4633 syscallarg(netbsd32_voidp) addr;
4634 syscallarg(netbsd32_size_t) len;
4635 syscallarg(int) inherit;
4636 } */ *uap = v;
4637 struct sys_minherit_args ua;
4638
4639 NETBSD32TOP_UAP(addr, void);
4640 NETBSD32TOX_UAP(len, size_t);
4641 NETBSD32TO64_UAP(inherit);
4642 return (sys_minherit(p, &ua, retval));
4643 }
4644
4645 int
4646 compat_netbsd32_lchmod(p, v, retval)
4647 struct proc *p;
4648 void *v;
4649 register_t *retval;
4650 {
4651 struct compat_netbsd32_lchmod_args /* {
4652 syscallarg(const netbsd32_charp) path;
4653 syscallarg(mode_t) mode;
4654 } */ *uap = v;
4655 struct sys_lchmod_args ua;
4656
4657 NETBSD32TOP_UAP(path, const char);
4658 NETBSD32TO64_UAP(mode);
4659 return (sys_lchmod(p, &ua, retval));
4660 }
4661
4662 int
4663 compat_netbsd32_lchown(p, v, retval)
4664 struct proc *p;
4665 void *v;
4666 register_t *retval;
4667 {
4668 struct compat_netbsd32_lchown_args /* {
4669 syscallarg(const netbsd32_charp) path;
4670 syscallarg(uid_t) uid;
4671 syscallarg(gid_t) gid;
4672 } */ *uap = v;
4673 struct sys_lchown_args ua;
4674
4675 NETBSD32TOP_UAP(path, const char);
4676 NETBSD32TO64_UAP(uid);
4677 NETBSD32TO64_UAP(gid);
4678 return (sys_lchown(p, &ua, retval));
4679 }
4680
4681 int
4682 compat_netbsd32_lutimes(p, v, retval)
4683 struct proc *p;
4684 void *v;
4685 register_t *retval;
4686 {
4687 struct compat_netbsd32_lutimes_args /* {
4688 syscallarg(const netbsd32_charp) path;
4689 syscallarg(const netbsd32_timevalp_t) tptr;
4690 } */ *uap = v;
4691 int error;
4692 struct nameidata nd;
4693
4694 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, (caddr_t)(u_long)SCARG(uap, path), p);
4695 if ((error = namei(&nd)) != 0)
4696 return (error);
4697
4698 error = change_utimes32(nd.ni_vp, (struct timeval *)(u_long)SCARG(uap, tptr), p);
4699
4700 vrele(nd.ni_vp);
4701 return (error);
4702 }
4703
4704
4705 int
4706 compat_netbsd32___msync13(p, v, retval)
4707 struct proc *p;
4708 void *v;
4709 register_t *retval;
4710 {
4711 struct compat_netbsd32___msync13_args /* {
4712 syscallarg(netbsd32_voidp) addr;
4713 syscallarg(netbsd32_size_t) len;
4714 syscallarg(int) flags;
4715 } */ *uap = v;
4716 struct sys___msync13_args ua;
4717
4718 NETBSD32TOP_UAP(addr, void);
4719 NETBSD32TOX_UAP(len, size_t);
4720 NETBSD32TO64_UAP(flags);
4721 return (sys___msync13(p, &ua, retval));
4722 }
4723
4724 int
4725 compat_netbsd32___stat13(p, v, retval)
4726 struct proc *p;
4727 void *v;
4728 register_t *retval;
4729 {
4730 struct compat_netbsd32___stat13_args /* {
4731 syscallarg(const netbsd32_charp) path;
4732 syscallarg(netbsd32_statp_t) ub;
4733 } */ *uap = v;
4734 struct netbsd32_stat sb32;
4735 struct stat sb;
4736 int error;
4737 struct nameidata nd;
4738
4739 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
4740 (caddr_t)(u_long)SCARG(uap, path), p);
4741 if ((error = namei(&nd)) != 0)
4742 return (error);
4743 error = vn_stat(nd.ni_vp, &sb, p);
4744 vput(nd.ni_vp);
4745 if (error)
4746 return (error);
4747 netbsd32_from___stat13(&sb, &sb32);
4748 error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, ub), sizeof(sb32));
4749 return (error);
4750 }
4751
4752 int
4753 compat_netbsd32___fstat13(p, v, retval)
4754 struct proc *p;
4755 void *v;
4756 register_t *retval;
4757 {
4758 struct compat_netbsd32___fstat13_args /* {
4759 syscallarg(int) fd;
4760 syscallarg(netbsd32_statp_t) sb;
4761 } */ *uap = v;
4762 int fd = SCARG(uap, fd);
4763 register struct filedesc *fdp = p->p_fd;
4764 register struct file *fp;
4765 struct netbsd32_stat sb32;
4766 struct stat ub;
4767 int error = 0;
4768
4769 if ((u_int)fd >= fdp->fd_nfiles ||
4770 (fp = fdp->fd_ofiles[fd]) == NULL)
4771 return (EBADF);
4772 switch (fp->f_type) {
4773
4774 case DTYPE_VNODE:
4775 error = vn_stat((struct vnode *)fp->f_data, &ub, p);
4776 break;
4777
4778 case DTYPE_SOCKET:
4779 error = soo_stat((struct socket *)fp->f_data, &ub);
4780 break;
4781
4782 default:
4783 panic("fstat");
4784 /*NOTREACHED*/
4785 }
4786 if (error == 0) {
4787 netbsd32_from___stat13(&ub, &sb32);
4788 error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, sb), sizeof(sb32));
4789 }
4790 return (error);
4791 }
4792
4793 int
4794 compat_netbsd32___lstat13(p, v, retval)
4795 struct proc *p;
4796 void *v;
4797 register_t *retval;
4798 {
4799 struct compat_netbsd32___lstat13_args /* {
4800 syscallarg(const netbsd32_charp) path;
4801 syscallarg(netbsd32_statp_t) ub;
4802 } */ *uap = v;
4803 struct netbsd32_stat sb32;
4804 struct stat sb;
4805 int error;
4806 struct nameidata nd;
4807
4808 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
4809 (caddr_t)(u_long)SCARG(uap, path), p);
4810 if ((error = namei(&nd)) != 0)
4811 return (error);
4812 error = vn_stat(nd.ni_vp, &sb, p);
4813 vput(nd.ni_vp);
4814 if (error)
4815 return (error);
4816 netbsd32_from___stat13(&sb, &sb32);
4817 error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, ub), sizeof(sb32));
4818 return (error);
4819 }
4820
4821 int
4822 compat_netbsd32___sigaltstack14(p, v, retval)
4823 struct proc *p;
4824 void *v;
4825 register_t *retval;
4826 {
4827 struct compat_netbsd32___sigaltstack14_args /* {
4828 syscallarg(const netbsd32_sigaltstackp_t) nss;
4829 syscallarg(netbsd32_sigaltstackp_t) oss;
4830 } */ *uap = v;
4831 struct netbsd32_sigaltstack s32;
4832 struct sigaltstack nss, oss;
4833 int error;
4834
4835 if (SCARG(uap, nss)) {
4836 error = copyin((caddr_t)(u_long)SCARG(uap, nss), &s32, sizeof(s32));
4837 if (error)
4838 return (error);
4839 nss.ss_sp = (void *)(u_long)s32.ss_sp;
4840 nss.ss_size = (size_t)s32.ss_size;
4841 nss.ss_flags = s32.ss_flags;
4842 }
4843 error = sigaltstack1(p,
4844 SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0);
4845 if (error)
4846 return (error);
4847 if (SCARG(uap, oss)) {
4848 s32.ss_sp = (netbsd32_voidp)(u_long)oss.ss_sp;
4849 s32.ss_size = (netbsd32_size_t)oss.ss_size;
4850 s32.ss_flags = oss.ss_flags;
4851 error = copyout(&s32, (caddr_t)(u_long)SCARG(uap, oss), sizeof(s32));
4852 if (error)
4853 return (error);
4854 }
4855 return (0);
4856 }
4857
4858 int
4859 compat_netbsd32___posix_chown(p, v, retval)
4860 struct proc *p;
4861 void *v;
4862 register_t *retval;
4863 {
4864 struct compat_netbsd32___posix_chown_args /* {
4865 syscallarg(const netbsd32_charp) path;
4866 syscallarg(uid_t) uid;
4867 syscallarg(gid_t) gid;
4868 } */ *uap = v;
4869 struct sys___posix_chown_args ua;
4870
4871 NETBSD32TOP_UAP(path, const char);
4872 NETBSD32TO64_UAP(uid);
4873 NETBSD32TO64_UAP(gid);
4874 return (sys___posix_chown(p, &ua, retval));
4875 }
4876
4877 int
4878 compat_netbsd32___posix_fchown(p, v, retval)
4879 struct proc *p;
4880 void *v;
4881 register_t *retval;
4882 {
4883 struct compat_netbsd32___posix_fchown_args /* {
4884 syscallarg(int) fd;
4885 syscallarg(uid_t) uid;
4886 syscallarg(gid_t) gid;
4887 } */ *uap = v;
4888 struct sys___posix_fchown_args ua;
4889
4890 NETBSD32TO64_UAP(fd);
4891 NETBSD32TO64_UAP(uid);
4892 NETBSD32TO64_UAP(gid);
4893 return (sys___posix_fchown(p, &ua, retval));
4894 }
4895
4896 int
4897 compat_netbsd32___posix_lchown(p, v, retval)
4898 struct proc *p;
4899 void *v;
4900 register_t *retval;
4901 {
4902 struct compat_netbsd32___posix_lchown_args /* {
4903 syscallarg(const netbsd32_charp) path;
4904 syscallarg(uid_t) uid;
4905 syscallarg(gid_t) gid;
4906 } */ *uap = v;
4907 struct sys___posix_lchown_args ua;
4908
4909 NETBSD32TOP_UAP(path, const char);
4910 NETBSD32TO64_UAP(uid);
4911 NETBSD32TO64_UAP(gid);
4912 return (sys___posix_lchown(p, &ua, retval));
4913 }
4914
4915 int
4916 compat_netbsd32_getsid(p, v, retval)
4917 struct proc *p;
4918 void *v;
4919 register_t *retval;
4920 {
4921 struct compat_netbsd32_getsid_args /* {
4922 syscallarg(pid_t) pid;
4923 } */ *uap = v;
4924 struct sys_getsid_args ua;
4925
4926 NETBSD32TO64_UAP(pid);
4927 return (sys_getsid(p, &ua, retval));
4928 }
4929
4930 int
4931 compat_netbsd32_fktrace(p, v, retval)
4932 struct proc *p;
4933 void *v;
4934 register_t *retval;
4935 {
4936 struct compat_netbsd32_fktrace_args /* {
4937 syscallarg(const int) fd;
4938 syscallarg(int) ops;
4939 syscallarg(int) facs;
4940 syscallarg(int) pid;
4941 } */ *uap = v;
4942 struct sys_fktrace_args ua;
4943
4944 NETBSD32TO64_UAP(fd);
4945 NETBSD32TO64_UAP(ops);
4946 NETBSD32TO64_UAP(facs);
4947 NETBSD32TO64_UAP(pid);
4948 return (sys_fktrace(p, &ua, retval));
4949 }
4950
4951 int
4952 compat_netbsd32_preadv(p, v, retval)
4953 struct proc *p;
4954 void *v;
4955 register_t *retval;
4956 {
4957 struct compat_netbsd32_preadv_args /* {
4958 syscallarg(int) fd;
4959 syscallarg(const netbsd32_iovecp_t) iovp;
4960 syscallarg(int) iovcnt;
4961 syscallarg(int) pad;
4962 syscallarg(off_t) offset;
4963 } */ *uap = v;
4964 struct filedesc *fdp = p->p_fd;
4965 struct file *fp;
4966 struct vnode *vp;
4967 off_t offset;
4968 int error, fd = SCARG(uap, fd);
4969
4970 if ((u_int)fd >= fdp->fd_nfiles ||
4971 (fp = fdp->fd_ofiles[fd]) == NULL ||
4972 (fp->f_flag & FREAD) == 0)
4973 return (EBADF);
4974
4975 vp = (struct vnode *)fp->f_data;
4976 if (fp->f_type != DTYPE_VNODE
4977 || vp->v_type == VFIFO)
4978 return (ESPIPE);
4979
4980 offset = SCARG(uap, offset);
4981
4982 /*
4983 * XXX This works because no file systems actually
4984 * XXX take any action on the seek operation.
4985 */
4986 if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
4987 return (error);
4988
4989 return (dofilereadv32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp), SCARG(uap, iovcnt),
4990 &offset, 0, retval));
4991 }
4992
4993 int
4994 compat_netbsd32_pwritev(p, v, retval)
4995 struct proc *p;
4996 void *v;
4997 register_t *retval;
4998 {
4999 struct compat_netbsd32_pwritev_args /* {
5000 syscallarg(int) fd;
5001 syscallarg(const netbsd32_iovecp_t) iovp;
5002 syscallarg(int) iovcnt;
5003 syscallarg(int) pad;
5004 syscallarg(off_t) offset;
5005 } */ *uap = v;
5006 struct filedesc *fdp = p->p_fd;
5007 struct file *fp;
5008 struct vnode *vp;
5009 off_t offset;
5010 int error, fd = SCARG(uap, fd);
5011
5012 if ((u_int)fd >= fdp->fd_nfiles ||
5013 (fp = fdp->fd_ofiles[fd]) == NULL ||
5014 (fp->f_flag & FWRITE) == 0)
5015 return (EBADF);
5016
5017 vp = (struct vnode *)fp->f_data;
5018 if (fp->f_type != DTYPE_VNODE
5019 || vp->v_type == VFIFO)
5020 return (ESPIPE);
5021
5022 offset = SCARG(uap, offset);
5023
5024 /*
5025 * XXX This works because no file systems actually
5026 * XXX take any action on the seek operation.
5027 */
5028 if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
5029 return (error);
5030
5031 return (dofilewritev32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp), SCARG(uap, iovcnt),
5032 &offset, 0, retval));
5033 }
5034
5035 int
5036 compat_13_compat_netbsd32_sigprocmask(p, v, retval)
5037 register struct proc *p;
5038 void *v;
5039 register_t *retval;
5040 {
5041 struct compat_13_compat_netbsd32_sigprocmask_args /* {
5042 syscallarg(int) how;
5043 syscallarg(int) mask;
5044 } */ *uap = v;
5045 sigset13_t ness, oess;
5046 sigset_t nbss, obss;
5047 int error;
5048
5049 ness = SCARG(uap, mask);
5050 native_sigset13_to_sigset(&ness, &nbss);
5051 error = sigprocmask1(p, SCARG(uap, how), &nbss, &obss);
5052 if (error)
5053 return (error);
5054 native_sigset_to_sigset13(&obss, &oess);
5055 *retval = oess;
5056 return (0);
5057 }
5058
5059 int
5060 compat_13_compat_netbsd32_sigsuspend(p, v, retval)
5061 register struct proc *p;
5062 void *v;
5063 register_t *retval;
5064 {
5065 struct compat_13_compat_netbsd32_sigsuspend_args /* {
5066 syscallarg(sigset13_t) mask;
5067 } */ *uap = v;
5068 sigset13_t ess;
5069 sigset_t bss;
5070
5071 ess = SCARG(uap, mask);
5072 native_sigset13_to_sigset(&ess, &bss);
5073 return (sigsuspend1(p, &bss));
5074 }
5075