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