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