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