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