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