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