netbsd32_netbsd.c revision 1.50 1 /* $NetBSD: netbsd32_netbsd.c,v 1.50 2001/02/02 13:05: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_lchflags(p, v, retval)
1561 struct proc *p;
1562 void *v;
1563 register_t *retval;
1564 {
1565 struct netbsd32_lchflags_args /* {
1566 syscallarg(int) fd;
1567 syscallarg(netbsd32_u_long) flags;
1568 } */ *uap = v;
1569 struct sys_lchflags_args ua;
1570
1571 NETBSD32TOP_UAP(path, const char);
1572 NETBSD32TO64_UAP(flags);
1573
1574 return (sys_lchflags(p, &ua, retval));
1575 }
1576
1577 int
1578 netbsd32_kill(p, v, retval)
1579 struct proc *p;
1580 void *v;
1581 register_t *retval;
1582 {
1583 struct netbsd32_kill_args /* {
1584 syscallarg(int) pid;
1585 syscallarg(int) signum;
1586 } */ *uap = v;
1587 struct sys_kill_args ua;
1588
1589 NETBSD32TO64_UAP(pid);
1590 NETBSD32TO64_UAP(signum);
1591
1592 return (sys_kill(p, &ua, retval));
1593 }
1594
1595 int
1596 netbsd32_dup(p, v, retval)
1597 struct proc *p;
1598 void *v;
1599 register_t *retval;
1600 {
1601 struct netbsd32_dup_args /* {
1602 syscallarg(int) fd;
1603 } */ *uap = v;
1604 struct sys_dup_args ua;
1605
1606 NETBSD32TO64_UAP(fd);
1607
1608 return (sys_dup(p, &ua, retval));
1609 }
1610
1611 int
1612 netbsd32_profil(p, v, retval)
1613 struct proc *p;
1614 void *v;
1615 register_t *retval;
1616 {
1617 struct netbsd32_profil_args /* {
1618 syscallarg(netbsd32_caddr_t) samples;
1619 syscallarg(netbsd32_size_t) size;
1620 syscallarg(netbsd32_u_long) offset;
1621 syscallarg(u_int) scale;
1622 } */ *uap = v;
1623 struct sys_profil_args ua;
1624
1625 NETBSD32TOX64_UAP(samples, caddr_t);
1626 NETBSD32TOX_UAP(size, size_t);
1627 NETBSD32TOX_UAP(offset, u_long);
1628 NETBSD32TO64_UAP(scale);
1629 return (sys_profil(p, &ua, retval));
1630 }
1631
1632 #ifdef KTRACE
1633 int
1634 netbsd32_ktrace(p, v, retval)
1635 struct proc *p;
1636 void *v;
1637 register_t *retval;
1638 {
1639 struct netbsd32_ktrace_args /* {
1640 syscallarg(const netbsd32_charp) fname;
1641 syscallarg(int) ops;
1642 syscallarg(int) facs;
1643 syscallarg(int) pid;
1644 } */ *uap = v;
1645 struct sys_ktrace_args ua;
1646
1647 NETBSD32TOP_UAP(fname, const char);
1648 NETBSD32TO64_UAP(ops);
1649 NETBSD32TO64_UAP(facs);
1650 NETBSD32TO64_UAP(pid);
1651 return (sys_ktrace(p, &ua, retval));
1652 }
1653 #endif /* KTRACE */
1654
1655 int
1656 netbsd32_utrace(p, v, retval)
1657 struct proc *p;
1658 void *v;
1659 register_t *retval;
1660 {
1661 struct netbsd32_utrace_args /* {
1662 syscallarg(const netbsd32_charp) label;
1663 syscallarg(netbsd32_voidp) addr;
1664 syscallarg(netbsd32_size_t) len;
1665 } */ *uap = v;
1666 struct sys_utrace_args ua;
1667
1668 NETBSD32TOP_UAP(label, const char);
1669 NETBSD32TOP_UAP(addr, void);
1670 NETBSD32TO64_UAP(len);
1671 return (sys_utrace(p, &ua, retval));
1672 }
1673
1674 int
1675 netbsd32_sigaction(p, v, retval)
1676 struct proc *p;
1677 void *v;
1678 register_t *retval;
1679 {
1680 struct netbsd32_sigaction_args /* {
1681 syscallarg(int) signum;
1682 syscallarg(const netbsd32_sigactionp_t) nsa;
1683 syscallarg(netbsd32_sigactionp_t) osa;
1684 } */ *uap = v;
1685 struct sigaction nsa, osa;
1686 struct netbsd32_sigaction *sa32p, sa32;
1687 int error;
1688
1689 if (SCARG(uap, nsa)) {
1690 sa32p = (struct netbsd32_sigaction *)(u_long)SCARG(uap, nsa);
1691 if (copyin(sa32p, &sa32, sizeof(sa32)))
1692 return EFAULT;
1693 nsa.sa_handler = (void *)(u_long)sa32.sa_handler;
1694 nsa.sa_mask = sa32.sa_mask;
1695 nsa.sa_flags = sa32.sa_flags;
1696 }
1697 error = sigaction1(p, SCARG(uap, signum),
1698 SCARG(uap, nsa) ? &nsa : 0,
1699 SCARG(uap, osa) ? &osa : 0);
1700
1701 if (error)
1702 return (error);
1703
1704 if (SCARG(uap, osa)) {
1705 sa32.sa_handler = (netbsd32_sigactionp_t)(u_long)osa.sa_handler;
1706 sa32.sa_mask = osa.sa_mask;
1707 sa32.sa_flags = osa.sa_flags;
1708 sa32p = (struct netbsd32_sigaction *)(u_long)SCARG(uap, osa);
1709 if (copyout(&sa32, sa32p, sizeof(sa32)))
1710 return EFAULT;
1711 }
1712
1713 return (0);
1714 }
1715
1716 int
1717 netbsd32___getlogin(p, v, retval)
1718 struct proc *p;
1719 void *v;
1720 register_t *retval;
1721 {
1722 struct netbsd32___getlogin_args /* {
1723 syscallarg(netbsd32_charp) namebuf;
1724 syscallarg(u_int) namelen;
1725 } */ *uap = v;
1726 struct sys___getlogin_args ua;
1727
1728 NETBSD32TOP_UAP(namebuf, char);
1729 NETBSD32TO64_UAP(namelen);
1730 return (sys___getlogin(p, &ua, retval));
1731 }
1732
1733 int
1734 netbsd32_setlogin(p, v, retval)
1735 struct proc *p;
1736 void *v;
1737 register_t *retval;
1738 {
1739 struct netbsd32_setlogin_args /* {
1740 syscallarg(const netbsd32_charp) namebuf;
1741 } */ *uap = v;
1742 struct sys_setlogin_args ua;
1743
1744 NETBSD32TOP_UAP(namebuf, char);
1745 return (sys_setlogin(p, &ua, retval));
1746 }
1747
1748 int
1749 netbsd32_acct(p, v, retval)
1750 struct proc *p;
1751 void *v;
1752 register_t *retval;
1753 {
1754 struct netbsd32_acct_args /* {
1755 syscallarg(const netbsd32_charp) path;
1756 } */ *uap = v;
1757 struct sys_acct_args ua;
1758
1759 NETBSD32TOP_UAP(path, const char);
1760 return (sys_acct(p, &ua, retval));
1761 }
1762
1763 int
1764 netbsd32_revoke(p, v, retval)
1765 struct proc *p;
1766 void *v;
1767 register_t *retval;
1768 {
1769 struct netbsd32_revoke_args /* {
1770 syscallarg(const netbsd32_charp) path;
1771 } */ *uap = v;
1772 struct sys_revoke_args ua;
1773 caddr_t sg;
1774
1775 NETBSD32TOP_UAP(path, const char);
1776 sg = stackgap_init(p->p_emul);
1777 CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
1778
1779 return (sys_revoke(p, &ua, retval));
1780 }
1781
1782 int
1783 netbsd32_symlink(p, v, retval)
1784 struct proc *p;
1785 void *v;
1786 register_t *retval;
1787 {
1788 struct netbsd32_symlink_args /* {
1789 syscallarg(const netbsd32_charp) path;
1790 syscallarg(const netbsd32_charp) link;
1791 } */ *uap = v;
1792 struct sys_symlink_args ua;
1793
1794 NETBSD32TOP_UAP(path, const char);
1795 NETBSD32TOP_UAP(link, const char);
1796
1797 return (sys_symlink(p, &ua, retval));
1798 }
1799
1800 int
1801 netbsd32_readlink(p, v, retval)
1802 struct proc *p;
1803 void *v;
1804 register_t *retval;
1805 {
1806 struct netbsd32_readlink_args /* {
1807 syscallarg(const netbsd32_charp) path;
1808 syscallarg(netbsd32_charp) buf;
1809 syscallarg(netbsd32_size_t) count;
1810 } */ *uap = v;
1811 struct sys_readlink_args ua;
1812 caddr_t sg;
1813
1814 NETBSD32TOP_UAP(path, const char);
1815 NETBSD32TOP_UAP(buf, char);
1816 NETBSD32TOX_UAP(count, size_t);
1817 sg = stackgap_init(p->p_emul);
1818 CHECK_ALT_SYMLINK(p, &sg, SCARG(&ua, path));
1819
1820 return (sys_readlink(p, &ua, retval));
1821 }
1822
1823 /*
1824 * Need to completly reimplement this syscall due to argument copying.
1825 */
1826 /* ARGSUSED */
1827 int
1828 netbsd32_execve(p, v, retval)
1829 struct proc *p;
1830 void *v;
1831 register_t *retval;
1832 {
1833 struct netbsd32_execve_args /* {
1834 syscallarg(const netbsd32_charp) path;
1835 syscallarg(netbsd32_charpp) argp;
1836 syscallarg(netbsd32_charpp) envp;
1837 } */ *uap = v;
1838 struct sys_execve_args ua;
1839 caddr_t sg;
1840
1841 NETBSD32TOP_UAP(path, const char);
1842 NETBSD32TOP_UAP(argp, char *);
1843 NETBSD32TOP_UAP(envp, char *);
1844 sg = stackgap_init(p->p_emul);
1845 CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
1846
1847 return netbsd32_execve2(p, &ua, retval);
1848 }
1849
1850 int
1851 netbsd32_execve2(p, uap, retval)
1852 struct proc *p;
1853 struct sys_execve_args *uap;
1854 register_t *retval;
1855 {
1856 /* Function args */
1857 int error, i;
1858 struct exec_package pack;
1859 struct nameidata nid;
1860 struct vattr attr;
1861 struct ucred *cred = p->p_ucred;
1862 char *argp;
1863 netbsd32_charp const *cpp;
1864 char *dp;
1865 netbsd32_charp sp;
1866 long argc, envc;
1867 size_t len;
1868 char *stack;
1869 struct ps_strings arginfo;
1870 struct vmspace *vm;
1871 char **tmpfap;
1872 int szsigcode;
1873 struct exec_vmcmd *base_vcp = NULL;
1874
1875 /* init the namei data to point the file user's program name */
1876 /* XXX cgd 960926: why do this here? most will be clobbered. */
1877 NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
1878
1879 /*
1880 * initialize the fields of the exec package.
1881 */
1882 pack.ep_name = SCARG(uap, path);
1883 pack.ep_hdr = malloc(exec_maxhdrsz, M_EXEC, M_WAITOK);
1884 pack.ep_hdrlen = exec_maxhdrsz;
1885 pack.ep_hdrvalid = 0;
1886 pack.ep_ndp = &nid;
1887 pack.ep_emul_arg = NULL;
1888 pack.ep_vmcmds.evs_cnt = 0;
1889 pack.ep_vmcmds.evs_used = 0;
1890 pack.ep_vap = &attr;
1891 pack.ep_flags = 0;
1892
1893 lockmgr(&exec_lock, LK_SHARED, NULL);
1894
1895 /* see if we can run it. */
1896 if ((error = check_exec(p, &pack)) != 0)
1897 goto freehdr;
1898
1899 /* XXX -- THE FOLLOWING SECTION NEEDS MAJOR CLEANUP */
1900
1901 /* allocate an argument buffer */
1902 argp = (char *) uvm_km_valloc_wait(exec_map, NCARGS);
1903 #ifdef DIAGNOSTIC
1904 if (argp == (vaddr_t) 0)
1905 panic("execve: argp == NULL");
1906 #endif
1907 dp = argp;
1908 argc = 0;
1909
1910 /* copy the fake args list, if there's one, freeing it as we go */
1911 if (pack.ep_flags & EXEC_HASARGL) {
1912 tmpfap = pack.ep_fa;
1913 while (*tmpfap != NULL) {
1914 char *cp;
1915
1916 cp = *tmpfap;
1917 while (*cp)
1918 *dp++ = *cp++;
1919 dp++;
1920
1921 FREE(*tmpfap, M_EXEC);
1922 tmpfap++; argc++;
1923 }
1924 FREE(pack.ep_fa, M_EXEC);
1925 pack.ep_flags &= ~EXEC_HASARGL;
1926 }
1927
1928 /* Now get argv & environment */
1929 if (!(cpp = (netbsd32_charp *)SCARG(uap, argp))) {
1930 error = EINVAL;
1931 goto bad;
1932 }
1933
1934 if (pack.ep_flags & EXEC_SKIPARG)
1935 cpp++;
1936
1937 while (1) {
1938 len = argp + ARG_MAX - dp;
1939 if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
1940 goto bad;
1941 if (!sp)
1942 break;
1943 if ((error = copyinstr((char *)(u_long)sp, dp,
1944 len, &len)) != 0) {
1945 if (error == ENAMETOOLONG)
1946 error = E2BIG;
1947 goto bad;
1948 }
1949 dp += len;
1950 cpp++;
1951 argc++;
1952 }
1953
1954 envc = 0;
1955 /* environment need not be there */
1956 if ((cpp = (netbsd32_charp *)SCARG(uap, envp)) != NULL ) {
1957 while (1) {
1958 len = argp + ARG_MAX - dp;
1959 if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
1960 goto bad;
1961 if (!sp)
1962 break;
1963 if ((error = copyinstr((char *)(u_long)sp,
1964 dp, len, &len)) != 0) {
1965 if (error == ENAMETOOLONG)
1966 error = E2BIG;
1967 goto bad;
1968 }
1969 dp += len;
1970 cpp++;
1971 envc++;
1972 }
1973 }
1974
1975 dp = (char *) ALIGN(dp);
1976
1977 szsigcode = pack.ep_es->es_emul->e_esigcode -
1978 pack.ep_es->es_emul->e_sigcode;
1979
1980 /* Now check if args & environ fit into new stack */
1981 if (pack.ep_flags & EXEC_32)
1982 len = ((argc + envc + 2 + pack.ep_es->es_arglen) *
1983 sizeof(int) + sizeof(int) + dp + STACKGAPLEN +
1984 szsigcode + sizeof(struct ps_strings)) - argp;
1985 else
1986 len = ((argc + envc + 2 + pack.ep_es->es_arglen) *
1987 sizeof(char *) + sizeof(int) + dp + STACKGAPLEN +
1988 szsigcode + sizeof(struct ps_strings)) - argp;
1989
1990 len = ALIGN(len); /* make the stack "safely" aligned */
1991
1992 if (len > pack.ep_ssize) { /* in effect, compare to initial limit */
1993 error = ENOMEM;
1994 goto bad;
1995 }
1996
1997 /* adjust "active stack depth" for process VSZ */
1998 pack.ep_ssize = len; /* maybe should go elsewhere, but... */
1999
2000 /*
2001 * Do whatever is necessary to prepare the address space
2002 * for remapping. Note that this might replace the current
2003 * vmspace with another!
2004 */
2005 uvmspace_exec(p);
2006
2007 /* Now map address space */
2008 vm = p->p_vmspace;
2009 vm->vm_taddr = (char *) pack.ep_taddr;
2010 vm->vm_tsize = btoc(pack.ep_tsize);
2011 vm->vm_daddr = (char *) pack.ep_daddr;
2012 vm->vm_dsize = btoc(pack.ep_dsize);
2013 vm->vm_ssize = btoc(pack.ep_ssize);
2014 vm->vm_maxsaddr = (char *) pack.ep_maxsaddr;
2015 vm->vm_minsaddr = (char *) pack.ep_minsaddr;
2016
2017 /* create the new process's VM space by running the vmcmds */
2018 #ifdef DIAGNOSTIC
2019 if (pack.ep_vmcmds.evs_used == 0)
2020 panic("execve: no vmcmds");
2021 #endif
2022 for (i = 0; i < pack.ep_vmcmds.evs_used && !error; i++) {
2023 struct exec_vmcmd *vcp;
2024
2025 vcp = &pack.ep_vmcmds.evs_cmds[i];
2026 if (vcp->ev_flags & VMCMD_RELATIVE) {
2027 #ifdef DIAGNOSTIC
2028 if (base_vcp == NULL)
2029 panic("execve: relative vmcmd with no base");
2030 if (vcp->ev_flags & VMCMD_BASE)
2031 panic("execve: illegal base & relative vmcmd");
2032 #endif
2033 vcp->ev_addr += base_vcp->ev_addr;
2034 }
2035 error = (*vcp->ev_proc)(p, vcp);
2036 #ifdef DEBUG
2037 if (error) {
2038 if (i > 0)
2039 printf("vmcmd[%d] = %#lx/%#lx @ %#lx\n", i-1,
2040 vcp[-1].ev_addr, vcp[-1].ev_len,
2041 vcp[-1].ev_offset);
2042 printf("vmcmd[%d] = %#lx/%#lx @ %#lx\n", i,
2043 vcp->ev_addr, vcp->ev_len, vcp->ev_offset);
2044 }
2045 #endif
2046 if (vcp->ev_flags & VMCMD_BASE)
2047 base_vcp = vcp;
2048 }
2049
2050 /* free the vmspace-creation commands, and release their references */
2051 kill_vmcmds(&pack.ep_vmcmds);
2052
2053 /* if an error happened, deallocate and punt */
2054 if (error) {
2055 #ifdef DEBUG
2056 printf("execve: vmcmd %i failed: %d\n", i-1, error);
2057 #endif
2058 goto exec_abort;
2059 }
2060
2061 /* remember information about the process */
2062 arginfo.ps_nargvstr = argc;
2063 arginfo.ps_nenvstr = envc;
2064
2065 stack = (char *) (vm->vm_minsaddr - len);
2066 /* Now copy argc, args & environ to new stack */
2067 if (!(*pack.ep_es->es_copyargs)(&pack, &arginfo, stack, argp)) {
2068 #ifdef DEBUG
2069 printf("execve: copyargs failed\n");
2070 #endif
2071 goto exec_abort;
2072 }
2073
2074 /* fill process ps_strings info */
2075 p->p_psstr = (struct ps_strings *)(stack - sizeof(struct ps_strings));
2076 p->p_psargv = offsetof(struct ps_strings, ps_argvstr);
2077 p->p_psnargv = offsetof(struct ps_strings, ps_nargvstr);
2078 p->p_psenv = offsetof(struct ps_strings, ps_envstr);
2079 p->p_psnenv = offsetof(struct ps_strings, ps_nenvstr);
2080
2081 /* copy out the process's ps_strings structure */
2082 if (copyout(&arginfo, (char *)p->p_psstr, sizeof(arginfo))) {
2083 #ifdef DEBUG
2084 printf("execve: ps_strings copyout failed\n");
2085 #endif
2086 goto exec_abort;
2087 }
2088
2089 /* copy out the process's signal trapoline code */
2090 if (szsigcode) {
2091 if (copyout((char *)pack.ep_es->es_emul->e_sigcode,
2092 p->p_sigctx.ps_sigcode = (char *)p->p_psstr - szsigcode,
2093 szsigcode)) {
2094 #ifdef DEBUG
2095 printf("execve: sig trampoline copyout failed\n");
2096 #endif
2097 goto exec_abort;
2098 }
2099 #ifdef PMAP_NEED_PROCWR
2100 /* This is code. Let the pmap do what is needed. */
2101 pmap_procwr(p, (vaddr_t)p->p_sigacts->ps_sigcode, szsigcode);
2102 #endif
2103 }
2104
2105 stopprofclock(p); /* stop profiling */
2106 fdcloseexec(p); /* handle close on exec */
2107 execsigs(p); /* reset catched signals */
2108 p->p_ctxlink = NULL; /* reset ucontext link */
2109
2110 /* set command name & other accounting info */
2111 len = min(nid.ni_cnd.cn_namelen, MAXCOMLEN);
2112 memcpy(p->p_comm, nid.ni_cnd.cn_nameptr, len);
2113 p->p_comm[len] = 0;
2114 p->p_acflag &= ~AFORK;
2115
2116 /* record proc's vnode, for use by procfs and others */
2117 if (p->p_textvp)
2118 vrele(p->p_textvp);
2119 VREF(pack.ep_vp);
2120 p->p_textvp = pack.ep_vp;
2121
2122 p->p_flag |= P_EXEC;
2123 if (p->p_flag & P_PPWAIT) {
2124 p->p_flag &= ~P_PPWAIT;
2125 wakeup((caddr_t) p->p_pptr);
2126 }
2127
2128 /*
2129 * deal with set[ug]id.
2130 * MNT_NOSUID and P_TRACED have already been used to disable s[ug]id.
2131 */
2132 if (((attr.va_mode & S_ISUID) != 0 && p->p_ucred->cr_uid != attr.va_uid)
2133 || ((attr.va_mode & S_ISGID) != 0 && p->p_ucred->cr_gid != attr.va_gid)){
2134 p->p_ucred = crcopy(cred);
2135 #ifdef KTRACE
2136 /*
2137 * If process is being ktraced, turn off - unless
2138 * root set it.
2139 */
2140 if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT))
2141 ktrderef(p);
2142 #endif
2143 if (attr.va_mode & S_ISUID)
2144 p->p_ucred->cr_uid = attr.va_uid;
2145 if (attr.va_mode & S_ISGID)
2146 p->p_ucred->cr_gid = attr.va_gid;
2147 p_sugid(p);
2148 } else
2149 p->p_flag &= ~P_SUGID;
2150 p->p_cred->p_svuid = p->p_ucred->cr_uid;
2151 p->p_cred->p_svgid = p->p_ucred->cr_gid;
2152
2153 doexechooks(p);
2154
2155 uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
2156
2157 PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
2158 vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
2159 VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
2160 vput(pack.ep_vp);
2161
2162 /* setup new registers and do misc. setup. */
2163 (*pack.ep_es->es_setregs)(p, &pack, (u_long) stack);
2164
2165 if (p->p_flag & P_TRACED)
2166 psignal(p, SIGTRAP);
2167
2168 free(pack.ep_hdr, M_EXEC);
2169
2170 /*
2171 * Call emulation specific exec hook. This can setup setup per-process
2172 * p->p_emuldata or do any other per-process stuff an emulation needs.
2173 *
2174 * If we are executing process of different emulation than the
2175 * original forked process, call e_proc_exit() of the old emulation
2176 * first, then e_proc_exec() of new emulation. If the emulation is
2177 * same, the exec hook code should deallocate any old emulation
2178 * resources held previously by this process.
2179 */
2180 if (p->p_emul && p->p_emul->e_proc_exit
2181 && p->p_emul != pack.ep_es->es_emul)
2182 (*p->p_emul->e_proc_exit)(p);
2183
2184 /*
2185 * Call exec hook. Emulation code may NOT store reference to anything
2186 * from &pack.
2187 */
2188 if (pack.ep_es->es_emul->e_proc_exec)
2189 (*pack.ep_es->es_emul->e_proc_exec)(p, &pack);
2190
2191 /* update p_emul, the old value is no longer needed */
2192 p->p_emul = pack.ep_es->es_emul;
2193
2194 #ifdef KTRACE
2195 if (KTRPOINT(p, KTR_EMUL))
2196 ktremul(p);
2197 #endif
2198
2199 lockmgr(&exec_lock, LK_RELEASE, NULL);
2200
2201 return (EJUSTRETURN);
2202
2203 bad:
2204 /* free the vmspace-creation commands, and release their references */
2205 kill_vmcmds(&pack.ep_vmcmds);
2206 /* kill any opened file descriptor, if necessary */
2207 if (pack.ep_flags & EXEC_HASFD) {
2208 pack.ep_flags &= ~EXEC_HASFD;
2209 (void) fdrelease(p, pack.ep_fd);
2210 }
2211 /* close and put the exec'd file */
2212 vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
2213 VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
2214 vput(pack.ep_vp);
2215 PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
2216 uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
2217
2218 freehdr:
2219 lockmgr(&exec_lock, LK_RELEASE, NULL);
2220
2221 free(pack.ep_hdr, M_EXEC);
2222 return error;
2223
2224 exec_abort:
2225 lockmgr(&exec_lock, LK_RELEASE, NULL);
2226
2227 /*
2228 * the old process doesn't exist anymore. exit gracefully.
2229 * get rid of the (new) address space we have created, if any, get rid
2230 * of our namei data and vnode, and exit noting failure
2231 */
2232 uvm_deallocate(&vm->vm_map, VM_MIN_ADDRESS,
2233 VM_MAXUSER_ADDRESS - VM_MIN_ADDRESS);
2234 if (pack.ep_emul_arg)
2235 FREE(pack.ep_emul_arg, M_TEMP);
2236 PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
2237 vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
2238 VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
2239 vput(pack.ep_vp);
2240 uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
2241 free(pack.ep_hdr, M_EXEC);
2242 exit1(p, W_EXITCODE(0, SIGABRT));
2243 exit1(p, -1);
2244
2245 /* NOTREACHED */
2246 return 0;
2247 }
2248
2249 int
2250 netbsd32_umask(p, v, retval)
2251 struct proc *p;
2252 void *v;
2253 register_t *retval;
2254 {
2255 struct netbsd32_umask_args /* {
2256 syscallarg(mode_t) newmask;
2257 } */ *uap = v;
2258 struct sys_umask_args ua;
2259
2260 NETBSD32TO64_UAP(newmask);
2261 return (sys_umask(p, &ua, retval));
2262 }
2263
2264 int
2265 netbsd32_chroot(p, v, retval)
2266 struct proc *p;
2267 void *v;
2268 register_t *retval;
2269 {
2270 struct netbsd32_chroot_args /* {
2271 syscallarg(const netbsd32_charp) path;
2272 } */ *uap = v;
2273 struct sys_chroot_args ua;
2274
2275 NETBSD32TOP_UAP(path, const char);
2276 return (sys_chroot(p, &ua, retval));
2277 }
2278
2279 int
2280 netbsd32_sbrk(p, v, retval)
2281 struct proc *p;
2282 void *v;
2283 register_t *retval;
2284 {
2285 struct netbsd32_sbrk_args /* {
2286 syscallarg(int) incr;
2287 } */ *uap = v;
2288 struct sys_sbrk_args ua;
2289
2290 NETBSD32TO64_UAP(incr);
2291 return (sys_sbrk(p, &ua, retval));
2292 }
2293
2294 int
2295 netbsd32_sstk(p, v, retval)
2296 struct proc *p;
2297 void *v;
2298 register_t *retval;
2299 {
2300 struct netbsd32_sstk_args /* {
2301 syscallarg(int) incr;
2302 } */ *uap = v;
2303 struct sys_sstk_args ua;
2304
2305 NETBSD32TO64_UAP(incr);
2306 return (sys_sstk(p, &ua, retval));
2307 }
2308
2309 int
2310 netbsd32_munmap(p, v, retval)
2311 struct proc *p;
2312 void *v;
2313 register_t *retval;
2314 {
2315 struct netbsd32_munmap_args /* {
2316 syscallarg(netbsd32_voidp) addr;
2317 syscallarg(netbsd32_size_t) len;
2318 } */ *uap = v;
2319 struct sys_munmap_args ua;
2320
2321 NETBSD32TOP_UAP(addr, void);
2322 NETBSD32TOX_UAP(len, size_t);
2323 return (sys_munmap(p, &ua, retval));
2324 }
2325
2326 int
2327 netbsd32_mprotect(p, v, retval)
2328 struct proc *p;
2329 void *v;
2330 register_t *retval;
2331 {
2332 struct netbsd32_mprotect_args /* {
2333 syscallarg(netbsd32_voidp) addr;
2334 syscallarg(netbsd32_size_t) len;
2335 syscallarg(int) prot;
2336 } */ *uap = v;
2337 struct sys_mprotect_args ua;
2338
2339 NETBSD32TOP_UAP(addr, void);
2340 NETBSD32TOX_UAP(len, size_t);
2341 NETBSD32TO64_UAP(prot);
2342 return (sys_mprotect(p, &ua, retval));
2343 }
2344
2345 int
2346 netbsd32_madvise(p, v, retval)
2347 struct proc *p;
2348 void *v;
2349 register_t *retval;
2350 {
2351 struct netbsd32_madvise_args /* {
2352 syscallarg(netbsd32_voidp) addr;
2353 syscallarg(netbsd32_size_t) len;
2354 syscallarg(int) behav;
2355 } */ *uap = v;
2356 struct sys_madvise_args ua;
2357
2358 NETBSD32TOP_UAP(addr, void);
2359 NETBSD32TOX_UAP(len, size_t);
2360 NETBSD32TO64_UAP(behav);
2361 return (sys_madvise(p, &ua, retval));
2362 }
2363
2364 int
2365 netbsd32_mincore(p, v, retval)
2366 struct proc *p;
2367 void *v;
2368 register_t *retval;
2369 {
2370 struct netbsd32_mincore_args /* {
2371 syscallarg(netbsd32_caddr_t) addr;
2372 syscallarg(netbsd32_size_t) len;
2373 syscallarg(netbsd32_charp) vec;
2374 } */ *uap = v;
2375 struct sys_mincore_args ua;
2376
2377 NETBSD32TOX64_UAP(addr, caddr_t);
2378 NETBSD32TOX_UAP(len, size_t);
2379 NETBSD32TOP_UAP(vec, char);
2380 return (sys_mincore(p, &ua, retval));
2381 }
2382
2383 int
2384 netbsd32_getgroups(p, v, retval)
2385 struct proc *p;
2386 void *v;
2387 register_t *retval;
2388 {
2389 struct netbsd32_getgroups_args /* {
2390 syscallarg(int) gidsetsize;
2391 syscallarg(netbsd32_gid_tp) gidset;
2392 } */ *uap = v;
2393 struct pcred *pc = p->p_cred;
2394 int ngrp;
2395 int error;
2396
2397 ngrp = SCARG(uap, gidsetsize);
2398 if (ngrp == 0) {
2399 *retval = pc->pc_ucred->cr_ngroups;
2400 return (0);
2401 }
2402 if (ngrp < pc->pc_ucred->cr_ngroups)
2403 return (EINVAL);
2404 ngrp = pc->pc_ucred->cr_ngroups;
2405 /* Should convert gid_t to netbsd32_gid_t, but they're the same */
2406 error = copyout((caddr_t)pc->pc_ucred->cr_groups,
2407 (caddr_t)(u_long)SCARG(uap, gidset),
2408 ngrp * sizeof(gid_t));
2409 if (error)
2410 return (error);
2411 *retval = ngrp;
2412 return (0);
2413 }
2414
2415 int
2416 netbsd32_setgroups(p, v, retval)
2417 struct proc *p;
2418 void *v;
2419 register_t *retval;
2420 {
2421 struct netbsd32_setgroups_args /* {
2422 syscallarg(int) gidsetsize;
2423 syscallarg(const netbsd32_gid_tp) gidset;
2424 } */ *uap = v;
2425 struct sys_setgroups_args ua;
2426
2427 NETBSD32TO64_UAP(gidsetsize);
2428 NETBSD32TOP_UAP(gidset, gid_t);
2429 return (sys_setgroups(p, &ua, retval));
2430 }
2431
2432 int
2433 netbsd32_setpgid(p, v, retval)
2434 struct proc *p;
2435 void *v;
2436 register_t *retval;
2437 {
2438 struct netbsd32_setpgid_args /* {
2439 syscallarg(int) pid;
2440 syscallarg(int) pgid;
2441 } */ *uap = v;
2442 struct sys_setpgid_args ua;
2443
2444 NETBSD32TO64_UAP(pid);
2445 NETBSD32TO64_UAP(pgid);
2446 return (sys_setpgid(p, &ua, retval));
2447 }
2448
2449 int
2450 netbsd32_setitimer(p, v, retval)
2451 struct proc *p;
2452 void *v;
2453 register_t *retval;
2454 {
2455 struct netbsd32_setitimer_args /* {
2456 syscallarg(int) which;
2457 syscallarg(const netbsd32_itimervalp_t) itv;
2458 syscallarg(netbsd32_itimervalp_t) oitv;
2459 } */ *uap = v;
2460 struct netbsd32_itimerval s32it, *itvp;
2461 int which = SCARG(uap, which);
2462 struct netbsd32_getitimer_args getargs;
2463 struct itimerval aitv;
2464 int s, error;
2465
2466 if ((u_int)which > ITIMER_PROF)
2467 return (EINVAL);
2468 itvp = (struct netbsd32_itimerval *)(u_long)SCARG(uap, itv);
2469 if (itvp && (error = copyin(itvp, &s32it, sizeof(s32it))))
2470 return (error);
2471 netbsd32_to_itimerval(&s32it, &aitv);
2472 if (SCARG(uap, oitv) != NULL) {
2473 SCARG(&getargs, which) = which;
2474 SCARG(&getargs, itv) = SCARG(uap, oitv);
2475 if ((error = netbsd32_getitimer(p, &getargs, retval)) != 0)
2476 return (error);
2477 }
2478 if (itvp == 0)
2479 return (0);
2480 if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval))
2481 return (EINVAL);
2482 s = splclock();
2483 if (which == ITIMER_REAL) {
2484 callout_stop(&p->p_realit_ch);
2485 if (timerisset(&aitv.it_value)) {
2486 /*
2487 * Don't need to check hzto() return value, here.
2488 * callout_reset() does it for us.
2489 */
2490 timeradd(&aitv.it_value, &time, &aitv.it_value);
2491 callout_reset(&p->p_realit_ch, hzto(&aitv.it_value),
2492 realitexpire, p);
2493 }
2494 p->p_realtimer = aitv;
2495 } else
2496 p->p_stats->p_timer[which] = aitv;
2497 splx(s);
2498 return (0);
2499 }
2500
2501 int
2502 netbsd32_getitimer(p, v, retval)
2503 struct proc *p;
2504 void *v;
2505 register_t *retval;
2506 {
2507 struct netbsd32_getitimer_args /* {
2508 syscallarg(int) which;
2509 syscallarg(netbsd32_itimervalp_t) itv;
2510 } */ *uap = v;
2511 int which = SCARG(uap, which);
2512 struct netbsd32_itimerval s32it;
2513 struct itimerval aitv;
2514 int s;
2515
2516 if ((u_int)which > ITIMER_PROF)
2517 return (EINVAL);
2518 s = splclock();
2519 if (which == ITIMER_REAL) {
2520 /*
2521 * Convert from absolute to relative time in .it_value
2522 * part of real time timer. If time for real time timer
2523 * has passed return 0, else return difference between
2524 * current time and time for the timer to go off.
2525 */
2526 aitv = p->p_realtimer;
2527 if (timerisset(&aitv.it_value)) {
2528 if (timercmp(&aitv.it_value, &time, <))
2529 timerclear(&aitv.it_value);
2530 else
2531 timersub(&aitv.it_value, &time, &aitv.it_value);
2532 }
2533 } else
2534 aitv = p->p_stats->p_timer[which];
2535 splx(s);
2536 netbsd32_from_itimerval(&aitv, &s32it);
2537 return (copyout(&s32it, (caddr_t)(u_long)SCARG(uap, itv), sizeof(s32it)));
2538 }
2539
2540 int
2541 netbsd32_fcntl(p, v, retval)
2542 struct proc *p;
2543 void *v;
2544 register_t *retval;
2545 {
2546 struct netbsd32_fcntl_args /* {
2547 syscallarg(int) fd;
2548 syscallarg(int) cmd;
2549 syscallarg(netbsd32_voidp) arg;
2550 } */ *uap = v;
2551 struct sys_fcntl_args ua;
2552
2553 NETBSD32TO64_UAP(fd);
2554 NETBSD32TO64_UAP(cmd);
2555 NETBSD32TOP_UAP(arg, void);
2556 /* XXXX we can do this 'cause flock doesn't change */
2557 return (sys_fcntl(p, &ua, retval));
2558 }
2559
2560 int
2561 netbsd32_dup2(p, v, retval)
2562 struct proc *p;
2563 void *v;
2564 register_t *retval;
2565 {
2566 struct netbsd32_dup2_args /* {
2567 syscallarg(int) from;
2568 syscallarg(int) to;
2569 } */ *uap = v;
2570 struct sys_dup2_args ua;
2571
2572 NETBSD32TO64_UAP(from);
2573 NETBSD32TO64_UAP(to);
2574 return (sys_dup2(p, &ua, retval));
2575 }
2576
2577 int
2578 netbsd32_select(p, v, retval)
2579 struct proc *p;
2580 void *v;
2581 register_t *retval;
2582 {
2583 struct netbsd32_select_args /* {
2584 syscallarg(int) nd;
2585 syscallarg(netbsd32_fd_setp_t) in;
2586 syscallarg(netbsd32_fd_setp_t) ou;
2587 syscallarg(netbsd32_fd_setp_t) ex;
2588 syscallarg(netbsd32_timevalp_t) tv;
2589 } */ *uap = v;
2590 /* This one must be done in-line 'cause of the timeval */
2591 struct netbsd32_timeval tv32;
2592 caddr_t bits;
2593 char smallbits[howmany(FD_SETSIZE, NFDBITS) * sizeof(fd_mask) * 6];
2594 struct timeval atv;
2595 int s, ncoll, error = 0, timo;
2596 size_t ni;
2597 extern int selwait, nselcoll;
2598 extern int selscan __P((struct proc *, fd_mask *, fd_mask *, int, register_t *));
2599
2600 if (SCARG(uap, nd) < 0)
2601 return (EINVAL);
2602 if (SCARG(uap, nd) > p->p_fd->fd_nfiles) {
2603 /* forgiving; slightly wrong */
2604 SCARG(uap, nd) = p->p_fd->fd_nfiles;
2605 }
2606 ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask);
2607 if (ni * 6 > sizeof(smallbits))
2608 bits = malloc(ni * 6, M_TEMP, M_WAITOK);
2609 else
2610 bits = smallbits;
2611
2612 #define getbits(name, x) \
2613 if (SCARG(uap, name)) { \
2614 error = copyin((caddr_t)(u_long)SCARG(uap, name), bits + ni * x, ni); \
2615 if (error) \
2616 goto done; \
2617 } else \
2618 memset(bits + ni * x, 0, ni);
2619 getbits(in, 0);
2620 getbits(ou, 1);
2621 getbits(ex, 2);
2622 #undef getbits
2623
2624 if (SCARG(uap, tv)) {
2625 error = copyin((caddr_t)(u_long)SCARG(uap, tv), (caddr_t)&tv32,
2626 sizeof(tv32));
2627 if (error)
2628 goto done;
2629 netbsd32_to_timeval(&tv32, &atv);
2630 if (itimerfix(&atv)) {
2631 error = EINVAL;
2632 goto done;
2633 }
2634 s = splclock();
2635 timeradd(&atv, &time, &atv);
2636 splx(s);
2637 } else
2638 timo = 0;
2639 retry:
2640 ncoll = nselcoll;
2641 p->p_flag |= P_SELECT;
2642 error = selscan(p, (fd_mask *)(bits + ni * 0),
2643 (fd_mask *)(bits + ni * 3), SCARG(uap, nd), retval);
2644 if (error || *retval)
2645 goto done;
2646 if (SCARG(uap, tv)) {
2647 /*
2648 * We have to recalculate the timeout on every retry.
2649 */
2650 timo = hzto(&atv);
2651 if (timo <= 0)
2652 goto done;
2653 }
2654 s = splhigh();
2655 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) {
2656 splx(s);
2657 goto retry;
2658 }
2659 p->p_flag &= ~P_SELECT;
2660 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
2661 splx(s);
2662 if (error == 0)
2663 goto retry;
2664 done:
2665 p->p_flag &= ~P_SELECT;
2666 /* select is not restarted after signals... */
2667 if (error == ERESTART)
2668 error = EINTR;
2669 if (error == EWOULDBLOCK)
2670 error = 0;
2671 if (error == 0) {
2672 #define putbits(name, x) \
2673 if (SCARG(uap, name)) { \
2674 error = copyout(bits + ni * x, (caddr_t)(u_long)SCARG(uap, name), ni); \
2675 if (error) \
2676 goto out; \
2677 }
2678 putbits(in, 3);
2679 putbits(ou, 4);
2680 putbits(ex, 5);
2681 #undef putbits
2682 }
2683 out:
2684 if (ni * 6 > sizeof(smallbits))
2685 free(bits, M_TEMP);
2686 return (error);
2687 }
2688
2689 int
2690 netbsd32_fsync(p, v, retval)
2691 struct proc *p;
2692 void *v;
2693 register_t *retval;
2694 {
2695 struct netbsd32_fsync_args /* {
2696 syscallarg(int) fd;
2697 } */ *uap = v;
2698 struct sys_fsync_args ua;
2699
2700 NETBSD32TO64_UAP(fd);
2701 return (sys_fsync(p, &ua, retval));
2702 }
2703
2704 int
2705 netbsd32_setpriority(p, v, retval)
2706 struct proc *p;
2707 void *v;
2708 register_t *retval;
2709 {
2710 struct netbsd32_setpriority_args /* {
2711 syscallarg(int) which;
2712 syscallarg(int) who;
2713 syscallarg(int) prio;
2714 } */ *uap = v;
2715 struct sys_setpriority_args ua;
2716
2717 NETBSD32TO64_UAP(which);
2718 NETBSD32TO64_UAP(who);
2719 NETBSD32TO64_UAP(prio);
2720 return (sys_setpriority(p, &ua, retval));
2721 }
2722
2723 int
2724 netbsd32_socket(p, v, retval)
2725 struct proc *p;
2726 void *v;
2727 register_t *retval;
2728 {
2729 struct netbsd32_socket_args /* {
2730 syscallarg(int) domain;
2731 syscallarg(int) type;
2732 syscallarg(int) protocol;
2733 } */ *uap = v;
2734 struct sys_socket_args ua;
2735
2736 NETBSD32TO64_UAP(domain);
2737 NETBSD32TO64_UAP(type);
2738 NETBSD32TO64_UAP(protocol);
2739 return (sys_socket(p, &ua, retval));
2740 }
2741
2742 int
2743 netbsd32_connect(p, v, retval)
2744 struct proc *p;
2745 void *v;
2746 register_t *retval;
2747 {
2748 struct netbsd32_connect_args /* {
2749 syscallarg(int) s;
2750 syscallarg(const netbsd32_sockaddrp_t) name;
2751 syscallarg(int) namelen;
2752 } */ *uap = v;
2753 struct sys_connect_args ua;
2754
2755 NETBSD32TO64_UAP(s);
2756 NETBSD32TOP_UAP(name, struct sockaddr);
2757 NETBSD32TO64_UAP(namelen);
2758 return (sys_connect(p, &ua, retval));
2759 }
2760
2761 int
2762 netbsd32_getpriority(p, v, retval)
2763 struct proc *p;
2764 void *v;
2765 register_t *retval;
2766 {
2767 struct netbsd32_getpriority_args /* {
2768 syscallarg(int) which;
2769 syscallarg(int) who;
2770 } */ *uap = v;
2771 struct sys_getpriority_args ua;
2772
2773 NETBSD32TO64_UAP(which);
2774 NETBSD32TO64_UAP(who);
2775 return (sys_getpriority(p, &ua, retval));
2776 }
2777
2778 int
2779 netbsd32_bind(p, v, retval)
2780 struct proc *p;
2781 void *v;
2782 register_t *retval;
2783 {
2784 struct netbsd32_bind_args /* {
2785 syscallarg(int) s;
2786 syscallarg(const netbsd32_sockaddrp_t) name;
2787 syscallarg(int) namelen;
2788 } */ *uap = v;
2789 struct sys_bind_args ua;
2790
2791 NETBSD32TO64_UAP(s);
2792 NETBSD32TOP_UAP(name, struct sockaddr);
2793 NETBSD32TO64_UAP(namelen);
2794 return (sys_bind(p, &ua, retval));
2795 }
2796
2797 int
2798 netbsd32_setsockopt(p, v, retval)
2799 struct proc *p;
2800 void *v;
2801 register_t *retval;
2802 {
2803 struct netbsd32_setsockopt_args /* {
2804 syscallarg(int) s;
2805 syscallarg(int) level;
2806 syscallarg(int) name;
2807 syscallarg(const netbsd32_voidp) val;
2808 syscallarg(int) valsize;
2809 } */ *uap = v;
2810 struct sys_setsockopt_args ua;
2811
2812 NETBSD32TO64_UAP(s);
2813 NETBSD32TO64_UAP(level);
2814 NETBSD32TO64_UAP(name);
2815 NETBSD32TOP_UAP(val, void);
2816 NETBSD32TO64_UAP(valsize);
2817 /* may be more efficient to do this inline. */
2818 return (sys_setsockopt(p, &ua, retval));
2819 }
2820
2821 int
2822 netbsd32_listen(p, v, retval)
2823 struct proc *p;
2824 void *v;
2825 register_t *retval;
2826 {
2827 struct netbsd32_listen_args /* {
2828 syscallarg(int) s;
2829 syscallarg(int) backlog;
2830 } */ *uap = v;
2831 struct sys_listen_args ua;
2832
2833 NETBSD32TO64_UAP(s);
2834 NETBSD32TO64_UAP(backlog);
2835 return (sys_listen(p, &ua, retval));
2836 }
2837
2838 int
2839 netbsd32_gettimeofday(p, v, retval)
2840 struct proc *p;
2841 void *v;
2842 register_t *retval;
2843 {
2844 struct netbsd32_gettimeofday_args /* {
2845 syscallarg(netbsd32_timevalp_t) tp;
2846 syscallarg(netbsd32_timezonep_t) tzp;
2847 } */ *uap = v;
2848 struct timeval atv;
2849 struct netbsd32_timeval tv32;
2850 int error = 0;
2851 struct netbsd32_timezone tzfake;
2852
2853 if (SCARG(uap, tp)) {
2854 microtime(&atv);
2855 netbsd32_from_timeval(&atv, &tv32);
2856 error = copyout(&tv32, (caddr_t)(u_long)SCARG(uap, tp), sizeof(tv32));
2857 if (error)
2858 return (error);
2859 }
2860 if (SCARG(uap, tzp)) {
2861 /*
2862 * NetBSD has no kernel notion of time zone, so we just
2863 * fake up a timezone struct and return it if demanded.
2864 */
2865 tzfake.tz_minuteswest = 0;
2866 tzfake.tz_dsttime = 0;
2867 error = copyout(&tzfake, (caddr_t)(u_long)SCARG(uap, tzp), sizeof(tzfake));
2868 }
2869 return (error);
2870 }
2871
2872 #if 0
2873 static int settime32 __P((struct timeval *));
2874 /* This function is used by clock_settime and settimeofday */
2875 static int
2876 settime32(tv)
2877 struct timeval *tv;
2878 {
2879 struct timeval delta;
2880 int s;
2881
2882 /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
2883 s = splclock();
2884 timersub(tv, &time, &delta);
2885 if ((delta.tv_sec < 0 || delta.tv_usec < 0) && securelevel > 1)
2886 return (EPERM);
2887 #ifdef notyet
2888 if ((delta.tv_sec < 86400) && securelevel > 0)
2889 return (EPERM);
2890 #endif
2891 time = *tv;
2892 (void) spllowersoftclock();
2893 timeradd(&boottime, &delta, &boottime);
2894 timeradd(&runtime, &delta, &runtime);
2895 # if defined(NFS) || defined(NFSSERVER)
2896 {
2897 extern void nqnfs_lease_updatetime __P((int));
2898
2899 nqnfs_lease_updatetime(delta.tv_sec);
2900 }
2901 # endif
2902 splx(s);
2903 resettodr();
2904 return (0);
2905 }
2906 #endif
2907
2908 int
2909 netbsd32_settimeofday(p, v, retval)
2910 struct proc *p;
2911 void *v;
2912 register_t *retval;
2913 {
2914 struct netbsd32_settimeofday_args /* {
2915 syscallarg(const netbsd32_timevalp_t) tv;
2916 syscallarg(const netbsd32_timezonep_t) tzp;
2917 } */ *uap = v;
2918 struct netbsd32_timeval atv32;
2919 struct timeval atv;
2920 struct netbsd32_timezone atz;
2921 int error;
2922
2923 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
2924 return (error);
2925 /* Verify all parameters before changing time. */
2926 if (SCARG(uap, tv) && (error = copyin((caddr_t)(u_long)SCARG(uap, tv),
2927 &atv32, sizeof(atv32))))
2928 return (error);
2929 netbsd32_to_timeval(&atv32, &atv);
2930 /* XXX since we don't use tz, probably no point in doing copyin. */
2931 if (SCARG(uap, tzp) && (error = copyin((caddr_t)(u_long)SCARG(uap, tzp),
2932 &atz, sizeof(atz))))
2933 return (error);
2934 if (SCARG(uap, tv))
2935 if ((error = settime(&atv)))
2936 return (error);
2937 /*
2938 * NetBSD has no kernel notion of time zone, and only an
2939 * obsolete program would try to set it, so we log a warning.
2940 */
2941 if (SCARG(uap, tzp))
2942 printf("pid %d attempted to set the "
2943 "(obsolete) kernel time zone\n", p->p_pid);
2944 return (0);
2945 }
2946
2947 int
2948 netbsd32_fchown(p, v, retval)
2949 struct proc *p;
2950 void *v;
2951 register_t *retval;
2952 {
2953 struct netbsd32_fchown_args /* {
2954 syscallarg(int) fd;
2955 syscallarg(uid_t) uid;
2956 syscallarg(gid_t) gid;
2957 } */ *uap = v;
2958 struct sys_fchown_args ua;
2959
2960 NETBSD32TO64_UAP(fd);
2961 NETBSD32TO64_UAP(uid);
2962 NETBSD32TO64_UAP(gid);
2963 return (sys_fchown(p, &ua, retval));
2964 }
2965
2966 int
2967 netbsd32_fchmod(p, v, retval)
2968 struct proc *p;
2969 void *v;
2970 register_t *retval;
2971 {
2972 struct netbsd32_fchmod_args /* {
2973 syscallarg(int) fd;
2974 syscallarg(mode_t) mode;
2975 } */ *uap = v;
2976 struct sys_fchmod_args ua;
2977
2978 NETBSD32TO64_UAP(fd);
2979 NETBSD32TO64_UAP(mode);
2980 return (sys_fchmod(p, &ua, retval));
2981 }
2982
2983 int
2984 netbsd32_setreuid(p, v, retval)
2985 struct proc *p;
2986 void *v;
2987 register_t *retval;
2988 {
2989 struct netbsd32_setreuid_args /* {
2990 syscallarg(uid_t) ruid;
2991 syscallarg(uid_t) euid;
2992 } */ *uap = v;
2993 struct sys_setreuid_args ua;
2994
2995 NETBSD32TO64_UAP(ruid);
2996 NETBSD32TO64_UAP(euid);
2997 return (sys_setreuid(p, &ua, retval));
2998 }
2999
3000 int
3001 netbsd32_setregid(p, v, retval)
3002 struct proc *p;
3003 void *v;
3004 register_t *retval;
3005 {
3006 struct netbsd32_setregid_args /* {
3007 syscallarg(gid_t) rgid;
3008 syscallarg(gid_t) egid;
3009 } */ *uap = v;
3010 struct sys_setregid_args ua;
3011
3012 NETBSD32TO64_UAP(rgid);
3013 NETBSD32TO64_UAP(egid);
3014 return (sys_setregid(p, &ua, retval));
3015 }
3016
3017 int
3018 netbsd32_getrusage(p, v, retval)
3019 struct proc *p;
3020 void *v;
3021 register_t *retval;
3022 {
3023 struct netbsd32_getrusage_args /* {
3024 syscallarg(int) who;
3025 syscallarg(netbsd32_rusagep_t) rusage;
3026 } */ *uap = v;
3027 struct rusage *rup;
3028 struct netbsd32_rusage ru;
3029
3030 switch (SCARG(uap, who)) {
3031
3032 case RUSAGE_SELF:
3033 rup = &p->p_stats->p_ru;
3034 calcru(p, &rup->ru_utime, &rup->ru_stime, NULL);
3035 break;
3036
3037 case RUSAGE_CHILDREN:
3038 rup = &p->p_stats->p_cru;
3039 break;
3040
3041 default:
3042 return (EINVAL);
3043 }
3044 netbsd32_from_rusage(rup, &ru);
3045 return (copyout(&ru, (caddr_t)(u_long)SCARG(uap, rusage), sizeof(ru)));
3046 }
3047
3048 int
3049 netbsd32_getsockopt(p, v, retval)
3050 struct proc *p;
3051 void *v;
3052 register_t *retval;
3053 {
3054 struct netbsd32_getsockopt_args /* {
3055 syscallarg(int) s;
3056 syscallarg(int) level;
3057 syscallarg(int) name;
3058 syscallarg(netbsd32_voidp) val;
3059 syscallarg(netbsd32_intp) avalsize;
3060 } */ *uap = v;
3061 struct sys_getsockopt_args ua;
3062
3063 NETBSD32TO64_UAP(s);
3064 NETBSD32TO64_UAP(level);
3065 NETBSD32TO64_UAP(name);
3066 NETBSD32TOP_UAP(val, void);
3067 NETBSD32TOP_UAP(avalsize, int);
3068 return (sys_getsockopt(p, &ua, retval));
3069 }
3070
3071 int
3072 netbsd32_readv(p, v, retval)
3073 struct proc *p;
3074 void *v;
3075 register_t *retval;
3076 {
3077 struct netbsd32_readv_args /* {
3078 syscallarg(int) fd;
3079 syscallarg(const netbsd32_iovecp_t) iovp;
3080 syscallarg(int) iovcnt;
3081 } */ *uap = v;
3082 int fd = SCARG(uap, fd);
3083 struct file *fp;
3084 struct filedesc *fdp = p->p_fd;
3085
3086 if ((u_int)fd >= fdp->fd_nfiles ||
3087 (fp = fdp->fd_ofiles[fd]) == NULL ||
3088 (fp->f_flag & FREAD) == 0)
3089 return (EBADF);
3090
3091 return (dofilereadv32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp),
3092 SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
3093 }
3094
3095 /* Damn thing copies in the iovec! */
3096 int
3097 dofilereadv32(p, fd, fp, iovp, iovcnt, offset, flags, retval)
3098 struct proc *p;
3099 int fd;
3100 struct file *fp;
3101 struct netbsd32_iovec *iovp;
3102 int iovcnt;
3103 off_t *offset;
3104 int flags;
3105 register_t *retval;
3106 {
3107 struct uio auio;
3108 struct iovec *iov;
3109 struct iovec *needfree;
3110 struct iovec aiov[UIO_SMALLIOV];
3111 long i, cnt, error = 0;
3112 u_int iovlen;
3113 #ifdef KTRACE
3114 struct iovec *ktriov = NULL;
3115 #endif
3116
3117 /* note: can't use iovlen until iovcnt is validated */
3118 iovlen = iovcnt * sizeof(struct iovec);
3119 if ((u_int)iovcnt > UIO_SMALLIOV) {
3120 if ((u_int)iovcnt > IOV_MAX)
3121 return (EINVAL);
3122 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
3123 needfree = iov;
3124 } else if ((u_int)iovcnt > 0) {
3125 iov = aiov;
3126 needfree = NULL;
3127 } else
3128 return (EINVAL);
3129
3130 auio.uio_iov = iov;
3131 auio.uio_iovcnt = iovcnt;
3132 auio.uio_rw = UIO_READ;
3133 auio.uio_segflg = UIO_USERSPACE;
3134 auio.uio_procp = p;
3135 error = netbsd32_to_iovecin(iovp, iov, iovcnt);
3136 if (error)
3137 goto done;
3138 auio.uio_resid = 0;
3139 for (i = 0; i < iovcnt; i++) {
3140 auio.uio_resid += iov->iov_len;
3141 /*
3142 * Reads return ssize_t because -1 is returned on error.
3143 * Therefore we must restrict the length to SSIZE_MAX to
3144 * avoid garbage return values.
3145 */
3146 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
3147 error = EINVAL;
3148 goto done;
3149 }
3150 iov++;
3151 }
3152 #ifdef KTRACE
3153 /*
3154 * if tracing, save a copy of iovec
3155 */
3156 if (KTRPOINT(p, KTR_GENIO)) {
3157 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
3158 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
3159 }
3160 #endif
3161 cnt = auio.uio_resid;
3162 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags);
3163 if (error)
3164 if (auio.uio_resid != cnt && (error == ERESTART ||
3165 error == EINTR || error == EWOULDBLOCK))
3166 error = 0;
3167 cnt -= auio.uio_resid;
3168 #ifdef KTRACE
3169 if (KTRPOINT(p, KTR_GENIO))
3170 if (error == 0) {
3171 ktrgenio(p, fd, UIO_READ, ktriov, cnt,
3172 error);
3173 FREE(ktriov, M_TEMP);
3174 }
3175 #endif
3176 *retval = cnt;
3177 done:
3178 if (needfree)
3179 FREE(needfree, M_IOV);
3180 return (error);
3181 }
3182
3183
3184 int
3185 netbsd32_writev(p, v, retval)
3186 struct proc *p;
3187 void *v;
3188 register_t *retval;
3189 {
3190 struct netbsd32_writev_args /* {
3191 syscallarg(int) fd;
3192 syscallarg(const netbsd32_iovecp_t) iovp;
3193 syscallarg(int) iovcnt;
3194 } */ *uap = v;
3195 int fd = SCARG(uap, fd);
3196 struct file *fp;
3197 struct filedesc *fdp = p->p_fd;
3198
3199 if ((u_int)fd >= fdp->fd_nfiles ||
3200 (fp = fdp->fd_ofiles[fd]) == NULL ||
3201 (fp->f_flag & FWRITE) == 0)
3202 return (EBADF);
3203
3204 return (dofilewritev32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp),
3205 SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval));
3206 }
3207
3208 int
3209 dofilewritev32(p, fd, fp, iovp, iovcnt, offset, flags, retval)
3210 struct proc *p;
3211 int fd;
3212 struct file *fp;
3213 struct netbsd32_iovec *iovp;
3214 int iovcnt;
3215 off_t *offset;
3216 int flags;
3217 register_t *retval;
3218 {
3219 struct uio auio;
3220 struct iovec *iov;
3221 struct iovec *needfree;
3222 struct iovec aiov[UIO_SMALLIOV];
3223 long i, cnt, error = 0;
3224 u_int iovlen;
3225 #ifdef KTRACE
3226 struct iovec *ktriov = NULL;
3227 #endif
3228
3229 /* note: can't use iovlen until iovcnt is validated */
3230 iovlen = iovcnt * sizeof(struct iovec);
3231 if ((u_int)iovcnt > UIO_SMALLIOV) {
3232 if ((u_int)iovcnt > IOV_MAX)
3233 return (EINVAL);
3234 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
3235 needfree = iov;
3236 } else if ((u_int)iovcnt > 0) {
3237 iov = aiov;
3238 needfree = NULL;
3239 } else
3240 return (EINVAL);
3241
3242 auio.uio_iov = iov;
3243 auio.uio_iovcnt = iovcnt;
3244 auio.uio_rw = UIO_WRITE;
3245 auio.uio_segflg = UIO_USERSPACE;
3246 auio.uio_procp = p;
3247 error = netbsd32_to_iovecin(iovp, iov, iovcnt);
3248 if (error)
3249 goto done;
3250 auio.uio_resid = 0;
3251 for (i = 0; i < iovcnt; i++) {
3252 auio.uio_resid += iov->iov_len;
3253 /*
3254 * Writes return ssize_t because -1 is returned on error.
3255 * Therefore we must restrict the length to SSIZE_MAX to
3256 * avoid garbage return values.
3257 */
3258 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) {
3259 error = EINVAL;
3260 goto done;
3261 }
3262 iov++;
3263 }
3264 #ifdef KTRACE
3265 /*
3266 * if tracing, save a copy of iovec
3267 */
3268 if (KTRPOINT(p, KTR_GENIO)) {
3269 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
3270 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen);
3271 }
3272 #endif
3273 cnt = auio.uio_resid;
3274 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags);
3275 if (error) {
3276 if (auio.uio_resid != cnt && (error == ERESTART ||
3277 error == EINTR || error == EWOULDBLOCK))
3278 error = 0;
3279 if (error == EPIPE)
3280 psignal(p, SIGPIPE);
3281 }
3282 cnt -= auio.uio_resid;
3283 #ifdef KTRACE
3284 if (KTRPOINT(p, KTR_GENIO))
3285 if (error == 0) {
3286 ktrgenio(p, fd, UIO_WRITE, ktriov, cnt,
3287 error);
3288 FREE(ktriov, M_TEMP);
3289 }
3290 #endif
3291 *retval = cnt;
3292 done:
3293 if (needfree)
3294 FREE(needfree, M_IOV);
3295 return (error);
3296 }
3297
3298
3299 int
3300 netbsd32_rename(p, v, retval)
3301 struct proc *p;
3302 void *v;
3303 register_t *retval;
3304 {
3305 struct netbsd32_rename_args /* {
3306 syscallarg(const netbsd32_charp) from;
3307 syscallarg(const netbsd32_charp) to;
3308 } */ *uap = v;
3309 struct sys_rename_args ua;
3310
3311 NETBSD32TOP_UAP(from, const char);
3312 NETBSD32TOP_UAP(to, const char)
3313
3314 return (sys_rename(p, &ua, retval));
3315 }
3316
3317 int
3318 netbsd32_flock(p, v, retval)
3319 struct proc *p;
3320 void *v;
3321 register_t *retval;
3322 {
3323 struct netbsd32_flock_args /* {
3324 syscallarg(int) fd;
3325 syscallarg(int) how;
3326 } */ *uap = v;
3327 struct sys_flock_args ua;
3328
3329 NETBSD32TO64_UAP(fd);
3330 NETBSD32TO64_UAP(how)
3331
3332 return (sys_flock(p, &ua, retval));
3333 }
3334
3335 int
3336 netbsd32_mkfifo(p, v, retval)
3337 struct proc *p;
3338 void *v;
3339 register_t *retval;
3340 {
3341 struct netbsd32_mkfifo_args /* {
3342 syscallarg(const netbsd32_charp) path;
3343 syscallarg(mode_t) mode;
3344 } */ *uap = v;
3345 struct sys_mkfifo_args ua;
3346
3347 NETBSD32TOP_UAP(path, const char)
3348 NETBSD32TO64_UAP(mode);
3349 return (sys_mkfifo(p, &ua, retval));
3350 }
3351
3352 int
3353 netbsd32_shutdown(p, v, retval)
3354 struct proc *p;
3355 void *v;
3356 register_t *retval;
3357 {
3358 struct netbsd32_shutdown_args /* {
3359 syscallarg(int) s;
3360 syscallarg(int) how;
3361 } */ *uap = v;
3362 struct sys_shutdown_args ua;
3363
3364 NETBSD32TO64_UAP(s)
3365 NETBSD32TO64_UAP(how);
3366 return (sys_shutdown(p, &ua, retval));
3367 }
3368
3369 int
3370 netbsd32_socketpair(p, v, retval)
3371 struct proc *p;
3372 void *v;
3373 register_t *retval;
3374 {
3375 struct netbsd32_socketpair_args /* {
3376 syscallarg(int) domain;
3377 syscallarg(int) type;
3378 syscallarg(int) protocol;
3379 syscallarg(netbsd32_intp) rsv;
3380 } */ *uap = v;
3381 struct sys_socketpair_args ua;
3382
3383 NETBSD32TO64_UAP(domain);
3384 NETBSD32TO64_UAP(type);
3385 NETBSD32TO64_UAP(protocol);
3386 NETBSD32TOP_UAP(rsv, int);
3387 /* Since we're just copying out two `int's we can do this */
3388 return (sys_socketpair(p, &ua, retval));
3389 }
3390
3391 int
3392 netbsd32_mkdir(p, v, retval)
3393 struct proc *p;
3394 void *v;
3395 register_t *retval;
3396 {
3397 struct netbsd32_mkdir_args /* {
3398 syscallarg(const netbsd32_charp) path;
3399 syscallarg(mode_t) mode;
3400 } */ *uap = v;
3401 struct sys_mkdir_args ua;
3402
3403 NETBSD32TOP_UAP(path, const char)
3404 NETBSD32TO64_UAP(mode);
3405 return (sys_mkdir(p, &ua, retval));
3406 }
3407
3408 int
3409 netbsd32_rmdir(p, v, retval)
3410 struct proc *p;
3411 void *v;
3412 register_t *retval;
3413 {
3414 struct netbsd32_rmdir_args /* {
3415 syscallarg(const netbsd32_charp) path;
3416 } */ *uap = v;
3417 struct sys_rmdir_args ua;
3418
3419 NETBSD32TOP_UAP(path, const char);
3420 return (sys_rmdir(p, &ua, retval));
3421 }
3422
3423 int
3424 netbsd32_utimes(p, v, retval)
3425 struct proc *p;
3426 void *v;
3427 register_t *retval;
3428 {
3429 struct netbsd32_utimes_args /* {
3430 syscallarg(const netbsd32_charp) path;
3431 syscallarg(const netbsd32_timevalp_t) tptr;
3432 } */ *uap = v;
3433 int error;
3434 struct nameidata nd;
3435
3436 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, (char *)(u_long)SCARG(uap, path), p);
3437 if ((error = namei(&nd)) != 0)
3438 return (error);
3439
3440 error = change_utimes32(nd.ni_vp, (struct timeval *)(u_long)SCARG(uap, tptr), p);
3441
3442 vrele(nd.ni_vp);
3443 return (error);
3444 }
3445
3446 /*
3447 * Common routine to set access and modification times given a vnode.
3448 */
3449 static int
3450 change_utimes32(vp, tptr, p)
3451 struct vnode *vp;
3452 struct timeval *tptr;
3453 struct proc *p;
3454 {
3455 struct netbsd32_timeval tv32[2];
3456 struct timeval tv[2];
3457 struct vattr vattr;
3458 int error;
3459
3460 VATTR_NULL(&vattr);
3461 if (tptr == NULL) {
3462 microtime(&tv[0]);
3463 tv[1] = tv[0];
3464 vattr.va_vaflags |= VA_UTIMES_NULL;
3465 } else {
3466 error = copyin(tptr, tv, sizeof(tv));
3467 if (error)
3468 return (error);
3469 }
3470 netbsd32_to_timeval(&tv32[0], &tv[0]);
3471 netbsd32_to_timeval(&tv32[1], &tv[1]);
3472 VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
3473 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
3474 vattr.va_atime.tv_sec = tv[0].tv_sec;
3475 vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
3476 vattr.va_mtime.tv_sec = tv[1].tv_sec;
3477 vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;
3478 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
3479 VOP_UNLOCK(vp, 0);
3480 return (error);
3481 }
3482
3483 int
3484 netbsd32_adjtime(p, v, retval)
3485 struct proc *p;
3486 void *v;
3487 register_t *retval;
3488 {
3489 struct netbsd32_adjtime_args /* {
3490 syscallarg(const netbsd32_timevalp_t) delta;
3491 syscallarg(netbsd32_timevalp_t) olddelta;
3492 } */ *uap = v;
3493 struct netbsd32_timeval atv;
3494 int32_t ndelta, ntickdelta, odelta;
3495 int s, error;
3496 extern long bigadj, timedelta;
3497 extern int tickdelta;
3498
3499 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
3500 return (error);
3501
3502 error = copyin((caddr_t)(u_long)SCARG(uap, delta), &atv, sizeof(struct timeval));
3503 if (error)
3504 return (error);
3505 /*
3506 * Compute the total correction and the rate at which to apply it.
3507 * Round the adjustment down to a whole multiple of the per-tick
3508 * delta, so that after some number of incremental changes in
3509 * hardclock(), tickdelta will become zero, lest the correction
3510 * overshoot and start taking us away from the desired final time.
3511 */
3512 ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
3513 if (ndelta > bigadj)
3514 ntickdelta = 10 * tickadj;
3515 else
3516 ntickdelta = tickadj;
3517 if (ndelta % ntickdelta)
3518 ndelta = ndelta / ntickdelta * ntickdelta;
3519
3520 /*
3521 * To make hardclock()'s job easier, make the per-tick delta negative
3522 * if we want time to run slower; then hardclock can simply compute
3523 * tick + tickdelta, and subtract tickdelta from timedelta.
3524 */
3525 if (ndelta < 0)
3526 ntickdelta = -ntickdelta;
3527 s = splclock();
3528 odelta = timedelta;
3529 timedelta = ndelta;
3530 tickdelta = ntickdelta;
3531 splx(s);
3532
3533 if (SCARG(uap, olddelta)) {
3534 atv.tv_sec = odelta / 1000000;
3535 atv.tv_usec = odelta % 1000000;
3536 (void) copyout(&atv, (caddr_t)(u_long)SCARG(uap, olddelta),
3537 sizeof(struct timeval));
3538 }
3539 return (0);
3540 }
3541
3542 int
3543 netbsd32_quotactl(p, v, retval)
3544 struct proc *p;
3545 void *v;
3546 register_t *retval;
3547 {
3548 struct netbsd32_quotactl_args /* {
3549 syscallarg(const netbsd32_charp) path;
3550 syscallarg(int) cmd;
3551 syscallarg(int) uid;
3552 syscallarg(netbsd32_caddr_t) arg;
3553 } */ *uap = v;
3554 struct sys_quotactl_args ua;
3555
3556 NETBSD32TOP_UAP(path, const char);
3557 NETBSD32TO64_UAP(cmd);
3558 NETBSD32TO64_UAP(uid);
3559 NETBSD32TOX64_UAP(arg, caddr_t);
3560 return (sys_quotactl(p, &ua, retval));
3561 }
3562
3563 #if defined(NFS) || defined(NFSSERVER)
3564 int
3565 netbsd32_nfssvc(p, v, retval)
3566 struct proc *p;
3567 void *v;
3568 register_t *retval;
3569 {
3570 #if 0
3571 struct netbsd32_nfssvc_args /* {
3572 syscallarg(int) flag;
3573 syscallarg(netbsd32_voidp) argp;
3574 } */ *uap = v;
3575 struct sys_nfssvc_args ua;
3576
3577 NETBSD32TO64_UAP(flag);
3578 NETBSD32TOP_UAP(argp, void);
3579 return (sys_nfssvc(p, &ua, retval));
3580 #else
3581 /* Why would we want to support a 32-bit nfsd? */
3582 return (ENOSYS);
3583 #endif
3584 }
3585 #endif
3586
3587 int
3588 netbsd32_statfs(p, v, retval)
3589 struct proc *p;
3590 void *v;
3591 register_t *retval;
3592 {
3593 struct netbsd32_statfs_args /* {
3594 syscallarg(const netbsd32_charp) path;
3595 syscallarg(netbsd32_statfsp_t) buf;
3596 } */ *uap = v;
3597 struct mount *mp;
3598 struct statfs *sp;
3599 struct netbsd32_statfs s32;
3600 int error;
3601 struct nameidata nd;
3602
3603 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, (char *)(u_long)SCARG(uap, path), p);
3604 if ((error = namei(&nd)) != 0)
3605 return (error);
3606 mp = nd.ni_vp->v_mount;
3607 sp = &mp->mnt_stat;
3608 vrele(nd.ni_vp);
3609 if ((error = VFS_STATFS(mp, sp, p)) != 0)
3610 return (error);
3611 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
3612 netbsd32_from_statfs(sp, &s32);
3613 return (copyout(&s32, (caddr_t)(u_long)SCARG(uap, buf), sizeof(s32)));
3614 }
3615
3616 int
3617 netbsd32_fstatfs(p, v, retval)
3618 struct proc *p;
3619 void *v;
3620 register_t *retval;
3621 {
3622 struct netbsd32_fstatfs_args /* {
3623 syscallarg(int) fd;
3624 syscallarg(netbsd32_statfsp_t) buf;
3625 } */ *uap = v;
3626 struct file *fp;
3627 struct mount *mp;
3628 struct statfs *sp;
3629 struct netbsd32_statfs s32;
3630 int error;
3631
3632 /* getvnode() will use the descriptor for us */
3633 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
3634 return (error);
3635 mp = ((struct vnode *)fp->f_data)->v_mount;
3636 sp = &mp->mnt_stat;
3637 if ((error = VFS_STATFS(mp, sp, p)) != 0)
3638 goto out;
3639 sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
3640 netbsd32_from_statfs(sp, &s32);
3641 error = copyout(&s32, (caddr_t)(u_long)SCARG(uap, buf), sizeof(s32));
3642 out:
3643 FILE_UNUSE(fp, p);
3644 return (error);
3645 }
3646
3647 #if defined(NFS) || defined(NFSSERVER)
3648 int
3649 netbsd32_getfh(p, v, retval)
3650 struct proc *p;
3651 void *v;
3652 register_t *retval;
3653 {
3654 struct netbsd32_getfh_args /* {
3655 syscallarg(const netbsd32_charp) fname;
3656 syscallarg(netbsd32_fhandlep_t) fhp;
3657 } */ *uap = v;
3658 struct sys_getfh_args ua;
3659
3660 NETBSD32TOP_UAP(fname, const char);
3661 NETBSD32TOP_UAP(fhp, struct fhandle);
3662 /* Lucky for us a fhandlep_t doesn't change sizes */
3663 return (sys_getfh(p, &ua, retval));
3664 }
3665 #endif
3666
3667 int
3668 netbsd32_sysarch(p, v, retval)
3669 struct proc *p;
3670 void *v;
3671 register_t *retval;
3672 {
3673 struct netbsd32_sysarch_args /* {
3674 syscallarg(int) op;
3675 syscallarg(netbsd32_voidp) parms;
3676 } */ *uap = v;
3677
3678 switch (SCARG(uap, op)) {
3679 default:
3680 printf("(sparc64) netbsd32_sysarch(%d)\n", SCARG(uap, op));
3681 return EINVAL;
3682 }
3683 }
3684
3685 int
3686 netbsd32_pread(p, v, retval)
3687 struct proc *p;
3688 void *v;
3689 register_t *retval;
3690 {
3691 struct netbsd32_pread_args /* {
3692 syscallarg(int) fd;
3693 syscallarg(netbsd32_voidp) buf;
3694 syscallarg(netbsd32_size_t) nbyte;
3695 syscallarg(int) pad;
3696 syscallarg(off_t) offset;
3697 } */ *uap = v;
3698 struct sys_pread_args ua;
3699 ssize_t rt;
3700 int error;
3701
3702 NETBSD32TO64_UAP(fd);
3703 NETBSD32TOP_UAP(buf, void);
3704 NETBSD32TOX_UAP(nbyte, size_t);
3705 NETBSD32TO64_UAP(pad);
3706 NETBSD32TO64_UAP(offset);
3707 error = sys_pread(p, &ua, (register_t *)&rt);
3708 *retval = rt;
3709 return (error);
3710 }
3711
3712 int
3713 netbsd32_pwrite(p, v, retval)
3714 struct proc *p;
3715 void *v;
3716 register_t *retval;
3717 {
3718 struct netbsd32_pwrite_args /* {
3719 syscallarg(int) fd;
3720 syscallarg(const netbsd32_voidp) buf;
3721 syscallarg(netbsd32_size_t) nbyte;
3722 syscallarg(int) pad;
3723 syscallarg(off_t) offset;
3724 } */ *uap = v;
3725 struct sys_pwrite_args ua;
3726 ssize_t rt;
3727 int error;
3728
3729 NETBSD32TO64_UAP(fd);
3730 NETBSD32TOP_UAP(buf, void);
3731 NETBSD32TOX_UAP(nbyte, size_t);
3732 NETBSD32TO64_UAP(pad);
3733 NETBSD32TO64_UAP(offset);
3734 error = sys_pwrite(p, &ua, (register_t *)&rt);
3735 *retval = rt;
3736 return (error);
3737 }
3738
3739 #ifdef NTP
3740 int
3741 netbsd32_ntp_gettime(p, v, retval)
3742 struct proc *p;
3743 void *v;
3744 register_t *retval;
3745 {
3746 struct netbsd32_ntp_gettime_args /* {
3747 syscallarg(netbsd32_ntptimevalp_t) ntvp;
3748 } */ *uap = v;
3749 struct netbsd32_ntptimeval ntv32;
3750 struct timeval atv;
3751 struct ntptimeval ntv;
3752 int error = 0;
3753 int s;
3754
3755 /* The following are NTP variables */
3756 extern long time_maxerror;
3757 extern long time_esterror;
3758 extern int time_status;
3759 extern int time_state; /* clock state */
3760 extern int time_status; /* clock status bits */
3761
3762 if (SCARG(uap, ntvp)) {
3763 s = splclock();
3764 #ifdef EXT_CLOCK
3765 /*
3766 * The microtime() external clock routine returns a
3767 * status code. If less than zero, we declare an error
3768 * in the clock status word and return the kernel
3769 * (software) time variable. While there are other
3770 * places that call microtime(), this is the only place
3771 * that matters from an application point of view.
3772 */
3773 if (microtime(&atv) < 0) {
3774 time_status |= STA_CLOCKERR;
3775 ntv.time = time;
3776 } else
3777 time_status &= ~STA_CLOCKERR;
3778 #else /* EXT_CLOCK */
3779 microtime(&atv);
3780 #endif /* EXT_CLOCK */
3781 ntv.time = atv;
3782 ntv.maxerror = time_maxerror;
3783 ntv.esterror = time_esterror;
3784 (void) splx(s);
3785
3786 netbsd32_from_timeval(&ntv.time, &ntv32.time);
3787 ntv32.maxerror = (netbsd32_long)ntv.maxerror;
3788 ntv32.esterror = (netbsd32_long)ntv.esterror;
3789 error = copyout((caddr_t)&ntv32, (caddr_t)(u_long)SCARG(uap, ntvp),
3790 sizeof(ntv32));
3791 }
3792 if (!error) {
3793
3794 /*
3795 * Status word error decode. If any of these conditions
3796 * occur, an error is returned, instead of the status
3797 * word. Most applications will care only about the fact
3798 * the system clock may not be trusted, not about the
3799 * details.
3800 *
3801 * Hardware or software error
3802 */
3803 if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
3804
3805 /*
3806 * PPS signal lost when either time or frequency
3807 * synchronization requested
3808 */
3809 (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
3810 !(time_status & STA_PPSSIGNAL)) ||
3811
3812 /*
3813 * PPS jitter exceeded when time synchronization
3814 * requested
3815 */
3816 (time_status & STA_PPSTIME &&
3817 time_status & STA_PPSJITTER) ||
3818
3819 /*
3820 * PPS wander exceeded or calibration error when
3821 * frequency synchronization requested
3822 */
3823 (time_status & STA_PPSFREQ &&
3824 time_status & (STA_PPSWANDER | STA_PPSERROR)))
3825 *retval = TIME_ERROR;
3826 else
3827 *retval = time_state;
3828 }
3829 return(error);
3830 }
3831
3832 int
3833 netbsd32_ntp_adjtime(p, v, retval)
3834 struct proc *p;
3835 void *v;
3836 register_t *retval;
3837 {
3838 struct netbsd32_ntp_adjtime_args /* {
3839 syscallarg(netbsd32_timexp_t) tp;
3840 } */ *uap = v;
3841 struct netbsd32_timex ntv32;
3842 struct timex ntv;
3843 int error = 0;
3844 int modes;
3845 int s;
3846 extern long time_freq; /* frequency offset (scaled ppm) */
3847 extern long time_maxerror;
3848 extern long time_esterror;
3849 extern int time_state; /* clock state */
3850 extern int time_status; /* clock status bits */
3851 extern long time_constant; /* pll time constant */
3852 extern long time_offset; /* time offset (us) */
3853 extern long time_tolerance; /* frequency tolerance (scaled ppm) */
3854 extern long time_precision; /* clock precision (us) */
3855
3856 if ((error = copyin((caddr_t)(u_long)SCARG(uap, tp), (caddr_t)&ntv32,
3857 sizeof(ntv32))))
3858 return (error);
3859 netbsd32_to_timex(&ntv32, &ntv);
3860
3861 /*
3862 * Update selected clock variables - only the superuser can
3863 * change anything. Note that there is no error checking here on
3864 * the assumption the superuser should know what it is doing.
3865 */
3866 modes = ntv.modes;
3867 if (modes != 0 && (error = suser(p->p_ucred, &p->p_acflag)))
3868 return (error);
3869
3870 s = splclock();
3871 if (modes & MOD_FREQUENCY)
3872 #ifdef PPS_SYNC
3873 time_freq = ntv.freq - pps_freq;
3874 #else /* PPS_SYNC */
3875 time_freq = ntv.freq;
3876 #endif /* PPS_SYNC */
3877 if (modes & MOD_MAXERROR)
3878 time_maxerror = ntv.maxerror;
3879 if (modes & MOD_ESTERROR)
3880 time_esterror = ntv.esterror;
3881 if (modes & MOD_STATUS) {
3882 time_status &= STA_RONLY;
3883 time_status |= ntv.status & ~STA_RONLY;
3884 }
3885 if (modes & MOD_TIMECONST)
3886 time_constant = ntv.constant;
3887 if (modes & MOD_OFFSET)
3888 hardupdate(ntv.offset);
3889
3890 /*
3891 * Retrieve all clock variables
3892 */
3893 if (time_offset < 0)
3894 ntv.offset = -(-time_offset >> SHIFT_UPDATE);
3895 else
3896 ntv.offset = time_offset >> SHIFT_UPDATE;
3897 #ifdef PPS_SYNC
3898 ntv.freq = time_freq + pps_freq;
3899 #else /* PPS_SYNC */
3900 ntv.freq = time_freq;
3901 #endif /* PPS_SYNC */
3902 ntv.maxerror = time_maxerror;
3903 ntv.esterror = time_esterror;
3904 ntv.status = time_status;
3905 ntv.constant = time_constant;
3906 ntv.precision = time_precision;
3907 ntv.tolerance = time_tolerance;
3908 #ifdef PPS_SYNC
3909 ntv.shift = pps_shift;
3910 ntv.ppsfreq = pps_freq;
3911 ntv.jitter = pps_jitter >> PPS_AVG;
3912 ntv.stabil = pps_stabil;
3913 ntv.calcnt = pps_calcnt;
3914 ntv.errcnt = pps_errcnt;
3915 ntv.jitcnt = pps_jitcnt;
3916 ntv.stbcnt = pps_stbcnt;
3917 #endif /* PPS_SYNC */
3918 (void)splx(s);
3919
3920 netbsd32_from_timex(&ntv, &ntv32);
3921 error = copyout((caddr_t)&ntv32, (caddr_t)(u_long)SCARG(uap, tp),
3922 sizeof(ntv32));
3923 if (!error) {
3924
3925 /*
3926 * Status word error decode. See comments in
3927 * ntp_gettime() routine.
3928 */
3929 if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) ||
3930 (time_status & (STA_PPSFREQ | STA_PPSTIME) &&
3931 !(time_status & STA_PPSSIGNAL)) ||
3932 (time_status & STA_PPSTIME &&
3933 time_status & STA_PPSJITTER) ||
3934 (time_status & STA_PPSFREQ &&
3935 time_status & (STA_PPSWANDER | STA_PPSERROR)))
3936 *retval = TIME_ERROR;
3937 else
3938 *retval = time_state;
3939 }
3940 return error;
3941 }
3942 #else
3943 int
3944 netbsd32_ntp_gettime(p, v, retval)
3945 struct proc *p;
3946 void *v;
3947 register_t *retval;
3948 {
3949 return(ENOSYS);
3950 }
3951
3952 int
3953 netbsd32_ntp_adjtime(p, v, retval)
3954 struct proc *p;
3955 void *v;
3956 register_t *retval;
3957 {
3958 return (ENOSYS);
3959 }
3960 #endif
3961
3962 int
3963 netbsd32_setgid(p, v, retval)
3964 struct proc *p;
3965 void *v;
3966 register_t *retval;
3967 {
3968 struct netbsd32_setgid_args /* {
3969 syscallarg(gid_t) gid;
3970 } */ *uap = v;
3971 struct sys_setgid_args ua;
3972
3973 NETBSD32TO64_UAP(gid);
3974 return (sys_setgid(p, v, retval));
3975 }
3976
3977 int
3978 netbsd32_setegid(p, v, retval)
3979 struct proc *p;
3980 void *v;
3981 register_t *retval;
3982 {
3983 struct netbsd32_setegid_args /* {
3984 syscallarg(gid_t) egid;
3985 } */ *uap = v;
3986 struct sys_setegid_args ua;
3987
3988 NETBSD32TO64_UAP(egid);
3989 return (sys_setegid(p, v, retval));
3990 }
3991
3992 int
3993 netbsd32_seteuid(p, v, retval)
3994 struct proc *p;
3995 void *v;
3996 register_t *retval;
3997 {
3998 struct netbsd32_seteuid_args /* {
3999 syscallarg(gid_t) euid;
4000 } */ *uap = v;
4001 struct sys_seteuid_args ua;
4002
4003 NETBSD32TO64_UAP(euid);
4004 return (sys_seteuid(p, v, retval));
4005 }
4006
4007 #ifdef LFS
4008 int
4009 netbsd32_sys_lfs_bmapv(p, v, retval)
4010 struct proc *p;
4011 void *v;
4012 register_t *retval;
4013 {
4014 #if 0
4015 struct netbsd32_lfs_bmapv_args /* {
4016 syscallarg(netbsd32_fsid_tp_t) fsidp;
4017 syscallarg(netbsd32_block_infop_t) blkiov;
4018 syscallarg(int) blkcnt;
4019 } */ *uap = v;
4020 struct sys_lfs_bmapv_args ua;
4021
4022 NETBSD32TOP_UAP(fdidp, struct fsid);
4023 NETBSD32TO64_UAP(blkcnt);
4024 /* XXX finish me */
4025 #else
4026
4027 return (ENOSYS); /* XXX */
4028 #endif
4029 }
4030
4031 int
4032 netbsd32_sys_lfs_markv(p, v, retval)
4033 struct proc *p;
4034 void *v;
4035 register_t *retval;
4036 {
4037 #if 0
4038 struct netbsd32_lfs_markv_args /* {
4039 syscallarg(netbsd32_fsid_tp_t) fsidp;
4040 syscallarg(netbsd32_block_infop_t) blkiov;
4041 syscallarg(int) blkcnt;
4042 } */ *uap = v;
4043 #endif
4044
4045 return (ENOSYS); /* XXX */
4046 }
4047
4048 int
4049 netbsd32_sys_lfs_segclean(p, v, retval)
4050 struct proc *p;
4051 void *v;
4052 register_t *retval;
4053 {
4054 #if 0
4055 struct netbsd32_lfs_segclean_args /* {
4056 syscallarg(netbsd32_fsid_tp_t) fsidp;
4057 syscallarg(netbsd32_u_long) segment;
4058 } */ *uap = v;
4059 #endif
4060
4061 return (ENOSYS); /* XXX */
4062 }
4063
4064 int
4065 netbsd32_sys_lfs_segwait(p, v, retval)
4066 struct proc *p;
4067 void *v;
4068 register_t *retval;
4069 {
4070 #if 0
4071 struct netbsd32_lfs_segwait_args /* {
4072 syscallarg(netbsd32_fsid_tp_t) fsidp;
4073 syscallarg(netbsd32_timevalp_t) tv;
4074 } */ *uap = v;
4075 #endif
4076
4077 return (ENOSYS); /* XXX */
4078 }
4079 #endif
4080
4081 int
4082 netbsd32_pathconf(p, v, retval)
4083 struct proc *p;
4084 void *v;
4085 register_t *retval;
4086 {
4087 struct netbsd32_pathconf_args /* {
4088 syscallarg(int) fd;
4089 syscallarg(int) name;
4090 } */ *uap = v;
4091 struct sys_pathconf_args ua;
4092 long rt;
4093 int error;
4094
4095 NETBSD32TOP_UAP(path, const char);
4096 NETBSD32TO64_UAP(name);
4097 error = sys_pathconf(p, &ua, (register_t *)&rt);
4098 *retval = rt;
4099 return (error);
4100 }
4101
4102 int
4103 netbsd32_fpathconf(p, v, retval)
4104 struct proc *p;
4105 void *v;
4106 register_t *retval;
4107 {
4108 struct netbsd32_fpathconf_args /* {
4109 syscallarg(int) fd;
4110 syscallarg(int) name;
4111 } */ *uap = v;
4112 struct sys_fpathconf_args ua;
4113 long rt;
4114 int error;
4115
4116 NETBSD32TO64_UAP(fd);
4117 NETBSD32TO64_UAP(name);
4118 error = sys_fpathconf(p, &ua, (register_t *)&rt);
4119 *retval = rt;
4120 return (error);
4121 }
4122
4123 int
4124 netbsd32_getrlimit(p, v, retval)
4125 struct proc *p;
4126 void *v;
4127 register_t *retval;
4128 {
4129 struct netbsd32_getrlimit_args /* {
4130 syscallarg(int) which;
4131 syscallarg(netbsd32_rlimitp_t) rlp;
4132 } */ *uap = v;
4133 int which = SCARG(uap, which);
4134
4135 if ((u_int)which >= RLIM_NLIMITS)
4136 return (EINVAL);
4137 return (copyout(&p->p_rlimit[which], (caddr_t)(u_long)SCARG(uap, rlp),
4138 sizeof(struct rlimit)));
4139 }
4140
4141 int
4142 netbsd32_setrlimit(p, v, retval)
4143 struct proc *p;
4144 void *v;
4145 register_t *retval;
4146 {
4147 struct netbsd32_setrlimit_args /* {
4148 syscallarg(int) which;
4149 syscallarg(const netbsd32_rlimitp_t) rlp;
4150 } */ *uap = v;
4151 int which = SCARG(uap, which);
4152 struct rlimit alim;
4153 int error;
4154
4155 error = copyin((caddr_t)(u_long)SCARG(uap, rlp), &alim, sizeof(struct rlimit));
4156 if (error)
4157 return (error);
4158 return (dosetrlimit(p, p->p_cred, which, &alim));
4159 }
4160
4161 int
4162 netbsd32_mmap(p, v, retval)
4163 struct proc *p;
4164 void *v;
4165 register_t *retval;
4166 {
4167 struct netbsd32_mmap_args /* {
4168 syscallarg(netbsd32_voidp) addr;
4169 syscallarg(netbsd32_size_t) len;
4170 syscallarg(int) prot;
4171 syscallarg(int) flags;
4172 syscallarg(int) fd;
4173 syscallarg(netbsd32_long) pad;
4174 syscallarg(off_t) pos;
4175 } */ *uap = v;
4176 struct sys_mmap_args ua;
4177 void *rt;
4178 int error;
4179
4180 NETBSD32TOP_UAP(addr, void);
4181 NETBSD32TOX_UAP(len, size_t);
4182 NETBSD32TO64_UAP(prot);
4183 NETBSD32TO64_UAP(flags);
4184 NETBSD32TO64_UAP(fd);
4185 NETBSD32TOX_UAP(pad, long);
4186 NETBSD32TOX_UAP(pos, off_t);
4187 error = sys_mmap(p, &ua, (register_t *)&rt);
4188 if ((long)rt > (long)UINT_MAX)
4189 printf("netbsd32_mmap: retval out of range: %p", rt);
4190 *retval = (netbsd32_voidp)(u_long)rt;
4191 return (error);
4192 }
4193
4194 int
4195 netbsd32_lseek(p, v, retval)
4196 struct proc *p;
4197 void *v;
4198 register_t *retval;
4199 {
4200 struct netbsd32_lseek_args /* {
4201 syscallarg(int) fd;
4202 syscallarg(int) pad;
4203 syscallarg(off_t) offset;
4204 syscallarg(int) whence;
4205 } */ *uap = v;
4206 struct sys_lseek_args ua;
4207
4208 NETBSD32TO64_UAP(fd);
4209 NETBSD32TO64_UAP(pad);
4210 NETBSD32TO64_UAP(offset);
4211 NETBSD32TO64_UAP(whence);
4212 return (sys_lseek(p, &ua, retval));
4213 }
4214
4215 int
4216 netbsd32_truncate(p, v, retval)
4217 struct proc *p;
4218 void *v;
4219 register_t *retval;
4220 {
4221 struct netbsd32_truncate_args /* {
4222 syscallarg(const netbsd32_charp) path;
4223 syscallarg(int) pad;
4224 syscallarg(off_t) length;
4225 } */ *uap = v;
4226 struct sys_truncate_args ua;
4227
4228 NETBSD32TOP_UAP(path, const char);
4229 NETBSD32TO64_UAP(pad);
4230 NETBSD32TO64_UAP(length);
4231 return (sys_truncate(p, &ua, retval));
4232 }
4233
4234 int
4235 netbsd32_ftruncate(p, v, retval)
4236 struct proc *p;
4237 void *v;
4238 register_t *retval;
4239 {
4240 struct netbsd32_ftruncate_args /* {
4241 syscallarg(int) fd;
4242 syscallarg(int) pad;
4243 syscallarg(off_t) length;
4244 } */ *uap = v;
4245 struct sys_ftruncate_args ua;
4246
4247 NETBSD32TO64_UAP(fd);
4248 NETBSD32TO64_UAP(pad);
4249 NETBSD32TO64_UAP(length);
4250 return (sys_ftruncate(p, &ua, retval));
4251 }
4252
4253 int
4254 netbsd32___sysctl(p, v, retval)
4255 struct proc *p;
4256 void *v;
4257 register_t *retval;
4258 {
4259 struct netbsd32___sysctl_args /* {
4260 syscallarg(netbsd32_intp) name;
4261 syscallarg(u_int) namelen;
4262 syscallarg(netbsd32_voidp) old;
4263 syscallarg(netbsd32_size_tp) oldlenp;
4264 syscallarg(netbsd32_voidp) new;
4265 syscallarg(netbsd32_size_t) newlen;
4266 } */ *uap = v;
4267 int error;
4268 netbsd32_size_t savelen = 0;
4269 size_t oldlen = 0;
4270 sysctlfn *fn;
4271 int name[CTL_MAXNAME];
4272
4273 /*
4274 * Some of these sysctl functions do their own copyin/copyout.
4275 * We need to disable or emulate the ones that need their
4276 * arguments converted.
4277 */
4278
4279 if (SCARG(uap, new) != NULL &&
4280 (error = suser(p->p_ucred, &p->p_acflag)))
4281 return (error);
4282 /*
4283 * all top-level sysctl names are non-terminal
4284 */
4285 if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
4286 return (EINVAL);
4287 error = copyin((caddr_t)(u_long)SCARG(uap, name), &name,
4288 SCARG(uap, namelen) * sizeof(int));
4289 if (error)
4290 return (error);
4291
4292 switch (name[0]) {
4293 case CTL_KERN:
4294 fn = kern_sysctl;
4295 break;
4296 case CTL_HW:
4297 fn = hw_sysctl;
4298 break;
4299 case CTL_VM:
4300 fn = uvm_sysctl;
4301 break;
4302 case CTL_NET:
4303 fn = net_sysctl;
4304 break;
4305 case CTL_VFS:
4306 fn = vfs_sysctl;
4307 break;
4308 case CTL_MACHDEP:
4309 fn = cpu_sysctl;
4310 break;
4311 #ifdef DEBUG
4312 case CTL_DEBUG:
4313 fn = debug_sysctl;
4314 break;
4315 #endif
4316 #ifdef DDB
4317 case CTL_DDB:
4318 fn = ddb_sysctl;
4319 break;
4320 #endif
4321 case CTL_PROC:
4322 fn = proc_sysctl;
4323 break;
4324 default:
4325 return (EOPNOTSUPP);
4326 }
4327
4328 /*
4329 * XXX Hey, we wire `old', but what about `new'?
4330 */
4331
4332 if (SCARG(uap, oldlenp) &&
4333 (error = copyin((caddr_t)(u_long)SCARG(uap, oldlenp), &savelen,
4334 sizeof(savelen))))
4335 return (error);
4336 if (SCARG(uap, old) != NULL) {
4337 error = lockmgr(&sysctl_memlock, LK_EXCLUSIVE, NULL);
4338 if (error)
4339 return (error);
4340 if (uvm_vslock(p, (void *)(u_long)SCARG(uap, old), savelen,
4341 VM_PROT_READ|VM_PROT_WRITE) != KERN_SUCCESS) {
4342 (void) lockmgr(&sysctl_memlock, LK_RELEASE, NULL);
4343 return (EFAULT);
4344 }
4345 oldlen = savelen;
4346 }
4347 error = (*fn)(name + 1, SCARG(uap, namelen) - 1,
4348 (void *)(u_long)SCARG(uap, old), &oldlen,
4349 (void *)(u_long)SCARG(uap, new), SCARG(uap, newlen), p);
4350 if (SCARG(uap, old) != NULL) {
4351 uvm_vsunlock(p, (void *)(u_long)SCARG(uap, old), savelen);
4352 (void) lockmgr(&sysctl_memlock, LK_RELEASE, NULL);
4353 }
4354 savelen = oldlen;
4355 if (error)
4356 return (error);
4357 if (SCARG(uap, oldlenp))
4358 error = copyout(&savelen,
4359 (caddr_t)(u_long)SCARG(uap, oldlenp), sizeof(savelen));
4360 return (error);
4361 }
4362
4363 int
4364 netbsd32_mlock(p, v, retval)
4365 struct proc *p;
4366 void *v;
4367 register_t *retval;
4368 {
4369 struct netbsd32_mlock_args /* {
4370 syscallarg(const netbsd32_voidp) addr;
4371 syscallarg(netbsd32_size_t) len;
4372 } */ *uap = v;
4373 struct sys_mlock_args ua;
4374
4375 NETBSD32TOP_UAP(addr, const void);
4376 NETBSD32TO64_UAP(len);
4377 return (sys_mlock(p, &ua, retval));
4378 }
4379
4380 int
4381 netbsd32_munlock(p, v, retval)
4382 struct proc *p;
4383 void *v;
4384 register_t *retval;
4385 {
4386 struct netbsd32_munlock_args /* {
4387 syscallarg(const netbsd32_voidp) addr;
4388 syscallarg(netbsd32_size_t) len;
4389 } */ *uap = v;
4390 struct sys_munlock_args ua;
4391
4392 NETBSD32TOP_UAP(addr, const void);
4393 NETBSD32TO64_UAP(len);
4394 return (sys_munlock(p, &ua, retval));
4395 }
4396
4397 int
4398 netbsd32_undelete(p, v, retval)
4399 struct proc *p;
4400 void *v;
4401 register_t *retval;
4402 {
4403 struct netbsd32_undelete_args /* {
4404 syscallarg(const netbsd32_charp) path;
4405 } */ *uap = v;
4406 struct sys_undelete_args ua;
4407
4408 NETBSD32TOP_UAP(path, const char);
4409 return (sys_undelete(p, &ua, retval));
4410 }
4411
4412 int
4413 netbsd32_futimes(p, v, retval)
4414 struct proc *p;
4415 void *v;
4416 register_t *retval;
4417 {
4418 struct netbsd32_futimes_args /* {
4419 syscallarg(int) fd;
4420 syscallarg(const netbsd32_timevalp_t) tptr;
4421 } */ *uap = v;
4422 int error;
4423 struct file *fp;
4424
4425 /* getvnode() will use the descriptor for us */
4426 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
4427 return (error);
4428
4429 error = change_utimes32((struct vnode *)fp->f_data,
4430 (struct timeval *)(u_long)SCARG(uap, tptr), p);
4431 FILE_UNUSE(fp, p);
4432 return (error);
4433 }
4434
4435 int
4436 netbsd32_getpgid(p, v, retval)
4437 struct proc *p;
4438 void *v;
4439 register_t *retval;
4440 {
4441 struct netbsd32_getpgid_args /* {
4442 syscallarg(pid_t) pid;
4443 } */ *uap = v;
4444 struct sys_getpgid_args ua;
4445
4446 NETBSD32TO64_UAP(pid);
4447 return (sys_getpgid(p, &ua, retval));
4448 }
4449
4450 int
4451 netbsd32_reboot(p, v, retval)
4452 struct proc *p;
4453 void *v;
4454 register_t *retval;
4455 {
4456 struct netbsd32_reboot_args /* {
4457 syscallarg(int) opt;
4458 syscallarg(netbsd32_charp) bootstr;
4459 } */ *uap = v;
4460 struct sys_reboot_args ua;
4461
4462 NETBSD32TO64_UAP(opt);
4463 NETBSD32TOP_UAP(bootstr, char);
4464 return (sys_reboot(p, &ua, retval));
4465 }
4466
4467 int
4468 netbsd32_poll(p, v, retval)
4469 struct proc *p;
4470 void *v;
4471 register_t *retval;
4472 {
4473 struct netbsd32_poll_args /* {
4474 syscallarg(netbsd32_pollfdp_t) fds;
4475 syscallarg(u_int) nfds;
4476 syscallarg(int) timeout;
4477 } */ *uap = v;
4478 struct sys_poll_args ua;
4479
4480 NETBSD32TOP_UAP(fds, struct pollfd);
4481 NETBSD32TO64_UAP(nfds);
4482 NETBSD32TO64_UAP(timeout);
4483 return (sys_poll(p, &ua, retval));
4484 }
4485
4486 #if defined(SYSVSEM)
4487 /*
4488 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4489 *
4490 * This is BSD. We won't support System V IPC.
4491 * Too much work.
4492 *
4493 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4494 */
4495 int
4496 netbsd32___semctl14(p, v, retval)
4497 struct proc *p;
4498 void *v;
4499 register_t *retval;
4500 {
4501 #if 0
4502 struct netbsd32___semctl_args /* {
4503 syscallarg(int) semid;
4504 syscallarg(int) semnum;
4505 syscallarg(int) cmd;
4506 syscallarg(netbsd32_semunu_t *) arg;
4507 } */ *uap = v;
4508 union netbsd32_semun sem32;
4509 int semid = SCARG(uap, semid);
4510 int semnum = SCARG(uap, semnum);
4511 int cmd = SCARG(uap, cmd);
4512 union netbsd32_semun *arg = (void*)(u_long)SCARG(uap, arg);
4513 union netbsd32_semun real_arg;
4514 struct ucred *cred = p->p_ucred;
4515 int i, rval, eval;
4516 struct netbsd32_semid_ds sbuf;
4517 struct semid_ds *semaptr;
4518
4519 semlock(p);
4520
4521 semid = IPCID_TO_IX(semid);
4522 if (semid < 0 || semid >= seminfo.semmsl)
4523 return(EINVAL);
4524
4525 semaptr = &sema[semid];
4526 if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
4527 semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
4528 return(EINVAL);
4529
4530 eval = 0;
4531 rval = 0;
4532
4533 switch (cmd) {
4534 case IPC_RMID:
4535 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
4536 return(eval);
4537 semaptr->sem_perm.cuid = cred->cr_uid;
4538 semaptr->sem_perm.uid = cred->cr_uid;
4539 semtot -= semaptr->sem_nsems;
4540 for (i = semaptr->_sem_base - sem; i < semtot; i++)
4541 sem[i] = sem[i + semaptr->sem_nsems];
4542 for (i = 0; i < seminfo.semmni; i++) {
4543 if ((sema[i].sem_perm.mode & SEM_ALLOC) &&
4544 sema[i]._sem_base > semaptr->_sem_base)
4545 sema[i]._sem_base -= semaptr->sem_nsems;
4546 }
4547 semaptr->sem_perm.mode = 0;
4548 semundo_clear(semid, -1);
4549 wakeup((caddr_t)semaptr);
4550 break;
4551
4552 case IPC_SET:
4553 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)))
4554 return(eval);
4555 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4556 return(eval);
4557 if ((eval = copyin((caddr_t)(u_long)real_arg.buf, (caddr_t)&sbuf,
4558 sizeof(sbuf))) != 0)
4559 return(eval);
4560 semaptr->sem_perm.uid = sbuf.sem_perm.uid;
4561 semaptr->sem_perm.gid = sbuf.sem_perm.gid;
4562 semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
4563 (sbuf.sem_perm.mode & 0777);
4564 semaptr->sem_ctime = time.tv_sec;
4565 break;
4566
4567 case IPC_STAT:
4568 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4569 return(eval);
4570 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4571 return(eval);
4572 eval = copyout((caddr_t)semaptr, (caddr_t)(u_long)real_arg.buf,
4573 sizeof(struct semid_ds));
4574 break;
4575
4576 case GETNCNT:
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].semncnt;
4582 break;
4583
4584 case GETPID:
4585 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4586 return(eval);
4587 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4588 return(EINVAL);
4589 rval = semaptr->_sem_base[semnum].sempid;
4590 break;
4591
4592 case GETVAL:
4593 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4594 return(eval);
4595 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4596 return(EINVAL);
4597 rval = semaptr->_sem_base[semnum].semval;
4598 break;
4599
4600 case GETALL:
4601 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4602 return(eval);
4603 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4604 return(eval);
4605 for (i = 0; i < semaptr->sem_nsems; i++) {
4606 eval = copyout((caddr_t)&semaptr->_sem_base[i].semval,
4607 &real_arg.array[i], sizeof(real_arg.array[0]));
4608 if (eval != 0)
4609 break;
4610 }
4611 break;
4612
4613 case GETZCNT:
4614 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
4615 return(eval);
4616 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4617 return(EINVAL);
4618 rval = semaptr->_sem_base[semnum].semzcnt;
4619 break;
4620
4621 case SETVAL:
4622 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
4623 return(eval);
4624 if (semnum < 0 || semnum >= semaptr->sem_nsems)
4625 return(EINVAL);
4626 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4627 return(eval);
4628 semaptr->_sem_base[semnum].semval = real_arg.val;
4629 semundo_clear(semid, semnum);
4630 wakeup((caddr_t)semaptr);
4631 break;
4632
4633 case SETALL:
4634 if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
4635 return(eval);
4636 if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
4637 return(eval);
4638 for (i = 0; i < semaptr->sem_nsems; i++) {
4639 eval = copyin(&real_arg.array[i],
4640 (caddr_t)&semaptr->_sem_base[i].semval,
4641 sizeof(real_arg.array[0]));
4642 if (eval != 0)
4643 break;
4644 }
4645 semundo_clear(semid, -1);
4646 wakeup((caddr_t)semaptr);
4647 break;
4648
4649 default:
4650 return(EINVAL);
4651 }
4652
4653 if (eval == 0)
4654 *retval = rval;
4655 return(eval);
4656 #else
4657 return (ENOSYS);
4658 #endif
4659 }
4660
4661 int
4662 netbsd32_semget(p, v, retval)
4663 struct proc *p;
4664 void *v;
4665 register_t *retval;
4666 {
4667 struct netbsd32_semget_args /* {
4668 syscallarg(netbsd32_key_t) key;
4669 syscallarg(int) nsems;
4670 syscallarg(int) semflg;
4671 } */ *uap = v;
4672 struct sys_semget_args ua;
4673
4674 NETBSD32TOX_UAP(key, key_t);
4675 NETBSD32TO64_UAP(nsems);
4676 NETBSD32TO64_UAP(semflg);
4677 return (sys_semget(p, &ua, retval));
4678 }
4679
4680 int
4681 netbsd32_semop(p, v, retval)
4682 struct proc *p;
4683 void *v;
4684 register_t *retval;
4685 {
4686 struct netbsd32_semop_args /* {
4687 syscallarg(int) semid;
4688 syscallarg(netbsd32_sembufp_t) sops;
4689 syscallarg(netbsd32_size_t) nsops;
4690 } */ *uap = v;
4691 struct sys_semop_args ua;
4692
4693 NETBSD32TO64_UAP(semid);
4694 NETBSD32TOP_UAP(sops, struct sembuf);
4695 NETBSD32TOX_UAP(nsops, size_t);
4696 return (sys_semop(p, &ua, retval));
4697 }
4698
4699 int
4700 netbsd32_semconfig(p, v, retval)
4701 struct proc *p;
4702 void *v;
4703 register_t *retval;
4704 {
4705 struct netbsd32_semconfig_args /* {
4706 syscallarg(int) flag;
4707 } */ *uap = v;
4708 struct sys_semconfig_args ua;
4709
4710 NETBSD32TO64_UAP(flag);
4711 return (sys_semconfig(p, &ua, retval));
4712 }
4713 #endif /* SYSVSEM */
4714
4715 #if defined(SYSVMSG)
4716
4717 int
4718 netbsd32___msgctl13(p, v, retval)
4719 struct proc *p;
4720 void *v;
4721 register_t *retval;
4722 {
4723 #if 0
4724 struct netbsd32_msgctl_args /* {
4725 syscallarg(int) msqid;
4726 syscallarg(int) cmd;
4727 syscallarg(netbsd32_msqid_dsp_t) buf;
4728 } */ *uap = v;
4729 struct sys_msgctl_args ua;
4730 struct msqid_ds ds;
4731 struct netbsd32_msqid_ds *ds32p;
4732 int error;
4733
4734 NETBSD32TO64_UAP(msqid);
4735 NETBSD32TO64_UAP(cmd);
4736 ds32p = (struct netbsd32_msqid_ds *)(u_long)SCARG(uap, buf);
4737 if (ds32p) {
4738 SCARG(&ua, buf) = NULL;
4739 netbsd32_to_msqid_ds(ds32p, &ds);
4740 } else
4741 SCARG(&ua, buf) = NULL;
4742 error = sys_msgctl(p, &ua, retval);
4743 if (error)
4744 return (error);
4745
4746 if (ds32p)
4747 netbsd32_from_msqid_ds(&ds, ds32p);
4748 return (0);
4749 #else
4750 return (ENOSYS);
4751 #endif
4752 }
4753
4754 int
4755 netbsd32_msgget(p, v, retval)
4756 struct proc *p;
4757 void *v;
4758 register_t *retval;
4759 {
4760 #if 0
4761 struct netbsd32_msgget_args /* {
4762 syscallarg(netbsd32_key_t) key;
4763 syscallarg(int) msgflg;
4764 } */ *uap = v;
4765 struct sys_msgget_args ua;
4766
4767 NETBSD32TOX_UAP(key, key_t);
4768 NETBSD32TO64_UAP(msgflg);
4769 return (sys_msgget(p, &ua, retval));
4770 #else
4771 return (ENOSYS);
4772 #endif
4773 }
4774
4775 int
4776 netbsd32_msgsnd(p, v, retval)
4777 struct proc *p;
4778 void *v;
4779 register_t *retval;
4780 {
4781 #if 0
4782 struct netbsd32_msgsnd_args /* {
4783 syscallarg(int) msqid;
4784 syscallarg(const netbsd32_voidp) msgp;
4785 syscallarg(netbsd32_size_t) msgsz;
4786 syscallarg(int) msgflg;
4787 } */ *uap = v;
4788 struct sys_msgsnd_args ua;
4789
4790 NETBSD32TO64_UAP(msqid);
4791 NETBSD32TOP_UAP(msgp, void);
4792 NETBSD32TOX_UAP(msgsz, size_t);
4793 NETBSD32TO64_UAP(msgflg);
4794 return (sys_msgsnd(p, &ua, retval));
4795 #else
4796 return (ENOSYS);
4797 #endif
4798 }
4799
4800 int
4801 netbsd32_msgrcv(p, v, retval)
4802 struct proc *p;
4803 void *v;
4804 register_t *retval;
4805 {
4806 #if 0
4807 struct netbsd32_msgrcv_args /* {
4808 syscallarg(int) msqid;
4809 syscallarg(netbsd32_voidp) msgp;
4810 syscallarg(netbsd32_size_t) msgsz;
4811 syscallarg(netbsd32_long) msgtyp;
4812 syscallarg(int) msgflg;
4813 } */ *uap = v;
4814 struct sys_msgrcv_args ua;
4815 ssize_t rt;
4816 int error;
4817
4818 NETBSD32TO64_UAP(msqid);
4819 NETBSD32TOP_UAP(msgp, void);
4820 NETBSD32TOX_UAP(msgsz, size_t);
4821 NETBSD32TOX_UAP(msgtyp, long);
4822 NETBSD32TO64_UAP(msgflg);
4823 error = sys_msgrcv(p, &ua, (register_t *)&rt);
4824 *retval = rt;
4825 return (error);
4826 #else
4827 return (ENOSYS);
4828 #endif
4829 }
4830 #endif /* SYSVMSG */
4831
4832 #if defined(SYSVSHM)
4833
4834 int
4835 netbsd32_shmat(p, v, retval)
4836 struct proc *p;
4837 void *v;
4838 register_t *retval;
4839 {
4840 #if 0
4841 struct netbsd32_shmat_args /* {
4842 syscallarg(int) shmid;
4843 syscallarg(const netbsd32_voidp) shmaddr;
4844 syscallarg(int) shmflg;
4845 } */ *uap = v;
4846 struct sys_shmat_args ua;
4847 void *rt;
4848 int error;
4849
4850 NETBSD32TO64_UAP(shmid);
4851 NETBSD32TOP_UAP(shmaddr, void);
4852 NETBSD32TO64_UAP(shmflg);
4853 error = sys_shmat(p, &ua, (register_t *)&rt);
4854 *retval = rt;
4855 return (error);
4856 #else
4857 return (ENOSYS);
4858 #endif
4859 }
4860
4861 int
4862 netbsd32___shmctl13(p, v, retval)
4863 struct proc *p;
4864 void *v;
4865 register_t *retval;
4866 {
4867 #if 0
4868 struct netbsd32_shmctl_args /* {
4869 syscallarg(int) shmid;
4870 syscallarg(int) cmd;
4871 syscallarg(netbsd32_shmid_dsp_t) buf;
4872 } */ *uap = v;
4873 struct sys_shmctl_args ua;
4874 struct shmid_ds ds;
4875 struct netbsd32_shmid_ds *ds32p;
4876 int error;
4877
4878 NETBSD32TO64_UAP(shmid);
4879 NETBSD32TO64_UAP(cmd);
4880 ds32p = (struct netbsd32_shmid_ds *)(u_long)SCARG(uap, buf);
4881 if (ds32p) {
4882 SCARG(&ua, buf) = NULL;
4883 netbsd32_to_shmid_ds(ds32p, &ds);
4884 } else
4885 SCARG(&ua, buf) = NULL;
4886 error = sys_shmctl(p, &ua, retval);
4887 if (error)
4888 return (error);
4889
4890 if (ds32p)
4891 netbsd32_from_shmid_ds(&ds, ds32p);
4892 return (0);
4893 #else
4894 return (ENOSYS);
4895 #endif
4896 }
4897
4898 int
4899 netbsd32_shmdt(p, v, retval)
4900 struct proc *p;
4901 void *v;
4902 register_t *retval;
4903 {
4904 #if 0
4905 struct netbsd32_shmdt_args /* {
4906 syscallarg(const netbsd32_voidp) shmaddr;
4907 } */ *uap = v;
4908 struct sys_shmdt_args ua;
4909
4910 NETBSD32TOP_UAP(shmaddr, const char);
4911 return (sys_shmdt(p, &ua, retval));
4912 #else
4913 return (ENOSYS);
4914 #endif
4915 }
4916
4917 int
4918 netbsd32_shmget(p, v, retval)
4919 struct proc *p;
4920 void *v;
4921 register_t *retval;
4922 {
4923 #if 0
4924 struct netbsd32_shmget_args /* {
4925 syscallarg(netbsd32_key_t) key;
4926 syscallarg(netbsd32_size_t) size;
4927 syscallarg(int) shmflg;
4928 } */ *uap = v;
4929 struct sys_shmget_args ua;
4930
4931 NETBSD32TOX_UAP(key, key_t)
4932 NETBSD32TOX_UAP(size, size_t)
4933 NETBSD32TO64_UAP(shmflg);
4934 return (sys_shmget(p, &ua, retval));
4935 #else
4936 return (ENOSYS);
4937 #endif
4938 }
4939 #endif /* SYSVSHM */
4940
4941 int
4942 netbsd32_clock_gettime(p, v, retval)
4943 struct proc *p;
4944 void *v;
4945 register_t *retval;
4946 {
4947 struct netbsd32_clock_gettime_args /* {
4948 syscallarg(netbsd32_clockid_t) clock_id;
4949 syscallarg(netbsd32_timespecp_t) tp;
4950 } */ *uap = v;
4951 clockid_t clock_id;
4952 struct timeval atv;
4953 struct timespec ats;
4954 struct netbsd32_timespec ts32;
4955
4956 clock_id = SCARG(uap, clock_id);
4957 if (clock_id != CLOCK_REALTIME)
4958 return (EINVAL);
4959
4960 microtime(&atv);
4961 TIMEVAL_TO_TIMESPEC(&atv,&ats);
4962 netbsd32_from_timespec(&ats, &ts32);
4963
4964 return copyout(&ts32, (caddr_t)(u_long)SCARG(uap, tp), sizeof(ts32));
4965 }
4966
4967 int
4968 netbsd32_clock_settime(p, v, retval)
4969 struct proc *p;
4970 void *v;
4971 register_t *retval;
4972 {
4973 struct netbsd32_clock_settime_args /* {
4974 syscallarg(netbsd32_clockid_t) clock_id;
4975 syscallarg(const netbsd32_timespecp_t) tp;
4976 } */ *uap = v;
4977 struct netbsd32_timespec ts32;
4978 clockid_t clock_id;
4979 struct timeval atv;
4980 struct timespec ats;
4981 int error;
4982
4983 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
4984 return (error);
4985
4986 clock_id = SCARG(uap, clock_id);
4987 if (clock_id != CLOCK_REALTIME)
4988 return (EINVAL);
4989
4990 if ((error = copyin((caddr_t)(u_long)SCARG(uap, tp), &ts32, sizeof(ts32))) != 0)
4991 return (error);
4992
4993 netbsd32_to_timespec(&ts32, &ats);
4994 TIMESPEC_TO_TIMEVAL(&atv,&ats);
4995 if ((error = settime(&atv)))
4996 return (error);
4997
4998 return 0;
4999 }
5000
5001 int
5002 netbsd32_clock_getres(p, v, retval)
5003 struct proc *p;
5004 void *v;
5005 register_t *retval;
5006 {
5007 struct netbsd32_clock_getres_args /* {
5008 syscallarg(netbsd32_clockid_t) clock_id;
5009 syscallarg(netbsd32_timespecp_t) tp;
5010 } */ *uap = v;
5011 struct netbsd32_timespec ts32;
5012 clockid_t clock_id;
5013 struct timespec ts;
5014 int error = 0;
5015
5016 clock_id = SCARG(uap, clock_id);
5017 if (clock_id != CLOCK_REALTIME)
5018 return (EINVAL);
5019
5020 if (SCARG(uap, tp)) {
5021 ts.tv_sec = 0;
5022 ts.tv_nsec = 1000000000 / hz;
5023
5024 netbsd32_from_timespec(&ts, &ts32);
5025 error = copyout(&ts, (caddr_t)(u_long)SCARG(uap, tp), sizeof(ts));
5026 }
5027
5028 return error;
5029 }
5030
5031 int
5032 netbsd32_nanosleep(p, v, retval)
5033 struct proc *p;
5034 void *v;
5035 register_t *retval;
5036 {
5037 struct netbsd32_nanosleep_args /* {
5038 syscallarg(const netbsd32_timespecp_t) rqtp;
5039 syscallarg(netbsd32_timespecp_t) rmtp;
5040 } */ *uap = v;
5041 static int nanowait;
5042 struct netbsd32_timespec ts32;
5043 struct timespec rqt;
5044 struct timespec rmt;
5045 struct timeval atv, utv;
5046 int error, s, timo;
5047
5048 error = copyin((caddr_t)(u_long)SCARG(uap, rqtp), (caddr_t)&ts32,
5049 sizeof(ts32));
5050 if (error)
5051 return (error);
5052
5053 netbsd32_to_timespec(&ts32, &rqt);
5054 TIMESPEC_TO_TIMEVAL(&atv,&rqt)
5055 if (itimerfix(&atv))
5056 return (EINVAL);
5057
5058 s = splclock();
5059 timeradd(&atv,&time,&atv);
5060 timo = hzto(&atv);
5061 /*
5062 * Avoid inadvertantly sleeping forever
5063 */
5064 if (timo == 0)
5065 timo = 1;
5066 splx(s);
5067
5068 error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo);
5069 if (error == ERESTART)
5070 error = EINTR;
5071 if (error == EWOULDBLOCK)
5072 error = 0;
5073
5074 if (SCARG(uap, rmtp)) {
5075 int error;
5076
5077 s = splclock();
5078 utv = time;
5079 splx(s);
5080
5081 timersub(&atv, &utv, &utv);
5082 if (utv.tv_sec < 0)
5083 timerclear(&utv);
5084
5085 TIMEVAL_TO_TIMESPEC(&utv,&rmt);
5086 netbsd32_from_timespec(&rmt, &ts32);
5087 error = copyout((caddr_t)&ts32, (caddr_t)(u_long)SCARG(uap,rmtp),
5088 sizeof(ts32));
5089 if (error)
5090 return (error);
5091 }
5092
5093 return error;
5094 }
5095
5096 int
5097 netbsd32_fdatasync(p, v, retval)
5098 struct proc *p;
5099 void *v;
5100 register_t *retval;
5101 {
5102 struct netbsd32_fdatasync_args /* {
5103 syscallarg(int) fd;
5104 } */ *uap = v;
5105 struct sys_fdatasync_args ua;
5106
5107 NETBSD32TO64_UAP(fd);
5108
5109 return (sys_fdatasync(p, &ua, retval));
5110 }
5111
5112 int
5113 netbsd32___posix_rename(p, v, retval)
5114 struct proc *p;
5115 void *v;
5116 register_t *retval;
5117 {
5118 struct netbsd32___posix_rename_args /* {
5119 syscallarg(const netbsd32_charp) from;
5120 syscallarg(const netbsd32_charp) to;
5121 } */ *uap = v;
5122 struct sys___posix_rename_args ua;
5123
5124 NETBSD32TOP_UAP(from, const char);
5125 NETBSD32TOP_UAP(to, const char);
5126
5127 return (sys___posix_rename(p, &ua, retval));
5128 }
5129
5130 int
5131 netbsd32_swapctl(p, v, retval)
5132 struct proc *p;
5133 void *v;
5134 register_t *retval;
5135 {
5136 struct netbsd32_swapctl_args /* {
5137 syscallarg(int) cmd;
5138 syscallarg(const netbsd32_voidp) arg;
5139 syscallarg(int) misc;
5140 } */ *uap = v;
5141 struct sys_swapctl_args ua;
5142
5143 NETBSD32TO64_UAP(cmd);
5144 NETBSD32TOP_UAP(arg, const void);
5145 NETBSD32TO64_UAP(misc);
5146 return (sys_swapctl(p, &ua, retval));
5147 }
5148
5149 int
5150 netbsd32_getdents(p, v, retval)
5151 struct proc *p;
5152 void *v;
5153 register_t *retval;
5154 {
5155 struct netbsd32_getdents_args /* {
5156 syscallarg(int) fd;
5157 syscallarg(netbsd32_charp) buf;
5158 syscallarg(netbsd32_size_t) count;
5159 } */ *uap = v;
5160 struct file *fp;
5161 int error, done;
5162
5163 /* getvnode() will use the descriptor for us */
5164 if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
5165 return (error);
5166 if ((fp->f_flag & FREAD) == 0) {
5167 error = EBADF;
5168 goto out;
5169 }
5170 error = vn_readdir(fp, (caddr_t)(u_long)SCARG(uap, buf), UIO_USERSPACE,
5171 SCARG(uap, count), &done, p, 0, 0);
5172 *retval = done;
5173 out:
5174 FILE_UNUSE(fp, p);
5175 return (error);
5176 }
5177
5178
5179 int
5180 netbsd32_minherit(p, v, retval)
5181 struct proc *p;
5182 void *v;
5183 register_t *retval;
5184 {
5185 struct netbsd32_minherit_args /* {
5186 syscallarg(netbsd32_voidp) addr;
5187 syscallarg(netbsd32_size_t) len;
5188 syscallarg(int) inherit;
5189 } */ *uap = v;
5190 struct sys_minherit_args ua;
5191
5192 NETBSD32TOP_UAP(addr, void);
5193 NETBSD32TOX_UAP(len, size_t);
5194 NETBSD32TO64_UAP(inherit);
5195 return (sys_minherit(p, &ua, retval));
5196 }
5197
5198 int
5199 netbsd32_lchmod(p, v, retval)
5200 struct proc *p;
5201 void *v;
5202 register_t *retval;
5203 {
5204 struct netbsd32_lchmod_args /* {
5205 syscallarg(const netbsd32_charp) path;
5206 syscallarg(mode_t) mode;
5207 } */ *uap = v;
5208 struct sys_lchmod_args ua;
5209
5210 NETBSD32TOP_UAP(path, const char);
5211 NETBSD32TO64_UAP(mode);
5212 return (sys_lchmod(p, &ua, retval));
5213 }
5214
5215 int
5216 netbsd32_lchown(p, v, retval)
5217 struct proc *p;
5218 void *v;
5219 register_t *retval;
5220 {
5221 struct netbsd32_lchown_args /* {
5222 syscallarg(const netbsd32_charp) path;
5223 syscallarg(uid_t) uid;
5224 syscallarg(gid_t) gid;
5225 } */ *uap = v;
5226 struct sys_lchown_args ua;
5227
5228 NETBSD32TOP_UAP(path, const char);
5229 NETBSD32TO64_UAP(uid);
5230 NETBSD32TO64_UAP(gid);
5231 return (sys_lchown(p, &ua, retval));
5232 }
5233
5234 int
5235 netbsd32_lutimes(p, v, retval)
5236 struct proc *p;
5237 void *v;
5238 register_t *retval;
5239 {
5240 struct netbsd32_lutimes_args /* {
5241 syscallarg(const netbsd32_charp) path;
5242 syscallarg(const netbsd32_timevalp_t) tptr;
5243 } */ *uap = v;
5244 int error;
5245 struct nameidata nd;
5246
5247 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, (caddr_t)(u_long)SCARG(uap, path), p);
5248 if ((error = namei(&nd)) != 0)
5249 return (error);
5250
5251 error = change_utimes32(nd.ni_vp, (struct timeval *)(u_long)SCARG(uap, tptr), p);
5252
5253 vrele(nd.ni_vp);
5254 return (error);
5255 }
5256
5257
5258 int
5259 netbsd32___msync13(p, v, retval)
5260 struct proc *p;
5261 void *v;
5262 register_t *retval;
5263 {
5264 struct netbsd32___msync13_args /* {
5265 syscallarg(netbsd32_voidp) addr;
5266 syscallarg(netbsd32_size_t) len;
5267 syscallarg(int) flags;
5268 } */ *uap = v;
5269 struct sys___msync13_args ua;
5270
5271 NETBSD32TOP_UAP(addr, void);
5272 NETBSD32TOX_UAP(len, size_t);
5273 NETBSD32TO64_UAP(flags);
5274 return (sys___msync13(p, &ua, retval));
5275 }
5276
5277 int
5278 netbsd32___stat13(p, v, retval)
5279 struct proc *p;
5280 void *v;
5281 register_t *retval;
5282 {
5283 struct netbsd32___stat13_args /* {
5284 syscallarg(const netbsd32_charp) path;
5285 syscallarg(netbsd32_statp_t) ub;
5286 } */ *uap = v;
5287 struct netbsd32_stat sb32;
5288 struct stat sb;
5289 int error;
5290 struct nameidata nd;
5291 caddr_t sg;
5292 const char *path;
5293
5294 path = (char *)(u_long)SCARG(uap, path);
5295 sg = stackgap_init(p->p_emul);
5296 CHECK_ALT_EXIST(p, &sg, path);
5297
5298 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, path, p);
5299 if ((error = namei(&nd)) != 0)
5300 return (error);
5301 error = vn_stat(nd.ni_vp, &sb, p);
5302 vput(nd.ni_vp);
5303 if (error)
5304 return (error);
5305 netbsd32_from___stat13(&sb, &sb32);
5306 error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, ub), sizeof(sb32));
5307 return (error);
5308 }
5309
5310 int
5311 netbsd32___fstat13(p, v, retval)
5312 struct proc *p;
5313 void *v;
5314 register_t *retval;
5315 {
5316 struct netbsd32___fstat13_args /* {
5317 syscallarg(int) fd;
5318 syscallarg(netbsd32_statp_t) sb;
5319 } */ *uap = v;
5320 int fd = SCARG(uap, fd);
5321 struct filedesc *fdp = p->p_fd;
5322 struct file *fp;
5323 struct netbsd32_stat sb32;
5324 struct stat ub;
5325 int error = 0;
5326
5327 if ((u_int)fd >= fdp->fd_nfiles ||
5328 (fp = fdp->fd_ofiles[fd]) == NULL)
5329 return (EBADF);
5330 switch (fp->f_type) {
5331
5332 case DTYPE_VNODE:
5333 error = vn_stat((struct vnode *)fp->f_data, &ub, p);
5334 break;
5335
5336 case DTYPE_SOCKET:
5337 error = soo_stat((struct socket *)fp->f_data, &ub);
5338 break;
5339
5340 default:
5341 panic("fstat");
5342 /*NOTREACHED*/
5343 }
5344 if (error == 0) {
5345 netbsd32_from___stat13(&ub, &sb32);
5346 error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, sb), sizeof(sb32));
5347 }
5348 return (error);
5349 }
5350
5351 int
5352 netbsd32___lstat13(p, v, retval)
5353 struct proc *p;
5354 void *v;
5355 register_t *retval;
5356 {
5357 struct netbsd32___lstat13_args /* {
5358 syscallarg(const netbsd32_charp) path;
5359 syscallarg(netbsd32_statp_t) ub;
5360 } */ *uap = v;
5361 struct netbsd32_stat sb32;
5362 struct stat sb;
5363 int error;
5364 struct nameidata nd;
5365 caddr_t sg;
5366 const char *path;
5367
5368 path = (char *)(u_long)SCARG(uap, path);
5369 sg = stackgap_init(p->p_emul);
5370 CHECK_ALT_EXIST(p, &sg, path);
5371
5372 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, path, p);
5373 if ((error = namei(&nd)) != 0)
5374 return (error);
5375 error = vn_stat(nd.ni_vp, &sb, p);
5376 vput(nd.ni_vp);
5377 if (error)
5378 return (error);
5379 netbsd32_from___stat13(&sb, &sb32);
5380 error = copyout(&sb32, (caddr_t)(u_long)SCARG(uap, ub), sizeof(sb32));
5381 return (error);
5382 }
5383
5384 int
5385 netbsd32___sigaltstack14(p, v, retval)
5386 struct proc *p;
5387 void *v;
5388 register_t *retval;
5389 {
5390 struct netbsd32___sigaltstack14_args /* {
5391 syscallarg(const netbsd32_sigaltstackp_t) nss;
5392 syscallarg(netbsd32_sigaltstackp_t) oss;
5393 } */ *uap = v;
5394 struct netbsd32_sigaltstack s32;
5395 struct sigaltstack nss, oss;
5396 int error;
5397
5398 if (SCARG(uap, nss)) {
5399 error = copyin((caddr_t)(u_long)SCARG(uap, nss), &s32, sizeof(s32));
5400 if (error)
5401 return (error);
5402 nss.ss_sp = (void *)(u_long)s32.ss_sp;
5403 nss.ss_size = (size_t)s32.ss_size;
5404 nss.ss_flags = s32.ss_flags;
5405 }
5406 error = sigaltstack1(p,
5407 SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0);
5408 if (error)
5409 return (error);
5410 if (SCARG(uap, oss)) {
5411 s32.ss_sp = (netbsd32_voidp)(u_long)oss.ss_sp;
5412 s32.ss_size = (netbsd32_size_t)oss.ss_size;
5413 s32.ss_flags = oss.ss_flags;
5414 error = copyout(&s32, (caddr_t)(u_long)SCARG(uap, oss), sizeof(s32));
5415 if (error)
5416 return (error);
5417 }
5418 return (0);
5419 }
5420
5421 int
5422 netbsd32___posix_chown(p, v, retval)
5423 struct proc *p;
5424 void *v;
5425 register_t *retval;
5426 {
5427 struct netbsd32___posix_chown_args /* {
5428 syscallarg(const netbsd32_charp) path;
5429 syscallarg(uid_t) uid;
5430 syscallarg(gid_t) gid;
5431 } */ *uap = v;
5432 struct sys___posix_chown_args ua;
5433
5434 NETBSD32TOP_UAP(path, const char);
5435 NETBSD32TO64_UAP(uid);
5436 NETBSD32TO64_UAP(gid);
5437 return (sys___posix_chown(p, &ua, retval));
5438 }
5439
5440 int
5441 netbsd32___posix_fchown(p, v, retval)
5442 struct proc *p;
5443 void *v;
5444 register_t *retval;
5445 {
5446 struct netbsd32___posix_fchown_args /* {
5447 syscallarg(int) fd;
5448 syscallarg(uid_t) uid;
5449 syscallarg(gid_t) gid;
5450 } */ *uap = v;
5451 struct sys___posix_fchown_args ua;
5452
5453 NETBSD32TO64_UAP(fd);
5454 NETBSD32TO64_UAP(uid);
5455 NETBSD32TO64_UAP(gid);
5456 return (sys___posix_fchown(p, &ua, retval));
5457 }
5458
5459 int
5460 netbsd32___posix_lchown(p, v, retval)
5461 struct proc *p;
5462 void *v;
5463 register_t *retval;
5464 {
5465 struct netbsd32___posix_lchown_args /* {
5466 syscallarg(const netbsd32_charp) path;
5467 syscallarg(uid_t) uid;
5468 syscallarg(gid_t) gid;
5469 } */ *uap = v;
5470 struct sys___posix_lchown_args ua;
5471
5472 NETBSD32TOP_UAP(path, const char);
5473 NETBSD32TO64_UAP(uid);
5474 NETBSD32TO64_UAP(gid);
5475 return (sys___posix_lchown(p, &ua, retval));
5476 }
5477
5478 int
5479 netbsd32_getsid(p, v, retval)
5480 struct proc *p;
5481 void *v;
5482 register_t *retval;
5483 {
5484 struct netbsd32_getsid_args /* {
5485 syscallarg(pid_t) pid;
5486 } */ *uap = v;
5487 struct sys_getsid_args ua;
5488
5489 NETBSD32TO64_UAP(pid);
5490 return (sys_getsid(p, &ua, retval));
5491 }
5492
5493 #ifdef KTRACE
5494 int
5495 netbsd32_fktrace(p, v, retval)
5496 struct proc *p;
5497 void *v;
5498 register_t *retval;
5499 {
5500 struct netbsd32_fktrace_args /* {
5501 syscallarg(const int) fd;
5502 syscallarg(int) ops;
5503 syscallarg(int) facs;
5504 syscallarg(int) pid;
5505 } */ *uap = v;
5506 #if 0
5507 struct sys_fktrace_args ua;
5508 #else
5509 /* XXXX */
5510 struct sys_fktrace_noconst_args {
5511 syscallarg(int) fd;
5512 syscallarg(int) ops;
5513 syscallarg(int) facs;
5514 syscallarg(int) pid;
5515 } ua;
5516 #endif
5517
5518 NETBSD32TOX_UAP(fd, int);
5519 NETBSD32TO64_UAP(ops);
5520 NETBSD32TO64_UAP(facs);
5521 NETBSD32TO64_UAP(pid);
5522 return (sys_fktrace(p, &ua, retval));
5523 }
5524 #endif /* KTRACE */
5525
5526 int
5527 netbsd32_preadv(p, v, retval)
5528 struct proc *p;
5529 void *v;
5530 register_t *retval;
5531 {
5532 struct netbsd32_preadv_args /* {
5533 syscallarg(int) fd;
5534 syscallarg(const netbsd32_iovecp_t) iovp;
5535 syscallarg(int) iovcnt;
5536 syscallarg(int) pad;
5537 syscallarg(off_t) offset;
5538 } */ *uap = v;
5539 struct filedesc *fdp = p->p_fd;
5540 struct file *fp;
5541 struct vnode *vp;
5542 off_t offset;
5543 int error, fd = SCARG(uap, fd);
5544
5545 if ((u_int)fd >= fdp->fd_nfiles ||
5546 (fp = fdp->fd_ofiles[fd]) == NULL ||
5547 (fp->f_flag & FREAD) == 0)
5548 return (EBADF);
5549
5550 vp = (struct vnode *)fp->f_data;
5551 if (fp->f_type != DTYPE_VNODE
5552 || vp->v_type == VFIFO)
5553 return (ESPIPE);
5554
5555 offset = SCARG(uap, offset);
5556
5557 /*
5558 * XXX This works because no file systems actually
5559 * XXX take any action on the seek operation.
5560 */
5561 if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
5562 return (error);
5563
5564 return (dofilereadv32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp), SCARG(uap, iovcnt),
5565 &offset, 0, retval));
5566 }
5567
5568 int
5569 netbsd32_pwritev(p, v, retval)
5570 struct proc *p;
5571 void *v;
5572 register_t *retval;
5573 {
5574 struct netbsd32_pwritev_args /* {
5575 syscallarg(int) fd;
5576 syscallarg(const netbsd32_iovecp_t) iovp;
5577 syscallarg(int) iovcnt;
5578 syscallarg(int) pad;
5579 syscallarg(off_t) offset;
5580 } */ *uap = v;
5581 struct filedesc *fdp = p->p_fd;
5582 struct file *fp;
5583 struct vnode *vp;
5584 off_t offset;
5585 int error, fd = SCARG(uap, fd);
5586
5587 if ((u_int)fd >= fdp->fd_nfiles ||
5588 (fp = fdp->fd_ofiles[fd]) == NULL ||
5589 (fp->f_flag & FWRITE) == 0)
5590 return (EBADF);
5591
5592 vp = (struct vnode *)fp->f_data;
5593 if (fp->f_type != DTYPE_VNODE
5594 || vp->v_type == VFIFO)
5595 return (ESPIPE);
5596
5597 offset = SCARG(uap, offset);
5598
5599 /*
5600 * XXX This works because no file systems actually
5601 * XXX take any action on the seek operation.
5602 */
5603 if ((error = VOP_SEEK(vp, fp->f_offset, offset, fp->f_cred)) != 0)
5604 return (error);
5605
5606 return (dofilewritev32(p, fd, fp, (struct netbsd32_iovec *)(u_long)SCARG(uap, iovp), SCARG(uap, iovcnt),
5607 &offset, 0, retval));
5608 }
5609
5610 /* ARGSUSED */
5611 int
5612 netbsd32___sigaction14(p, v, retval)
5613 struct proc *p;
5614 void *v;
5615 register_t *retval;
5616 {
5617 struct netbsd32___sigaction14_args /* {
5618 syscallarg(int) signum;
5619 syscallarg(const struct sigaction *) nsa;
5620 syscallarg(struct sigaction *) osa;
5621 } */ *uap = v;
5622 struct netbsd32_sigaction sa32;
5623 struct sigaction nsa, osa;
5624 int error;
5625
5626 if (SCARG(uap, nsa)) {
5627 error = copyin((caddr_t)(u_long)SCARG(uap, nsa),
5628 &sa32, sizeof(sa32));
5629 if (error)
5630 return (error);
5631 nsa.sa_handler = (void *)(u_long)sa32.sa_handler;
5632 nsa.sa_mask = sa32.sa_mask;
5633 nsa.sa_flags = sa32.sa_flags;
5634 }
5635 error = sigaction1(p, SCARG(uap, signum),
5636 SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0);
5637 if (error)
5638 return (error);
5639 if (SCARG(uap, osa)) {
5640 sa32.sa_handler = (netbsd32_voidp)(u_long)osa.sa_handler;
5641 sa32.sa_mask = osa.sa_mask;
5642 sa32.sa_flags = osa.sa_flags;
5643 error = copyout(&sa32, (caddr_t)(u_long)SCARG(uap, osa), sizeof(sa32));
5644 if (error)
5645 return (error);
5646 }
5647 return (0);
5648 }
5649
5650 int netbsd32___sigpending14(p, v, retval)
5651 struct proc *p;
5652 void *v;
5653 register_t *retval;
5654 {
5655 struct netbsd32___sigpending14_args /* {
5656 syscallarg(sigset_t *) set;
5657 } */ *uap = v;
5658 struct sys___sigpending14_args ua;
5659
5660 NETBSD32TOP_UAP(set, sigset_t);
5661 return (sys___sigpending14(p, &ua, retval));
5662 }
5663
5664 int netbsd32___sigprocmask14(p, v, retval)
5665 struct proc *p;
5666 void *v;
5667 register_t *retval;
5668 {
5669 struct netbsd32___sigprocmask14_args /* {
5670 syscallarg(int) how;
5671 syscallarg(const sigset_t *) set;
5672 syscallarg(sigset_t *) oset;
5673 } */ *uap = v;
5674 struct sys___sigprocmask14_args ua;
5675
5676 NETBSD32TO64_UAP(how);
5677 NETBSD32TOP_UAP(set, sigset_t);
5678 NETBSD32TOP_UAP(oset, sigset_t);
5679 return (sys___sigprocmask14(p, &ua, retval));
5680 }
5681
5682 int netbsd32___sigsuspend14(p, v, retval)
5683 struct proc *p;
5684 void *v;
5685 register_t *retval;
5686 {
5687 struct netbsd32___sigsuspend14_args /* {
5688 syscallarg(const sigset_t *) set;
5689 } */ *uap = v;
5690 struct sys___sigsuspend14_args ua;
5691
5692 NETBSD32TOP_UAP(set, sigset_t);
5693 return (sys___sigsuspend14(p, &ua, retval));
5694 };
5695
5696
5697 /*
5698 * Find pathname of process's current directory.
5699 *
5700 * Use vfs vnode-to-name reverse cache; if that fails, fall back
5701 * to reading directory contents.
5702 */
5703 int
5704 getcwd_common __P((struct vnode *, struct vnode *,
5705 char **, char *, int, int, struct proc *));
5706
5707 int netbsd32___getcwd(p, v, retval)
5708 struct proc *p;
5709 void *v;
5710 register_t *retval;
5711 {
5712 struct netbsd32___getcwd_args /* {
5713 syscallarg(char *) bufp;
5714 syscallarg(size_t) length;
5715 } */ *uap = v;
5716
5717 int error;
5718 char *path;
5719 char *bp, *bend;
5720 int len = (int)SCARG(uap, length);
5721 int lenused;
5722
5723 if (len > MAXPATHLEN*4)
5724 len = MAXPATHLEN*4;
5725 else if (len < 2)
5726 return ERANGE;
5727
5728 path = (char *)malloc(len, M_TEMP, M_WAITOK);
5729 if (!path)
5730 return ENOMEM;
5731
5732 bp = &path[len];
5733 bend = bp;
5734 *(--bp) = '\0';
5735
5736 /*
5737 * 5th argument here is "max number of vnodes to traverse".
5738 * Since each entry takes up at least 2 bytes in the output buffer,
5739 * limit it to N/2 vnodes for an N byte buffer.
5740 */
5741 #define GETCWD_CHECK_ACCESS 0x0001
5742 error = getcwd_common (p->p_cwdi->cwdi_cdir, NULL, &bp, path, len/2,
5743 GETCWD_CHECK_ACCESS, p);
5744
5745 if (error)
5746 goto out;
5747 lenused = bend - bp;
5748 *retval = lenused;
5749 /* put the result into user buffer */
5750 error = copyout(bp, (caddr_t)(u_long)SCARG(uap, bufp), lenused);
5751
5752 out:
5753 free(path, M_TEMP);
5754 return error;
5755 }
5756
5757 int netbsd32_fchroot(p, v, retval)
5758 struct proc *p;
5759 void *v;
5760 register_t *retval;
5761 {
5762 struct netbsd32_fchroot_args /* {
5763 syscallarg(int) fd;
5764 } */ *uap = v;
5765 struct sys_fchroot_args ua;
5766
5767 NETBSD32TO64_UAP(fd);
5768 return (sys_fchroot(p, &ua, retval));
5769 }
5770
5771 /*
5772 * Open a file given a file handle.
5773 *
5774 * Check permissions, allocate an open file structure,
5775 * and call the device open routine if any.
5776 */
5777 int
5778 netbsd32_fhopen(p, v, retval)
5779 struct proc *p;
5780 void *v;
5781 register_t *retval;
5782 {
5783 struct netbsd32_fhopen_args /* {
5784 syscallarg(const fhandle_t *) fhp;
5785 syscallarg(int) flags;
5786 } */ *uap = v;
5787 struct sys_fhopen_args ua;
5788
5789 NETBSD32TOP_UAP(fhp, fhandle_t);
5790 NETBSD32TO64_UAP(flags);
5791 return (sys_fhopen(p, &ua, retval));
5792 }
5793
5794 int netbsd32_fhstat(p, v, retval)
5795 struct proc *p;
5796 void *v;
5797 register_t *retval;
5798 {
5799 struct netbsd32_fhstat_args /* {
5800 syscallarg(const netbsd32_fhandlep_t) fhp;
5801 syscallarg(struct stat *) sb;
5802 } */ *uap = v;
5803 struct sys_fhstat_args ua;
5804
5805 NETBSD32TOP_UAP(fhp, const fhandle_t);
5806 NETBSD32TOP_UAP(sb, struct stat);
5807 return (sys_fhstat(p, &ua, retval));
5808 }
5809
5810 int netbsd32_fhstatfs(p, v, retval)
5811 struct proc *p;
5812 void *v;
5813 register_t *retval;
5814 {
5815 struct netbsd32_fhstatfs_args /* {
5816 syscallarg(const netbsd32_fhandlep_t) fhp;
5817 syscallarg(struct statfs *) buf;
5818 } */ *uap = v;
5819 struct sys_fhstatfs_args ua;
5820
5821 NETBSD32TOP_UAP(fhp, const fhandle_t);
5822 NETBSD32TOP_UAP(buf, struct statfs);
5823 return (sys_fhstatfs(p, &ua, retval));
5824 }
5825
5826 /* virtual memory syscalls */
5827 int
5828 netbsd32_ovadvise(p, v, retval)
5829 struct proc *p;
5830 void *v;
5831 register_t *retval;
5832 {
5833 struct netbsd32_ovadvise_args /* {
5834 syscallarg(int) anom;
5835 } */ *uap = v;
5836 struct sys_ovadvise_args ua;
5837
5838 NETBSD32TO64_UAP(anom);
5839 return (sys_ovadvise(p, &ua, retval));
5840 }
5841
5842