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