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