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