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