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