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