netbsd32_netbsd.c revision 1.23 1 /* $NetBSD: netbsd32_netbsd.c,v 1.23 2000/02/06 16:45:56 eeh 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 register int nfound;
670 register 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 register struct mount *mp, *nmp;
936 register 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 register 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 register 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 register struct pcred *pc = p->p_cred;
2226 register 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 untimeout(realitexpire, p);
2317 if (timerisset(&aitv.it_value)) {
2318 timeradd(&aitv.it_value, &time, &aitv.it_value);
2319 timeout(realitexpire, p, hzto(&aitv.it_value));
2320 }
2321 p->p_realtimer = aitv;
2322 } else
2323 p->p_stats->p_timer[which] = aitv;
2324 splx(s);
2325 return (0);
2326 }
2327
2328 int
2329 netbsd32_getitimer(p, v, retval)
2330 struct proc *p;
2331 void *v;
2332 register_t *retval;
2333 {
2334 struct netbsd32_getitimer_args /* {
2335 syscallarg(int) which;
2336 syscallarg(netbsd32_itimervalp_t) itv;
2337 } */ *uap = v;
2338 int which = SCARG(uap, which);
2339 struct netbsd32_itimerval s32it;
2340 struct itimerval aitv;
2341 int s;
2342
2343 if ((u_int)which > ITIMER_PROF)
2344 return (EINVAL);
2345 s = splclock();
2346 if (which == ITIMER_REAL) {
2347 /*
2348 * Convert from absolute to relative time in .it_value
2349 * part of real time timer. If time for real time timer
2350 * has passed return 0, else return difference between
2351 * current time and time for the timer to go off.
2352 */
2353 aitv = p->p_realtimer;
2354 if (timerisset(&aitv.it_value)) {
2355 if (timercmp(&aitv.it_value, &time, <))
2356 timerclear(&aitv.it_value);
2357 else
2358 timersub(&aitv.it_value, &time, &aitv.it_value);
2359 }
2360 } else
2361 aitv = p->p_stats->p_timer[which];
2362 splx(s);
2363 netbsd32_from_itimerval(&aitv, &s32it);
2364 return (copyout(&s32it, (caddr_t)(u_long)SCARG(uap, itv), sizeof(s32it)));
2365 }
2366
2367 int
2368 netbsd32_fcntl(p, v, retval)
2369 struct proc *p;
2370 void *v;
2371 register_t *retval;
2372 {
2373 struct netbsd32_fcntl_args /* {
2374 syscallarg(int) fd;
2375 syscallarg(int) cmd;
2376 syscallarg(netbsd32_voidp) arg;
2377 } */ *uap = v;
2378 struct sys_fcntl_args ua;
2379
2380 NETBSD32TO64_UAP(fd);
2381 NETBSD32TO64_UAP(cmd);
2382 NETBSD32TOP_UAP(arg, void);
2383 /* XXXX we can do this 'cause flock doesn't change */
2384 return (sys_fcntl(p, &ua, retval));
2385 }
2386
2387 int
2388 netbsd32_dup2(p, v, retval)
2389 struct proc *p;
2390 void *v;
2391 register_t *retval;
2392 {
2393 struct netbsd32_dup2_args /* {
2394 syscallarg(int) from;
2395 syscallarg(int) to;
2396 } */ *uap = v;
2397 struct sys_dup2_args ua;
2398
2399 NETBSD32TO64_UAP(from);
2400 NETBSD32TO64_UAP(to);
2401 return (sys_dup2(p, &ua, retval));
2402 }
2403
2404 int
2405 netbsd32_select(p, v, retval)
2406 struct proc *p;
2407 void *v;
2408 register_t *retval;
2409 {
2410 struct netbsd32_select_args /* {
2411 syscallarg(int) nd;
2412 syscallarg(netbsd32_fd_setp_t) in;
2413 syscallarg(netbsd32_fd_setp_t) ou;
2414 syscallarg(netbsd32_fd_setp_t) ex;
2415 syscallarg(netbsd32_timevalp_t) tv;
2416 } */ *uap = v;
2417 /* This one must be done in-line 'cause of the timeval */
2418 struct netbsd32_timeval tv32;
2419 caddr_t bits;
2420 char smallbits[howmany(FD_SETSIZE, NFDBITS) * sizeof(fd_mask) * 6];
2421 struct timeval atv;
2422 int s, ncoll, error = 0, timo;
2423 size_t ni;
2424 extern int selwait, nselcoll;
2425 extern int selscan __P((struct proc *, fd_mask *, fd_mask *, int, register_t *));
2426
2427 if (SCARG(uap, nd) < 0)
2428 return (EINVAL);
2429 if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
2430 /* forgiving; slightly wrong */
2431 SCARG(uap, nd) = p->p_fd->fd_nfiles;
2432 }
2433 ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
2434 if (ni * 6 > sizeof(smallbits))
2435 bits = malloc(ni * 6, M_TEMP, M_WAITOK);
2436 else
2437 bits = smallbits;
2438
2439 #define getbits(name, x) \
2440 if (SCARG(uap, name)) { \
2441 error = copyin((caddr_t)(u_long)SCARG(uap, name), bits + ni * x, ni); \
2442 if (error) \
2443 goto done; \
2444 } else \
2445 memset(bits + ni * x, 0, ni);
2446 getbits(in, 0);
2447 getbits(ou, 1);
2448 getbits(ex, 2);
2449 #undef getbits
2450
2451 if (SCARG(uap, tv)) {
2452 error = copyin((caddr_t)(u_long)SCARG(uap, tv), (caddr_t)&tv32,
2453 sizeof(tv32));
2454 if (error)
2455 goto done;
2456 netbsd32_to_timeval(&tv32, &atv);
2457 if (itimerfix(&atv)) {
2458 error = EINVAL;
2459 goto done;
2460 }
2461 s = splclock();
2462 timeradd(&atv, &time, &atv);
2463 timo = hzto(&atv);
2464 /*
2465 * Avoid inadvertently sleeping forever.
2466 */
2467 if (timo == 0)
2468 timo = 1;
2469 splx(s);
2470 } else
2471 timo = 0;
2472 retry:
2473 ncoll = nselcoll;
2474 p->p_flag |= P_SELECT;
2475 error = selscan(p, (fd_mask *)(bits + ni * 0),
2476 (fd_mask *)(bits + ni * 3), SCARG(uap, nd), retval);
2477 if (error || *retval)
2478 goto done;
2479 s = splhigh();
2480 if (timo && timercmp(&time, &atv, >=)) {
2481 splx(s);
2482 goto done;
2483 }
2484 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
2485 splx(s);
2486 goto retry;
2487 }
2488 p->p_flag &= ~P_SELECT;
2489 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
2490 splx(s);
2491 if (error == 0)
2492 goto retry;
2493 done:
2494 p->p_flag &= ~P_SELECT;
2495 /* select is not restarted after signals... */
2496 if (error == ERESTART)
2497 error = EINTR;
2498 if (error == EWOULDBLOCK)
2499 error = 0;
2500 if (error == 0) {
2501 #define putbits(name, x) \
2502 if (SCARG(uap, name)) { \
2503 error = copyout(bits + ni * x, (caddr_t)(u_long)SCARG(uap, name), ni); \
2504 if (error) \
2505 goto out; \
2506 }
2507 putbits(in, 3);
2508 putbits(ou, 4);
2509 putbits(ex, 5);
2510 #undef putbits
2511 }
2512 out:
2513 if (ni * 6 > sizeof(smallbits))
2514 free(bits, M_TEMP);
2515 return (error);
2516 }
2517
2518 int
2519 netbsd32_fsync(p, v, retval)
2520 struct proc *p;
2521 void *v;
2522 register_t *retval;
2523 {
2524 struct netbsd32_fsync_args /* {
2525 syscallarg(int) fd;
2526 } */ *uap = v;
2527 struct sys_fsync_args ua;
2528
2529 NETBSD32TO64_UAP(fd);
2530 return (sys_fsync(p, &ua, retval));
2531 }
2532
2533 int
2534 netbsd32_setpriority(p, v, retval)
2535 struct proc *p;
2536 void *v;
2537 register_t *retval;
2538 {
2539 struct netbsd32_setpriority_args /* {
2540 syscallarg(int) which;
2541 syscallarg(int) who;
2542 syscallarg(int) prio;
2543 } */ *uap = v;
2544 struct sys_setpriority_args ua;
2545
2546 NETBSD32TO64_UAP(which);
2547 NETBSD32TO64_UAP(who);
2548 NETBSD32TO64_UAP(prio);
2549 return (sys_setpriority(p, &ua, retval));
2550 }
2551
2552 int
2553 netbsd32_socket(p, v, retval)
2554 struct proc *p;
2555 void *v;
2556 register_t *retval;
2557 {
2558 struct netbsd32_socket_args /* {
2559 syscallarg(int) domain;
2560 syscallarg(int) type;
2561 syscallarg(int) protocol;
2562 } */ *uap = v;
2563 struct sys_socket_args ua;
2564
2565 NETBSD32TO64_UAP(domain);
2566 NETBSD32TO64_UAP(type);
2567 NETBSD32TO64_UAP(protocol);
2568 return (sys_socket(p, &ua, retval));
2569 }
2570
2571 int
2572 netbsd32_connect(p, v, retval)
2573 struct proc *p;
2574 void *v;
2575 register_t *retval;
2576 {
2577 struct netbsd32_connect_args /* {
2578 syscallarg(int) s;
2579 syscallarg(const netbsd32_sockaddrp_t) name;
2580 syscallarg(int) namelen;
2581 } */ *uap = v;
2582 struct sys_connect_args ua;
2583
2584 NETBSD32TO64_UAP(s);
2585 NETBSD32TOP_UAP(name, struct sockaddr);
2586 NETBSD32TO64_UAP(namelen);
2587 return (sys_connect(p, &ua, retval));
2588 }
2589
2590 int
2591 netbsd32_getpriority(p, v, retval)
2592 struct proc *p;
2593 void *v;
2594 register_t *retval;
2595 {
2596 struct netbsd32_getpriority_args /* {
2597 syscallarg(int) which;
2598 syscallarg(int) who;
2599 } */ *uap = v;
2600 struct sys_getpriority_args ua;
2601
2602 NETBSD32TO64_UAP(which);
2603 NETBSD32TO64_UAP(who);
2604 return (sys_getpriority(p, &ua, retval));
2605 }
2606
2607 int
2608 netbsd32_bind(p, v, retval)
2609 struct proc *p;
2610 void *v;
2611 register_t *retval;
2612 {
2613 struct netbsd32_bind_args /* {
2614 syscallarg(int) s;
2615 syscallarg(const netbsd32_sockaddrp_t) name;
2616 syscallarg(int) namelen;
2617 } */ *uap = v;
2618 struct sys_bind_args ua;
2619
2620 NETBSD32TO64_UAP(s);
2621 NETBSD32TOP_UAP(name, struct sockaddr);
2622 NETBSD32TO64_UAP(namelen);
2623 return (sys_bind(p, &ua, retval));
2624 }
2625
2626 int
2627 netbsd32_setsockopt(p, v, retval)
2628 struct proc *p;
2629 void *v;
2630 register_t *retval;
2631 {
2632 struct netbsd32_setsockopt_args /* {
2633 syscallarg(int) s;
2634 syscallarg(int) level;
2635 syscallarg(int) name;
2636 syscallarg(const netbsd32_voidp) val;
2637 syscallarg(int) valsize;
2638 } */ *uap = v;
2639 struct sys_setsockopt_args ua;
2640
2641 NETBSD32TO64_UAP(s);
2642 NETBSD32TO64_UAP(level);
2643 NETBSD32TO64_UAP(name);
2644 NETBSD32TOP_UAP(val, void);
2645 NETBSD32TO64_UAP(valsize);
2646 /* may be more efficient to do this inline. */
2647 return (sys_setsockopt(p, &ua, retval));
2648 }
2649
2650 int
2651 netbsd32_listen(p, v, retval)
2652 struct proc *p;
2653 void *v;
2654 register_t *retval;
2655 {
2656 struct netbsd32_listen_args /* {
2657 syscallarg(int) s;
2658 syscallarg(int) backlog;
2659 } */ *uap = v;
2660 struct sys_listen_args ua;
2661
2662 NETBSD32TO64_UAP(s);
2663 NETBSD32TO64_UAP(backlog);
2664 return (sys_listen(p, &ua, retval));
2665 }
2666
2667 int
2668 netbsd32_gettimeofday(p, v, retval)
2669 struct proc *p;
2670 void *v;
2671 register_t *retval;
2672 {
2673 struct netbsd32_gettimeofday_args /* {
2674 syscallarg(netbsd32_timevalp_t) tp;
2675 syscallarg(netbsd32_timezonep_t) tzp;
2676 } */ *uap = v;
2677 struct timeval atv;
2678 struct netbsd32_timeval tv32;
2679 int error = 0;
2680 struct netbsd32_timezone tzfake;
2681
2682 if (SCARG(uap, tp)) {
2683 microtime(&atv);
2684 netbsd32_from_timeval(&atv, &tv32);
2685 error = copyout(&tv32, (caddr_t)(u_long)SCARG(uap, tp), sizeof(tv32));
2686 if (error)
2687 return (error);
2688 }
2689 if (SCARG(uap, tzp)) {
2690 /*
2691 * NetBSD has no kernel notion of time zone, so we just
2692 * fake up a timezone struct and return it if demanded.
2693 */
2694 tzfake.tz_minuteswest = 0;
2695 tzfake.tz_dsttime = 0;
2696 error = copyout(&tzfake, (caddr_t)(u_long)SCARG(uap, tzp), sizeof(tzfake));
2697 }
2698 return (error);
2699 }
2700
2701 #if 0
2702 static int settime32 __P((struct timeval *));
2703 /* This function is used by clock_settime and settimeofday */
2704 static int
2705 settime32(tv)
2706 struct timeval *tv;
2707 {
2708 struct timeval delta;
2709 int s;
2710
2711 /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
2712 s = splclock();
2713 timersub(tv, &time, &delta);
2714 if ((delta.tv_sec < 0 || delta.tv_usec < 0) && securelevel > 1)
2715 return (EPERM);
2716 #ifdef notyet
2717 if ((delta.tv_sec < 86400) && securelevel > 0)
2718 return (EPERM);
2719 #endif
2720 time = *tv;
2721 (void) spllowersoftclock();
2722 timeradd(&boottime, &delta, &boottime);
2723 timeradd(&runtime, &delta, &runtime);
2724 # if defined(NFS) || defined(NFSSERVER)
2725 {
2726 extern void nqnfs_lease_updatetime __P((int));
2727
2728 nqnfs_lease_updatetime(delta.tv_sec);
2729 }
2730 # endif
2731 splx(s);
2732 resettodr();
2733 return (0);
2734 }
2735 #endif
2736
2737 int
2738 netbsd32_settimeofday(p, v, retval)
2739 struct proc *p;
2740 void *v;
2741 register_t *retval;
2742 {
2743 struct netbsd32_settimeofday_args /* {
2744 syscallarg(const netbsd32_timevalp_t) tv;
2745 syscallarg(const netbsd32_timezonep_t) tzp;
2746 } */ *uap = v;
2747 struct netbsd32_timeval atv32;
2748 struct timeval atv;
2749 struct netbsd32_timezone atz;
2750 int error;
2751
2752 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
2753 return (error);
2754 /* Verify all parameters before changing time. */
2755 if (SCARG(uap, tv) && (error = copyin((caddr_t)(u_long)SCARG(uap, tv),
2756 &atv32, sizeof(atv32))))
2757 return (error);
2758 netbsd32_to_timeval(&atv32, &atv);
2759 /* XXX since we don't use tz, probably no point in doing copyin. */
2760 if (SCARG(uap, tzp) && (error = copyin((caddr_t)(u_long)SCARG(uap, tzp),
2761 &atz, sizeof(atz))))
2762 return (error);
2763 if (SCARG(uap, tv))
2764 if ((error = settime(&atv)))
2765 return (error);
2766 /*
2767 * NetBSD has no kernel notion of time zone, and only an
2768 * obsolete program would try to set it, so we log a warning.
2769 */
2770 if (SCARG(uap, tzp))
2771 printf("pid %d attempted to set the "
2772 "(obsolete) kernel time zone\n", p->p_pid);
2773 return (0);
2774 }
2775
2776 int
2777 netbsd32_fchown(p, v, retval)
2778 struct proc *p;
2779 void *v;
2780 register_t *retval;
2781 {
2782 struct netbsd32_fchown_args /* {
2783 syscallarg(int) fd;
2784 syscallarg(uid_t) uid;
2785 syscallarg(gid_t) gid;
2786 } */ *uap = v;
2787 struct sys_fchown_args ua;
2788
2789 NETBSD32TO64_UAP(fd);
2790 NETBSD32TO64_UAP(uid);
2791 NETBSD32TO64_UAP(gid);
2792 return (sys_fchown(p, &ua, retval));
2793 }
2794
2795 int
2796 netbsd32_fchmod(p, v, retval)
2797 struct proc *p;
2798 void *v;
2799 register_t *retval;
2800 {
2801 struct netbsd32_fchmod_args /* {
2802 syscallarg(int) fd;
2803 syscallarg(mode_t) mode;
2804 } */ *uap = v;
2805 struct sys_fchmod_args ua;
2806
2807 NETBSD32TO64_UAP(fd);
2808 NETBSD32TO64_UAP(mode);
2809 return (sys_fchmod(p, &ua, retval));
2810 }
2811
2812 int
2813 netbsd32_setreuid(p, v, retval)
2814 struct proc *p;
2815 void *v;
2816 register_t *retval;
2817 {
2818 struct netbsd32_setreuid_args /* {
2819 syscallarg(uid_t) ruid;
2820 syscallarg(uid_t) euid;
2821 } */ *uap = v;
2822 struct sys_setreuid_args ua;
2823
2824 NETBSD32TO64_UAP(ruid);
2825 NETBSD32TO64_UAP(euid);
2826 return (sys_setreuid(p, &ua, retval));
2827 }
2828
2829 int
2830 netbsd32_setregid(p, v, retval)
2831 struct proc *p;
2832 void *v;
2833 register_t *retval;
2834 {
2835 struct netbsd32_setregid_args /* {
2836 syscallarg(gid_t) rgid;
2837 syscallarg(gid_t) egid;
2838 } */ *uap = v;
2839 struct sys_setregid_args ua;
2840
2841 NETBSD32TO64_UAP(rgid);
2842 NETBSD32TO64_UAP(egid);
2843 return (sys_setregid(p, &ua, retval));
2844 }
2845
2846 int
2847 netbsd32_getrusage(p, v, retval)
2848 struct proc *p;
2849 void *v;
2850 register_t *retval;
2851 {
2852 struct netbsd32_getrusage_args /* {
2853 syscallarg(int) who;
2854 syscallarg(netbsd32_rusagep_t) rusage;
2855 } */ *uap = v;
2856 struct rusage *rup;
2857 struct netbsd32_rusage ru;
2858
2859 switch (SCARG(uap, who)) {
2860
2861 case RUSAGE_SELF:
2862 rup = &p->p_stats->p_ru;
2863 calcru(p, &rup->ru_utime, &rup->ru_stime, NULL);
2864 break;
2865
2866 case RUSAGE_CHILDREN:
2867 rup = &p->p_stats->p_cru;
2868 break;
2869
2870 default:
2871 return (EINVAL);
2872 }
2873 netbsd32_from_rusage(rup, &ru);
2874 return (copyout(&ru, (caddr_t)(u_long)SCARG(uap, rusage), sizeof(ru)));
2875 }
2876
2877 int
2878 netbsd32_getsockopt(p, v, retval)
2879 struct proc *p;
2880 void *v;
2881 register_t *retval;
2882 {
2883 struct netbsd32_getsockopt_args /* {
2884 syscallarg(int) s;
2885 syscallarg(int) level;
2886 syscallarg(int) name;
2887 syscallarg(netbsd32_voidp) val;
2888 syscallarg(netbsd32_intp) avalsize;
2889 } */ *uap = v;
2890 struct sys_getsockopt_args ua;
2891
2892 NETBSD32TO64_UAP(s);
2893 NETBSD32TO64_UAP(level);
2894 NETBSD32TO64_UAP(name);
2895 NETBSD32TOP_UAP(val, void);
2896 NETBSD32TOP_UAP(avalsize, int);
2897 return (sys_getsockopt(p, &ua, retval));
2898 }
2899
2900 int
2901 netbsd32_readv(p, v, retval)
2902 struct proc *p;
2903 void *v;
2904 register_t *retval;
2905 {
2906 struct netbsd32_readv_args /* {
2907 syscallarg(int) fd;
2908 syscallarg(const netbsd32_iovecp_t) iovp;
2909 syscallarg(int) iovcnt;
2910 } */ *uap = v;
2911 int fd = SCARG(uap, fd);
2912 register struct file *fp;
2913 register struct filedesc *fdp = p->p_fd;
2914
2915 if ((u_int)fd >= fdp->fd_nfiles ||
2916 (fp = fdp->fd_ofiles[fd]) == NULL ||
2917 (fp->f_flag & FREAD) == 0)
2918 return (EBADF);
2919
2920 return (dofilereadv32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp),
2921 SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
2922 }
2923
2924 /* Damn thing copies in the iovec! */
2925 int
2926 dofilereadv32(p, fd, fp, iovp, iovcnt, offset, flags, retval)
2927 struct proc *p;
2928 int fd;
2929 struct file *fp;
2930 struct netbsd32_iovec *iovp;
2931 int iovcnt;
2932 off_t *offset;
2933 int flags;
2934 register_t *retval;
2935 {
2936 struct uio auio;
2937 register struct iovec *iov;
2938 struct iovec *needfree;
2939 struct iovec aiov[UIO_SMALLIOV];
2940 long i, cnt, error = 0;
2941 u_int iovlen;
2942 #ifdef KTRACE
2943 struct iovec *ktriov = NULL;
2944 #endif
2945
2946 /* note: can't use iovlen until iovcnt is validated */
2947 iovlen = iovcnt * sizeof(struct iovec);
2948 if ((u_int)iovcnt > UIO_SMALLIOV) {
2949 if ((u_int)iovcnt > IOV_MAX)
2950 return (EINVAL);
2951 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
2952 needfree = iov;
2953 } else if ((u_int)iovcnt > 0) {
2954 iov = aiov;
2955 needfree = NULL;
2956 } else
2957 return (EINVAL);
2958
2959 auio.uio_iov = iov;
2960 auio.uio_iovcnt = iovcnt;
2961 auio.uio_rw = UIO_READ;
2962 auio.uio_segflg = UIO_USERSPACE;
2963 auio.uio_procp = p;
2964 error = netbsd32_to_iovecin(iovp, iov, iovcnt);
2965 if (error)
2966 goto done;
2967 auio.uio_resid = 0;
2968 for (i = 0; i < iovcnt; i++) {
2969 auio.uio_resid += iov->iov_len;
2970 /*
2971 * Reads return ssize_t because -1 is returned on error.
2972 * Therefore we must restrict the length to SSIZE_MAX to
2973 * avoid garbage return values.
2974 */
2975 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
2976 error = EINVAL;
2977 goto done;
2978 }
2979 iov++;
2980 }
2981 #ifdef KTRACE
2982 /*
2983 * if tracing, save a copy of iovec
2984 */
2985 if (KTRPOINT(p, KTR_GENIO)) {
2986 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
2987 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
2988 }
2989 #endif
2990 cnt = auio.uio_resid;
2991 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags);
2992 if (error)
2993 if (auio.uio_resid != cnt && (error == ERESTART ||
2994 error == EINTR || error == EWOULDBLOCK))
2995 error = 0;
2996 cnt -= auio.uio_resid;
2997 #ifdef KTRACE
2998 if (KTRPOINT(p, KTR_GENIO))
2999 if (error == 0) {
3000 ktrgenio(p->p_tracep, fd, UIO_READ, ktriov, cnt,
3001 error);
3002 FREE(ktriov, M_TEMP);
3003 }
3004 #endif
3005 *retval = cnt;
3006 done:
3007 if (needfree)
3008 FREE(needfree, M_IOV);
3009 return (error);
3010 }
3011
3012
3013 int
3014 netbsd32_writev(p, v, retval)
3015 struct proc *p;
3016 void *v;
3017 register_t *retval;
3018 {
3019 struct netbsd32_writev_args /* {
3020 syscallarg(int) fd;
3021 syscallarg(const netbsd32_iovecp_t) iovp;
3022 syscallarg(int) iovcnt;
3023 } */ *uap = v;
3024 int fd = SCARG(uap, fd);
3025 register struct file *fp;
3026 register struct filedesc *fdp = p->p_fd;
3027
3028 if ((u_int)fd >= fdp->fd_nfiles ||
3029 (fp = fdp->fd_ofiles[fd]) == NULL ||
3030 (fp->f_flag & FWRITE) == 0)
3031 return (EBADF);
3032
3033 return (dofilewritev32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp),
3034 SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
3035 }
3036
3037 int
3038 dofilewritev32(p, fd, fp, iovp, iovcnt, offset, flags, retval)
3039 struct proc *p;
3040 int fd;
3041 struct file *fp;
3042 struct netbsd32_iovec *iovp;
3043 int iovcnt;
3044 off_t *offset;
3045 int flags;
3046 register_t *retval;
3047 {
3048 struct uio auio;
3049 register struct iovec *iov;
3050 struct iovec *needfree;
3051 struct iovec aiov[UIO_SMALLIOV];
3052 long i, cnt, error = 0;
3053 u_int iovlen;
3054 #ifdef KTRACE
3055 struct iovec *ktriov = NULL;
3056 #endif
3057
3058 /* note: can't use iovlen until iovcnt is validated */
3059 iovlen = iovcnt * sizeof(struct iovec);
3060 if ((u_int)iovcnt > UIO_SMALLIOV) {
3061 if ((u_int)iovcnt > IOV_MAX)
3062 return (EINVAL);
3063 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
3064 needfree = iov;
3065 } else if ((u_int)iovcnt > 0) {
3066 iov = aiov;
3067 needfree = NULL;
3068 } else
3069 return (EINVAL);
3070
3071 auio.uio_iov = iov;
3072 auio.uio_iovcnt = iovcnt;
3073 auio.uio_rw = UIO_WRITE;
3074 auio.uio_segflg = UIO_USERSPACE;
3075 auio.uio_procp = p;
3076 error = netbsd32_to_iovecin(iovp, iov, iovcnt);
3077 if (error)
3078 goto done;
3079 auio.uio_resid = 0;
3080 for (i = 0; i < iovcnt; i++) {
3081 auio.uio_resid += iov->iov_len;
3082 /*
3083 * Writes return ssize_t because -1 is returned on error.
3084 * Therefore we must restrict the length to SSIZE_MAX to
3085 * avoid garbage return values.
3086 */
3087 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
3088 error = EINVAL;
3089 goto done;
3090 }
3091 iov++;
3092 }
3093 #ifdef KTRACE
3094 /*
3095 * if tracing, save a copy of iovec
3096 */
3097 if (KTRPOINT(p, KTR_GENIO)) {
3098 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
3099 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
3100 }
3101 #endif
3102 cnt = auio.uio_resid;
3103 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags);
3104 if (error) {
3105 if (auio.uio_resid != cnt && (error == ERESTART ||
3106 error == EINTR || error == EWOULDBLOCK))
3107 error = 0;
3108 if (error == EPIPE)
3109 psignal(p, SIGPIPE);
3110 }
3111 cnt -= auio.uio_resid;
3112 #ifdef KTRACE
3113 if (KTRPOINT(p, KTR_GENIO))
3114 if (error == 0) {
3115 ktrgenio(p->p_tracep, fd, UIO_WRITE, ktriov, cnt,
3116 error);
3117 FREE(ktriov, M_TEMP);
3118 }
3119 #endif
3120 *retval = cnt;
3121 done:
3122 if (needfree)
3123 FREE(needfree, M_IOV);
3124 return (error);
3125 }
3126
3127
3128 int
3129 netbsd32_rename(p, v, retval)
3130 struct proc *p;
3131 void *v;
3132 register_t *retval;
3133 {
3134 struct netbsd32_rename_args /* {
3135 syscallarg(const netbsd32_charp) from;
3136 syscallarg(const netbsd32_charp) to;
3137 } */ *uap = v;
3138 struct sys_rename_args ua;
3139
3140 NETBSD32TOP_UAP(from, const char);
3141 NETBSD32TOP_UAP(to, const char)
3142
3143 return (sys_rename(p, &ua, retval));
3144 }
3145
3146 int
3147 netbsd32_flock(p, v, retval)
3148 struct proc *p;
3149 void *v;
3150 register_t *retval;
3151 {
3152 struct netbsd32_flock_args /* {
3153 syscallarg(int) fd;
3154 syscallarg(int) how;
3155 } */ *uap = v;
3156 struct sys_flock_args ua;
3157
3158 NETBSD32TO64_UAP(fd);
3159 NETBSD32TO64_UAP(how)
3160
3161 return (sys_flock(p, &ua, retval));
3162 }
3163
3164 int
3165 netbsd32_mkfifo(p, v, retval)
3166 struct proc *p;
3167 void *v;
3168 register_t *retval;
3169 {
3170 struct netbsd32_mkfifo_args /* {
3171 syscallarg(const netbsd32_charp) path;
3172 syscallarg(mode_t) mode;
3173 } */ *uap = v;
3174 struct sys_mkfifo_args ua;
3175
3176 NETBSD32TOP_UAP(path, const char)
3177 NETBSD32TO64_UAP(mode);
3178 return (sys_mkfifo(p, &ua, retval));
3179 }
3180
3181 int
3182 netbsd32_shutdown(p, v, retval)
3183 struct proc *p;
3184 void *v;
3185 register_t *retval;
3186 {
3187 struct netbsd32_shutdown_args /* {
3188 syscallarg(int) s;
3189 syscallarg(int) how;
3190 } */ *uap = v;
3191 struct sys_shutdown_args ua;
3192
3193 NETBSD32TO64_UAP(s)
3194 NETBSD32TO64_UAP(how);
3195 return (sys_shutdown(p, &ua, retval));
3196 }
3197
3198 int
3199 netbsd32_socketpair(p, v, retval)
3200 struct proc *p;
3201 void *v;
3202 register_t *retval;
3203 {
3204 struct netbsd32_socketpair_args /* {
3205 syscallarg(int) domain;
3206 syscallarg(int) type;
3207 syscallarg(int) protocol;
3208 syscallarg(netbsd32_intp) rsv;
3209 } */ *uap = v;
3210 struct sys_socketpair_args ua;
3211
3212 NETBSD32TO64_UAP(domain);
3213 NETBSD32TO64_UAP(type);
3214 NETBSD32TO64_UAP(protocol);
3215 NETBSD32TOP_UAP(rsv, int);
3216 /* Since we're just copying out two `int's we can do this */
3217 return (sys_socketpair(p, &ua, retval));
3218 }
3219
3220 int
3221 netbsd32_mkdir(p, v, retval)
3222 struct proc *p;
3223 void *v;
3224 register_t *retval;
3225 {
3226 struct netbsd32_mkdir_args /* {
3227 syscallarg(const netbsd32_charp) path;
3228 syscallarg(mode_t) mode;
3229 } */ *uap = v;
3230 struct sys_mkdir_args ua;
3231
3232 NETBSD32TOP_UAP(path, const char)
3233 NETBSD32TO64_UAP(mode);
3234 return (sys_mkdir(p, &ua, retval));
3235 }
3236
3237 int
3238 netbsd32_rmdir(p, v, retval)
3239 struct proc *p;
3240 void *v;
3241 register_t *retval;
3242 {
3243 struct netbsd32_rmdir_args /* {
3244 syscallarg(const netbsd32_charp) path;
3245 } */ *uap = v;
3246 struct sys_rmdir_args ua;
3247
3248 NETBSD32TOP_UAP(path, const char);
3249 return (sys_rmdir(p, &ua, retval));
3250 }
3251
3252 int
3253 netbsd32_utimes(p, v, retval)
3254 struct proc *p;
3255 void *v;
3256 register_t *retval;
3257 {
3258 struct netbsd32_utimes_args /* {
3259 syscallarg(const netbsd32_charp) path;
3260 syscallarg(const netbsd32_timevalp_t) tptr;
3261 } */ *uap = v;
3262 int error;
3263 struct nameidata nd;
3264
3265 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, (char *)(u_long)SCARG(uap, path), p);
3266 if ((error = namei(&nd)) != 0)
3267 return (error);
3268
3269 error = change_utimes32(nd.ni_vp, (struct timeval *)(u_long)SCARG(uap, tptr), p);
3270
3271 vrele(nd.ni_vp);
3272 return (error);
3273 }
3274
3275 /*
3276 * Common routine to set access and modification times given a vnode.
3277 */
3278 static int
3279 change_utimes32(vp, tptr, p)
3280 struct vnode *vp;
3281 struct timeval *tptr;
3282 struct proc *p;
3283 {
3284 struct netbsd32_timeval tv32[2];
3285 struct timeval tv[2];
3286 struct vattr vattr;
3287 int error;
3288
3289 VATTR_NULL(&vattr);
3290 if (tptr == NULL) {
3291 microtime(&tv[0]);
3292 tv[1] = tv[0];
3293 vattr.va_vaflags |= VA_UTIMES_NULL;
3294 } else {
3295 error = copyin(tptr, tv, sizeof(tv));
3296 if (error)
3297 return (error);
3298 }
3299 netbsd32_to_timeval(&tv32[0], &tv[0]);
3300 netbsd32_to_timeval(&tv32[1], &tv[1]);
3301 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
3302 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
3303 vattr.va_atime.tv_sec = tv[0].tv_sec;
3304 vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
3305 vattr.va_mtime.tv_sec = tv[1].tv_sec;
3306 vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;
3307 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
3308 VOP_UNLOCK(vp, 0);
3309 return (error);
3310 }
3311
3312 int
3313 netbsd32_adjtime(p, v, retval)
3314 struct proc *p;
3315 void *v;
3316 register_t *retval;
3317 {
3318 struct netbsd32_adjtime_args /* {
3319 syscallarg(const netbsd32_timevalp_t) delta;
3320 syscallarg(netbsd32_timevalp_t) olddelta;
3321 } */ *uap = v;
3322 struct netbsd32_timeval atv;
3323 int32_t ndelta, ntickdelta, odelta;
3324 int s, error;
3325 extern long bigadj, timedelta;
3326 extern int tickdelta;
3327
3328 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
3329 return (error);
3330
3331 error = copyin((caddr_t)(u_long)SCARG(uap, delta), &atv, sizeof(struct timeval));
3332 if (error)
3333 return (error);
3334 /*
3335 * Compute the total correction and the rate at which to apply it.
3336 * Round the adjustment down to a whole multiple of the per-tick
3337 * delta, so that after some number of incremental changes in
3338 * hardclock(), tickdelta will become zero, lest the correction
3339 * overshoot and start taking us away from the desired final time.
3340 */
3341 ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
3342 if (ndelta > bigadj)
3343 ntickdelta = 10 * tickadj;
3344 else
3345 ntickdelta = tickadj;
3346 if (ndelta % ntickdelta)
3347 ndelta = ndelta / ntickdelta * ntickdelta;
3348
3349 /*
3350 * To make hardclock()'s job easier, make the per-tick delta negative
3351 * if we want time to run slower; then hardclock can simply compute
3352 * tick + tickdelta, and subtract tickdelta from timedelta.
3353 */
3354 if (ndelta < 0)
3355 ntickdelta = -ntickdelta;
3356 s = splclock();
3357 odelta = timedelta;
3358 timedelta = ndelta;
3359 tickdelta = ntickdelta;
3360 splx(s);
3361
3362 if (SCARG(uap, olddelta)) {
3363 atv.tv_sec = odelta / 1000000;
3364 atv.tv_usec = odelta % 1000000;
3365 (void) copyout(&atv, (caddr_t)(u_long)SCARG(uap, olddelta),
3366 sizeof(struct timeval));
3367 }
3368 return (0);
3369 }
3370
3371 int
3372 netbsd32_quotactl(p, v, retval)
3373 struct proc *p;
3374 void *v;
3375 register_t *retval;
3376 {
3377 struct netbsd32_quotactl_args /* {
3378 syscallarg(const netbsd32_charp) path;
3379 syscallarg(int) cmd;
3380 syscallarg(int) uid;
3381 syscallarg(netbsd32_caddr_t) arg;
3382 } */ *uap = v;
3383 struct sys_quotactl_args ua;
3384
3385 NETBSD32TOP_UAP(path, const char);
3386 NETBSD32TO64_UAP(cmd);
3387 NETBSD32TO64_UAP(uid);
3388 NETBSD32TOX64_UAP(arg, caddr_t);
3389 return (sys_quotactl(p, &ua, retval));
3390 }
3391
3392 #if defined(NFS) || defined(NFSSERVER)
3393 int
3394 netbsd32_nfssvc(p, v, retval)
3395 struct proc *p;
3396 void *v;
3397 register_t *retval;
3398 {
3399 #if 0
3400 struct netbsd32_nfssvc_args /* {
3401 syscallarg(int) flag;
3402 syscallarg(netbsd32_voidp) argp;
3403 } */ *uap = v;
3404 struct sys_nfssvc_args ua;
3405
3406 NETBSD32TO64_UAP(flag);
3407 NETBSD32TOP_UAP(argp, void);
3408 return (sys_nfssvc(p, &ua, retval));
3409 #else
3410 /* Why would we want to support a 32-bit nfsd? */
3411 return (ENOSYS);
3412 #endif
3413 }
3414 #endif
3415
3416 int
3417 netbsd32_statfs(p, v, retval)
3418 struct proc *p;
3419 void *v;
3420 register_t *retval;
3421 {
3422 struct netbsd32_statfs_args /* {
3423 syscallarg(const netbsd32_charp) path;
3424 syscallarg(netbsd32_statfsp_t) buf;
3425 } */ *uap = v;
3426 register struct mount *mp;
3427 register struct statfs *sp;
3428 struct netbsd32_statfs s32;
3429 int error;
3430 struct nameidata nd;
3431
3432 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, (char *)(u_long)SCARG(uap, path), p);
3433 if ((error = namei(&nd)) != 0)
3434 return (error);
3435 mp = nd.ni_vp->v_mount;
3436 sp = &mp->mnt_stat;
3437 vrele(nd.ni_vp);
3438 if ((error = VFS_STATFS(mp, sp, p)) != 0)
3439 return (error);
3440 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
3441 netbsd32_from_statfs(sp, &s32);
3442 return (copyout(&s32, (caddr_t)(u_long)SCARG(uap, buf), sizeof(s32)));
3443 }
3444
3445 int
3446 netbsd32_fstatfs(p, v, retval)
3447 struct proc *p;
3448 void *v;
3449 register_t *retval;
3450 {
3451 struct netbsd32_fstatfs_args /* {
3452 syscallarg(int) fd;
3453 syscallarg(netbsd32_statfsp_t) buf;
3454 } */ *uap = v;
3455 struct file *fp;
3456 register struct mount *mp;
3457 register struct statfs *sp;
3458 struct netbsd32_statfs s32;
3459 int error;
3460
3461 /* getvnode() will use the descriptor for us */
3462 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
3463 return (error);
3464 mp = ((struct vnode *)fp->f_data)->v_mount;
3465 sp = &mp->mnt_stat;
3466 if ((error = VFS_STATFS(mp, sp, p)) != 0)
3467 goto out;
3468 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
3469 netbsd32_from_statfs(sp, &s32);
3470 error = copyout(&s32, (caddr_t)(u_long)SCARG(uap, buf), sizeof(s32));
3471 out:
3472 FILE_UNUSE(fp, p);
3473 return (error);
3474 }
3475
3476 #if defined(NFS) || defined(NFSSERVER)
3477 int
3478 netbsd32_getfh(p, v, retval)
3479 struct proc *p;
3480 void *v;
3481 register_t *retval;
3482 {
3483 struct netbsd32_getfh_args /* {
3484 syscallarg(const netbsd32_charp) fname;
3485 syscallarg(netbsd32_fhandlep_t) fhp;
3486 } */ *uap = v;
3487 struct sys_getfh_args ua;
3488
3489 NETBSD32TOP_UAP(fname, const char);
3490 NETBSD32TOP_UAP(fhp, struct fhandle);
3491 /* Lucky for us a fhandlep_t doesn't change sizes */
3492 return (sys_getfh(p, &ua, retval));
3493 }
3494 #endif
3495
3496 int
3497 netbsd32_sysarch(p, v, retval)
3498 struct proc *p;
3499 void *v;
3500 register_t *retval;
3501 {
3502 struct netbsd32_sysarch_args /* {
3503 syscallarg(int) op;
3504 syscallarg(netbsd32_voidp) parms;
3505 } */ *uap = v;
3506
3507 switch (SCARG(uap, op)) {
3508 default:
3509 printf("(sparc64) netbsd32_sysarch(%d)\n", SCARG(uap, op));
3510 return EINVAL;
3511 }
3512 }
3513
3514 int
3515 netbsd32_pread(p, v, retval)
3516 struct proc *p;
3517 void *v;
3518 register_t *retval;
3519 {
3520 struct netbsd32_pread_args /* {
3521 syscallarg(int) fd;
3522 syscallarg(netbsd32_voidp) buf;
3523 syscallarg(netbsd32_size_t) nbyte;
3524 syscallarg(int) pad;
3525 syscallarg(off_t) offset;
3526 } */ *uap = v;
3527 struct sys_pread_args ua;
3528 ssize_t rt;
3529 int error;
3530
3531 NETBSD32TO64_UAP(fd);
3532 NETBSD32TOP_UAP(buf, void);
3533 NETBSD32TOX_UAP(nbyte, size_t);
3534 NETBSD32TO64_UAP(pad);
3535 NETBSD32TO64_UAP(offset);
3536 error = sys_pread(p, &ua, (register_t *)&rt);
3537 *(netbsd32_ssize_t *)retval = rt;
3538 return (error);
3539 }
3540
3541 int
3542 netbsd32_pwrite(p, v, retval)
3543 struct proc *p;
3544 void *v;
3545 register_t *retval;
3546 {
3547 struct netbsd32_pwrite_args /* {
3548 syscallarg(int) fd;
3549 syscallarg(const netbsd32_voidp) buf;
3550 syscallarg(netbsd32_size_t) nbyte;
3551 syscallarg(int) pad;
3552 syscallarg(off_t) offset;
3553 } */ *uap = v;
3554 struct sys_pwrite_args ua;
3555 ssize_t rt;
3556 int error;
3557
3558 NETBSD32TO64_UAP(fd);
3559 NETBSD32TOP_UAP(buf, void);
3560 NETBSD32TOX_UAP(nbyte, size_t);
3561 NETBSD32TO64_UAP(pad);
3562 NETBSD32TO64_UAP(offset);
3563 error = sys_pwrite(p, &ua, (register_t *)&rt);
3564 *(netbsd32_ssize_t *)retval = rt;
3565 return (error);
3566 }
3567
3568 #ifdef NTP
3569 int
3570 netbsd32_ntp_gettime(p, v, retval)
3571 struct proc *p;
3572 void *v;
3573 register_t *retval;
3574 {
3575 struct netbsd32_ntp_gettime_args /* {
3576 syscallarg(netbsd32_ntptimevalp_t) ntvp;
3577 } */ *uap = v;
3578 struct netbsd32_ntptimeval ntv32;
3579 struct timeval atv;
3580 struct ntptimeval ntv;
3581 int error = 0;
3582 int s;
3583
3584 /* The following are NTP variables */
3585 extern long time_maxerror;
3586 extern long time_esterror;
3587 extern int time_status;
3588 extern int time_state; /* clock state */
3589 extern int time_status; /* clock status bits */
3590
3591 if (SCARG(uap, ntvp)) {
3592 s = splclock();
3593 #ifdef EXT_CLOCK
3594 /*
3595 * The microtime() external clock routine returns a
3596 * status code. If less than zero, we declare an error
3597 * in the clock status word and return the kernel
3598 * (software) time variable. While there are other
3599 * places that call microtime(), this is the only place
3600 * that matters from an application point of view.
3601 */
3602 if (microtime(&atv) < 0) {
3603 time_status |= STA_CLOCKERR;
3604 ntv.time = time;
3605 } else
3606 time_status &= ~STA_CLOCKERR;
3607 #else /* EXT_CLOCK */
3608 microtime(&atv);
3609 #endif /* EXT_CLOCK */
3610 ntv.time = atv;
3611 ntv.maxerror = time_maxerror;
3612 ntv.esterror = time_esterror;
3613 (void) splx(s);
3614
3615 netbsd32_from_timeval(&ntv.time, &ntv32.time);
3616 ntv32.maxerror = (netbsd32_long)ntv.maxerror;
3617 ntv32.esterror = (netbsd32_long)ntv.esterror;
3618 error = copyout((caddr_t)&ntv32, (caddr_t)(u_long)SCARG(uap, ntvp),
3619 sizeof(ntv32));
3620 }
3621 if (!error) {
3622
3623 /*
3624 * Status word error decode. If any of these conditions
3625 * occur, an error is returned, instead of the status
3626 * word. Most applications will care only about the fact
3627 * the system clock may not be trusted, not about the
3628 * details.
3629 *
3630 * Hardware or software error
3631 */
3632 if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
3633
3634 /*
3635 * PPS signal lost when either time or frequency
3636 * synchronization requested
3637 */
3638 (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
3639 !(time_status & STA_PPSSIGNAL)) ||
3640
3641 /*
3642 * PPS jitter exceeded when time synchronization
3643 * requested
3644 */
3645 (time_status & STA_PPSTIME &&
3646 time_status & STA_PPSJITTER) ||
3647
3648 /*
3649 * PPS wander exceeded or calibration error when
3650 * frequency synchronization requested
3651 */
3652 (time_status & STA_PPSFREQ &&
3653 time_status & (STA_PPSWANDER | STA_PPSERROR)))
3654 *retval = TIME_ERROR;
3655 else
3656 *retval = (register_t)time_state;
3657 }
3658 return(error);
3659 }
3660
3661 int
3662 netbsd32_ntp_adjtime(p, v, retval)
3663 struct proc *p;
3664 void *v;
3665 register_t *retval;
3666 {
3667 struct netbsd32_ntp_adjtime_args /* {
3668 syscallarg(netbsd32_timexp_t) tp;
3669 } */ *uap = v;
3670 struct netbsd32_timex ntv32;
3671 struct timex ntv;
3672 int error = 0;
3673 int modes;
3674 int s;
3675 extern long time_freq; /* frequency offset (scaled ppm) */
3676 extern long time_maxerror;
3677 extern long time_esterror;
3678 extern int time_state; /* clock state */
3679 extern int time_status; /* clock status bits */
3680 extern long time_constant; /* pll time constant */
3681 extern long time_offset; /* time offset (us) */
3682 extern long time_tolerance; /* frequency tolerance (scaled ppm) */
3683 extern long time_precision; /* clock precision (us) */
3684
3685 if ((error = copyin((caddr_t)(u_long)SCARG(uap, tp), (caddr_t)&ntv32,
3686 sizeof(ntv32))))
3687 return (error);
3688 netbsd32_to_timex(&ntv32, &ntv);
3689
3690 /*
3691 * Update selected clock variables - only the superuser can
3692 * change anything. Note that there is no error checking here on
3693 * the assumption the superuser should know what it is doing.
3694 */
3695 modes = ntv.modes;
3696 if (modes != 0 && (error = suser(p->p_ucred, &p->p_acflag)))
3697 return (error);
3698
3699 s = splclock();
3700 if (modes & MOD_FREQUENCY)
3701 #ifdef PPS_SYNC
3702 time_freq = ntv.freq - pps_freq;
3703 #else /* PPS_SYNC */
3704 time_freq = ntv.freq;
3705 #endif /* PPS_SYNC */
3706 if (modes & MOD_MAXERROR)
3707 time_maxerror = ntv.maxerror;
3708 if (modes & MOD_ESTERROR)
3709 time_esterror = ntv.esterror;
3710 if (modes & MOD_STATUS) {
3711 time_status &= STA_RONLY;
3712 time_status |= ntv.status & ~STA_RONLY;
3713 }
3714 if (modes & MOD_TIMECONST)
3715 time_constant = ntv.constant;
3716 if (modes & MOD_OFFSET)
3717 hardupdate(ntv.offset);
3718
3719 /*
3720 * Retrieve all clock variables
3721 */
3722 if (time_offset < 0)
3723 ntv.offset = -(-time_offset >> SHIFT_UPDATE);
3724 else
3725 ntv.offset = time_offset >> SHIFT_UPDATE;
3726 #ifdef PPS_SYNC
3727 ntv.freq = time_freq + pps_freq;
3728 #else /* PPS_SYNC */
3729 ntv.freq = time_freq;
3730 #endif /* PPS_SYNC */
3731 ntv.maxerror = time_maxerror;
3732 ntv.esterror = time_esterror;
3733 ntv.status = time_status;
3734 ntv.constant = time_constant;
3735 ntv.precision = time_precision;
3736 ntv.tolerance = time_tolerance;
3737 #ifdef PPS_SYNC
3738 ntv.shift = pps_shift;
3739 ntv.ppsfreq = pps_freq;
3740 ntv.jitter = pps_jitter >> PPS_AVG;
3741 ntv.stabil = pps_stabil;
3742 ntv.calcnt = pps_calcnt;
3743 ntv.errcnt = pps_errcnt;
3744 ntv.jitcnt = pps_jitcnt;
3745 ntv.stbcnt = pps_stbcnt;
3746 #endif /* PPS_SYNC */
3747 (void)splx(s);
3748
3749 netbsd32_from_timeval(&ntv, &ntv32);
3750 error = copyout((caddr_t)&ntv32, (caddr_t)SCARG(uap, tp), sizeof(ntv32));
3751 if (!error) {
3752
3753 /*
3754 * Status word error decode. See comments in
3755 * ntp_gettime() routine.
3756 */
3757 if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
3758 (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
3759 !(time_status & STA_PPSSIGNAL)) ||
3760 (time_status & STA_PPSTIME &&
3761 time_status & STA_PPSJITTER) ||
3762 (time_status & STA_PPSFREQ &&
3763 time_status & (STA_PPSWANDER | STA_PPSERROR)))
3764 *retval = TIME_ERROR;
3765 else
3766 *retval = (register_t)time_state;
3767 }
3768 return error;
3769 }
3770 #endif
3771
3772 int
3773 netbsd32_setgid(p, v, retval)
3774 struct proc *p;
3775 void *v;
3776 register_t *retval;
3777 {
3778 struct netbsd32_setgid_args /* {
3779 syscallarg(gid_t) gid;
3780 } */ *uap = v;
3781 struct sys_setgid_args ua;
3782
3783 NETBSD32TO64_UAP(gid);
3784 return (sys_setgid(p, v, retval));
3785 }
3786
3787 int
3788 netbsd32_setegid(p, v, retval)
3789 struct proc *p;
3790 void *v;
3791 register_t *retval;
3792 {
3793 struct netbsd32_setegid_args /* {
3794 syscallarg(gid_t) egid;
3795 } */ *uap = v;
3796 struct sys_setegid_args ua;
3797
3798 NETBSD32TO64_UAP(egid);
3799 return (sys_setegid(p, v, retval));
3800 }
3801
3802 int
3803 netbsd32_seteuid(p, v, retval)
3804 struct proc *p;
3805 void *v;
3806 register_t *retval;
3807 {
3808 struct netbsd32_seteuid_args /* {
3809 syscallarg(gid_t) euid;
3810 } */ *uap = v;
3811 struct sys_seteuid_args ua;
3812
3813 NETBSD32TO64_UAP(euid);
3814 return (sys_seteuid(p, v, retval));
3815 }
3816
3817 #ifdef LFS
3818 int
3819 netbsd32_sys_lfs_bmapv(p, v, retval)
3820 struct proc *p;
3821 void *v;
3822 register_t *retval;
3823 {
3824 #if 0
3825 struct netbsd32_lfs_bmapv_args /* {
3826 syscallarg(netbsd32_fsid_tp_t) fsidp;
3827 syscallarg(netbsd32_block_infop_t) blkiov;
3828 syscallarg(int) blkcnt;
3829 } */ *uap = v;
3830 struct sys_lfs_bmapv_args ua;
3831
3832 NETBSD32TOP_UAP(fdidp, struct fsid);
3833 NETBSD32TO64_UAP(blkcnt);
3834 /* XXX finish me */
3835 #else
3836
3837 return (ENOSYS); /* XXX */
3838 #endif
3839 }
3840
3841 int
3842 netbsd32_sys_lfs_markv(p, v, retval)
3843 struct proc *p;
3844 void *v;
3845 register_t *retval;
3846 {
3847 #if 0
3848 struct netbsd32_lfs_markv_args /* {
3849 syscallarg(netbsd32_fsid_tp_t) fsidp;
3850 syscallarg(netbsd32_block_infop_t) blkiov;
3851 syscallarg(int) blkcnt;
3852 } */ *uap = v;
3853 #endif
3854
3855 return (ENOSYS); /* XXX */
3856 }
3857
3858 int
3859 netbsd32_sys_lfs_segclean(p, v, retval)
3860 struct proc *p;
3861 void *v;
3862 register_t *retval;
3863 {
3864 #if 0
3865 struct netbsd32_lfs_segclean_args /* {
3866 syscallarg(netbsd32_fsid_tp_t) fsidp;
3867 syscallarg(netbsd32_u_long) segment;
3868 } */ *uap = v;
3869 #endif
3870
3871 return (ENOSYS); /* XXX */
3872 }
3873
3874 int
3875 netbsd32_sys_lfs_segwait(p, v, retval)
3876 struct proc *p;
3877 void *v;
3878 register_t *retval;
3879 {
3880 #if 0
3881 struct netbsd32_lfs_segwait_args /* {
3882 syscallarg(netbsd32_fsid_tp_t) fsidp;
3883 syscallarg(netbsd32_timevalp_t) tv;
3884 } */ *uap = v;
3885 #endif
3886
3887 return (ENOSYS); /* XXX */
3888 }
3889 #endif
3890
3891 int
3892 netbsd32_pathconf(p, v, retval)
3893 struct proc *p;
3894 void *v;
3895 register_t *retval;
3896 {
3897 struct netbsd32_pathconf_args /* {
3898 syscallarg(int) fd;
3899 syscallarg(int) name;
3900 } */ *uap = v;
3901 struct sys_pathconf_args ua;
3902 long rt;
3903 int error;
3904
3905 NETBSD32TOP_UAP(path, const char);
3906 NETBSD32TO64_UAP(name);
3907 error = sys_pathconf(p, &ua, (register_t *)&rt);
3908 *(netbsd32_long *)retval = (netbsd32_long)rt;
3909 return (error);
3910 }
3911
3912 int
3913 netbsd32_fpathconf(p, v, retval)
3914 struct proc *p;
3915 void *v;
3916 register_t *retval;
3917 {
3918 struct netbsd32_fpathconf_args /* {
3919 syscallarg(int) fd;
3920 syscallarg(int) name;
3921 } */ *uap = v;
3922 struct sys_fpathconf_args ua;
3923 long rt;
3924 int error;
3925
3926 NETBSD32TO64_UAP(fd);
3927 NETBSD32TO64_UAP(name);
3928 error = sys_fpathconf(p, &ua, (register_t *)&rt);
3929 *(netbsd32_long *)retval = (netbsd32_long)rt;
3930 return (error);
3931 }
3932
3933 int
3934 netbsd32_getrlimit(p, v, retval)
3935 struct proc *p;
3936 void *v;
3937 register_t *retval;
3938 {
3939 struct netbsd32_getrlimit_args /* {
3940 syscallarg(int) which;
3941 syscallarg(netbsd32_rlimitp_t) rlp;
3942 } */ *uap = v;
3943 int which = SCARG(uap, which);
3944
3945 if ((u_int)which >= RLIM_NLIMITS)
3946 return (EINVAL);
3947 return (copyout(&p->p_rlimit[which], (caddr_t)(u_long)SCARG(uap, rlp),
3948 sizeof(struct rlimit)));
3949 }
3950
3951 int
3952 netbsd32_setrlimit(p, v, retval)
3953 struct proc *p;
3954 void *v;
3955 register_t *retval;
3956 {
3957 struct netbsd32_setrlimit_args /* {
3958 syscallarg(int) which;
3959 syscallarg(const netbsd32_rlimitp_t) rlp;
3960 } */ *uap = v;
3961 int which = SCARG(uap, which);
3962 struct rlimit alim;
3963 int error;
3964
3965 error = copyin((caddr_t)(u_long)SCARG(uap, rlp), &alim, sizeof(struct rlimit));
3966 if (error)
3967 return (error);
3968 return (dosetrlimit(p, p->p_cred, which, &alim));
3969 }
3970
3971 int
3972 netbsd32_mmap(p, v, retval)
3973 struct proc *p;
3974 void *v;
3975 register_t *retval;
3976 {
3977 struct netbsd32_mmap_args /* {
3978 syscallarg(netbsd32_voidp) addr;
3979 syscallarg(netbsd32_size_t) len;
3980 syscallarg(int) prot;
3981 syscallarg(int) flags;
3982 syscallarg(int) fd;
3983 syscallarg(netbsd32_long) pad;
3984 syscallarg(off_t) pos;
3985 } */ *uap = v;
3986 struct sys_mmap_args ua;
3987 void *rt;
3988 int error;
3989
3990 NETBSD32TOP_UAP(addr, void);
3991 NETBSD32TOX_UAP(len, size_t);
3992 NETBSD32TO64_UAP(prot);
3993 NETBSD32TO64_UAP(flags);
3994 NETBSD32TO64_UAP(fd);
3995 NETBSD32TOX_UAP(pad, long);
3996 NETBSD32TOX_UAP(pos, off_t);
3997 error = sys_mmap(p, &ua, (register_t *)&rt);
3998 if ((long)rt > (long)UINT_MAX)
3999 printf("netbsd32_mmap: retval out of range: 0x%qx",
4000 rt);
4001 *retval = (netbsd32_voidp)(u_long)rt;
4002 return (error);
4003 }
4004
4005 int
4006 netbsd32_lseek(p, v, retval)
4007 struct proc *p;
4008 void *v;
4009 register_t *retval;
4010 {
4011 struct netbsd32_lseek_args /* {
4012 syscallarg(int) fd;
4013 syscallarg(int) pad;
4014 syscallarg(off_t) offset;
4015 syscallarg(int) whence;
4016 } */ *uap = v;
4017 struct sys_lseek_args ua;
4018
4019 NETBSD32TO64_UAP(fd);
4020 NETBSD32TO64_UAP(pad);
4021 NETBSD32TO64_UAP(offset);
4022 NETBSD32TO64_UAP(whence);
4023 return (sys_lseek(p, &ua, retval));
4024 }
4025
4026 int
4027 netbsd32_truncate(p, v, retval)
4028 struct proc *p;
4029 void *v;
4030 register_t *retval;
4031 {
4032 struct netbsd32_truncate_args /* {
4033 syscallarg(const netbsd32_charp) path;
4034 syscallarg(int) pad;
4035 syscallarg(off_t) length;
4036 } */ *uap = v;
4037 struct sys_truncate_args ua;
4038
4039 NETBSD32TOP_UAP(path, const char);
4040 NETBSD32TO64_UAP(pad);
4041 NETBSD32TO64_UAP(length);
4042 return (sys_truncate(p, &ua, retval));
4043 }
4044
4045 int
4046 netbsd32_ftruncate(p, v, retval)
4047 struct proc *p;
4048 void *v;
4049 register_t *retval;
4050 {
4051 struct netbsd32_ftruncate_args /* {
4052 syscallarg(int) fd;
4053 syscallarg(int) pad;
4054 syscallarg(off_t) length;
4055 } */ *uap = v;
4056 struct sys_ftruncate_args ua;
4057
4058 NETBSD32TO64_UAP(fd);
4059 NETBSD32TO64_UAP(pad);
4060 NETBSD32TO64_UAP(length);
4061 return (sys_ftruncate(p, &ua, retval));
4062 }
4063
4064 int
4065 netbsd32___sysctl(p, v, retval)
4066 struct proc *p;
4067 void *v;
4068 register_t *retval;
4069 {
4070 struct netbsd32___sysctl_args /* {
4071 syscallarg(netbsd32_intp) name;
4072 syscallarg(u_int) namelen;
4073 syscallarg(netbsd32_voidp) old;
4074 syscallarg(netbsd32_size_tp) oldlenp;
4075 syscallarg(netbsd32_voidp) new;
4076 syscallarg(netbsd32_size_t) newlen;
4077 } */ *uap = v;
4078 int error, dolock = 1;
4079 netbsd32_size_t savelen = 0;
4080 size_t oldlen = 0;
4081 sysctlfn *fn;
4082 int name[CTL_MAXNAME];
4083
4084 /*
4085 * Some of these sysctl functions do their own copyin/copyout.
4086 * We need to disable or emulate the ones that need their
4087 * arguments converted.
4088 */
4089
4090 if (SCARG(uap, new) != NULL &&
4091 (error = suser(p->p_ucred, &p->p_acflag)))
4092 return (error);
4093 /*
4094 * all top-level sysctl names are non-terminal
4095 */
4096 if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
4097 return (EINVAL);
4098 error = copyin((caddr_t)(u_long)SCARG(uap, name), &name,
4099 SCARG(uap, namelen) * sizeof(int));
4100 if (error)
4101 return (error);
4102
4103 switch (name[0]) {
4104 case CTL_KERN:
4105 fn = kern_sysctl;
4106 if (name[2] != KERN_VNODE) /* XXX */
4107 dolock = 0;
4108 break;
4109 case CTL_HW:
4110 fn = hw_sysctl;
4111 break;
4112 case CTL_VM:
4113 fn = uvm_sysctl;
4114 break;
4115 case CTL_NET:
4116 fn = net_sysctl;
4117 break;
4118 case CTL_VFS:
4119 fn = vfs_sysctl;
4120 break;
4121 case CTL_MACHDEP:
4122 fn = cpu_sysctl;
4123 break;
4124 #ifdef DEBUG
4125 case CTL_DEBUG:
4126 fn = debug_sysctl;
4127 break;
4128 #endif
4129 #ifdef DDB
4130 case CTL_DDB:
4131 fn = ddb_sysctl;
4132 break;
4133 #endif
4134 default:
4135 return (EOPNOTSUPP);
4136 }
4137
4138 if (SCARG(uap, oldlenp) &&
4139 (error = copyin((caddr_t)(u_long)SCARG(uap, oldlenp), &savelen, sizeof(savelen))))
4140 return (error);
4141 if (SCARG(uap, old) != NULL) {
4142 if (!uvm_useracc((caddr_t)(u_long)SCARG(uap, old), savelen, B_WRITE))
4143 return (EFAULT);
4144 #if 0 /* XXXXXXXX */
4145 while (memlock.sl_lock) {
4146 memlock.sl_want = 1;
4147 sleep((caddr_t)&memlock, PRIBIO+1);
4148 memlock.sl_locked++;
4149 }
4150 memlock.sl_lock = 1;
4151 #endif /* XXXXXXXX */
4152 if (dolock) {
4153 /*
4154 * XXX Um, this is kind of evil. What should
4155 * XXX we be passing here?
4156 */
4157 if (uvm_vslock(p, (void *)(u_long)SCARG(uap, old), savelen,
4158 VM_PROT_NONE) != KERN_SUCCESS) {
4159 #if 0 /* XXXXXXXX */
4160 memlock.sl_lock = 0;
4161 if (memlock.sl_want) {
4162 memlock.sl_want = 0;
4163 wakeup((caddr_t)&memlock);
4164 }
4165 #endif /* XXXXXXXX */
4166 return (EFAULT);
4167 }
4168 }
4169 oldlen = savelen;
4170 }
4171 error = (*fn)(name + 1, SCARG(uap, namelen) - 1,
4172 (void *)(u_long)SCARG(uap, old), &oldlen,
4173 (void *)(u_long)SCARG(uap, new), SCARG(uap, newlen), p);
4174 if (SCARG(uap, old) != NULL) {
4175 if (dolock)
4176 uvm_vsunlock(p, (void *)(u_long)SCARG(uap, old), savelen);
4177 #if 0 /* XXXXXXXXXXX */
4178 memlock.sl_lock = 0;
4179 if (memlock.sl_want) {
4180 memlock.sl_want = 0;
4181 wakeup((caddr_t)&memlock);
4182 }
4183 #endif /* XXXXXXXXX */
4184 }
4185 savelen = oldlen;
4186 if (error)
4187 return (error);
4188 if (SCARG(uap, oldlenp))
4189 error = copyout(&savelen, (caddr_t)(u_long)SCARG(uap, oldlenp), sizeof(savelen));
4190 return (error);
4191 }
4192
4193 int
4194 netbsd32_mlock(p, v, retval)
4195 struct proc *p;
4196 void *v;
4197 register_t *retval;
4198 {
4199 struct netbsd32_mlock_args /* {
4200 syscallarg(const netbsd32_voidp) addr;
4201 syscallarg(netbsd32_size_t) len;
4202 } */ *uap = v;
4203 struct sys_mlock_args ua;
4204
4205 NETBSD32TOP_UAP(addr, const void);
4206 NETBSD32TO64_UAP(len);
4207 return (sys_mlock(p, &ua, retval));
4208 }
4209
4210 int
4211 netbsd32_munlock(p, v, retval)
4212 struct proc *p;
4213 void *v;
4214 register_t *retval;
4215 {
4216 struct netbsd32_munlock_args /* {
4217 syscallarg(const netbsd32_voidp) addr;
4218 syscallarg(netbsd32_size_t) len;
4219 } */ *uap = v;
4220 struct sys_munlock_args ua;
4221
4222 NETBSD32TOP_UAP(addr, const void);
4223 NETBSD32TO64_UAP(len);
4224 return (sys_munlock(p, &ua, retval));
4225 }
4226
4227 int
4228 netbsd32_undelete(p, v, retval)
4229 struct proc *p;
4230 void *v;
4231 register_t *retval;
4232 {
4233 struct netbsd32_undelete_args /* {
4234 syscallarg(const netbsd32_charp) path;
4235 } */ *uap = v;
4236 struct sys_undelete_args ua;
4237
4238 NETBSD32TOP_UAP(path, const char);
4239 return (sys_undelete(p, &ua, retval));
4240 }
4241
4242 int
4243 netbsd32_futimes(p, v, retval)
4244 struct proc *p;
4245 void *v;
4246 register_t *retval;
4247 {
4248 struct netbsd32_futimes_args /* {
4249 syscallarg(int) fd;
4250 syscallarg(const netbsd32_timevalp_t) tptr;
4251 } */ *uap = v;
4252 int error;
4253 struct file *fp;
4254
4255 /* getvnode() will use the descriptor for us */
4256 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
4257 return (error);
4258
4259 error = change_utimes32((struct vnode *)fp->f_data,
4260 (struct timeval *)(u_long)SCARG(uap, tptr), p);
4261 FILE_UNUSE(fp, p);
4262 return (error);
4263 }
4264
4265 int
4266 netbsd32_getpgid(p, v, retval)
4267 struct proc *p;
4268 void *v;
4269 register_t *retval;
4270 {
4271 struct netbsd32_getpgid_args /* {
4272 syscallarg(pid_t) pid;
4273 } */ *uap = v;
4274 struct sys_getpgid_args ua;
4275
4276 NETBSD32TO64_UAP(pid);
4277 return (sys_getpgid(p, &ua, retval));
4278 }
4279
4280 int
4281 netbsd32_reboot(p, v, retval)
4282 struct proc *p;
4283 void *v;
4284 register_t *retval;
4285 {
4286 struct netbsd32_reboot_args /* {
4287 syscallarg(int) opt;
4288 syscallarg(netbsd32_charp) bootstr;
4289 } */ *uap = v;
4290 struct sys_reboot_args ua;
4291
4292 NETBSD32TO64_UAP(opt);
4293 NETBSD32TOP_UAP(bootstr, char);
4294 return (sys_reboot(p, &ua, retval));
4295 }
4296
4297 int
4298 netbsd32_poll(p, v, retval)
4299 struct proc *p;
4300 void *v;
4301 register_t *retval;
4302 {
4303 struct netbsd32_poll_args /* {
4304 syscallarg(netbsd32_pollfdp_t) fds;
4305 syscallarg(u_int) nfds;
4306 syscallarg(int) timeout;
4307 } */ *uap = v;
4308 struct sys_poll_args ua;
4309
4310 NETBSD32TOP_UAP(fds, struct pollfd);
4311 NETBSD32TO64_UAP(nfds);
4312 NETBSD32TO64_UAP(timeout);
4313 return (sys_poll(p, &ua, retval));
4314 }
4315
4316 #if defined(SYSVSEM)
4317 /*
4318 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4319 *
4320 * This is BSD. We won't support System V IPC.
4321 * Too much work.
4322 *
4323 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4324 */
4325 int
4326 netbsd32___semctl14(p, v, retval)
4327 struct proc *p;
4328 void *v;
4329 register_t *retval;
4330 {
4331 #if 0
4332 struct netbsd32___semctl_args /* {
4333 syscallarg(int) semid;
4334 syscallarg(int) semnum;
4335 syscallarg(int) cmd;
4336 syscallarg(netbsd32_semunu_t *) arg;
4337 } */ *uap = v;
4338 union netbsd32_semun sem32;
4339 int semid = SCARG(uap, semid);
4340 int semnum = SCARG(uap, semnum);
4341 int cmd = SCARG(uap, cmd);
4342 union netbsd32_semun *arg = (void*)(u_long)SCARG(uap, arg);
4343 union netbsd32_semun real_arg;
4344 struct ucred *cred = p->p_ucred;
4345 int i, rval, eval;
4346 struct netbsd32_semid_ds sbuf;
4347 register struct semid_ds *semaptr;
4348
4349 semlock(p);
4350
4351 semid = IPCID_TO_IX(semid);
4352 if (semid < 0 || semid >= seminfo.semmsl)
4353 return(EINVAL);
4354
4355 semaptr = &sema[semid];
4356 if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
4357 semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
4358 return(EINVAL);
4359
4360 eval = 0;
4361 rval = 0;
4362
4363 switch (cmd) {
4364 case IPC_RMID:
4365 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
4366 return(eval);
4367 semaptr->sem_perm.cuid = cred->cr_uid;
4368 semaptr->sem_perm.uid = cred->cr_uid;
4369 semtot -= semaptr->sem_nsems;
4370 for (i = semaptr->_sem_base - sem; i < semtot; i++)
4371 sem[i] = sem[i + semaptr->sem_nsems];
4372 for (i = 0; i < seminfo.semmni; i++) {
4373 if ((sema[i].sem_perm.mode & SEM_ALLOC) &&
4374 sema[i]._sem_base > semaptr->_sem_base)
4375 sema[i]._sem_base -= semaptr->sem_nsems;
4376 }
4377 semaptr->sem_perm.mode = 0;
4378 semundo_clear(semid, -1);
4379 wakeup((caddr_t)semaptr);
4380 break;
4381
4382 case IPC_SET:
4383 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)))
4384 return(eval);
4385 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4386 return(eval);
4387 if ((eval = copyin((caddr_t)(u_long)real_arg.buf, (caddr_t)&sbuf,
4388 sizeof(sbuf))) != 0)
4389 return(eval);
4390 semaptr->sem_perm.uid = sbuf.sem_perm.uid;
4391 semaptr->sem_perm.gid = sbuf.sem_perm.gid;
4392 semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
4393 (sbuf.sem_perm.mode & 0777);
4394 semaptr->sem_ctime = time.tv_sec;
4395 break;
4396
4397 case IPC_STAT:
4398 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4399 return(eval);
4400 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4401 return(eval);
4402 eval = copyout((caddr_t)semaptr, (caddr_t)(u_long)real_arg.buf,
4403 sizeof(struct semid_ds));
4404 break;
4405
4406 case GETNCNT:
4407 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4408 return(eval);
4409 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4410 return(EINVAL);
4411 rval = semaptr->_sem_base[semnum].semncnt;
4412 break;
4413
4414 case GETPID:
4415 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4416 return(eval);
4417 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4418 return(EINVAL);
4419 rval = semaptr->_sem_base[semnum].sempid;
4420 break;
4421
4422 case GETVAL:
4423 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4424 return(eval);
4425 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4426 return(EINVAL);
4427 rval = semaptr->_sem_base[semnum].semval;
4428 break;
4429
4430 case GETALL:
4431 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4432 return(eval);
4433 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4434 return(eval);
4435 for (i = 0; i < semaptr->sem_nsems; i++) {
4436 eval = copyout((caddr_t)&semaptr->_sem_base[i].semval,
4437 &real_arg.array[i], sizeof(real_arg.array[0]));
4438 if (eval != 0)
4439 break;
4440 }
4441 break;
4442
4443 case GETZCNT:
4444 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4445 return(eval);
4446 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4447 return(EINVAL);
4448 rval = semaptr->_sem_base[semnum].semzcnt;
4449 break;
4450
4451 case SETVAL:
4452 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
4453 return(eval);
4454 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4455 return(EINVAL);
4456 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4457 return(eval);
4458 semaptr->_sem_base[semnum].semval = real_arg.val;
4459 semundo_clear(semid, semnum);
4460 wakeup((caddr_t)semaptr);
4461 break;
4462
4463 case SETALL:
4464 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
4465 return(eval);
4466 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4467 return(eval);
4468 for (i = 0; i < semaptr->sem_nsems; i++) {
4469 eval = copyin(&real_arg.array[i],
4470 (caddr_t)&semaptr->_sem_base[i].semval,
4471 sizeof(real_arg.array[0]));
4472 if (eval != 0)
4473 break;
4474 }
4475 semundo_clear(semid, -1);
4476 wakeup((caddr_t)semaptr);
4477 break;
4478
4479 default:
4480 return(EINVAL);
4481 }
4482
4483 if (eval == 0)
4484 *retval = rval;
4485 return(eval);
4486 #else
4487 return (ENOSYS);
4488 #endif
4489 }
4490
4491 int
4492 netbsd32_semget(p, v, retval)
4493 struct proc *p;
4494 void *v;
4495 register_t *retval;
4496 {
4497 struct netbsd32_semget_args /* {
4498 syscallarg(netbsd32_key_t) key;
4499 syscallarg(int) nsems;
4500 syscallarg(int) semflg;
4501 } */ *uap = v;
4502 struct sys_semget_args ua;
4503
4504 NETBSD32TOX_UAP(key, key_t);
4505 NETBSD32TO64_UAP(nsems);
4506 NETBSD32TO64_UAP(semflg);
4507 return (sys_semget(p, &ua, retval));
4508 }
4509
4510 int
4511 netbsd32_semop(p, v, retval)
4512 struct proc *p;
4513 void *v;
4514 register_t *retval;
4515 {
4516 struct netbsd32_semop_args /* {
4517 syscallarg(int) semid;
4518 syscallarg(netbsd32_sembufp_t) sops;
4519 syscallarg(netbsd32_size_t) nsops;
4520 } */ *uap = v;
4521 struct sys_semop_args ua;
4522
4523 NETBSD32TO64_UAP(semid);
4524 NETBSD32TOP_UAP(sops, struct sembuf);
4525 NETBSD32TOX_UAP(nsops, size_t);
4526 return (sys_semop(p, &ua, retval));
4527 }
4528
4529 int
4530 netbsd32_semconfig(p, v, retval)
4531 struct proc *p;
4532 void *v;
4533 register_t *retval;
4534 {
4535 struct netbsd32_semconfig_args /* {
4536 syscallarg(int) flag;
4537 } */ *uap = v;
4538 struct sys_semconfig_args ua;
4539
4540 NETBSD32TO64_UAP(flag);
4541 return (sys_semconfig(p, &ua, retval));
4542 }
4543 #endif /* SYSVSEM */
4544
4545 #if defined(SYSVMSG)
4546
4547 int
4548 netbsd32___msgctl13(p, v, retval)
4549 struct proc *p;
4550 void *v;
4551 register_t *retval;
4552 {
4553 #if 0
4554 struct netbsd32_msgctl_args /* {
4555 syscallarg(int) msqid;
4556 syscallarg(int) cmd;
4557 syscallarg(netbsd32_msqid_dsp_t) buf;
4558 } */ *uap = v;
4559 struct sys_msgctl_args ua;
4560 struct msqid_ds ds;
4561 struct netbsd32_msqid_ds *ds32p;
4562 int error;
4563
4564 NETBSD32TO64_UAP(msqid);
4565 NETBSD32TO64_UAP(cmd);
4566 ds32p = (struct netbsd32_msqid_ds *)(u_long)SCARG(uap, buf);
4567 if (ds32p) {
4568 SCARG(&ua, buf) = NULL;
4569 netbsd32_to_msqid_ds(ds32p, &ds);
4570 } else
4571 SCARG(&ua, buf) = NULL;
4572 error = sys_msgctl(p, &ua, retval);
4573 if (error)
4574 return (error);
4575
4576 if (ds32p)
4577 netbsd32_from_msqid_ds(&ds, ds32p);
4578 return (0);
4579 #else
4580 return (ENOSYS);
4581 #endif
4582 }
4583
4584 int
4585 netbsd32_msgget(p, v, retval)
4586 struct proc *p;
4587 void *v;
4588 register_t *retval;
4589 {
4590 #if 0
4591 struct netbsd32_msgget_args /* {
4592 syscallarg(netbsd32_key_t) key;
4593 syscallarg(int) msgflg;
4594 } */ *uap = v;
4595 struct sys_msgget_args ua;
4596
4597 NETBSD32TOX_UAP(key, key_t);
4598 NETBSD32TO64_UAP(msgflg);
4599 return (sys_msgget(p, &ua, retval));
4600 #else
4601 return (ENOSYS);
4602 #endif
4603 }
4604
4605 int
4606 netbsd32_msgsnd(p, v, retval)
4607 struct proc *p;
4608 void *v;
4609 register_t *retval;
4610 {
4611 #if 0
4612 struct netbsd32_msgsnd_args /* {
4613 syscallarg(int) msqid;
4614 syscallarg(const netbsd32_voidp) msgp;
4615 syscallarg(netbsd32_size_t) msgsz;
4616 syscallarg(int) msgflg;
4617 } */ *uap = v;
4618 struct sys_msgsnd_args ua;
4619
4620 NETBSD32TO64_UAP(msqid);
4621 NETBSD32TOP_UAP(msgp, void);
4622 NETBSD32TOX_UAP(msgsz, size_t);
4623 NETBSD32TO64_UAP(msgflg);
4624 return (sys_msgsnd(p, &ua, retval));
4625 #else
4626 return (ENOSYS);
4627 #endif
4628 }
4629
4630 int
4631 netbsd32_msgrcv(p, v, retval)
4632 struct proc *p;
4633 void *v;
4634 register_t *retval;
4635 {
4636 #if 0
4637 struct netbsd32_msgrcv_args /* {
4638 syscallarg(int) msqid;
4639 syscallarg(netbsd32_voidp) msgp;
4640 syscallarg(netbsd32_size_t) msgsz;
4641 syscallarg(netbsd32_long) msgtyp;
4642 syscallarg(int) msgflg;
4643 } */ *uap = v;
4644 struct sys_msgrcv_args ua;
4645 ssize_t rt;
4646 int error;
4647
4648 NETBSD32TO64_UAP(msqid);
4649 NETBSD32TOP_UAP(msgp, void);
4650 NETBSD32TOX_UAP(msgsz, size_t);
4651 NETBSD32TOX_UAP(msgtyp, long);
4652 NETBSD32TO64_UAP(msgflg);
4653 error = sys_msgrcv(p, &ua, (register_t *)&rt);
4654 *(netbsd32_ssize_t *)retval = rt;
4655 return (error);
4656 #else
4657 return (ENOSYS);
4658 #endif
4659 }
4660 #endif /* SYSVMSG */
4661
4662 #if defined(SYSVSHM)
4663
4664 int
4665 netbsd32_shmat(p, v, retval)
4666 struct proc *p;
4667 void *v;
4668 register_t *retval;
4669 {
4670 #if 0
4671 struct netbsd32_shmat_args /* {
4672 syscallarg(int) shmid;
4673 syscallarg(const netbsd32_voidp) shmaddr;
4674 syscallarg(int) shmflg;
4675 } */ *uap = v;
4676 struct sys_shmat_args ua;
4677 void *rt;
4678 int error;
4679
4680 NETBSD32TO64_UAP(shmid);
4681 NETBSD32TOP_UAP(shmaddr, void);
4682 NETBSD32TO64_UAP(shmflg);
4683 error = sys_shmat(p, &ua, (register_t *)&rt);
4684 *retval = (netbsd32_voidp)(u_long)rt;
4685 return (error);
4686 #else
4687 return (ENOSYS);
4688 #endif
4689 }
4690
4691 int
4692 netbsd32___shmctl13(p, v, retval)
4693 struct proc *p;
4694 void *v;
4695 register_t *retval;
4696 {
4697 #if 0
4698 struct netbsd32_shmctl_args /* {
4699 syscallarg(int) shmid;
4700 syscallarg(int) cmd;
4701 syscallarg(netbsd32_shmid_dsp_t) buf;
4702 } */ *uap = v;
4703 struct sys_shmctl_args ua;
4704 struct shmid_ds ds;
4705 struct netbsd32_shmid_ds *ds32p;
4706 int error;
4707
4708 NETBSD32TO64_UAP(shmid);
4709 NETBSD32TO64_UAP(cmd);
4710 ds32p = (struct netbsd32_shmid_ds *)(u_long)SCARG(uap, buf);
4711 if (ds32p) {
4712 SCARG(&ua, buf) = NULL;
4713 netbsd32_to_shmid_ds(ds32p, &ds);
4714 } else
4715 SCARG(&ua, buf) = NULL;
4716 error = sys_shmctl(p, &ua, retval);
4717 if (error)
4718 return (error);
4719
4720 if (ds32p)
4721 netbsd32_from_shmid_ds(&ds, ds32p);
4722 return (0);
4723 #else
4724 return (ENOSYS);
4725 #endif
4726 }
4727
4728 int
4729 netbsd32_shmdt(p, v, retval)
4730 struct proc *p;
4731 void *v;
4732 register_t *retval;
4733 {
4734 #if 0
4735 struct netbsd32_shmdt_args /* {
4736 syscallarg(const netbsd32_voidp) shmaddr;
4737 } */ *uap = v;
4738 struct sys_shmdt_args ua;
4739
4740 NETBSD32TOP_UAP(shmaddr, const char);
4741 return (sys_shmdt(p, &ua, retval));
4742 #else
4743 return (ENOSYS);
4744 #endif
4745 }
4746
4747 int
4748 netbsd32_shmget(p, v, retval)
4749 struct proc *p;
4750 void *v;
4751 register_t *retval;
4752 {
4753 #if 0
4754 struct netbsd32_shmget_args /* {
4755 syscallarg(netbsd32_key_t) key;
4756 syscallarg(netbsd32_size_t) size;
4757 syscallarg(int) shmflg;
4758 } */ *uap = v;
4759 struct sys_shmget_args ua;
4760
4761 NETBSD32TOX_UAP(key, key_t)
4762 NETBSD32TOX_UAP(size, size_t)
4763 NETBSD32TO64_UAP(shmflg);
4764 return (sys_shmget(p, &ua, retval));
4765 #else
4766 return (ENOSYS);
4767 #endif
4768 }
4769 #endif /* SYSVSHM */
4770
4771 int
4772 netbsd32_clock_gettime(p, v, retval)
4773 struct proc *p;
4774 void *v;
4775 register_t *retval;
4776 {
4777 struct netbsd32_clock_gettime_args /* {
4778 syscallarg(netbsd32_clockid_t) clock_id;
4779 syscallarg(netbsd32_timespecp_t) tp;
4780 } */ *uap = v;
4781 clockid_t clock_id;
4782 struct timeval atv;
4783 struct timespec ats;
4784 struct netbsd32_timespec ts32;
4785
4786 clock_id = SCARG(uap, clock_id);
4787 if (clock_id != CLOCK_REALTIME)
4788 return (EINVAL);
4789
4790 microtime(&atv);
4791 TIMEVAL_TO_TIMESPEC(&atv,&ats);
4792 netbsd32_from_timespec(&ats, &ts32);
4793
4794 return copyout(&ts32, (caddr_t)(u_long)SCARG(uap, tp), sizeof(ts32));
4795 }
4796
4797 int
4798 netbsd32_clock_settime(p, v, retval)
4799 struct proc *p;
4800 void *v;
4801 register_t *retval;
4802 {
4803 struct netbsd32_clock_settime_args /* {
4804 syscallarg(netbsd32_clockid_t) clock_id;
4805 syscallarg(const netbsd32_timespecp_t) tp;
4806 } */ *uap = v;
4807 struct netbsd32_timespec ts32;
4808 clockid_t clock_id;
4809 struct timeval atv;
4810 struct timespec ats;
4811 int error;
4812
4813 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
4814 return (error);
4815
4816 clock_id = SCARG(uap, clock_id);
4817 if (clock_id != CLOCK_REALTIME)
4818 return (EINVAL);
4819
4820 if ((error = copyin((caddr_t)(u_long)SCARG(uap, tp), &ts32, sizeof(ts32))) != 0)
4821 return (error);
4822
4823 netbsd32_to_timespec(&ts32, &ats);
4824 TIMESPEC_TO_TIMEVAL(&atv,&ats);
4825 if ((error = settime(&atv)))
4826 return (error);
4827
4828 return 0;
4829 }
4830
4831 int
4832 netbsd32_clock_getres(p, v, retval)
4833 struct proc *p;
4834 void *v;
4835 register_t *retval;
4836 {
4837 struct netbsd32_clock_getres_args /* {
4838 syscallarg(netbsd32_clockid_t) clock_id;
4839 syscallarg(netbsd32_timespecp_t) tp;
4840 } */ *uap = v;
4841 struct netbsd32_timespec ts32;
4842 clockid_t clock_id;
4843 struct timespec ts;
4844 int error = 0;
4845
4846 clock_id = SCARG(uap, clock_id);
4847 if (clock_id != CLOCK_REALTIME)
4848 return (EINVAL);
4849
4850 if (SCARG(uap, tp)) {
4851 ts.tv_sec = 0;
4852 ts.tv_nsec = 1000000000 / hz;
4853
4854 netbsd32_from_timespec(&ts, &ts32);
4855 error = copyout(&ts, (caddr_t)(u_long)SCARG(uap, tp), sizeof(ts));
4856 }
4857
4858 return error;
4859 }
4860
4861 int
4862 netbsd32_nanosleep(p, v, retval)
4863 struct proc *p;
4864 void *v;
4865 register_t *retval;
4866 {
4867 struct netbsd32_nanosleep_args /* {
4868 syscallarg(const netbsd32_timespecp_t) rqtp;
4869 syscallarg(netbsd32_timespecp_t) rmtp;
4870 } */ *uap = v;
4871 static int nanowait;
4872 struct netbsd32_timespec ts32;
4873 struct timespec rqt;
4874 struct timespec rmt;
4875 struct timeval atv, utv;
4876 int error, s, timo;
4877
4878 error = copyin((caddr_t)(u_long)SCARG(uap, rqtp), (caddr_t)&ts32,
4879 sizeof(ts32));
4880 if (error)
4881 return (error);
4882
4883 netbsd32_to_timespec(&ts32, &rqt);
4884 TIMESPEC_TO_TIMEVAL(&atv,&rqt)
4885 if (itimerfix(&atv))
4886 return (EINVAL);
4887
4888 s = splclock();
4889 timeradd(&atv,&time,&atv);
4890 timo = hzto(&atv);
4891 /*
4892 * Avoid inadvertantly sleeping forever
4893 */
4894 if (timo == 0)
4895 timo = 1;
4896 splx(s);
4897
4898 error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo);
4899 if (error == ERESTART)
4900 error = EINTR;
4901 if (error == EWOULDBLOCK)
4902 error = 0;
4903
4904 if (SCARG(uap, rmtp)) {
4905 int error;
4906
4907 s = splclock();
4908 utv = time;
4909 splx(s);
4910
4911 timersub(&atv, &utv, &utv);
4912 if (utv.tv_sec < 0)
4913 timerclear(&utv);
4914
4915 TIMEVAL_TO_TIMESPEC(&utv,&rmt);
4916 netbsd32_from_timespec(&rmt, &ts32);
4917 error = copyout((caddr_t)&ts32, (caddr_t)(u_long)SCARG(uap,rmtp),
4918 sizeof(ts32));
4919 if (error)
4920 return (error);
4921 }
4922
4923 return error;
4924 }
4925
4926 int
4927 netbsd32_fdatasync(p, v, retval)
4928 struct proc *p;
4929 void *v;
4930 register_t *retval;
4931 {
4932 struct netbsd32_fdatasync_args /* {
4933 syscallarg(int) fd;
4934 } */ *uap = v;
4935 struct sys_fdatasync_args ua;
4936
4937 NETBSD32TO64_UAP(fd);
4938
4939 return (sys_fdatasync(p, &ua, retval));
4940 }
4941
4942 int
4943 netbsd32___posix_rename(p, v, retval)
4944 struct proc *p;
4945 void *v;
4946 register_t *retval;
4947 {
4948 struct netbsd32___posix_rename_args /* {
4949 syscallarg(const netbsd32_charp) from;
4950 syscallarg(const netbsd32_charp) to;
4951 } */ *uap = v;
4952 struct sys___posix_rename_args ua;
4953
4954 NETBSD32TOP_UAP(from, const char);
4955 NETBSD32TOP_UAP(to, const char);
4956
4957 return (sys___posix_rename(p, &ua, retval));
4958 }
4959
4960 int
4961 netbsd32_swapctl(p, v, retval)
4962 struct proc *p;
4963 void *v;
4964 register_t *retval;
4965 {
4966 struct netbsd32_swapctl_args /* {
4967 syscallarg(int) cmd;
4968 syscallarg(const netbsd32_voidp) arg;
4969 syscallarg(int) misc;
4970 } */ *uap = v;
4971 struct sys_swapctl_args ua;
4972
4973 NETBSD32TO64_UAP(cmd);
4974 NETBSD32TOP_UAP(arg, const void);
4975 NETBSD32TO64_UAP(misc);
4976 return (sys_swapctl(p, &ua, retval));
4977 }
4978
4979 int
4980 netbsd32_getdents(p, v, retval)
4981 struct proc *p;
4982 void *v;
4983 register_t *retval;
4984 {
4985 struct netbsd32_getdents_args /* {
4986 syscallarg(int) fd;
4987 syscallarg(netbsd32_charp) buf;
4988 syscallarg(netbsd32_size_t) count;
4989 } */ *uap = v;
4990 struct file *fp;
4991 int error, done;
4992
4993 /* getvnode() will use the descriptor for us */
4994 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
4995 return (error);
4996 if ((fp->f_flag & FREAD) == 0) {
4997 error = EBADF;
4998 goto out;
4999 }
5000 error = vn_readdir(fp, (caddr_t)(u_long)SCARG(uap, buf), UIO_USERSPACE,
5001 SCARG(uap, count), &done, p, 0, 0);
5002 *retval = done;
5003 out:
5004 FILE_UNUSE(fp, p);
5005 return (error);
5006 }
5007
5008
5009 int
5010 netbsd32_minherit(p, v, retval)
5011 struct proc *p;
5012 void *v;
5013 register_t *retval;
5014 {
5015 struct netbsd32_minherit_args /* {
5016 syscallarg(netbsd32_voidp) addr;
5017 syscallarg(netbsd32_size_t) len;
5018 syscallarg(int) inherit;
5019 } */ *uap = v;
5020 struct sys_minherit_args ua;
5021
5022 NETBSD32TOP_UAP(addr, void);
5023 NETBSD32TOX_UAP(len, size_t);
5024 NETBSD32TO64_UAP(inherit);
5025 return (sys_minherit(p, &ua, retval));
5026 }
5027
5028 int
5029 netbsd32_lchmod(p, v, retval)
5030 struct proc *p;
5031 void *v;
5032 register_t *retval;
5033 {
5034 struct netbsd32_lchmod_args /* {
5035 syscallarg(const netbsd32_charp) path;
5036 syscallarg(mode_t) mode;
5037 } */ *uap = v;
5038 struct sys_lchmod_args ua;
5039
5040 NETBSD32TOP_UAP(path, const char);
5041 NETBSD32TO64_UAP(mode);
5042 return (sys_lchmod(p, &ua, retval));
5043 }
5044
5045 int
5046 netbsd32_lchown(p, v, retval)
5047 struct proc *p;
5048 void *v;
5049 register_t *retval;
5050 {
5051 struct netbsd32_lchown_args /* {
5052 syscallarg(const netbsd32_charp) path;
5053 syscallarg(uid_t) uid;
5054 syscallarg(gid_t) gid;
5055 } */ *uap = v;
5056 struct sys_lchown_args ua;
5057
5058 NETBSD32TOP_UAP(path, const char);
5059 NETBSD32TO64_UAP(uid);
5060 NETBSD32TO64_UAP(gid);
5061 return (sys_lchown(p, &ua, retval));
5062 }
5063
5064 int
5065 netbsd32_lutimes(p, v, retval)
5066 struct proc *p;
5067 void *v;
5068 register_t *retval;
5069 {
5070 struct netbsd32_lutimes_args /* {
5071 syscallarg(const netbsd32_charp) path;
5072 syscallarg(const netbsd32_timevalp_t) tptr;
5073 } */ *uap = v;
5074 int error;
5075 struct nameidata nd;
5076
5077 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, (caddr_t)(u_long)SCARG(uap, path), p);
5078 if ((error = namei(&nd)) != 0)
5079 return (error);
5080
5081 error = change_utimes32(nd.ni_vp, (struct timeval *)(u_long)SCARG(uap, tptr), p);
5082
5083 vrele(nd.ni_vp);
5084 return (error);
5085 }
5086
5087
5088 int
5089 netbsd32___msync13(p, v, retval)
5090 struct proc *p;
5091 void *v;
5092 register_t *retval;
5093 {
5094 struct netbsd32___msync13_args /* {
5095 syscallarg(netbsd32_voidp) addr;
5096 syscallarg(netbsd32_size_t) len;
5097 syscallarg(int) flags;
5098 } */ *uap = v;
5099 struct sys___msync13_args ua;
5100
5101 NETBSD32TOP_UAP(addr, void);
5102 NETBSD32TOX_UAP(len, size_t);
5103 NETBSD32TO64_UAP(flags);
5104 return (sys___msync13(p, &ua, retval));
5105 }
5106
5107 int
5108 netbsd32___stat13(p, v, retval)
5109 struct proc *p;
5110 void *v;
5111 register_t *retval;
5112 {
5113 struct netbsd32___stat13_args /* {
5114 syscallarg(const netbsd32_charp) path;
5115 syscallarg(netbsd32_statp_t) ub;
5116 } */ *uap = v;
5117 struct netbsd32_stat sb32;
5118 struct stat sb;
5119 int error;
5120 struct nameidata nd;
5121
5122 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
5123 (caddr_t)(u_long)SCARG(uap, path), p);
5124 if ((error = namei(&nd)) != 0)
5125 return (error);
5126 error = vn_stat(nd.ni_vp, &sb, p);
5127 vput(nd.ni_vp);
5128 if (error)
5129 return (error);
5130 netbsd32_from___stat13(&sb, &sb32);
5131 error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, ub), sizeof(sb32));
5132 return (error);
5133 }
5134
5135 int
5136 netbsd32___fstat13(p, v, retval)
5137 struct proc *p;
5138 void *v;
5139 register_t *retval;
5140 {
5141 struct netbsd32___fstat13_args /* {
5142 syscallarg(int) fd;
5143 syscallarg(netbsd32_statp_t) sb;
5144 } */ *uap = v;
5145 int fd = SCARG(uap, fd);
5146 register struct filedesc *fdp = p->p_fd;
5147 register struct file *fp;
5148 struct netbsd32_stat sb32;
5149 struct stat ub;
5150 int error = 0;
5151
5152 if ((u_int)fd >= fdp->fd_nfiles ||
5153 (fp = fdp->fd_ofiles[fd]) == NULL)
5154 return (EBADF);
5155 switch (fp->f_type) {
5156
5157 case DTYPE_VNODE:
5158 error = vn_stat((struct vnode *)fp->f_data, &ub, p);
5159 break;
5160
5161 case DTYPE_SOCKET:
5162 error = soo_stat((struct socket *)fp->f_data, &ub);
5163 break;
5164
5165 default:
5166 panic("fstat");
5167 /*NOTREACHED*/
5168 }
5169 if (error == 0) {
5170 netbsd32_from___stat13(&ub, &sb32);
5171 error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, sb), sizeof(sb32));
5172 }
5173 return (error);
5174 }
5175
5176 int
5177 netbsd32___lstat13(p, v, retval)
5178 struct proc *p;
5179 void *v;
5180 register_t *retval;
5181 {
5182 struct netbsd32___lstat13_args /* {
5183 syscallarg(const netbsd32_charp) path;
5184 syscallarg(netbsd32_statp_t) ub;
5185 } */ *uap = v;
5186 struct netbsd32_stat sb32;
5187 struct stat sb;
5188 int error;
5189 struct nameidata nd;
5190
5191 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
5192 (caddr_t)(u_long)SCARG(uap, path), p);
5193 if ((error = namei(&nd)) != 0)
5194 return (error);
5195 error = vn_stat(nd.ni_vp, &sb, p);
5196 vput(nd.ni_vp);
5197 if (error)
5198 return (error);
5199 netbsd32_from___stat13(&sb, &sb32);
5200 error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, ub), sizeof(sb32));
5201 return (error);
5202 }
5203
5204 int
5205 netbsd32___sigaltstack14(p, v, retval)
5206 struct proc *p;
5207 void *v;
5208 register_t *retval;
5209 {
5210 struct netbsd32___sigaltstack14_args /* {
5211 syscallarg(const netbsd32_sigaltstackp_t) nss;
5212 syscallarg(netbsd32_sigaltstackp_t) oss;
5213 } */ *uap = v;
5214 struct netbsd32_sigaltstack s32;
5215 struct sigaltstack nss, oss;
5216 int error;
5217
5218 if (SCARG(uap, nss)) {
5219 error = copyin((caddr_t)(u_long)SCARG(uap, nss), &s32, sizeof(s32));
5220 if (error)
5221 return (error);
5222 nss.ss_sp = (void *)(u_long)s32.ss_sp;
5223 nss.ss_size = (size_t)s32.ss_size;
5224 nss.ss_flags = s32.ss_flags;
5225 }
5226 error = sigaltstack1(p,
5227 SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0);
5228 if (error)
5229 return (error);
5230 if (SCARG(uap, oss)) {
5231 s32.ss_sp = (netbsd32_voidp)(u_long)oss.ss_sp;
5232 s32.ss_size = (netbsd32_size_t)oss.ss_size;
5233 s32.ss_flags = oss.ss_flags;
5234 error = copyout(&s32, (caddr_t)(u_long)SCARG(uap, oss), sizeof(s32));
5235 if (error)
5236 return (error);
5237 }
5238 return (0);
5239 }
5240
5241 int
5242 netbsd32___posix_chown(p, v, retval)
5243 struct proc *p;
5244 void *v;
5245 register_t *retval;
5246 {
5247 struct netbsd32___posix_chown_args /* {
5248 syscallarg(const netbsd32_charp) path;
5249 syscallarg(uid_t) uid;
5250 syscallarg(gid_t) gid;
5251 } */ *uap = v;
5252 struct sys___posix_chown_args ua;
5253
5254 NETBSD32TOP_UAP(path, const char);
5255 NETBSD32TO64_UAP(uid);
5256 NETBSD32TO64_UAP(gid);
5257 return (sys___posix_chown(p, &ua, retval));
5258 }
5259
5260 int
5261 netbsd32___posix_fchown(p, v, retval)
5262 struct proc *p;
5263 void *v;
5264 register_t *retval;
5265 {
5266 struct netbsd32___posix_fchown_args /* {
5267 syscallarg(int) fd;
5268 syscallarg(uid_t) uid;
5269 syscallarg(gid_t) gid;
5270 } */ *uap = v;
5271 struct sys___posix_fchown_args ua;
5272
5273 NETBSD32TO64_UAP(fd);
5274 NETBSD32TO64_UAP(uid);
5275 NETBSD32TO64_UAP(gid);
5276 return (sys___posix_fchown(p, &ua, retval));
5277 }
5278
5279 int
5280 netbsd32___posix_lchown(p, v, retval)
5281 struct proc *p;
5282 void *v;
5283 register_t *retval;
5284 {
5285 struct netbsd32___posix_lchown_args /* {
5286 syscallarg(const netbsd32_charp) path;
5287 syscallarg(uid_t) uid;
5288 syscallarg(gid_t) gid;
5289 } */ *uap = v;
5290 struct sys___posix_lchown_args ua;
5291
5292 NETBSD32TOP_UAP(path, const char);
5293 NETBSD32TO64_UAP(uid);
5294 NETBSD32TO64_UAP(gid);
5295 return (sys___posix_lchown(p, &ua, retval));
5296 }
5297
5298 int
5299 netbsd32_getsid(p, v, retval)
5300 struct proc *p;
5301 void *v;
5302 register_t *retval;
5303 {
5304 struct netbsd32_getsid_args /* {
5305 syscallarg(pid_t) pid;
5306 } */ *uap = v;
5307 struct sys_getsid_args ua;
5308
5309 NETBSD32TO64_UAP(pid);
5310 return (sys_getsid(p, &ua, retval));
5311 }
5312
5313 int
5314 netbsd32_fktrace(p, v, retval)
5315 struct proc *p;
5316 void *v;
5317 register_t *retval;
5318 {
5319 struct netbsd32_fktrace_args /* {
5320 syscallarg(const int) fd;
5321 syscallarg(int) ops;
5322 syscallarg(int) facs;
5323 syscallarg(int) pid;
5324 } */ *uap = v;
5325 struct sys_fktrace_args ua;
5326
5327 NETBSD32TOX_UAP(fd, const int);
5328 NETBSD32TO64_UAP(ops);
5329 NETBSD32TO64_UAP(facs);
5330 NETBSD32TO64_UAP(pid);
5331 return (sys_fktrace(p, &ua, retval));
5332 }
5333
5334 int
5335 netbsd32_preadv(p, v, retval)
5336 struct proc *p;
5337 void *v;
5338 register_t *retval;
5339 {
5340 struct netbsd32_preadv_args /* {
5341 syscallarg(int) fd;
5342 syscallarg(const netbsd32_iovecp_t) iovp;
5343 syscallarg(int) iovcnt;
5344 syscallarg(int) pad;
5345 syscallarg(off_t) offset;
5346 } */ *uap = v;
5347 struct filedesc *fdp = p->p_fd;
5348 struct file *fp;
5349 struct vnode *vp;
5350 off_t offset;
5351 int error, fd = SCARG(uap, fd);
5352
5353 if ((u_int)fd >= fdp->fd_nfiles ||
5354 (fp = fdp->fd_ofiles[fd]) == NULL ||
5355 (fp->f_flag & FREAD) == 0)
5356 return (EBADF);
5357
5358 vp = (struct vnode *)fp->f_data;
5359 if (fp->f_type != DTYPE_VNODE
5360 || vp->v_type == VFIFO)
5361 return (ESPIPE);
5362
5363 offset = SCARG(uap, offset);
5364
5365 /*
5366 * XXX This works because no file systems actually
5367 * XXX take any action on the seek operation.
5368 */
5369 if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
5370 return (error);
5371
5372 return (dofilereadv32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp), SCARG(uap, iovcnt),
5373 &offset, 0, retval));
5374 }
5375
5376 int
5377 netbsd32_pwritev(p, v, retval)
5378 struct proc *p;
5379 void *v;
5380 register_t *retval;
5381 {
5382 struct netbsd32_pwritev_args /* {
5383 syscallarg(int) fd;
5384 syscallarg(const netbsd32_iovecp_t) iovp;
5385 syscallarg(int) iovcnt;
5386 syscallarg(int) pad;
5387 syscallarg(off_t) offset;
5388 } */ *uap = v;
5389 struct filedesc *fdp = p->p_fd;
5390 struct file *fp;
5391 struct vnode *vp;
5392 off_t offset;
5393 int error, fd = SCARG(uap, fd);
5394
5395 if ((u_int)fd >= fdp->fd_nfiles ||
5396 (fp = fdp->fd_ofiles[fd]) == NULL ||
5397 (fp->f_flag & FWRITE) == 0)
5398 return (EBADF);
5399
5400 vp = (struct vnode *)fp->f_data;
5401 if (fp->f_type != DTYPE_VNODE
5402 || vp->v_type == VFIFO)
5403 return (ESPIPE);
5404
5405 offset = SCARG(uap, offset);
5406
5407 /*
5408 * XXX This works because no file systems actually
5409 * XXX take any action on the seek operation.
5410 */
5411 if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
5412 return (error);
5413
5414 return (dofilewritev32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp), SCARG(uap, iovcnt),
5415 &offset, 0, retval));
5416 }
5417
5418 /* ARGSUSED */
5419 int
5420 netbsd32___sigaction14(p, v, retval)
5421 struct proc *p;
5422 void *v;
5423 register_t *retval;
5424 {
5425 register struct netbsd32___sigaction14_args /* {
5426 syscallarg(int) signum;
5427 syscallarg(const struct sigaction *) nsa;
5428 syscallarg(struct sigaction *) osa;
5429 } */ *uap = v;
5430 struct netbsd32_sigaction sa32;
5431 struct sigaction nsa, osa;
5432 int error;
5433
5434 if (SCARG(uap, nsa)) {
5435 error = copyin((caddr_t)(u_long)SCARG(uap, nsa),
5436 &sa32, sizeof(sa32));
5437 if (error)
5438 return (error);
5439 nsa.sa_handler = (void *)(u_long)sa32.sa_handler;
5440 nsa.sa_mask = sa32.sa_mask;
5441 nsa.sa_flags = sa32.sa_flags;
5442 }
5443 error = sigaction1(p, SCARG(uap, signum),
5444 SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0);
5445 if (error)
5446 return (error);
5447 if (SCARG(uap, osa)) {
5448 sa32.sa_handler = (netbsd32_voidp)(u_long)osa.sa_handler;
5449 sa32.sa_mask = osa.sa_mask;
5450 sa32.sa_flags = osa.sa_flags;
5451 error = copyout(&sa32, (caddr_t)(u_long)SCARG(uap, osa), sizeof(sa32));
5452 if (error)
5453 return (error);
5454 }
5455 return (0);
5456 }
5457
5458 int netbsd32___sigpending14(p, v, retval)
5459 struct proc *p;
5460 void *v;
5461 register_t *retval;
5462 {
5463 register struct netbsd32___sigpending14_args /* {
5464 syscallarg(sigset_t *) set;
5465 } */ *uap = v;
5466 struct sys___sigpending14_args ua;
5467
5468 NETBSD32TOP_UAP(set, sigset_t);
5469 return (sys___sigpending14(p, &ua, retval));
5470 }
5471
5472 int netbsd32___sigprocmask14(p, v, retval)
5473 struct proc *p;
5474 void *v;
5475 register_t *retval;
5476 {
5477 register struct netbsd32___sigprocmask14_args /* {
5478 syscallarg(int) how;
5479 syscallarg(const sigset_t *) set;
5480 syscallarg(sigset_t *) oset;
5481 } */ *uap = v;
5482 struct sys___sigprocmask14_args ua;
5483
5484 NETBSD32TO64_UAP(how);
5485 NETBSD32TOP_UAP(set, sigset_t);
5486 NETBSD32TOP_UAP(oset, sigset_t);
5487 return (sys___sigprocmask14(p, &ua, retval));
5488 }
5489
5490 int netbsd32___sigsuspend14(p, v, retval)
5491 struct proc *p;
5492 void *v;
5493 register_t *retval;
5494 {
5495 struct netbsd32___sigsuspend14_args /* {
5496 syscallarg(const sigset_t *) set;
5497 } */ *uap = v;
5498 struct sys___sigsuspend14_args ua;
5499
5500 NETBSD32TOP_UAP(set, sigset_t);
5501 return (sys___sigsuspend14(p, &ua, retval));
5502 };
5503
5504
5505 /*
5506 * Find pathname of process's current directory.
5507 *
5508 * Use vfs vnode-to-name reverse cache; if that fails, fall back
5509 * to reading directory contents.
5510 */
5511 int
5512 getcwd_common __P((struct vnode *, struct vnode *,
5513 char **, char *, int, int, struct proc *));
5514
5515 int netbsd32___getcwd(p, v, retval)
5516 struct proc *p;
5517 void *v;
5518 register_t *retval;
5519 {
5520 register struct netbsd32___getcwd_args /* {
5521 syscallarg(char *) bufp;
5522 syscallarg(size_t) length;
5523 } */ *uap = v;
5524
5525 int error;
5526 char *path;
5527 char *bp, *bend;
5528 int len = (int)SCARG(uap, length);
5529 int lenused;
5530
5531 if (len > MAXPATHLEN*4)
5532 len = MAXPATHLEN*4;
5533 else if (len < 2)
5534 return ERANGE;
5535
5536 path = (char *)malloc(len, M_TEMP, M_WAITOK);
5537 if (!path)
5538 return ENOMEM;
5539
5540 bp = &path[len];
5541 bend = bp;
5542 *(--bp) = '\0';
5543
5544 /*
5545 * 5th argument here is "max number of vnodes to traverse".
5546 * Since each entry takes up at least 2 bytes in the output buffer,
5547 * limit it to N/2 vnodes for an N byte buffer.
5548 */
5549 #define GETCWD_CHECK_ACCESS 0x0001
5550 error = getcwd_common (p->p_cwdi->cwdi_cdir, NULL, &bp, path, len/2,
5551 GETCWD_CHECK_ACCESS, p);
5552
5553 if (error)
5554 goto out;
5555 lenused = bend - bp;
5556 *retval = lenused;
5557 /* put the result into user buffer */
5558 error = copyout(bp, (caddr_t)(u_long)SCARG(uap, bufp), lenused);
5559
5560 out:
5561 free(path, M_TEMP);
5562 return error;
5563 }
5564
5565 int netbsd32_fchroot(p, v, retval)
5566 struct proc *p;
5567 void *v;
5568 register_t *retval;
5569 {
5570 register struct netbsd32_fchroot_args /* {
5571 syscallarg(int) fd;
5572 } */ *uap = v;
5573 struct sys_fchroot_args ua;
5574
5575 NETBSD32TO64_UAP(fd);
5576 return (sys_fchroot(p, &ua, retval));
5577 }
5578
5579 /*
5580 * Open a file given a file handle.
5581 *
5582 * Check permissions, allocate an open file structure,
5583 * and call the device open routine if any.
5584 */
5585 int
5586 netbsd32_fhopen(p, v, retval)
5587 struct proc *p;
5588 void *v;
5589 register_t *retval;
5590 {
5591 register struct netbsd32_fhopen_args /* {
5592 syscallarg(const fhandle_t *) fhp;
5593 syscallarg(int) flags;
5594 } */ *uap = v;
5595 struct sys_fhopen_args ua;
5596
5597 NETBSD32TOP_UAP(fhp, fhandle_t);
5598 NETBSD32TO64_UAP(flags);
5599 return (sys_fhopen(p, &ua, retval));
5600 }
5601
5602 int netbsd32_fhstat(p, v, retval)
5603 struct proc *p;
5604 void *v;
5605 register_t *retval;
5606 {
5607 register struct netbsd32_fhstat_args /* {
5608 syscallarg(const netbsd32_fhandlep_t) fhp;
5609 syscallarg(struct stat *) sb;
5610 } */ *uap = v;
5611 struct sys_fhstat_args ua;
5612
5613 NETBSD32TOP_UAP(fhp, const fhandle_t);
5614 NETBSD32TOP_UAP(sb, struct stat);
5615 return (sys_fhstat(p, &ua, retval));
5616 }
5617
5618 int netbsd32_fhstatfs(p, v, retval)
5619 struct proc *p;
5620 void *v;
5621 register_t *retval;
5622 {
5623 register struct netbsd32_fhstatfs_args /* {
5624 syscallarg(const netbsd32_fhandlep_t) fhp;
5625 syscallarg(struct statfs *) buf;
5626 } */ *uap = v;
5627 struct sys_fhstatfs_args ua;
5628
5629 NETBSD32TOP_UAP(fhp, const fhandle_t);
5630 NETBSD32TOP_UAP(buf, struct statfs);
5631 return (sys_fhstatfs(p, &ua, retval));
5632 }
5633