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