29 */ 30 31/* 32 * SVR4 compatibility module. 33 * 34 * SVR4 system calls that are implemented differently in BSD are 35 * handled here. 36 */ 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/dirent.h> 41#include <sys/fcntl.h> 42#include <sys/filedesc.h> 43#include <sys/jail.h> 44#include <sys/kernel.h> 45#include <sys/lock.h> 46#include <sys/malloc.h> 47#include <sys/file.h> /* Must come after sys/malloc.h */ 48#include <sys/mman.h> 49#include <sys/mount.h> 50#include <sys/msg.h> 51#include <sys/mutex.h> 52#include <sys/namei.h> 53#include <sys/proc.h> 54#include <sys/ptrace.h> 55#include <sys/resource.h> 56#include <sys/resourcevar.h> 57#include <sys/sem.h> 58#include <sys/stat.h> 59#include <sys/sx.h> 60#include <sys/sysproto.h> 61#include <sys/time.h> 62#include <sys/times.h> 63#include <sys/uio.h> 64#include <sys/user.h> 65#include <sys/vnode.h> 66#include <sys/wait.h> 67 68#include <compat/svr4/svr4.h> 69#include <compat/svr4/svr4_types.h> 70#include <compat/svr4/svr4_signal.h> 71#include <compat/svr4/svr4_proto.h> 72#include <compat/svr4/svr4_util.h> 73#include <compat/svr4/svr4_sysconfig.h> 74#include <compat/svr4/svr4_dirent.h> 75#include <compat/svr4/svr4_acl.h> 76#include <compat/svr4/svr4_ulimit.h> 77#include <compat/svr4/svr4_statvfs.h> 78#include <compat/svr4/svr4_hrt.h> 79#include <compat/svr4/svr4_mman.h> 80#include <compat/svr4/svr4_wait.h> 81 82#include <machine/vmparam.h> 83#include <vm/vm.h> 84#include <vm/vm_param.h> 85#include <vm/vm_map.h> 86#if defined(__FreeBSD__) 87#include <vm/vm_zone.h> 88#endif 89 90#if defined(NetBSD) 91# if defined(UVM) 92# include <uvm/uvm_extern.h> 93# endif 94#endif 95 96#define BSD_DIRENT(cp) ((struct dirent *)(cp)) 97 98static int svr4_mknod __P((struct thread *, register_t *, char *, 99 svr4_mode_t, svr4_dev_t)); 100 101static __inline clock_t timeval_to_clock_t __P((struct timeval *)); 102static int svr4_setinfo __P((struct proc *, int, svr4_siginfo_t *)); 103 104struct svr4_hrtcntl_args; 105static int svr4_hrtcntl __P((struct thread *, struct svr4_hrtcntl_args *, 106 register_t *)); 107static void bsd_statfs_to_svr4_statvfs __P((const struct statfs *, 108 struct svr4_statvfs *)); 109static void bsd_statfs_to_svr4_statvfs64 __P((const struct statfs *, 110 struct svr4_statvfs64 *)); 111static struct proc *svr4_pfind __P((pid_t pid)); 112 113/* BOGUS noop */ 114#if defined(BOGUS) 115int 116svr4_sys_setitimer(td, uap) 117 register struct thread *td; 118 struct svr4_sys_setitimer_args *uap; 119{ 120 td->td_retval[0] = 0; 121 return 0; 122} 123#endif 124 125int 126svr4_sys_wait(td, uap) 127 struct thread *td; 128 struct svr4_sys_wait_args *uap; 129{ 130 struct wait_args w4; 131 int error, *retval = td->td_retval, st, sig; 132 size_t sz = sizeof(*SCARG(&w4, status)); 133 134 SCARG(&w4, rusage) = NULL; 135 SCARG(&w4, options) = 0; 136 137 if (SCARG(uap, status) == NULL) { 138 caddr_t sg = stackgap_init(); 139 140 SCARG(&w4, status) = stackgap_alloc(&sg, sz); 141 } 142 else 143 SCARG(&w4, status) = SCARG(uap, status); 144 145 SCARG(&w4, pid) = WAIT_ANY; 146 147 if ((error = wait4(td, &w4)) != 0) 148 return error; 149 150 if ((error = copyin(SCARG(&w4, status), &st, sizeof(st))) != 0) 151 return error; 152 153 if (WIFSIGNALED(st)) { 154 sig = WTERMSIG(st); 155 if (sig >= 0 && sig < NSIG) 156 st = (st & ~0177) | SVR4_BSD2SVR4_SIG(sig); 157 } else if (WIFSTOPPED(st)) { 158 sig = WSTOPSIG(st); 159 if (sig >= 0 && sig < NSIG) 160 st = (st & ~0xff00) | (SVR4_BSD2SVR4_SIG(sig) << 8); 161 } 162 163 /* 164 * It looks like wait(2) on svr4/solaris/2.4 returns 165 * the status in retval[1], and the pid on retval[0]. 166 */ 167 retval[1] = st; 168 169 if (SCARG(uap, status)) 170 if ((error = copyout(&st, SCARG(uap, status), sizeof(st))) != 0) 171 return error; 172 173 return 0; 174} 175 176int 177svr4_sys_execv(td, uap) 178 struct thread *td; 179 struct svr4_sys_execv_args *uap; 180{ 181 struct execve_args ap; 182 caddr_t sg; 183 184 sg = stackgap_init(); 185 CHECKALTEXIST(td, &sg, SCARG(uap, path)); 186 187 SCARG(&ap, fname) = SCARG(uap, path); 188 SCARG(&ap, argv) = SCARG(uap, argp); 189 SCARG(&ap, envv) = NULL; 190 191 return execve(td, &ap); 192} 193 194int 195svr4_sys_execve(td, uap) 196 struct thread *td; 197 struct svr4_sys_execve_args *uap; 198{ 199 struct execve_args ap; 200 caddr_t sg; 201 202 sg = stackgap_init(); 203 CHECKALTEXIST(td, &sg, uap->path); 204 205 SCARG(&ap, fname) = SCARG(uap, path); 206 SCARG(&ap, argv) = SCARG(uap, argp); 207 SCARG(&ap, envv) = SCARG(uap, envp); 208 209 return execve(td, &ap); 210} 211 212int 213svr4_sys_time(td, v) 214 struct thread *td; 215 struct svr4_sys_time_args *v; 216{ 217 struct svr4_sys_time_args *uap = v; 218 int error = 0; 219 struct timeval tv; 220 221 microtime(&tv); 222 if (SCARG(uap, t)) 223 error = copyout(&tv.tv_sec, SCARG(uap, t), 224 sizeof(*(SCARG(uap, t)))); 225 td->td_retval[0] = (int) tv.tv_sec; 226 227 return error; 228} 229 230 231/* 232 * Read SVR4-style directory entries. We suck them into kernel space so 233 * that they can be massaged before being copied out to user code. 234 * 235 * This code is ported from the Linux emulator: Changes to the VFS interface 236 * between FreeBSD and NetBSD have made it simpler to port it from there than 237 * to adapt the NetBSD version. 238 */ 239int 240svr4_sys_getdents64(td, uap) 241 struct thread *td; 242 struct svr4_sys_getdents64_args *uap; 243{ 244 register struct dirent *bdp; 245 struct vnode *vp; 246 caddr_t inp, buf; /* BSD-format */ 247 int len, reclen; /* BSD-format */ 248 caddr_t outp; /* SVR4-format */ 249 int resid, svr4reclen=0; /* SVR4-format */ 250 struct file *fp; 251 struct uio auio; 252 struct iovec aiov; 253 struct vattr va; 254 off_t off; 255 struct svr4_dirent64 svr4_dirent; 256 int buflen, error, eofflag, nbytes, justone; 257 u_long *cookies = NULL, *cookiep; 258 int ncookies; 259 260 DPRINTF(("svr4_sys_getdents64(%d, *, %d)\n", 261 td->td_proc->p_pid, SCARG(uap, fd), SCARG(uap, nbytes))); 262 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0) { 263 return (error); 264 } 265 266 if ((fp->f_flag & FREAD) == 0) 267 return (EBADF); 268 269 vp = (struct vnode *) fp->f_data; 270 271 if (vp->v_type != VDIR) 272 return (EINVAL); 273 274 if ((error = VOP_GETATTR(vp, &va, td->td_proc->p_ucred, td))) { 275 return error; 276 } 277 278 nbytes = SCARG(uap, nbytes); 279 if (nbytes == 1) { 280 nbytes = sizeof (struct svr4_dirent64); 281 justone = 1; 282 } 283 else 284 justone = 0; 285 286 off = fp->f_offset; 287#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */ 288 buflen = max(DIRBLKSIZ, nbytes); 289 buflen = min(buflen, MAXBSIZE); 290 buf = malloc(buflen, M_TEMP, M_WAITOK); 291 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 292again: 293 aiov.iov_base = buf; 294 aiov.iov_len = buflen; 295 auio.uio_iov = &aiov; 296 auio.uio_iovcnt = 1; 297 auio.uio_rw = UIO_READ; 298 auio.uio_segflg = UIO_SYSSPACE; 299 auio.uio_td = td; 300 auio.uio_resid = buflen; 301 auio.uio_offset = off; 302 303 if (cookies) { 304 free(cookies, M_TEMP); 305 cookies = NULL; 306 } 307 308 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 309 &ncookies, &cookies); 310 if (error) { 311 goto out; 312 } 313 314 inp = buf; 315 outp = (caddr_t) SCARG(uap, dp); 316 resid = nbytes; 317 if ((len = buflen - auio.uio_resid) <= 0) { 318 goto eof; 319 } 320 321 cookiep = cookies; 322 323 if (cookies) { 324 /* 325 * When using cookies, the vfs has the option of reading from 326 * a different offset than that supplied (UFS truncates the 327 * offset to a block boundary to make sure that it never reads 328 * partway through a directory entry, even if the directory 329 * has been compacted). 330 */ 331 while (len > 0 && ncookies > 0 && *cookiep <= off) { 332 bdp = (struct dirent *) inp; 333 len -= bdp->d_reclen; 334 inp += bdp->d_reclen; 335 cookiep++; 336 ncookies--; 337 } 338 } 339 340 while (len > 0) { 341 if (cookiep && ncookies == 0) 342 break; 343 bdp = (struct dirent *) inp; 344 reclen = bdp->d_reclen; 345 if (reclen & 3) { 346 DPRINTF(("svr4_readdir: reclen=%d\n", reclen)); 347 error = EFAULT; 348 goto out; 349 } 350 351 if (bdp->d_fileno == 0) { 352 inp += reclen; 353 if (cookiep) { 354 off = *cookiep++; 355 ncookies--; 356 } else 357 off += reclen; 358 len -= reclen; 359 continue; 360 } 361 svr4reclen = SVR4_RECLEN(&svr4_dirent, bdp->d_namlen); 362 if (reclen > len || resid < svr4reclen) { 363 outp++; 364 break; 365 } 366 svr4_dirent.d_ino = (long) bdp->d_fileno; 367 if (justone) { 368 /* 369 * old svr4-style readdir usage. 370 */ 371 svr4_dirent.d_off = (svr4_off_t) svr4reclen; 372 svr4_dirent.d_reclen = (u_short) bdp->d_namlen; 373 } else { 374 svr4_dirent.d_off = (svr4_off_t)(off + reclen); 375 svr4_dirent.d_reclen = (u_short) svr4reclen; 376 } 377 strcpy(svr4_dirent.d_name, bdp->d_name); 378 if ((error = copyout((caddr_t)&svr4_dirent, outp, svr4reclen))) 379 goto out; 380 inp += reclen; 381 if (cookiep) { 382 off = *cookiep++; 383 ncookies--; 384 } else 385 off += reclen; 386 outp += svr4reclen; 387 resid -= svr4reclen; 388 len -= reclen; 389 if (justone) 390 break; 391 } 392 393 if (outp == (caddr_t) SCARG(uap, dp)) 394 goto again; 395 fp->f_offset = off; 396 397 if (justone) 398 nbytes = resid + svr4reclen; 399 400eof: 401 td->td_retval[0] = nbytes - resid; 402out: 403 if (cookies) 404 free(cookies, M_TEMP); 405 VOP_UNLOCK(vp, 0, td); 406 free(buf, M_TEMP); 407 return error; 408} 409 410 411int 412svr4_sys_getdents(td, uap) 413 struct thread *td; 414 struct svr4_sys_getdents_args *uap; 415{ 416 struct dirent *bdp; 417 struct vnode *vp; 418 caddr_t inp, buf; /* BSD-format */ 419 int len, reclen; /* BSD-format */ 420 caddr_t outp; /* SVR4-format */ 421 int resid, svr4_reclen; /* SVR4-format */ 422 struct file *fp; 423 struct uio auio; 424 struct iovec aiov; 425 struct svr4_dirent idb; 426 off_t off; /* true file offset */ 427 int buflen, error, eofflag; 428 u_long *cookiebuf = NULL, *cookie; 429 int ncookies = 0, *retval = td->td_retval; 430 431 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0) 432 return (error); 433 434 if ((fp->f_flag & FREAD) == 0) 435 return (EBADF); 436 437 vp = (struct vnode *)fp->f_data; 438 if (vp->v_type != VDIR) 439 return (EINVAL); 440 441 buflen = min(MAXBSIZE, SCARG(uap, nbytes)); 442 buf = malloc(buflen, M_TEMP, M_WAITOK); 443 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 444 off = fp->f_offset; 445again: 446 aiov.iov_base = buf; 447 aiov.iov_len = buflen; 448 auio.uio_iov = &aiov; 449 auio.uio_iovcnt = 1; 450 auio.uio_rw = UIO_READ; 451 auio.uio_segflg = UIO_SYSSPACE; 452 auio.uio_td = td; 453 auio.uio_resid = buflen; 454 auio.uio_offset = off; 455 /* 456 * First we read into the malloc'ed buffer, then 457 * we massage it into user space, one record at a time. 458 */ 459 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, 460 &cookiebuf); 461 if (error) 462 goto out; 463 464 inp = buf; 465 outp = SCARG(uap, buf); 466 resid = SCARG(uap, nbytes); 467 if ((len = buflen - auio.uio_resid) == 0) 468 goto eof; 469 470 for (cookie = cookiebuf; len > 0; len -= reclen) { 471 bdp = (struct dirent *)inp; 472 reclen = bdp->d_reclen; 473 if (reclen & 3) 474 panic("svr4_sys_getdents64: bad reclen"); 475 off = *cookie++; /* each entry points to the next */ 476 if ((off >> 32) != 0) { 477 uprintf("svr4_sys_getdents64: dir offset too large for emulated program"); 478 error = EINVAL; 479 goto out; 480 } 481 if (bdp->d_fileno == 0) { 482 inp += reclen; /* it is a hole; squish it out */ 483 continue; 484 } 485 svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen); 486 if (reclen > len || resid < svr4_reclen) { 487 /* entry too big for buffer, so just stop */ 488 outp++; 489 break; 490 } 491 /* 492 * Massage in place to make a SVR4-shaped dirent (otherwise 493 * we have to worry about touching user memory outside of 494 * the copyout() call). 495 */ 496 idb.d_ino = (svr4_ino_t)bdp->d_fileno; 497 idb.d_off = (svr4_off_t)off; 498 idb.d_reclen = (u_short)svr4_reclen; 499 strcpy(idb.d_name, bdp->d_name); 500 if ((error = copyout((caddr_t)&idb, outp, svr4_reclen))) 501 goto out; 502 /* advance past this real entry */ 503 inp += reclen; 504 /* advance output past SVR4-shaped entry */ 505 outp += svr4_reclen; 506 resid -= svr4_reclen; 507 } 508 509 /* if we squished out the whole block, try again */ 510 if (outp == SCARG(uap, buf)) 511 goto again; 512 fp->f_offset = off; /* update the vnode offset */ 513 514eof: 515 *retval = SCARG(uap, nbytes) - resid; 516out: 517 VOP_UNLOCK(vp, 0, td); 518 if (cookiebuf) 519 free(cookiebuf, M_TEMP); 520 free(buf, M_TEMP); 521 return error; 522} 523 524 525int 526svr4_sys_mmap(td, uap) 527 struct thread *td; 528 struct svr4_sys_mmap_args *uap; 529{ 530 struct mmap_args mm; 531 int *retval; 532 533 retval = td->td_retval; 534#define _MAP_NEW 0x80000000 535 /* 536 * Verify the arguments. 537 */ 538 if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) 539 return EINVAL; /* XXX still needed? */ 540 541 if (SCARG(uap, len) == 0) 542 return EINVAL; 543 544 SCARG(&mm, prot) = SCARG(uap, prot); 545 SCARG(&mm, len) = SCARG(uap, len); 546 SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW; 547 SCARG(&mm, fd) = SCARG(uap, fd); 548 SCARG(&mm, addr) = SCARG(uap, addr); 549 SCARG(&mm, pos) = SCARG(uap, pos); 550 551 return mmap(td, &mm); 552} 553 554int 555svr4_sys_mmap64(td, uap) 556 struct thread *td; 557 struct svr4_sys_mmap64_args *uap; 558{ 559 struct mmap_args mm; 560 void *rp; 561 562#define _MAP_NEW 0x80000000 563 /* 564 * Verify the arguments. 565 */ 566 if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) 567 return EINVAL; /* XXX still needed? */ 568 569 if (SCARG(uap, len) == 0) 570 return EINVAL; 571 572 SCARG(&mm, prot) = SCARG(uap, prot); 573 SCARG(&mm, len) = SCARG(uap, len); 574 SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW; 575 SCARG(&mm, fd) = SCARG(uap, fd); 576 SCARG(&mm, addr) = SCARG(uap, addr); 577 SCARG(&mm, pos) = SCARG(uap, pos); 578
| 29 */ 30 31/* 32 * SVR4 compatibility module. 33 * 34 * SVR4 system calls that are implemented differently in BSD are 35 * handled here. 36 */ 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/dirent.h> 41#include <sys/fcntl.h> 42#include <sys/filedesc.h> 43#include <sys/jail.h> 44#include <sys/kernel.h> 45#include <sys/lock.h> 46#include <sys/malloc.h> 47#include <sys/file.h> /* Must come after sys/malloc.h */ 48#include <sys/mman.h> 49#include <sys/mount.h> 50#include <sys/msg.h> 51#include <sys/mutex.h> 52#include <sys/namei.h> 53#include <sys/proc.h> 54#include <sys/ptrace.h> 55#include <sys/resource.h> 56#include <sys/resourcevar.h> 57#include <sys/sem.h> 58#include <sys/stat.h> 59#include <sys/sx.h> 60#include <sys/sysproto.h> 61#include <sys/time.h> 62#include <sys/times.h> 63#include <sys/uio.h> 64#include <sys/user.h> 65#include <sys/vnode.h> 66#include <sys/wait.h> 67 68#include <compat/svr4/svr4.h> 69#include <compat/svr4/svr4_types.h> 70#include <compat/svr4/svr4_signal.h> 71#include <compat/svr4/svr4_proto.h> 72#include <compat/svr4/svr4_util.h> 73#include <compat/svr4/svr4_sysconfig.h> 74#include <compat/svr4/svr4_dirent.h> 75#include <compat/svr4/svr4_acl.h> 76#include <compat/svr4/svr4_ulimit.h> 77#include <compat/svr4/svr4_statvfs.h> 78#include <compat/svr4/svr4_hrt.h> 79#include <compat/svr4/svr4_mman.h> 80#include <compat/svr4/svr4_wait.h> 81 82#include <machine/vmparam.h> 83#include <vm/vm.h> 84#include <vm/vm_param.h> 85#include <vm/vm_map.h> 86#if defined(__FreeBSD__) 87#include <vm/vm_zone.h> 88#endif 89 90#if defined(NetBSD) 91# if defined(UVM) 92# include <uvm/uvm_extern.h> 93# endif 94#endif 95 96#define BSD_DIRENT(cp) ((struct dirent *)(cp)) 97 98static int svr4_mknod __P((struct thread *, register_t *, char *, 99 svr4_mode_t, svr4_dev_t)); 100 101static __inline clock_t timeval_to_clock_t __P((struct timeval *)); 102static int svr4_setinfo __P((struct proc *, int, svr4_siginfo_t *)); 103 104struct svr4_hrtcntl_args; 105static int svr4_hrtcntl __P((struct thread *, struct svr4_hrtcntl_args *, 106 register_t *)); 107static void bsd_statfs_to_svr4_statvfs __P((const struct statfs *, 108 struct svr4_statvfs *)); 109static void bsd_statfs_to_svr4_statvfs64 __P((const struct statfs *, 110 struct svr4_statvfs64 *)); 111static struct proc *svr4_pfind __P((pid_t pid)); 112 113/* BOGUS noop */ 114#if defined(BOGUS) 115int 116svr4_sys_setitimer(td, uap) 117 register struct thread *td; 118 struct svr4_sys_setitimer_args *uap; 119{ 120 td->td_retval[0] = 0; 121 return 0; 122} 123#endif 124 125int 126svr4_sys_wait(td, uap) 127 struct thread *td; 128 struct svr4_sys_wait_args *uap; 129{ 130 struct wait_args w4; 131 int error, *retval = td->td_retval, st, sig; 132 size_t sz = sizeof(*SCARG(&w4, status)); 133 134 SCARG(&w4, rusage) = NULL; 135 SCARG(&w4, options) = 0; 136 137 if (SCARG(uap, status) == NULL) { 138 caddr_t sg = stackgap_init(); 139 140 SCARG(&w4, status) = stackgap_alloc(&sg, sz); 141 } 142 else 143 SCARG(&w4, status) = SCARG(uap, status); 144 145 SCARG(&w4, pid) = WAIT_ANY; 146 147 if ((error = wait4(td, &w4)) != 0) 148 return error; 149 150 if ((error = copyin(SCARG(&w4, status), &st, sizeof(st))) != 0) 151 return error; 152 153 if (WIFSIGNALED(st)) { 154 sig = WTERMSIG(st); 155 if (sig >= 0 && sig < NSIG) 156 st = (st & ~0177) | SVR4_BSD2SVR4_SIG(sig); 157 } else if (WIFSTOPPED(st)) { 158 sig = WSTOPSIG(st); 159 if (sig >= 0 && sig < NSIG) 160 st = (st & ~0xff00) | (SVR4_BSD2SVR4_SIG(sig) << 8); 161 } 162 163 /* 164 * It looks like wait(2) on svr4/solaris/2.4 returns 165 * the status in retval[1], and the pid on retval[0]. 166 */ 167 retval[1] = st; 168 169 if (SCARG(uap, status)) 170 if ((error = copyout(&st, SCARG(uap, status), sizeof(st))) != 0) 171 return error; 172 173 return 0; 174} 175 176int 177svr4_sys_execv(td, uap) 178 struct thread *td; 179 struct svr4_sys_execv_args *uap; 180{ 181 struct execve_args ap; 182 caddr_t sg; 183 184 sg = stackgap_init(); 185 CHECKALTEXIST(td, &sg, SCARG(uap, path)); 186 187 SCARG(&ap, fname) = SCARG(uap, path); 188 SCARG(&ap, argv) = SCARG(uap, argp); 189 SCARG(&ap, envv) = NULL; 190 191 return execve(td, &ap); 192} 193 194int 195svr4_sys_execve(td, uap) 196 struct thread *td; 197 struct svr4_sys_execve_args *uap; 198{ 199 struct execve_args ap; 200 caddr_t sg; 201 202 sg = stackgap_init(); 203 CHECKALTEXIST(td, &sg, uap->path); 204 205 SCARG(&ap, fname) = SCARG(uap, path); 206 SCARG(&ap, argv) = SCARG(uap, argp); 207 SCARG(&ap, envv) = SCARG(uap, envp); 208 209 return execve(td, &ap); 210} 211 212int 213svr4_sys_time(td, v) 214 struct thread *td; 215 struct svr4_sys_time_args *v; 216{ 217 struct svr4_sys_time_args *uap = v; 218 int error = 0; 219 struct timeval tv; 220 221 microtime(&tv); 222 if (SCARG(uap, t)) 223 error = copyout(&tv.tv_sec, SCARG(uap, t), 224 sizeof(*(SCARG(uap, t)))); 225 td->td_retval[0] = (int) tv.tv_sec; 226 227 return error; 228} 229 230 231/* 232 * Read SVR4-style directory entries. We suck them into kernel space so 233 * that they can be massaged before being copied out to user code. 234 * 235 * This code is ported from the Linux emulator: Changes to the VFS interface 236 * between FreeBSD and NetBSD have made it simpler to port it from there than 237 * to adapt the NetBSD version. 238 */ 239int 240svr4_sys_getdents64(td, uap) 241 struct thread *td; 242 struct svr4_sys_getdents64_args *uap; 243{ 244 register struct dirent *bdp; 245 struct vnode *vp; 246 caddr_t inp, buf; /* BSD-format */ 247 int len, reclen; /* BSD-format */ 248 caddr_t outp; /* SVR4-format */ 249 int resid, svr4reclen=0; /* SVR4-format */ 250 struct file *fp; 251 struct uio auio; 252 struct iovec aiov; 253 struct vattr va; 254 off_t off; 255 struct svr4_dirent64 svr4_dirent; 256 int buflen, error, eofflag, nbytes, justone; 257 u_long *cookies = NULL, *cookiep; 258 int ncookies; 259 260 DPRINTF(("svr4_sys_getdents64(%d, *, %d)\n", 261 td->td_proc->p_pid, SCARG(uap, fd), SCARG(uap, nbytes))); 262 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0) { 263 return (error); 264 } 265 266 if ((fp->f_flag & FREAD) == 0) 267 return (EBADF); 268 269 vp = (struct vnode *) fp->f_data; 270 271 if (vp->v_type != VDIR) 272 return (EINVAL); 273 274 if ((error = VOP_GETATTR(vp, &va, td->td_proc->p_ucred, td))) { 275 return error; 276 } 277 278 nbytes = SCARG(uap, nbytes); 279 if (nbytes == 1) { 280 nbytes = sizeof (struct svr4_dirent64); 281 justone = 1; 282 } 283 else 284 justone = 0; 285 286 off = fp->f_offset; 287#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */ 288 buflen = max(DIRBLKSIZ, nbytes); 289 buflen = min(buflen, MAXBSIZE); 290 buf = malloc(buflen, M_TEMP, M_WAITOK); 291 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 292again: 293 aiov.iov_base = buf; 294 aiov.iov_len = buflen; 295 auio.uio_iov = &aiov; 296 auio.uio_iovcnt = 1; 297 auio.uio_rw = UIO_READ; 298 auio.uio_segflg = UIO_SYSSPACE; 299 auio.uio_td = td; 300 auio.uio_resid = buflen; 301 auio.uio_offset = off; 302 303 if (cookies) { 304 free(cookies, M_TEMP); 305 cookies = NULL; 306 } 307 308 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 309 &ncookies, &cookies); 310 if (error) { 311 goto out; 312 } 313 314 inp = buf; 315 outp = (caddr_t) SCARG(uap, dp); 316 resid = nbytes; 317 if ((len = buflen - auio.uio_resid) <= 0) { 318 goto eof; 319 } 320 321 cookiep = cookies; 322 323 if (cookies) { 324 /* 325 * When using cookies, the vfs has the option of reading from 326 * a different offset than that supplied (UFS truncates the 327 * offset to a block boundary to make sure that it never reads 328 * partway through a directory entry, even if the directory 329 * has been compacted). 330 */ 331 while (len > 0 && ncookies > 0 && *cookiep <= off) { 332 bdp = (struct dirent *) inp; 333 len -= bdp->d_reclen; 334 inp += bdp->d_reclen; 335 cookiep++; 336 ncookies--; 337 } 338 } 339 340 while (len > 0) { 341 if (cookiep && ncookies == 0) 342 break; 343 bdp = (struct dirent *) inp; 344 reclen = bdp->d_reclen; 345 if (reclen & 3) { 346 DPRINTF(("svr4_readdir: reclen=%d\n", reclen)); 347 error = EFAULT; 348 goto out; 349 } 350 351 if (bdp->d_fileno == 0) { 352 inp += reclen; 353 if (cookiep) { 354 off = *cookiep++; 355 ncookies--; 356 } else 357 off += reclen; 358 len -= reclen; 359 continue; 360 } 361 svr4reclen = SVR4_RECLEN(&svr4_dirent, bdp->d_namlen); 362 if (reclen > len || resid < svr4reclen) { 363 outp++; 364 break; 365 } 366 svr4_dirent.d_ino = (long) bdp->d_fileno; 367 if (justone) { 368 /* 369 * old svr4-style readdir usage. 370 */ 371 svr4_dirent.d_off = (svr4_off_t) svr4reclen; 372 svr4_dirent.d_reclen = (u_short) bdp->d_namlen; 373 } else { 374 svr4_dirent.d_off = (svr4_off_t)(off + reclen); 375 svr4_dirent.d_reclen = (u_short) svr4reclen; 376 } 377 strcpy(svr4_dirent.d_name, bdp->d_name); 378 if ((error = copyout((caddr_t)&svr4_dirent, outp, svr4reclen))) 379 goto out; 380 inp += reclen; 381 if (cookiep) { 382 off = *cookiep++; 383 ncookies--; 384 } else 385 off += reclen; 386 outp += svr4reclen; 387 resid -= svr4reclen; 388 len -= reclen; 389 if (justone) 390 break; 391 } 392 393 if (outp == (caddr_t) SCARG(uap, dp)) 394 goto again; 395 fp->f_offset = off; 396 397 if (justone) 398 nbytes = resid + svr4reclen; 399 400eof: 401 td->td_retval[0] = nbytes - resid; 402out: 403 if (cookies) 404 free(cookies, M_TEMP); 405 VOP_UNLOCK(vp, 0, td); 406 free(buf, M_TEMP); 407 return error; 408} 409 410 411int 412svr4_sys_getdents(td, uap) 413 struct thread *td; 414 struct svr4_sys_getdents_args *uap; 415{ 416 struct dirent *bdp; 417 struct vnode *vp; 418 caddr_t inp, buf; /* BSD-format */ 419 int len, reclen; /* BSD-format */ 420 caddr_t outp; /* SVR4-format */ 421 int resid, svr4_reclen; /* SVR4-format */ 422 struct file *fp; 423 struct uio auio; 424 struct iovec aiov; 425 struct svr4_dirent idb; 426 off_t off; /* true file offset */ 427 int buflen, error, eofflag; 428 u_long *cookiebuf = NULL, *cookie; 429 int ncookies = 0, *retval = td->td_retval; 430 431 if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0) 432 return (error); 433 434 if ((fp->f_flag & FREAD) == 0) 435 return (EBADF); 436 437 vp = (struct vnode *)fp->f_data; 438 if (vp->v_type != VDIR) 439 return (EINVAL); 440 441 buflen = min(MAXBSIZE, SCARG(uap, nbytes)); 442 buf = malloc(buflen, M_TEMP, M_WAITOK); 443 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 444 off = fp->f_offset; 445again: 446 aiov.iov_base = buf; 447 aiov.iov_len = buflen; 448 auio.uio_iov = &aiov; 449 auio.uio_iovcnt = 1; 450 auio.uio_rw = UIO_READ; 451 auio.uio_segflg = UIO_SYSSPACE; 452 auio.uio_td = td; 453 auio.uio_resid = buflen; 454 auio.uio_offset = off; 455 /* 456 * First we read into the malloc'ed buffer, then 457 * we massage it into user space, one record at a time. 458 */ 459 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, 460 &cookiebuf); 461 if (error) 462 goto out; 463 464 inp = buf; 465 outp = SCARG(uap, buf); 466 resid = SCARG(uap, nbytes); 467 if ((len = buflen - auio.uio_resid) == 0) 468 goto eof; 469 470 for (cookie = cookiebuf; len > 0; len -= reclen) { 471 bdp = (struct dirent *)inp; 472 reclen = bdp->d_reclen; 473 if (reclen & 3) 474 panic("svr4_sys_getdents64: bad reclen"); 475 off = *cookie++; /* each entry points to the next */ 476 if ((off >> 32) != 0) { 477 uprintf("svr4_sys_getdents64: dir offset too large for emulated program"); 478 error = EINVAL; 479 goto out; 480 } 481 if (bdp->d_fileno == 0) { 482 inp += reclen; /* it is a hole; squish it out */ 483 continue; 484 } 485 svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen); 486 if (reclen > len || resid < svr4_reclen) { 487 /* entry too big for buffer, so just stop */ 488 outp++; 489 break; 490 } 491 /* 492 * Massage in place to make a SVR4-shaped dirent (otherwise 493 * we have to worry about touching user memory outside of 494 * the copyout() call). 495 */ 496 idb.d_ino = (svr4_ino_t)bdp->d_fileno; 497 idb.d_off = (svr4_off_t)off; 498 idb.d_reclen = (u_short)svr4_reclen; 499 strcpy(idb.d_name, bdp->d_name); 500 if ((error = copyout((caddr_t)&idb, outp, svr4_reclen))) 501 goto out; 502 /* advance past this real entry */ 503 inp += reclen; 504 /* advance output past SVR4-shaped entry */ 505 outp += svr4_reclen; 506 resid -= svr4_reclen; 507 } 508 509 /* if we squished out the whole block, try again */ 510 if (outp == SCARG(uap, buf)) 511 goto again; 512 fp->f_offset = off; /* update the vnode offset */ 513 514eof: 515 *retval = SCARG(uap, nbytes) - resid; 516out: 517 VOP_UNLOCK(vp, 0, td); 518 if (cookiebuf) 519 free(cookiebuf, M_TEMP); 520 free(buf, M_TEMP); 521 return error; 522} 523 524 525int 526svr4_sys_mmap(td, uap) 527 struct thread *td; 528 struct svr4_sys_mmap_args *uap; 529{ 530 struct mmap_args mm; 531 int *retval; 532 533 retval = td->td_retval; 534#define _MAP_NEW 0x80000000 535 /* 536 * Verify the arguments. 537 */ 538 if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) 539 return EINVAL; /* XXX still needed? */ 540 541 if (SCARG(uap, len) == 0) 542 return EINVAL; 543 544 SCARG(&mm, prot) = SCARG(uap, prot); 545 SCARG(&mm, len) = SCARG(uap, len); 546 SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW; 547 SCARG(&mm, fd) = SCARG(uap, fd); 548 SCARG(&mm, addr) = SCARG(uap, addr); 549 SCARG(&mm, pos) = SCARG(uap, pos); 550 551 return mmap(td, &mm); 552} 553 554int 555svr4_sys_mmap64(td, uap) 556 struct thread *td; 557 struct svr4_sys_mmap64_args *uap; 558{ 559 struct mmap_args mm; 560 void *rp; 561 562#define _MAP_NEW 0x80000000 563 /* 564 * Verify the arguments. 565 */ 566 if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) 567 return EINVAL; /* XXX still needed? */ 568 569 if (SCARG(uap, len) == 0) 570 return EINVAL; 571 572 SCARG(&mm, prot) = SCARG(uap, prot); 573 SCARG(&mm, len) = SCARG(uap, len); 574 SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW; 575 SCARG(&mm, fd) = SCARG(uap, fd); 576 SCARG(&mm, addr) = SCARG(uap, addr); 577 SCARG(&mm, pos) = SCARG(uap, pos); 578
|
580 if ((SCARG(&mm, flags) & MAP_FIXED) == 0 && 581 SCARG(&mm, addr) != 0 && (void *)SCARG(&mm, addr) < rp) 582 SCARG(&mm, addr) = rp; 583 584 return mmap(td, &mm); 585} 586 587 588int 589svr4_sys_fchroot(td, uap) 590 struct thread *td; 591 struct svr4_sys_fchroot_args *uap; 592{ 593 struct filedesc *fdp = td->td_proc->p_fd; 594 struct vnode *vp; 595 struct file *fp; 596 int error; 597 598 if ((error = suser_td(td)) != 0) 599 return error; 600 if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0) 601 return error; 602 vp = (struct vnode *) fp->f_data; 603 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 604 if (vp->v_type != VDIR) 605 error = ENOTDIR; 606 else 607 error = VOP_ACCESS(vp, VEXEC, td->td_proc->p_ucred, td); 608 VOP_UNLOCK(vp, 0, td); 609 if (error) 610 return error; 611 VREF(vp); 612 if (fdp->fd_rdir != NULL) 613 vrele(fdp->fd_rdir); 614 fdp->fd_rdir = vp; 615 return 0; 616} 617 618 619static int 620svr4_mknod(td, retval, path, mode, dev) 621 struct thread *td; 622 register_t *retval; 623 char *path; 624 svr4_mode_t mode; 625 svr4_dev_t dev; 626{ 627 caddr_t sg = stackgap_init(); 628 629 CHECKALTEXIST(td, &sg, path); 630 631 if (S_ISFIFO(mode)) { 632 struct mkfifo_args ap; 633 SCARG(&ap, path) = path; 634 SCARG(&ap, mode) = mode; 635 return mkfifo(td, &ap); 636 } else { 637 struct mknod_args ap; 638 SCARG(&ap, path) = path; 639 SCARG(&ap, mode) = mode; 640 SCARG(&ap, dev) = dev; 641 return mknod(td, &ap); 642 } 643} 644 645 646int 647svr4_sys_mknod(td, uap) 648 register struct thread *td; 649 struct svr4_sys_mknod_args *uap; 650{ 651 int *retval = td->td_retval; 652 return svr4_mknod(td, retval, 653 SCARG(uap, path), SCARG(uap, mode), 654 (svr4_dev_t)svr4_to_bsd_odev_t(SCARG(uap, dev))); 655} 656 657 658int 659svr4_sys_xmknod(td, uap) 660 struct thread *td; 661 struct svr4_sys_xmknod_args *uap; 662{ 663 int *retval = td->td_retval; 664 return svr4_mknod(td, retval, 665 SCARG(uap, path), SCARG(uap, mode), 666 (svr4_dev_t)svr4_to_bsd_dev_t(SCARG(uap, dev))); 667} 668 669 670int 671svr4_sys_vhangup(td, uap) 672 struct thread *td; 673 struct svr4_sys_vhangup_args *uap; 674{ 675 return 0; 676} 677 678 679int 680svr4_sys_sysconfig(td, uap) 681 struct thread *td; 682 struct svr4_sys_sysconfig_args *uap; 683{ 684 int *retval; 685 686 retval = &(td->td_retval[0]); 687 688 switch (SCARG(uap, name)) { 689 case SVR4_CONFIG_UNUSED: 690 *retval = 0; 691 break; 692 case SVR4_CONFIG_NGROUPS: 693 *retval = NGROUPS_MAX; 694 break; 695 case SVR4_CONFIG_CHILD_MAX: 696 *retval = maxproc; 697 break; 698 case SVR4_CONFIG_OPEN_FILES: 699 *retval = maxfiles; 700 break; 701 case SVR4_CONFIG_POSIX_VER: 702 *retval = 198808; 703 break; 704 case SVR4_CONFIG_PAGESIZE: 705 *retval = PAGE_SIZE; 706 break; 707 case SVR4_CONFIG_CLK_TCK: 708 *retval = 60; /* should this be `hz', ie. 100? */ 709 break; 710 case SVR4_CONFIG_XOPEN_VER: 711 *retval = 2; /* XXX: What should that be? */ 712 break; 713 case SVR4_CONFIG_PROF_TCK: 714 *retval = 60; /* XXX: What should that be? */ 715 break; 716 case SVR4_CONFIG_NPROC_CONF: 717 *retval = 1; /* Only one processor for now */ 718 break; 719 case SVR4_CONFIG_NPROC_ONLN: 720 *retval = 1; /* And it better be online */ 721 break; 722 case SVR4_CONFIG_AIO_LISTIO_MAX: 723 case SVR4_CONFIG_AIO_MAX: 724 case SVR4_CONFIG_AIO_PRIO_DELTA_MAX: 725 *retval = 0; /* No aio support */ 726 break; 727 case SVR4_CONFIG_DELAYTIMER_MAX: 728 *retval = 0; /* No delaytimer support */ 729 break; 730 case SVR4_CONFIG_MQ_OPEN_MAX: 731 *retval = msginfo.msgmni; 732 break; 733 case SVR4_CONFIG_MQ_PRIO_MAX: 734 *retval = 0; /* XXX: Don't know */ 735 break; 736 case SVR4_CONFIG_RTSIG_MAX: 737 *retval = 0; 738 break; 739 case SVR4_CONFIG_SEM_NSEMS_MAX: 740 *retval = seminfo.semmni; 741 break; 742 case SVR4_CONFIG_SEM_VALUE_MAX: 743 *retval = seminfo.semvmx; 744 break; 745 case SVR4_CONFIG_SIGQUEUE_MAX: 746 *retval = 0; /* XXX: Don't know */ 747 break; 748 case SVR4_CONFIG_SIGRT_MIN: 749 case SVR4_CONFIG_SIGRT_MAX: 750 *retval = 0; /* No real time signals */ 751 break; 752 case SVR4_CONFIG_TIMER_MAX: 753 *retval = 3; /* XXX: real, virtual, profiling */ 754 break; 755#if defined(NOTYET) 756 case SVR4_CONFIG_PHYS_PAGES: 757#if defined(UVM) 758 *retval = uvmexp.free; /* XXX: free instead of total */ 759#else 760 *retval = cnt.v_free_count; /* XXX: free instead of total */ 761#endif 762 break; 763 case SVR4_CONFIG_AVPHYS_PAGES: 764#if defined(UVM) 765 *retval = uvmexp.active; /* XXX: active instead of avg */ 766#else 767 *retval = cnt.v_active_count; /* XXX: active instead of avg */ 768#endif 769 break; 770#endif /* NOTYET */ 771 772 default: 773 return EINVAL; 774 } 775 return 0; 776} 777 778extern int swap_pager_full; 779 780/* ARGSUSED */ 781int 782svr4_sys_break(td, uap) 783 struct thread *td; 784 struct svr4_sys_break_args *uap; 785{ 786 struct vmspace *vm = td->td_proc->p_vmspace; 787 vm_offset_t new, old, base, ns; 788 int rv; 789 790 base = round_page((vm_offset_t) vm->vm_daddr); 791 ns = (vm_offset_t)SCARG(uap, nsize); 792 new = round_page(ns); 793 /* For p_rlimit. */ 794 mtx_assert(&Giant, MA_OWNED); 795 if (new > base) { 796 if ((new - base) > (unsigned) td->td_proc->p_rlimit[RLIMIT_DATA].rlim_cur) { 797 return ENOMEM; 798 } 799 if (new >= VM_MAXUSER_ADDRESS) { 800 return (ENOMEM); 801 } 802 } else if (new < base) { 803 /* 804 * This is simply an invalid value. If someone wants to 805 * do fancy address space manipulations, mmap and munmap 806 * can do most of what the user would want. 807 */ 808 return EINVAL; 809 } 810 811 old = base + ctob(vm->vm_dsize); 812 813 if (new > old) { 814 vm_size_t diff; 815 if (swap_pager_full) { 816 return (ENOMEM); 817 } 818 diff = new - old; 819 rv = vm_map_find(&vm->vm_map, NULL, 0, &old, diff, FALSE, 820 VM_PROT_ALL, VM_PROT_ALL, 0); 821 if (rv != KERN_SUCCESS) { 822 return (ENOMEM); 823 } 824 vm->vm_dsize += btoc(diff); 825 } else if (new < old) { 826 rv = vm_map_remove(&vm->vm_map, new, old); 827 if (rv != KERN_SUCCESS) { 828 return (ENOMEM); 829 } 830 vm->vm_dsize -= btoc(old - new); 831 } 832 833 return (0); 834} 835 836static __inline clock_t 837timeval_to_clock_t(tv) 838 struct timeval *tv; 839{ 840 return tv->tv_sec * hz + tv->tv_usec / (1000000 / hz); 841} 842 843 844int 845svr4_sys_times(td, uap) 846 struct thread *td; 847 struct svr4_sys_times_args *uap; 848{ 849 int error, *retval = td->td_retval; 850 struct tms tms; 851 struct timeval t; 852 struct rusage *ru; 853 struct rusage r; 854 struct getrusage_args ga; 855 856 caddr_t sg = stackgap_init(); 857 ru = stackgap_alloc(&sg, sizeof(struct rusage)); 858 859 SCARG(&ga, who) = RUSAGE_SELF; 860 SCARG(&ga, rusage) = ru; 861 862 error = getrusage(td, &ga); 863 if (error) 864 return error; 865 866 if ((error = copyin(ru, &r, sizeof r)) != 0) 867 return error; 868 869 tms.tms_utime = timeval_to_clock_t(&r.ru_utime); 870 tms.tms_stime = timeval_to_clock_t(&r.ru_stime); 871 872 SCARG(&ga, who) = RUSAGE_CHILDREN; 873 error = getrusage(td, &ga); 874 if (error) 875 return error; 876 877 if ((error = copyin(ru, &r, sizeof r)) != 0) 878 return error; 879 880 tms.tms_cutime = timeval_to_clock_t(&r.ru_utime); 881 tms.tms_cstime = timeval_to_clock_t(&r.ru_stime); 882 883 microtime(&t); 884 *retval = timeval_to_clock_t(&t); 885 886 return copyout(&tms, SCARG(uap, tp), sizeof(tms)); 887} 888 889 890int 891svr4_sys_ulimit(td, uap) 892 struct thread *td; 893 struct svr4_sys_ulimit_args *uap; 894{ 895 int *retval = td->td_retval; 896 897 switch (SCARG(uap, cmd)) { 898 case SVR4_GFILLIM: 899 /* For p_rlimit below. */ 900 mtx_assert(&Giant, MA_OWNED); 901 *retval = td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur / 512; 902 if (*retval == -1) 903 *retval = 0x7fffffff; 904 return 0; 905 906 case SVR4_SFILLIM: 907 { 908 int error; 909 struct __setrlimit_args srl; 910 struct rlimit krl; 911 caddr_t sg = stackgap_init(); 912 struct rlimit *url = (struct rlimit *) 913 stackgap_alloc(&sg, sizeof *url); 914 915 krl.rlim_cur = SCARG(uap, newlimit) * 512; 916 mtx_assert(&Giant, MA_OWNED); 917 krl.rlim_max = td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_max; 918 919 error = copyout(&krl, url, sizeof(*url)); 920 if (error) 921 return error; 922 923 SCARG(&srl, which) = RLIMIT_FSIZE; 924 SCARG(&srl, rlp) = url; 925 926 error = setrlimit(td, &srl); 927 if (error) 928 return error; 929 930 mtx_assert(&Giant, MA_OWNED); 931 *retval = td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur; 932 if (*retval == -1) 933 *retval = 0x7fffffff; 934 return 0; 935 } 936 937 case SVR4_GMEMLIM: 938 { 939 struct vmspace *vm = td->td_proc->p_vmspace; 940 register_t r; 941 942 mtx_assert(&Giant, MA_OWNED); 943 r = td->td_proc->p_rlimit[RLIMIT_DATA].rlim_cur; 944 945 if (r == -1) 946 r = 0x7fffffff; 947 r += (long) vm->vm_daddr; 948 if (r < 0) 949 r = 0x7fffffff; 950 *retval = r; 951 return 0; 952 } 953 954 case SVR4_GDESLIM: 955 mtx_assert(&Giant, MA_OWNED); 956 *retval = td->td_proc->p_rlimit[RLIMIT_NOFILE].rlim_cur; 957 if (*retval == -1) 958 *retval = 0x7fffffff; 959 return 0; 960 961 default: 962 return EINVAL; 963 } 964} 965 966static struct proc * 967svr4_pfind(pid) 968 pid_t pid; 969{ 970 struct proc *p; 971 972 /* look in the live processes */ 973 if ((p = pfind(pid)) == NULL) 974 /* look in the zombies */ 975 p = zpfind(pid); 976 977 return p; 978} 979 980 981int 982svr4_sys_pgrpsys(td, uap) 983 struct thread *td; 984 struct svr4_sys_pgrpsys_args *uap; 985{ 986 int *retval = td->td_retval; 987 struct proc *p = td->td_proc; 988 989 switch (SCARG(uap, cmd)) { 990 case 1: /* setpgrp() */ 991 /* 992 * SVR4 setpgrp() (which takes no arguments) has the 993 * semantics that the session ID is also created anew, so 994 * in almost every sense, setpgrp() is identical to 995 * setsid() for SVR4. (Under BSD, the difference is that 996 * a setpgid(0,0) will not create a new session.) 997 */ 998 setsid(td, NULL); 999 /*FALLTHROUGH*/ 1000 1001 case 0: /* getpgrp() */ 1002 *retval = p->p_pgrp->pg_id; 1003 return 0; 1004 1005 case 2: /* getsid(pid) */ 1006 if (SCARG(uap, pid) != 0 && 1007 (p = svr4_pfind(SCARG(uap, pid))) == NULL) 1008 return ESRCH; 1009 /* 1010 * This has already been initialized to the pid of 1011 * the session leader. 1012 */ 1013 *retval = (register_t) p->p_session->s_leader->p_pid; 1014 PROC_UNLOCK(p); 1015 return 0; 1016 1017 case 3: /* setsid() */ 1018 return setsid(td, NULL); 1019 1020 case 4: /* getpgid(pid) */ 1021 1022 if (SCARG(uap, pid) != 0 && 1023 (p = svr4_pfind(SCARG(uap, pid))) == NULL) 1024 return ESRCH; 1025 1026 *retval = (int) p->p_pgrp->pg_id; 1027 PROC_UNLOCK(p); 1028 return 0; 1029 1030 case 5: /* setpgid(pid, pgid); */ 1031 { 1032 struct setpgid_args sa; 1033 1034 SCARG(&sa, pid) = SCARG(uap, pid); 1035 SCARG(&sa, pgid) = SCARG(uap, pgid); 1036 return setpgid(td, &sa); 1037 } 1038 1039 default: 1040 return EINVAL; 1041 } 1042} 1043 1044#define syscallarg(x) union { x datum; register_t pad; } 1045 1046struct svr4_hrtcntl_args { 1047 int cmd; 1048 int fun; 1049 int clk; 1050 svr4_hrt_interval_t * iv; 1051 svr4_hrt_time_t * ti; 1052}; 1053 1054 1055static int 1056svr4_hrtcntl(td, uap, retval) 1057 struct thread *td; 1058 struct svr4_hrtcntl_args *uap; 1059 register_t *retval; 1060{ 1061 switch (SCARG(uap, fun)) { 1062 case SVR4_HRT_CNTL_RES: 1063 DPRINTF(("htrcntl(RES)\n")); 1064 *retval = SVR4_HRT_USEC; 1065 return 0; 1066 1067 case SVR4_HRT_CNTL_TOFD: 1068 DPRINTF(("htrcntl(TOFD)\n")); 1069 { 1070 struct timeval tv; 1071 svr4_hrt_time_t t; 1072 if (SCARG(uap, clk) != SVR4_HRT_CLK_STD) { 1073 DPRINTF(("clk == %d\n", SCARG(uap, clk))); 1074 return EINVAL; 1075 } 1076 if (SCARG(uap, ti) == NULL) { 1077 DPRINTF(("ti NULL\n")); 1078 return EINVAL; 1079 } 1080 microtime(&tv); 1081 t.h_sec = tv.tv_sec; 1082 t.h_rem = tv.tv_usec; 1083 t.h_res = SVR4_HRT_USEC; 1084 return copyout(&t, SCARG(uap, ti), sizeof(t)); 1085 } 1086 1087 case SVR4_HRT_CNTL_START: 1088 DPRINTF(("htrcntl(START)\n")); 1089 return ENOSYS; 1090 1091 case SVR4_HRT_CNTL_GET: 1092 DPRINTF(("htrcntl(GET)\n")); 1093 return ENOSYS; 1094 default: 1095 DPRINTF(("Bad htrcntl command %d\n", SCARG(uap, fun))); 1096 return ENOSYS; 1097 } 1098} 1099 1100 1101int 1102svr4_sys_hrtsys(td, uap) 1103 struct thread *td; 1104 struct svr4_sys_hrtsys_args *uap; 1105{ 1106 int *retval = td->td_retval; 1107 1108 switch (SCARG(uap, cmd)) { 1109 case SVR4_HRT_CNTL: 1110 return svr4_hrtcntl(td, (struct svr4_hrtcntl_args *) uap, 1111 retval); 1112 1113 case SVR4_HRT_ALRM: 1114 DPRINTF(("hrtalarm\n")); 1115 return ENOSYS; 1116 1117 case SVR4_HRT_SLP: 1118 DPRINTF(("hrtsleep\n")); 1119 return ENOSYS; 1120 1121 case SVR4_HRT_CAN: 1122 DPRINTF(("hrtcancel\n")); 1123 return ENOSYS; 1124 1125 default: 1126 DPRINTF(("Bad hrtsys command %d\n", SCARG(uap, cmd))); 1127 return EINVAL; 1128 } 1129} 1130 1131 1132static int 1133svr4_setinfo(p, st, s) 1134 struct proc *p; 1135 int st; 1136 svr4_siginfo_t *s; 1137{ 1138 svr4_siginfo_t i; 1139 int sig; 1140 1141 memset(&i, 0, sizeof(i)); 1142 1143 i.si_signo = SVR4_SIGCHLD; 1144 i.si_errno = 0; /* XXX? */ 1145 1146 if (p) { 1147 i.si_pid = p->p_pid; 1148 mtx_lock_spin(&sched_lock); 1149 if (p->p_stat == SZOMB) { 1150 i.si_stime = p->p_ru->ru_stime.tv_sec; 1151 i.si_utime = p->p_ru->ru_utime.tv_sec; 1152 } 1153 else { 1154 i.si_stime = p->p_stats->p_ru.ru_stime.tv_sec; 1155 i.si_utime = p->p_stats->p_ru.ru_utime.tv_sec; 1156 } 1157 mtx_unlock_spin(&sched_lock); 1158 } 1159 1160 if (WIFEXITED(st)) { 1161 i.si_status = WEXITSTATUS(st); 1162 i.si_code = SVR4_CLD_EXITED; 1163 } else if (WIFSTOPPED(st)) { 1164 sig = WSTOPSIG(st); 1165 if (sig >= 0 && sig < NSIG) 1166 i.si_status = SVR4_BSD2SVR4_SIG(sig); 1167 1168 if (i.si_status == SVR4_SIGCONT) 1169 i.si_code = SVR4_CLD_CONTINUED; 1170 else 1171 i.si_code = SVR4_CLD_STOPPED; 1172 } else { 1173 sig = WTERMSIG(st); 1174 if (sig >= 0 && sig < NSIG) 1175 i.si_status = SVR4_BSD2SVR4_SIG(sig); 1176 1177 if (WCOREDUMP(st)) 1178 i.si_code = SVR4_CLD_DUMPED; 1179 else 1180 i.si_code = SVR4_CLD_KILLED; 1181 } 1182 1183 DPRINTF(("siginfo [pid %ld signo %d code %d errno %d status %d]\n", 1184 i.si_pid, i.si_signo, i.si_code, i.si_errno, i.si_status)); 1185 1186 return copyout(&i, s, sizeof(i)); 1187} 1188 1189 1190int 1191svr4_sys_waitsys(td, uap) 1192 struct thread *td; 1193 struct svr4_sys_waitsys_args *uap; 1194{ 1195 int nfound; 1196 int error, *retval = td->td_retval; 1197 struct proc *q, *t; 1198 1199 1200 switch (SCARG(uap, grp)) { 1201 case SVR4_P_PID: 1202 break; 1203 1204 case SVR4_P_PGID: 1205 SCARG(uap, id) = -td->td_proc->p_pgid; 1206 break; 1207 1208 case SVR4_P_ALL: 1209 SCARG(uap, id) = WAIT_ANY; 1210 break; 1211 1212 default: 1213 return EINVAL; 1214 } 1215 1216 DPRINTF(("waitsys(%d, %d, %p, %x)\n", 1217 SCARG(uap, grp), SCARG(uap, id), 1218 SCARG(uap, info), SCARG(uap, options))); 1219 1220loop: 1221 nfound = 0; 1222 sx_slock(&proctree_lock); 1223 LIST_FOREACH(q, &td->td_proc->p_children, p_sibling) { 1224 if (SCARG(uap, id) != WAIT_ANY && 1225 q->p_pid != SCARG(uap, id) && 1226 q->p_pgid != -SCARG(uap, id)) { 1227 DPRINTF(("pid %d pgid %d != %d\n", q->p_pid, 1228 q->p_pgid, SCARG(uap, id))); 1229 continue; 1230 } 1231 nfound++; 1232 PROC_LOCK(q); 1233 mtx_lock_spin(&sched_lock); 1234 if (q->p_stat == SZOMB && 1235 ((SCARG(uap, options) & (SVR4_WEXITED|SVR4_WTRAPPED)))) { 1236 mtx_unlock_spin(&sched_lock); 1237 PROC_UNLOCK(q); 1238 sx_sunlock(&proctree_lock); 1239 *retval = 0; 1240 DPRINTF(("found %d\n", q->p_pid)); 1241 error = svr4_setinfo(q, q->p_xstat, SCARG(uap, info)); 1242 if (error != 0) 1243 return error; 1244 1245 1246 if ((SCARG(uap, options) & SVR4_WNOWAIT)) { 1247 DPRINTF(("Don't wait\n")); 1248 return 0; 1249 } 1250 1251 /* 1252 * If we got the child via ptrace(2) or procfs, and 1253 * the parent is different (meaning the process was 1254 * attached, rather than run as a child), then we need 1255 * to give it back to the old parent, and send the 1256 * parent a SIGCHLD. The rest of the cleanup will be 1257 * done when the old parent waits on the child. 1258 */ 1259 sx_xlock(&proctree_lock); 1260 PROC_LOCK(q); 1261 if (q->p_flag & P_TRACED) { 1262 if (q->p_oppid != q->p_pptr->p_pid) { 1263 PROC_UNLOCK(q); 1264 t = pfind(q->p_oppid); 1265 PROC_LOCK(q); 1266 proc_reparent(q, t ? t : initproc); 1267 q->p_oppid = 0; 1268 q->p_flag &= ~(P_TRACED | P_WAITED); 1269 PROC_UNLOCK(q); 1270 psignal(t, SIGCHLD); 1271 wakeup(t); 1272 PROC_UNLOCK(t); 1273 sx_xunlock(&proctree_lock); 1274 return 0; 1275 } 1276 } 1277 PROC_UNLOCK(q); 1278 sx_xunlock(&proctree_lock); 1279 q->p_xstat = 0; 1280 ruadd(&td->td_proc->p_stats->p_cru, q->p_ru); 1281 FREE(q->p_ru, M_ZOMBIE); 1282 q->p_ru = 0; 1283 1284 /* 1285 * Decrement the count of procs running with this uid. 1286 */ 1287 (void)chgproccnt(q->p_ucred->cr_ruidinfo, -1, 0); 1288 1289 /* 1290 * Release reference to text vnode. 1291 */ 1292 if (q->p_textvp) 1293 vrele(q->p_textvp); 1294 1295 /* 1296 * Free up credentials. 1297 */ 1298 crfree(q->p_ucred); 1299 q->p_ucred = NULL; 1300 1301 /* 1302 * Remove unused arguments 1303 */ 1304 if (q->p_args && --q->p_args->ar_ref == 0) 1305 FREE(q->p_args, M_PARGS); 1306 PROC_UNLOCK(q); 1307 1308 /* 1309 * Finally finished with old proc entry. 1310 * Unlink it from its process group and free it. 1311 */ 1312 leavepgrp(q); 1313 1314 sx_xlock(&allproc_lock); 1315 LIST_REMOVE(q, p_list); /* off zombproc */ 1316 sx_xunlock(&allproc_lock); 1317 1318 sx_xlock(&proctree_lock); 1319 LIST_REMOVE(q, p_sibling); 1320 sx_xunlock(&proctree_lock); 1321 1322 PROC_LOCK(q); 1323 if (--q->p_procsig->ps_refcnt == 0) { 1324 if (q->p_sigacts != &q->p_uarea->u_sigacts) 1325 FREE(q->p_sigacts, M_SUBPROC); 1326 FREE(q->p_procsig, M_SUBPROC); 1327 q->p_procsig = NULL; 1328 } 1329 PROC_UNLOCK(q); 1330 1331 /* 1332 * Give machine-dependent layer a chance 1333 * to free anything that cpu_exit couldn't 1334 * release while still running in process context. 1335 */ 1336 cpu_wait(q); 1337#if defined(__NetBSD__) 1338 pool_put(&proc_pool, q); 1339#endif 1340#ifdef __FreeBSD__ 1341 mtx_destroy(&q->p_mtx); 1342 zfree(proc_zone, q); 1343#endif 1344 nprocs--; 1345 return 0; 1346 } 1347 if (q->p_stat == SSTOP && (q->p_flag & P_WAITED) == 0 && 1348 (q->p_flag & P_TRACED || 1349 (SCARG(uap, options) & (SVR4_WSTOPPED|SVR4_WCONTINUED)))) { 1350 mtx_unlock_spin(&sched_lock); 1351 DPRINTF(("jobcontrol %d\n", q->p_pid)); 1352 if (((SCARG(uap, options) & SVR4_WNOWAIT)) == 0) 1353 q->p_flag |= P_WAITED; 1354 PROC_UNLOCK(q); 1355 *retval = 0; 1356 return svr4_setinfo(q, W_STOPCODE(q->p_xstat), 1357 SCARG(uap, info)); 1358 } 1359 mtx_unlock_spin(&sched_lock); 1360 PROC_UNLOCK(q); 1361 } 1362 1363 if (nfound == 0) 1364 return ECHILD; 1365 1366 if (SCARG(uap, options) & SVR4_WNOHANG) { 1367 *retval = 0; 1368 if ((error = svr4_setinfo(NULL, 0, SCARG(uap, info))) != 0) 1369 return error; 1370 return 0; 1371 } 1372 1373 if ((error = tsleep((caddr_t)td->td_proc, PWAIT | PCATCH, "svr4_wait", 0)) != 0) 1374 return error; 1375 goto loop; 1376} 1377 1378 1379static void 1380bsd_statfs_to_svr4_statvfs(bfs, sfs) 1381 const struct statfs *bfs; 1382 struct svr4_statvfs *sfs; 1383{ 1384 sfs->f_bsize = bfs->f_iosize; /* XXX */ 1385 sfs->f_frsize = bfs->f_bsize; 1386 sfs->f_blocks = bfs->f_blocks; 1387 sfs->f_bfree = bfs->f_bfree; 1388 sfs->f_bavail = bfs->f_bavail; 1389 sfs->f_files = bfs->f_files; 1390 sfs->f_ffree = bfs->f_ffree; 1391 sfs->f_favail = bfs->f_ffree; 1392 sfs->f_fsid = bfs->f_fsid.val[0]; 1393 memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype)); 1394 sfs->f_flag = 0; 1395 if (bfs->f_flags & MNT_RDONLY) 1396 sfs->f_flag |= SVR4_ST_RDONLY; 1397 if (bfs->f_flags & MNT_NOSUID) 1398 sfs->f_flag |= SVR4_ST_NOSUID; 1399 sfs->f_namemax = MAXNAMLEN; 1400 memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */ 1401 memset(sfs->f_filler, 0, sizeof(sfs->f_filler)); 1402} 1403 1404 1405static void 1406bsd_statfs_to_svr4_statvfs64(bfs, sfs) 1407 const struct statfs *bfs; 1408 struct svr4_statvfs64 *sfs; 1409{ 1410 sfs->f_bsize = bfs->f_iosize; /* XXX */ 1411 sfs->f_frsize = bfs->f_bsize; 1412 sfs->f_blocks = bfs->f_blocks; 1413 sfs->f_bfree = bfs->f_bfree; 1414 sfs->f_bavail = bfs->f_bavail; 1415 sfs->f_files = bfs->f_files; 1416 sfs->f_ffree = bfs->f_ffree; 1417 sfs->f_favail = bfs->f_ffree; 1418 sfs->f_fsid = bfs->f_fsid.val[0]; 1419 memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype)); 1420 sfs->f_flag = 0; 1421 if (bfs->f_flags & MNT_RDONLY) 1422 sfs->f_flag |= SVR4_ST_RDONLY; 1423 if (bfs->f_flags & MNT_NOSUID) 1424 sfs->f_flag |= SVR4_ST_NOSUID; 1425 sfs->f_namemax = MAXNAMLEN; 1426 memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */ 1427 memset(sfs->f_filler, 0, sizeof(sfs->f_filler)); 1428} 1429 1430 1431int 1432svr4_sys_statvfs(td, uap) 1433 struct thread *td; 1434 struct svr4_sys_statvfs_args *uap; 1435{ 1436 struct statfs_args fs_args; 1437 caddr_t sg = stackgap_init(); 1438 struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs)); 1439 struct statfs bfs; 1440 struct svr4_statvfs sfs; 1441 int error; 1442 1443 CHECKALTEXIST(td, &sg, SCARG(uap, path)); 1444 SCARG(&fs_args, path) = SCARG(uap, path); 1445 SCARG(&fs_args, buf) = fs; 1446 1447 if ((error = statfs(td, &fs_args)) != 0) 1448 return error; 1449 1450 if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0) 1451 return error; 1452 1453 bsd_statfs_to_svr4_statvfs(&bfs, &sfs); 1454 1455 return copyout(&sfs, SCARG(uap, fs), sizeof(sfs)); 1456} 1457 1458 1459int 1460svr4_sys_fstatvfs(td, uap) 1461 struct thread *td; 1462 struct svr4_sys_fstatvfs_args *uap; 1463{ 1464 struct fstatfs_args fs_args; 1465 caddr_t sg = stackgap_init(); 1466 struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs)); 1467 struct statfs bfs; 1468 struct svr4_statvfs sfs; 1469 int error; 1470 1471 SCARG(&fs_args, fd) = SCARG(uap, fd); 1472 SCARG(&fs_args, buf) = fs; 1473 1474 if ((error = fstatfs(td, &fs_args)) != 0) 1475 return error; 1476 1477 if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0) 1478 return error; 1479 1480 bsd_statfs_to_svr4_statvfs(&bfs, &sfs); 1481 1482 return copyout(&sfs, SCARG(uap, fs), sizeof(sfs)); 1483} 1484 1485 1486int 1487svr4_sys_statvfs64(td, uap) 1488 struct thread *td; 1489 struct svr4_sys_statvfs64_args *uap; 1490{ 1491 struct statfs_args fs_args; 1492 caddr_t sg = stackgap_init(); 1493 struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs)); 1494 struct statfs bfs; 1495 struct svr4_statvfs64 sfs; 1496 int error; 1497 1498 CHECKALTEXIST(td, &sg, SCARG(uap, path)); 1499 SCARG(&fs_args, path) = SCARG(uap, path); 1500 SCARG(&fs_args, buf) = fs; 1501 1502 if ((error = statfs(td, &fs_args)) != 0) 1503 return error; 1504 1505 if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0) 1506 return error; 1507 1508 bsd_statfs_to_svr4_statvfs64(&bfs, &sfs); 1509 1510 return copyout(&sfs, SCARG(uap, fs), sizeof(sfs)); 1511} 1512 1513 1514int 1515svr4_sys_fstatvfs64(td, uap) 1516 struct thread *td; 1517 struct svr4_sys_fstatvfs64_args *uap; 1518{ 1519 struct fstatfs_args fs_args; 1520 caddr_t sg = stackgap_init(); 1521 struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs)); 1522 struct statfs bfs; 1523 struct svr4_statvfs64 sfs; 1524 int error; 1525 1526 SCARG(&fs_args, fd) = SCARG(uap, fd); 1527 SCARG(&fs_args, buf) = fs; 1528 1529 if ((error = fstatfs(td, &fs_args)) != 0) 1530 return error; 1531 1532 if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0) 1533 return error; 1534 1535 bsd_statfs_to_svr4_statvfs64(&bfs, &sfs); 1536 1537 return copyout(&sfs, SCARG(uap, fs), sizeof(sfs)); 1538} 1539 1540int 1541svr4_sys_alarm(td, uap) 1542 struct thread *td; 1543 struct svr4_sys_alarm_args *uap; 1544{ 1545 int error; 1546 struct itimerval *itp, *oitp; 1547 struct setitimer_args sa; 1548 caddr_t sg = stackgap_init(); 1549 1550 itp = stackgap_alloc(&sg, sizeof(*itp)); 1551 oitp = stackgap_alloc(&sg, sizeof(*oitp)); 1552 timevalclear(&itp->it_interval); 1553 itp->it_value.tv_sec = SCARG(uap, sec); 1554 itp->it_value.tv_usec = 0; 1555 1556 SCARG(&sa, which) = ITIMER_REAL; 1557 SCARG(&sa, itv) = itp; 1558 SCARG(&sa, oitv) = oitp; 1559 error = setitimer(td, &sa); 1560 if (error) 1561 return error; 1562 if (oitp->it_value.tv_usec) 1563 oitp->it_value.tv_sec++; 1564 td->td_retval[0] = oitp->it_value.tv_sec; 1565 return 0; 1566 1567} 1568 1569int 1570svr4_sys_gettimeofday(td, uap) 1571 struct thread *td; 1572 struct svr4_sys_gettimeofday_args *uap; 1573{ 1574 if (SCARG(uap, tp)) { 1575 struct timeval atv; 1576 1577 microtime(&atv); 1578 return copyout(&atv, SCARG(uap, tp), sizeof (atv)); 1579 } 1580 1581 return 0; 1582} 1583 1584int 1585svr4_sys_facl(td, uap) 1586 struct thread *td; 1587 struct svr4_sys_facl_args *uap; 1588{ 1589 int *retval; 1590 1591 retval = td->td_retval; 1592 *retval = 0; 1593 1594 switch (SCARG(uap, cmd)) { 1595 case SVR4_SYS_SETACL: 1596 /* We don't support acls on any filesystem */ 1597 return ENOSYS; 1598 1599 case SVR4_SYS_GETACL: 1600 return copyout(retval, &SCARG(uap, num), 1601 sizeof(SCARG(uap, num))); 1602 1603 case SVR4_SYS_GETACLCNT: 1604 return 0; 1605 1606 default: 1607 return EINVAL; 1608 } 1609} 1610 1611 1612int 1613svr4_sys_acl(td, uap) 1614 struct thread *td; 1615 struct svr4_sys_acl_args *uap; 1616{ 1617 /* XXX: for now the same */ 1618 return svr4_sys_facl(td, (struct svr4_sys_facl_args *)uap); 1619} 1620 1621int 1622svr4_sys_auditsys(td, uap) 1623 struct thread *td; 1624 struct svr4_sys_auditsys_args *uap; 1625{ 1626 /* 1627 * XXX: Big brother is *not* watching. 1628 */ 1629 return 0; 1630} 1631 1632int 1633svr4_sys_memcntl(td, uap) 1634 struct thread *td; 1635 struct svr4_sys_memcntl_args *uap; 1636{ 1637 switch (SCARG(uap, cmd)) { 1638 case SVR4_MC_SYNC: 1639 { 1640 struct msync_args msa; 1641 1642 SCARG(&msa, addr) = SCARG(uap, addr); 1643 SCARG(&msa, len) = SCARG(uap, len); 1644 SCARG(&msa, flags) = (int)SCARG(uap, arg); 1645 1646 return msync(td, &msa); 1647 } 1648 case SVR4_MC_ADVISE: 1649 { 1650 struct madvise_args maa; 1651 1652 SCARG(&maa, addr) = SCARG(uap, addr); 1653 SCARG(&maa, len) = SCARG(uap, len); 1654 SCARG(&maa, behav) = (int)SCARG(uap, arg); 1655 1656 return madvise(td, &maa); 1657 } 1658 case SVR4_MC_LOCK: 1659 case SVR4_MC_UNLOCK: 1660 case SVR4_MC_LOCKAS: 1661 case SVR4_MC_UNLOCKAS: 1662 return EOPNOTSUPP; 1663 default: 1664 return ENOSYS; 1665 } 1666} 1667 1668 1669int 1670svr4_sys_nice(td, uap) 1671 struct thread *td; 1672 struct svr4_sys_nice_args *uap; 1673{ 1674 struct setpriority_args ap; 1675 int error; 1676 1677 SCARG(&ap, which) = PRIO_PROCESS; 1678 SCARG(&ap, who) = 0; 1679 SCARG(&ap, prio) = SCARG(uap, prio); 1680 1681 if ((error = setpriority(td, &ap)) != 0) 1682 return error; 1683 1684 /* the cast is stupid, but the structures are the same */ 1685 if ((error = getpriority(td, (struct getpriority_args *)&ap)) != 0) 1686 return error; 1687 1688 return 0; 1689} 1690 1691int 1692svr4_sys_resolvepath(td, uap) 1693 struct thread *td; 1694 struct svr4_sys_resolvepath_args *uap; 1695{ 1696 struct nameidata nd; 1697 int error, *retval = td->td_retval; 1698 1699 NDINIT(&nd, LOOKUP, NOFOLLOW | SAVENAME, UIO_USERSPACE, 1700 SCARG(uap, path), td); 1701 1702 if ((error = namei(&nd)) != 0) 1703 return error; 1704 1705 if ((error = copyout(nd.ni_cnd.cn_pnbuf, SCARG(uap, buf), 1706 SCARG(uap, bufsiz))) != 0) 1707 goto bad; 1708 1709 *retval = strlen(nd.ni_cnd.cn_pnbuf) < SCARG(uap, bufsiz) ? 1710 strlen(nd.ni_cnd.cn_pnbuf) + 1 : SCARG(uap, bufsiz); 1711bad: 1712 NDFREE(&nd, NDF_ONLY_PNBUF); 1713 vput(nd.ni_vp); 1714 return error; 1715}
| 580 if ((SCARG(&mm, flags) & MAP_FIXED) == 0 && 581 SCARG(&mm, addr) != 0 && (void *)SCARG(&mm, addr) < rp) 582 SCARG(&mm, addr) = rp; 583 584 return mmap(td, &mm); 585} 586 587 588int 589svr4_sys_fchroot(td, uap) 590 struct thread *td; 591 struct svr4_sys_fchroot_args *uap; 592{ 593 struct filedesc *fdp = td->td_proc->p_fd; 594 struct vnode *vp; 595 struct file *fp; 596 int error; 597 598 if ((error = suser_td(td)) != 0) 599 return error; 600 if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0) 601 return error; 602 vp = (struct vnode *) fp->f_data; 603 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 604 if (vp->v_type != VDIR) 605 error = ENOTDIR; 606 else 607 error = VOP_ACCESS(vp, VEXEC, td->td_proc->p_ucred, td); 608 VOP_UNLOCK(vp, 0, td); 609 if (error) 610 return error; 611 VREF(vp); 612 if (fdp->fd_rdir != NULL) 613 vrele(fdp->fd_rdir); 614 fdp->fd_rdir = vp; 615 return 0; 616} 617 618 619static int 620svr4_mknod(td, retval, path, mode, dev) 621 struct thread *td; 622 register_t *retval; 623 char *path; 624 svr4_mode_t mode; 625 svr4_dev_t dev; 626{ 627 caddr_t sg = stackgap_init(); 628 629 CHECKALTEXIST(td, &sg, path); 630 631 if (S_ISFIFO(mode)) { 632 struct mkfifo_args ap; 633 SCARG(&ap, path) = path; 634 SCARG(&ap, mode) = mode; 635 return mkfifo(td, &ap); 636 } else { 637 struct mknod_args ap; 638 SCARG(&ap, path) = path; 639 SCARG(&ap, mode) = mode; 640 SCARG(&ap, dev) = dev; 641 return mknod(td, &ap); 642 } 643} 644 645 646int 647svr4_sys_mknod(td, uap) 648 register struct thread *td; 649 struct svr4_sys_mknod_args *uap; 650{ 651 int *retval = td->td_retval; 652 return svr4_mknod(td, retval, 653 SCARG(uap, path), SCARG(uap, mode), 654 (svr4_dev_t)svr4_to_bsd_odev_t(SCARG(uap, dev))); 655} 656 657 658int 659svr4_sys_xmknod(td, uap) 660 struct thread *td; 661 struct svr4_sys_xmknod_args *uap; 662{ 663 int *retval = td->td_retval; 664 return svr4_mknod(td, retval, 665 SCARG(uap, path), SCARG(uap, mode), 666 (svr4_dev_t)svr4_to_bsd_dev_t(SCARG(uap, dev))); 667} 668 669 670int 671svr4_sys_vhangup(td, uap) 672 struct thread *td; 673 struct svr4_sys_vhangup_args *uap; 674{ 675 return 0; 676} 677 678 679int 680svr4_sys_sysconfig(td, uap) 681 struct thread *td; 682 struct svr4_sys_sysconfig_args *uap; 683{ 684 int *retval; 685 686 retval = &(td->td_retval[0]); 687 688 switch (SCARG(uap, name)) { 689 case SVR4_CONFIG_UNUSED: 690 *retval = 0; 691 break; 692 case SVR4_CONFIG_NGROUPS: 693 *retval = NGROUPS_MAX; 694 break; 695 case SVR4_CONFIG_CHILD_MAX: 696 *retval = maxproc; 697 break; 698 case SVR4_CONFIG_OPEN_FILES: 699 *retval = maxfiles; 700 break; 701 case SVR4_CONFIG_POSIX_VER: 702 *retval = 198808; 703 break; 704 case SVR4_CONFIG_PAGESIZE: 705 *retval = PAGE_SIZE; 706 break; 707 case SVR4_CONFIG_CLK_TCK: 708 *retval = 60; /* should this be `hz', ie. 100? */ 709 break; 710 case SVR4_CONFIG_XOPEN_VER: 711 *retval = 2; /* XXX: What should that be? */ 712 break; 713 case SVR4_CONFIG_PROF_TCK: 714 *retval = 60; /* XXX: What should that be? */ 715 break; 716 case SVR4_CONFIG_NPROC_CONF: 717 *retval = 1; /* Only one processor for now */ 718 break; 719 case SVR4_CONFIG_NPROC_ONLN: 720 *retval = 1; /* And it better be online */ 721 break; 722 case SVR4_CONFIG_AIO_LISTIO_MAX: 723 case SVR4_CONFIG_AIO_MAX: 724 case SVR4_CONFIG_AIO_PRIO_DELTA_MAX: 725 *retval = 0; /* No aio support */ 726 break; 727 case SVR4_CONFIG_DELAYTIMER_MAX: 728 *retval = 0; /* No delaytimer support */ 729 break; 730 case SVR4_CONFIG_MQ_OPEN_MAX: 731 *retval = msginfo.msgmni; 732 break; 733 case SVR4_CONFIG_MQ_PRIO_MAX: 734 *retval = 0; /* XXX: Don't know */ 735 break; 736 case SVR4_CONFIG_RTSIG_MAX: 737 *retval = 0; 738 break; 739 case SVR4_CONFIG_SEM_NSEMS_MAX: 740 *retval = seminfo.semmni; 741 break; 742 case SVR4_CONFIG_SEM_VALUE_MAX: 743 *retval = seminfo.semvmx; 744 break; 745 case SVR4_CONFIG_SIGQUEUE_MAX: 746 *retval = 0; /* XXX: Don't know */ 747 break; 748 case SVR4_CONFIG_SIGRT_MIN: 749 case SVR4_CONFIG_SIGRT_MAX: 750 *retval = 0; /* No real time signals */ 751 break; 752 case SVR4_CONFIG_TIMER_MAX: 753 *retval = 3; /* XXX: real, virtual, profiling */ 754 break; 755#if defined(NOTYET) 756 case SVR4_CONFIG_PHYS_PAGES: 757#if defined(UVM) 758 *retval = uvmexp.free; /* XXX: free instead of total */ 759#else 760 *retval = cnt.v_free_count; /* XXX: free instead of total */ 761#endif 762 break; 763 case SVR4_CONFIG_AVPHYS_PAGES: 764#if defined(UVM) 765 *retval = uvmexp.active; /* XXX: active instead of avg */ 766#else 767 *retval = cnt.v_active_count; /* XXX: active instead of avg */ 768#endif 769 break; 770#endif /* NOTYET */ 771 772 default: 773 return EINVAL; 774 } 775 return 0; 776} 777 778extern int swap_pager_full; 779 780/* ARGSUSED */ 781int 782svr4_sys_break(td, uap) 783 struct thread *td; 784 struct svr4_sys_break_args *uap; 785{ 786 struct vmspace *vm = td->td_proc->p_vmspace; 787 vm_offset_t new, old, base, ns; 788 int rv; 789 790 base = round_page((vm_offset_t) vm->vm_daddr); 791 ns = (vm_offset_t)SCARG(uap, nsize); 792 new = round_page(ns); 793 /* For p_rlimit. */ 794 mtx_assert(&Giant, MA_OWNED); 795 if (new > base) { 796 if ((new - base) > (unsigned) td->td_proc->p_rlimit[RLIMIT_DATA].rlim_cur) { 797 return ENOMEM; 798 } 799 if (new >= VM_MAXUSER_ADDRESS) { 800 return (ENOMEM); 801 } 802 } else if (new < base) { 803 /* 804 * This is simply an invalid value. If someone wants to 805 * do fancy address space manipulations, mmap and munmap 806 * can do most of what the user would want. 807 */ 808 return EINVAL; 809 } 810 811 old = base + ctob(vm->vm_dsize); 812 813 if (new > old) { 814 vm_size_t diff; 815 if (swap_pager_full) { 816 return (ENOMEM); 817 } 818 diff = new - old; 819 rv = vm_map_find(&vm->vm_map, NULL, 0, &old, diff, FALSE, 820 VM_PROT_ALL, VM_PROT_ALL, 0); 821 if (rv != KERN_SUCCESS) { 822 return (ENOMEM); 823 } 824 vm->vm_dsize += btoc(diff); 825 } else if (new < old) { 826 rv = vm_map_remove(&vm->vm_map, new, old); 827 if (rv != KERN_SUCCESS) { 828 return (ENOMEM); 829 } 830 vm->vm_dsize -= btoc(old - new); 831 } 832 833 return (0); 834} 835 836static __inline clock_t 837timeval_to_clock_t(tv) 838 struct timeval *tv; 839{ 840 return tv->tv_sec * hz + tv->tv_usec / (1000000 / hz); 841} 842 843 844int 845svr4_sys_times(td, uap) 846 struct thread *td; 847 struct svr4_sys_times_args *uap; 848{ 849 int error, *retval = td->td_retval; 850 struct tms tms; 851 struct timeval t; 852 struct rusage *ru; 853 struct rusage r; 854 struct getrusage_args ga; 855 856 caddr_t sg = stackgap_init(); 857 ru = stackgap_alloc(&sg, sizeof(struct rusage)); 858 859 SCARG(&ga, who) = RUSAGE_SELF; 860 SCARG(&ga, rusage) = ru; 861 862 error = getrusage(td, &ga); 863 if (error) 864 return error; 865 866 if ((error = copyin(ru, &r, sizeof r)) != 0) 867 return error; 868 869 tms.tms_utime = timeval_to_clock_t(&r.ru_utime); 870 tms.tms_stime = timeval_to_clock_t(&r.ru_stime); 871 872 SCARG(&ga, who) = RUSAGE_CHILDREN; 873 error = getrusage(td, &ga); 874 if (error) 875 return error; 876 877 if ((error = copyin(ru, &r, sizeof r)) != 0) 878 return error; 879 880 tms.tms_cutime = timeval_to_clock_t(&r.ru_utime); 881 tms.tms_cstime = timeval_to_clock_t(&r.ru_stime); 882 883 microtime(&t); 884 *retval = timeval_to_clock_t(&t); 885 886 return copyout(&tms, SCARG(uap, tp), sizeof(tms)); 887} 888 889 890int 891svr4_sys_ulimit(td, uap) 892 struct thread *td; 893 struct svr4_sys_ulimit_args *uap; 894{ 895 int *retval = td->td_retval; 896 897 switch (SCARG(uap, cmd)) { 898 case SVR4_GFILLIM: 899 /* For p_rlimit below. */ 900 mtx_assert(&Giant, MA_OWNED); 901 *retval = td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur / 512; 902 if (*retval == -1) 903 *retval = 0x7fffffff; 904 return 0; 905 906 case SVR4_SFILLIM: 907 { 908 int error; 909 struct __setrlimit_args srl; 910 struct rlimit krl; 911 caddr_t sg = stackgap_init(); 912 struct rlimit *url = (struct rlimit *) 913 stackgap_alloc(&sg, sizeof *url); 914 915 krl.rlim_cur = SCARG(uap, newlimit) * 512; 916 mtx_assert(&Giant, MA_OWNED); 917 krl.rlim_max = td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_max; 918 919 error = copyout(&krl, url, sizeof(*url)); 920 if (error) 921 return error; 922 923 SCARG(&srl, which) = RLIMIT_FSIZE; 924 SCARG(&srl, rlp) = url; 925 926 error = setrlimit(td, &srl); 927 if (error) 928 return error; 929 930 mtx_assert(&Giant, MA_OWNED); 931 *retval = td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur; 932 if (*retval == -1) 933 *retval = 0x7fffffff; 934 return 0; 935 } 936 937 case SVR4_GMEMLIM: 938 { 939 struct vmspace *vm = td->td_proc->p_vmspace; 940 register_t r; 941 942 mtx_assert(&Giant, MA_OWNED); 943 r = td->td_proc->p_rlimit[RLIMIT_DATA].rlim_cur; 944 945 if (r == -1) 946 r = 0x7fffffff; 947 r += (long) vm->vm_daddr; 948 if (r < 0) 949 r = 0x7fffffff; 950 *retval = r; 951 return 0; 952 } 953 954 case SVR4_GDESLIM: 955 mtx_assert(&Giant, MA_OWNED); 956 *retval = td->td_proc->p_rlimit[RLIMIT_NOFILE].rlim_cur; 957 if (*retval == -1) 958 *retval = 0x7fffffff; 959 return 0; 960 961 default: 962 return EINVAL; 963 } 964} 965 966static struct proc * 967svr4_pfind(pid) 968 pid_t pid; 969{ 970 struct proc *p; 971 972 /* look in the live processes */ 973 if ((p = pfind(pid)) == NULL) 974 /* look in the zombies */ 975 p = zpfind(pid); 976 977 return p; 978} 979 980 981int 982svr4_sys_pgrpsys(td, uap) 983 struct thread *td; 984 struct svr4_sys_pgrpsys_args *uap; 985{ 986 int *retval = td->td_retval; 987 struct proc *p = td->td_proc; 988 989 switch (SCARG(uap, cmd)) { 990 case 1: /* setpgrp() */ 991 /* 992 * SVR4 setpgrp() (which takes no arguments) has the 993 * semantics that the session ID is also created anew, so 994 * in almost every sense, setpgrp() is identical to 995 * setsid() for SVR4. (Under BSD, the difference is that 996 * a setpgid(0,0) will not create a new session.) 997 */ 998 setsid(td, NULL); 999 /*FALLTHROUGH*/ 1000 1001 case 0: /* getpgrp() */ 1002 *retval = p->p_pgrp->pg_id; 1003 return 0; 1004 1005 case 2: /* getsid(pid) */ 1006 if (SCARG(uap, pid) != 0 && 1007 (p = svr4_pfind(SCARG(uap, pid))) == NULL) 1008 return ESRCH; 1009 /* 1010 * This has already been initialized to the pid of 1011 * the session leader. 1012 */ 1013 *retval = (register_t) p->p_session->s_leader->p_pid; 1014 PROC_UNLOCK(p); 1015 return 0; 1016 1017 case 3: /* setsid() */ 1018 return setsid(td, NULL); 1019 1020 case 4: /* getpgid(pid) */ 1021 1022 if (SCARG(uap, pid) != 0 && 1023 (p = svr4_pfind(SCARG(uap, pid))) == NULL) 1024 return ESRCH; 1025 1026 *retval = (int) p->p_pgrp->pg_id; 1027 PROC_UNLOCK(p); 1028 return 0; 1029 1030 case 5: /* setpgid(pid, pgid); */ 1031 { 1032 struct setpgid_args sa; 1033 1034 SCARG(&sa, pid) = SCARG(uap, pid); 1035 SCARG(&sa, pgid) = SCARG(uap, pgid); 1036 return setpgid(td, &sa); 1037 } 1038 1039 default: 1040 return EINVAL; 1041 } 1042} 1043 1044#define syscallarg(x) union { x datum; register_t pad; } 1045 1046struct svr4_hrtcntl_args { 1047 int cmd; 1048 int fun; 1049 int clk; 1050 svr4_hrt_interval_t * iv; 1051 svr4_hrt_time_t * ti; 1052}; 1053 1054 1055static int 1056svr4_hrtcntl(td, uap, retval) 1057 struct thread *td; 1058 struct svr4_hrtcntl_args *uap; 1059 register_t *retval; 1060{ 1061 switch (SCARG(uap, fun)) { 1062 case SVR4_HRT_CNTL_RES: 1063 DPRINTF(("htrcntl(RES)\n")); 1064 *retval = SVR4_HRT_USEC; 1065 return 0; 1066 1067 case SVR4_HRT_CNTL_TOFD: 1068 DPRINTF(("htrcntl(TOFD)\n")); 1069 { 1070 struct timeval tv; 1071 svr4_hrt_time_t t; 1072 if (SCARG(uap, clk) != SVR4_HRT_CLK_STD) { 1073 DPRINTF(("clk == %d\n", SCARG(uap, clk))); 1074 return EINVAL; 1075 } 1076 if (SCARG(uap, ti) == NULL) { 1077 DPRINTF(("ti NULL\n")); 1078 return EINVAL; 1079 } 1080 microtime(&tv); 1081 t.h_sec = tv.tv_sec; 1082 t.h_rem = tv.tv_usec; 1083 t.h_res = SVR4_HRT_USEC; 1084 return copyout(&t, SCARG(uap, ti), sizeof(t)); 1085 } 1086 1087 case SVR4_HRT_CNTL_START: 1088 DPRINTF(("htrcntl(START)\n")); 1089 return ENOSYS; 1090 1091 case SVR4_HRT_CNTL_GET: 1092 DPRINTF(("htrcntl(GET)\n")); 1093 return ENOSYS; 1094 default: 1095 DPRINTF(("Bad htrcntl command %d\n", SCARG(uap, fun))); 1096 return ENOSYS; 1097 } 1098} 1099 1100 1101int 1102svr4_sys_hrtsys(td, uap) 1103 struct thread *td; 1104 struct svr4_sys_hrtsys_args *uap; 1105{ 1106 int *retval = td->td_retval; 1107 1108 switch (SCARG(uap, cmd)) { 1109 case SVR4_HRT_CNTL: 1110 return svr4_hrtcntl(td, (struct svr4_hrtcntl_args *) uap, 1111 retval); 1112 1113 case SVR4_HRT_ALRM: 1114 DPRINTF(("hrtalarm\n")); 1115 return ENOSYS; 1116 1117 case SVR4_HRT_SLP: 1118 DPRINTF(("hrtsleep\n")); 1119 return ENOSYS; 1120 1121 case SVR4_HRT_CAN: 1122 DPRINTF(("hrtcancel\n")); 1123 return ENOSYS; 1124 1125 default: 1126 DPRINTF(("Bad hrtsys command %d\n", SCARG(uap, cmd))); 1127 return EINVAL; 1128 } 1129} 1130 1131 1132static int 1133svr4_setinfo(p, st, s) 1134 struct proc *p; 1135 int st; 1136 svr4_siginfo_t *s; 1137{ 1138 svr4_siginfo_t i; 1139 int sig; 1140 1141 memset(&i, 0, sizeof(i)); 1142 1143 i.si_signo = SVR4_SIGCHLD; 1144 i.si_errno = 0; /* XXX? */ 1145 1146 if (p) { 1147 i.si_pid = p->p_pid; 1148 mtx_lock_spin(&sched_lock); 1149 if (p->p_stat == SZOMB) { 1150 i.si_stime = p->p_ru->ru_stime.tv_sec; 1151 i.si_utime = p->p_ru->ru_utime.tv_sec; 1152 } 1153 else { 1154 i.si_stime = p->p_stats->p_ru.ru_stime.tv_sec; 1155 i.si_utime = p->p_stats->p_ru.ru_utime.tv_sec; 1156 } 1157 mtx_unlock_spin(&sched_lock); 1158 } 1159 1160 if (WIFEXITED(st)) { 1161 i.si_status = WEXITSTATUS(st); 1162 i.si_code = SVR4_CLD_EXITED; 1163 } else if (WIFSTOPPED(st)) { 1164 sig = WSTOPSIG(st); 1165 if (sig >= 0 && sig < NSIG) 1166 i.si_status = SVR4_BSD2SVR4_SIG(sig); 1167 1168 if (i.si_status == SVR4_SIGCONT) 1169 i.si_code = SVR4_CLD_CONTINUED; 1170 else 1171 i.si_code = SVR4_CLD_STOPPED; 1172 } else { 1173 sig = WTERMSIG(st); 1174 if (sig >= 0 && sig < NSIG) 1175 i.si_status = SVR4_BSD2SVR4_SIG(sig); 1176 1177 if (WCOREDUMP(st)) 1178 i.si_code = SVR4_CLD_DUMPED; 1179 else 1180 i.si_code = SVR4_CLD_KILLED; 1181 } 1182 1183 DPRINTF(("siginfo [pid %ld signo %d code %d errno %d status %d]\n", 1184 i.si_pid, i.si_signo, i.si_code, i.si_errno, i.si_status)); 1185 1186 return copyout(&i, s, sizeof(i)); 1187} 1188 1189 1190int 1191svr4_sys_waitsys(td, uap) 1192 struct thread *td; 1193 struct svr4_sys_waitsys_args *uap; 1194{ 1195 int nfound; 1196 int error, *retval = td->td_retval; 1197 struct proc *q, *t; 1198 1199 1200 switch (SCARG(uap, grp)) { 1201 case SVR4_P_PID: 1202 break; 1203 1204 case SVR4_P_PGID: 1205 SCARG(uap, id) = -td->td_proc->p_pgid; 1206 break; 1207 1208 case SVR4_P_ALL: 1209 SCARG(uap, id) = WAIT_ANY; 1210 break; 1211 1212 default: 1213 return EINVAL; 1214 } 1215 1216 DPRINTF(("waitsys(%d, %d, %p, %x)\n", 1217 SCARG(uap, grp), SCARG(uap, id), 1218 SCARG(uap, info), SCARG(uap, options))); 1219 1220loop: 1221 nfound = 0; 1222 sx_slock(&proctree_lock); 1223 LIST_FOREACH(q, &td->td_proc->p_children, p_sibling) { 1224 if (SCARG(uap, id) != WAIT_ANY && 1225 q->p_pid != SCARG(uap, id) && 1226 q->p_pgid != -SCARG(uap, id)) { 1227 DPRINTF(("pid %d pgid %d != %d\n", q->p_pid, 1228 q->p_pgid, SCARG(uap, id))); 1229 continue; 1230 } 1231 nfound++; 1232 PROC_LOCK(q); 1233 mtx_lock_spin(&sched_lock); 1234 if (q->p_stat == SZOMB && 1235 ((SCARG(uap, options) & (SVR4_WEXITED|SVR4_WTRAPPED)))) { 1236 mtx_unlock_spin(&sched_lock); 1237 PROC_UNLOCK(q); 1238 sx_sunlock(&proctree_lock); 1239 *retval = 0; 1240 DPRINTF(("found %d\n", q->p_pid)); 1241 error = svr4_setinfo(q, q->p_xstat, SCARG(uap, info)); 1242 if (error != 0) 1243 return error; 1244 1245 1246 if ((SCARG(uap, options) & SVR4_WNOWAIT)) { 1247 DPRINTF(("Don't wait\n")); 1248 return 0; 1249 } 1250 1251 /* 1252 * If we got the child via ptrace(2) or procfs, and 1253 * the parent is different (meaning the process was 1254 * attached, rather than run as a child), then we need 1255 * to give it back to the old parent, and send the 1256 * parent a SIGCHLD. The rest of the cleanup will be 1257 * done when the old parent waits on the child. 1258 */ 1259 sx_xlock(&proctree_lock); 1260 PROC_LOCK(q); 1261 if (q->p_flag & P_TRACED) { 1262 if (q->p_oppid != q->p_pptr->p_pid) { 1263 PROC_UNLOCK(q); 1264 t = pfind(q->p_oppid); 1265 PROC_LOCK(q); 1266 proc_reparent(q, t ? t : initproc); 1267 q->p_oppid = 0; 1268 q->p_flag &= ~(P_TRACED | P_WAITED); 1269 PROC_UNLOCK(q); 1270 psignal(t, SIGCHLD); 1271 wakeup(t); 1272 PROC_UNLOCK(t); 1273 sx_xunlock(&proctree_lock); 1274 return 0; 1275 } 1276 } 1277 PROC_UNLOCK(q); 1278 sx_xunlock(&proctree_lock); 1279 q->p_xstat = 0; 1280 ruadd(&td->td_proc->p_stats->p_cru, q->p_ru); 1281 FREE(q->p_ru, M_ZOMBIE); 1282 q->p_ru = 0; 1283 1284 /* 1285 * Decrement the count of procs running with this uid. 1286 */ 1287 (void)chgproccnt(q->p_ucred->cr_ruidinfo, -1, 0); 1288 1289 /* 1290 * Release reference to text vnode. 1291 */ 1292 if (q->p_textvp) 1293 vrele(q->p_textvp); 1294 1295 /* 1296 * Free up credentials. 1297 */ 1298 crfree(q->p_ucred); 1299 q->p_ucred = NULL; 1300 1301 /* 1302 * Remove unused arguments 1303 */ 1304 if (q->p_args && --q->p_args->ar_ref == 0) 1305 FREE(q->p_args, M_PARGS); 1306 PROC_UNLOCK(q); 1307 1308 /* 1309 * Finally finished with old proc entry. 1310 * Unlink it from its process group and free it. 1311 */ 1312 leavepgrp(q); 1313 1314 sx_xlock(&allproc_lock); 1315 LIST_REMOVE(q, p_list); /* off zombproc */ 1316 sx_xunlock(&allproc_lock); 1317 1318 sx_xlock(&proctree_lock); 1319 LIST_REMOVE(q, p_sibling); 1320 sx_xunlock(&proctree_lock); 1321 1322 PROC_LOCK(q); 1323 if (--q->p_procsig->ps_refcnt == 0) { 1324 if (q->p_sigacts != &q->p_uarea->u_sigacts) 1325 FREE(q->p_sigacts, M_SUBPROC); 1326 FREE(q->p_procsig, M_SUBPROC); 1327 q->p_procsig = NULL; 1328 } 1329 PROC_UNLOCK(q); 1330 1331 /* 1332 * Give machine-dependent layer a chance 1333 * to free anything that cpu_exit couldn't 1334 * release while still running in process context. 1335 */ 1336 cpu_wait(q); 1337#if defined(__NetBSD__) 1338 pool_put(&proc_pool, q); 1339#endif 1340#ifdef __FreeBSD__ 1341 mtx_destroy(&q->p_mtx); 1342 zfree(proc_zone, q); 1343#endif 1344 nprocs--; 1345 return 0; 1346 } 1347 if (q->p_stat == SSTOP && (q->p_flag & P_WAITED) == 0 && 1348 (q->p_flag & P_TRACED || 1349 (SCARG(uap, options) & (SVR4_WSTOPPED|SVR4_WCONTINUED)))) { 1350 mtx_unlock_spin(&sched_lock); 1351 DPRINTF(("jobcontrol %d\n", q->p_pid)); 1352 if (((SCARG(uap, options) & SVR4_WNOWAIT)) == 0) 1353 q->p_flag |= P_WAITED; 1354 PROC_UNLOCK(q); 1355 *retval = 0; 1356 return svr4_setinfo(q, W_STOPCODE(q->p_xstat), 1357 SCARG(uap, info)); 1358 } 1359 mtx_unlock_spin(&sched_lock); 1360 PROC_UNLOCK(q); 1361 } 1362 1363 if (nfound == 0) 1364 return ECHILD; 1365 1366 if (SCARG(uap, options) & SVR4_WNOHANG) { 1367 *retval = 0; 1368 if ((error = svr4_setinfo(NULL, 0, SCARG(uap, info))) != 0) 1369 return error; 1370 return 0; 1371 } 1372 1373 if ((error = tsleep((caddr_t)td->td_proc, PWAIT | PCATCH, "svr4_wait", 0)) != 0) 1374 return error; 1375 goto loop; 1376} 1377 1378 1379static void 1380bsd_statfs_to_svr4_statvfs(bfs, sfs) 1381 const struct statfs *bfs; 1382 struct svr4_statvfs *sfs; 1383{ 1384 sfs->f_bsize = bfs->f_iosize; /* XXX */ 1385 sfs->f_frsize = bfs->f_bsize; 1386 sfs->f_blocks = bfs->f_blocks; 1387 sfs->f_bfree = bfs->f_bfree; 1388 sfs->f_bavail = bfs->f_bavail; 1389 sfs->f_files = bfs->f_files; 1390 sfs->f_ffree = bfs->f_ffree; 1391 sfs->f_favail = bfs->f_ffree; 1392 sfs->f_fsid = bfs->f_fsid.val[0]; 1393 memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype)); 1394 sfs->f_flag = 0; 1395 if (bfs->f_flags & MNT_RDONLY) 1396 sfs->f_flag |= SVR4_ST_RDONLY; 1397 if (bfs->f_flags & MNT_NOSUID) 1398 sfs->f_flag |= SVR4_ST_NOSUID; 1399 sfs->f_namemax = MAXNAMLEN; 1400 memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */ 1401 memset(sfs->f_filler, 0, sizeof(sfs->f_filler)); 1402} 1403 1404 1405static void 1406bsd_statfs_to_svr4_statvfs64(bfs, sfs) 1407 const struct statfs *bfs; 1408 struct svr4_statvfs64 *sfs; 1409{ 1410 sfs->f_bsize = bfs->f_iosize; /* XXX */ 1411 sfs->f_frsize = bfs->f_bsize; 1412 sfs->f_blocks = bfs->f_blocks; 1413 sfs->f_bfree = bfs->f_bfree; 1414 sfs->f_bavail = bfs->f_bavail; 1415 sfs->f_files = bfs->f_files; 1416 sfs->f_ffree = bfs->f_ffree; 1417 sfs->f_favail = bfs->f_ffree; 1418 sfs->f_fsid = bfs->f_fsid.val[0]; 1419 memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype)); 1420 sfs->f_flag = 0; 1421 if (bfs->f_flags & MNT_RDONLY) 1422 sfs->f_flag |= SVR4_ST_RDONLY; 1423 if (bfs->f_flags & MNT_NOSUID) 1424 sfs->f_flag |= SVR4_ST_NOSUID; 1425 sfs->f_namemax = MAXNAMLEN; 1426 memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */ 1427 memset(sfs->f_filler, 0, sizeof(sfs->f_filler)); 1428} 1429 1430 1431int 1432svr4_sys_statvfs(td, uap) 1433 struct thread *td; 1434 struct svr4_sys_statvfs_args *uap; 1435{ 1436 struct statfs_args fs_args; 1437 caddr_t sg = stackgap_init(); 1438 struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs)); 1439 struct statfs bfs; 1440 struct svr4_statvfs sfs; 1441 int error; 1442 1443 CHECKALTEXIST(td, &sg, SCARG(uap, path)); 1444 SCARG(&fs_args, path) = SCARG(uap, path); 1445 SCARG(&fs_args, buf) = fs; 1446 1447 if ((error = statfs(td, &fs_args)) != 0) 1448 return error; 1449 1450 if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0) 1451 return error; 1452 1453 bsd_statfs_to_svr4_statvfs(&bfs, &sfs); 1454 1455 return copyout(&sfs, SCARG(uap, fs), sizeof(sfs)); 1456} 1457 1458 1459int 1460svr4_sys_fstatvfs(td, uap) 1461 struct thread *td; 1462 struct svr4_sys_fstatvfs_args *uap; 1463{ 1464 struct fstatfs_args fs_args; 1465 caddr_t sg = stackgap_init(); 1466 struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs)); 1467 struct statfs bfs; 1468 struct svr4_statvfs sfs; 1469 int error; 1470 1471 SCARG(&fs_args, fd) = SCARG(uap, fd); 1472 SCARG(&fs_args, buf) = fs; 1473 1474 if ((error = fstatfs(td, &fs_args)) != 0) 1475 return error; 1476 1477 if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0) 1478 return error; 1479 1480 bsd_statfs_to_svr4_statvfs(&bfs, &sfs); 1481 1482 return copyout(&sfs, SCARG(uap, fs), sizeof(sfs)); 1483} 1484 1485 1486int 1487svr4_sys_statvfs64(td, uap) 1488 struct thread *td; 1489 struct svr4_sys_statvfs64_args *uap; 1490{ 1491 struct statfs_args fs_args; 1492 caddr_t sg = stackgap_init(); 1493 struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs)); 1494 struct statfs bfs; 1495 struct svr4_statvfs64 sfs; 1496 int error; 1497 1498 CHECKALTEXIST(td, &sg, SCARG(uap, path)); 1499 SCARG(&fs_args, path) = SCARG(uap, path); 1500 SCARG(&fs_args, buf) = fs; 1501 1502 if ((error = statfs(td, &fs_args)) != 0) 1503 return error; 1504 1505 if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0) 1506 return error; 1507 1508 bsd_statfs_to_svr4_statvfs64(&bfs, &sfs); 1509 1510 return copyout(&sfs, SCARG(uap, fs), sizeof(sfs)); 1511} 1512 1513 1514int 1515svr4_sys_fstatvfs64(td, uap) 1516 struct thread *td; 1517 struct svr4_sys_fstatvfs64_args *uap; 1518{ 1519 struct fstatfs_args fs_args; 1520 caddr_t sg = stackgap_init(); 1521 struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs)); 1522 struct statfs bfs; 1523 struct svr4_statvfs64 sfs; 1524 int error; 1525 1526 SCARG(&fs_args, fd) = SCARG(uap, fd); 1527 SCARG(&fs_args, buf) = fs; 1528 1529 if ((error = fstatfs(td, &fs_args)) != 0) 1530 return error; 1531 1532 if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0) 1533 return error; 1534 1535 bsd_statfs_to_svr4_statvfs64(&bfs, &sfs); 1536 1537 return copyout(&sfs, SCARG(uap, fs), sizeof(sfs)); 1538} 1539 1540int 1541svr4_sys_alarm(td, uap) 1542 struct thread *td; 1543 struct svr4_sys_alarm_args *uap; 1544{ 1545 int error; 1546 struct itimerval *itp, *oitp; 1547 struct setitimer_args sa; 1548 caddr_t sg = stackgap_init(); 1549 1550 itp = stackgap_alloc(&sg, sizeof(*itp)); 1551 oitp = stackgap_alloc(&sg, sizeof(*oitp)); 1552 timevalclear(&itp->it_interval); 1553 itp->it_value.tv_sec = SCARG(uap, sec); 1554 itp->it_value.tv_usec = 0; 1555 1556 SCARG(&sa, which) = ITIMER_REAL; 1557 SCARG(&sa, itv) = itp; 1558 SCARG(&sa, oitv) = oitp; 1559 error = setitimer(td, &sa); 1560 if (error) 1561 return error; 1562 if (oitp->it_value.tv_usec) 1563 oitp->it_value.tv_sec++; 1564 td->td_retval[0] = oitp->it_value.tv_sec; 1565 return 0; 1566 1567} 1568 1569int 1570svr4_sys_gettimeofday(td, uap) 1571 struct thread *td; 1572 struct svr4_sys_gettimeofday_args *uap; 1573{ 1574 if (SCARG(uap, tp)) { 1575 struct timeval atv; 1576 1577 microtime(&atv); 1578 return copyout(&atv, SCARG(uap, tp), sizeof (atv)); 1579 } 1580 1581 return 0; 1582} 1583 1584int 1585svr4_sys_facl(td, uap) 1586 struct thread *td; 1587 struct svr4_sys_facl_args *uap; 1588{ 1589 int *retval; 1590 1591 retval = td->td_retval; 1592 *retval = 0; 1593 1594 switch (SCARG(uap, cmd)) { 1595 case SVR4_SYS_SETACL: 1596 /* We don't support acls on any filesystem */ 1597 return ENOSYS; 1598 1599 case SVR4_SYS_GETACL: 1600 return copyout(retval, &SCARG(uap, num), 1601 sizeof(SCARG(uap, num))); 1602 1603 case SVR4_SYS_GETACLCNT: 1604 return 0; 1605 1606 default: 1607 return EINVAL; 1608 } 1609} 1610 1611 1612int 1613svr4_sys_acl(td, uap) 1614 struct thread *td; 1615 struct svr4_sys_acl_args *uap; 1616{ 1617 /* XXX: for now the same */ 1618 return svr4_sys_facl(td, (struct svr4_sys_facl_args *)uap); 1619} 1620 1621int 1622svr4_sys_auditsys(td, uap) 1623 struct thread *td; 1624 struct svr4_sys_auditsys_args *uap; 1625{ 1626 /* 1627 * XXX: Big brother is *not* watching. 1628 */ 1629 return 0; 1630} 1631 1632int 1633svr4_sys_memcntl(td, uap) 1634 struct thread *td; 1635 struct svr4_sys_memcntl_args *uap; 1636{ 1637 switch (SCARG(uap, cmd)) { 1638 case SVR4_MC_SYNC: 1639 { 1640 struct msync_args msa; 1641 1642 SCARG(&msa, addr) = SCARG(uap, addr); 1643 SCARG(&msa, len) = SCARG(uap, len); 1644 SCARG(&msa, flags) = (int)SCARG(uap, arg); 1645 1646 return msync(td, &msa); 1647 } 1648 case SVR4_MC_ADVISE: 1649 { 1650 struct madvise_args maa; 1651 1652 SCARG(&maa, addr) = SCARG(uap, addr); 1653 SCARG(&maa, len) = SCARG(uap, len); 1654 SCARG(&maa, behav) = (int)SCARG(uap, arg); 1655 1656 return madvise(td, &maa); 1657 } 1658 case SVR4_MC_LOCK: 1659 case SVR4_MC_UNLOCK: 1660 case SVR4_MC_LOCKAS: 1661 case SVR4_MC_UNLOCKAS: 1662 return EOPNOTSUPP; 1663 default: 1664 return ENOSYS; 1665 } 1666} 1667 1668 1669int 1670svr4_sys_nice(td, uap) 1671 struct thread *td; 1672 struct svr4_sys_nice_args *uap; 1673{ 1674 struct setpriority_args ap; 1675 int error; 1676 1677 SCARG(&ap, which) = PRIO_PROCESS; 1678 SCARG(&ap, who) = 0; 1679 SCARG(&ap, prio) = SCARG(uap, prio); 1680 1681 if ((error = setpriority(td, &ap)) != 0) 1682 return error; 1683 1684 /* the cast is stupid, but the structures are the same */ 1685 if ((error = getpriority(td, (struct getpriority_args *)&ap)) != 0) 1686 return error; 1687 1688 return 0; 1689} 1690 1691int 1692svr4_sys_resolvepath(td, uap) 1693 struct thread *td; 1694 struct svr4_sys_resolvepath_args *uap; 1695{ 1696 struct nameidata nd; 1697 int error, *retval = td->td_retval; 1698 1699 NDINIT(&nd, LOOKUP, NOFOLLOW | SAVENAME, UIO_USERSPACE, 1700 SCARG(uap, path), td); 1701 1702 if ((error = namei(&nd)) != 0) 1703 return error; 1704 1705 if ((error = copyout(nd.ni_cnd.cn_pnbuf, SCARG(uap, buf), 1706 SCARG(uap, bufsiz))) != 0) 1707 goto bad; 1708 1709 *retval = strlen(nd.ni_cnd.cn_pnbuf) < SCARG(uap, bufsiz) ? 1710 strlen(nd.ni_cnd.cn_pnbuf) + 1 : SCARG(uap, bufsiz); 1711bad: 1712 NDFREE(&nd, NDF_ONLY_PNBUF); 1713 vput(nd.ni_vp); 1714 return error; 1715}
|