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