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