Annotation of sys/compat/svr4/svr4_misc.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: svr4_misc.c,v 1.47 2007/03/15 10:22:30 art Exp $ */
! 2: /* $NetBSD: svr4_misc.c,v 1.42 1996/12/06 03:22:34 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1994 Christos Zoulas
! 6: * All rights reserved.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: * 3. The name of the author may not be used to endorse or promote products
! 17: * derived from this software without specific prior written permission
! 18: *
! 19: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 20: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 21: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 22: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 23: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 24: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 25: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 26: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 27: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 28: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 29: */
! 30:
! 31: /*
! 32: * SVR4 compatibility module.
! 33: *
! 34: * SVR4 system calls that are implemented differently in BSD are
! 35: * handled here.
! 36: */
! 37:
! 38: #include <sys/param.h>
! 39: #include <sys/systm.h>
! 40: #include <sys/exec.h>
! 41: #include <sys/exec_olf.h>
! 42: #include <sys/namei.h>
! 43: #include <sys/dirent.h>
! 44: #include <sys/proc.h>
! 45: #include <sys/sched.h>
! 46: #include <sys/file.h>
! 47: #include <sys/stat.h>
! 48: #include <sys/time.h>
! 49: #include <sys/filedesc.h>
! 50: #include <sys/ioctl.h>
! 51: #include <sys/kernel.h>
! 52: #include <sys/malloc.h>
! 53: #include <sys/mbuf.h>
! 54: #include <sys/ktrace.h>
! 55: #include <sys/mman.h>
! 56: #include <sys/mount.h>
! 57: #include <sys/pool.h>
! 58: #include <sys/resource.h>
! 59: #include <sys/resourcevar.h>
! 60: #include <sys/socket.h>
! 61: #include <sys/vnode.h>
! 62: #include <sys/uio.h>
! 63: #include <sys/wait.h>
! 64: #include <sys/utsname.h>
! 65: #include <sys/unistd.h>
! 66: #include <sys/times.h>
! 67: #include <sys/sem.h>
! 68: #include <sys/msg.h>
! 69: #include <sys/ptrace.h>
! 70: #include <sys/signalvar.h>
! 71:
! 72: #include <netinet/in.h>
! 73: #include <sys/syscallargs.h>
! 74:
! 75: #include <miscfs/specfs/specdev.h>
! 76:
! 77: #include <compat/svr4/svr4_types.h>
! 78: #include <compat/svr4/svr4_signal.h>
! 79: #include <compat/svr4/svr4_syscallargs.h>
! 80: #include <compat/svr4/svr4_util.h>
! 81: #include <compat/svr4/svr4_time.h>
! 82: #include <compat/svr4/svr4_dirent.h>
! 83: #include <compat/svr4/svr4_ulimit.h>
! 84: #include <compat/svr4/svr4_hrt.h>
! 85: #include <compat/svr4/svr4_wait.h>
! 86: #include <compat/svr4/svr4_statvfs.h>
! 87: #include <compat/svr4/svr4_sysconfig.h>
! 88: #include <compat/svr4/svr4_acl.h>
! 89:
! 90: #include <compat/common/compat_dir.h>
! 91:
! 92: #include <uvm/uvm_extern.h>
! 93:
! 94: static __inline clock_t timeval_to_clock_t(struct timeval *);
! 95: static int svr4_setinfo(struct proc *, int, svr4_siginfo_t *);
! 96:
! 97: struct svr4_hrtcntl_args;
! 98: static int svr4_hrtcntl(struct proc *, struct svr4_hrtcntl_args *,
! 99: register_t *);
! 100: static void bsd_statfs_to_svr4_statvfs(const struct statfs *,
! 101: struct svr4_statvfs *);
! 102: static void bsd_statfs_to_svr4_statvfs64(const struct statfs *,
! 103: struct svr4_statvfs64 *);
! 104: static struct proc *svr4_pfind(pid_t pid);
! 105:
! 106: static int svr4_mknod(struct proc *, register_t *, char *,
! 107: svr4_mode_t, svr4_dev_t);
! 108:
! 109: int
! 110: svr4_sys_wait(p, v, retval)
! 111: register struct proc *p;
! 112: void *v;
! 113: register_t *retval;
! 114: {
! 115: struct svr4_sys_wait_args *uap = v;
! 116: struct sys_wait4_args w4;
! 117: int error;
! 118: size_t sz = sizeof(*SCARG(&w4, status));
! 119:
! 120: SCARG(&w4, rusage) = NULL;
! 121: SCARG(&w4, options) = 0;
! 122:
! 123: if (SCARG(uap, status) == NULL) {
! 124: caddr_t sg = stackgap_init(p->p_emul);
! 125: SCARG(&w4, status) = stackgap_alloc(&sg, sz);
! 126: }
! 127: else
! 128: SCARG(&w4, status) = SCARG(uap, status);
! 129:
! 130: SCARG(&w4, pid) = WAIT_ANY;
! 131:
! 132: if ((error = sys_wait4(p, &w4, retval)) != 0)
! 133: return error;
! 134:
! 135: /*
! 136: * It looks like wait(2) on svr4/solaris/2.4 returns
! 137: * the status in retval[1], and the pid on retval[0].
! 138: * NB: this can break if register_t stops being an int.
! 139: */
! 140: return copyin(SCARG(&w4, status), &retval[1], sz);
! 141: }
! 142:
! 143:
! 144: int
! 145: svr4_sys_execv(p, v, retval)
! 146: register struct proc *p;
! 147: void *v;
! 148: register_t *retval;
! 149: {
! 150: struct svr4_sys_execv_args /* {
! 151: syscallarg(char *) path;
! 152: syscallarg(char **) argv;
! 153: } */ *uap = v;
! 154: struct sys_execve_args ap;
! 155: caddr_t sg;
! 156:
! 157: sg = stackgap_init(p->p_emul);
! 158: SVR4_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 159:
! 160: SCARG(&ap, path) = SCARG(uap, path);
! 161: SCARG(&ap, argp) = SCARG(uap, argp);
! 162: SCARG(&ap, envp) = NULL;
! 163:
! 164: return sys_execve(p, &ap, retval);
! 165: }
! 166:
! 167:
! 168: int
! 169: svr4_sys_execve(p, v, retval)
! 170: register struct proc *p;
! 171: void *v;
! 172: register_t *retval;
! 173: {
! 174: struct svr4_sys_execve_args /* {
! 175: syscallarg(char *) path;
! 176: syscallarg(char **) argv;
! 177: syscallarg(char **) envp;
! 178: } */ *uap = v;
! 179: struct sys_execve_args ap;
! 180: caddr_t sg;
! 181:
! 182: sg = stackgap_init(p->p_emul);
! 183: SVR4_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 184:
! 185: SCARG(&ap, path) = SCARG(uap, path);
! 186: SCARG(&ap, argp) = SCARG(uap, argp);
! 187: SCARG(&ap, envp) = SCARG(uap, envp);
! 188:
! 189: return sys_execve(p, &ap, retval);
! 190: }
! 191:
! 192:
! 193: int
! 194: svr4_sys_time(p, v, retval)
! 195: register struct proc *p;
! 196: void *v;
! 197: register_t *retval;
! 198: {
! 199: struct svr4_sys_time_args *uap = v;
! 200: int error = 0;
! 201: struct timeval tv;
! 202:
! 203: microtime(&tv);
! 204: if (SCARG(uap, t))
! 205: error = copyout(&tv.tv_sec, SCARG(uap, t),
! 206: sizeof(*(SCARG(uap, t))));
! 207: *retval = (int) tv.tv_sec;
! 208:
! 209: return error;
! 210: }
! 211:
! 212:
! 213: /*
! 214: * Read SVR4-style directory entries. We suck them into kernel space so
! 215: * that they can be massaged before being copied out to user code. Like
! 216: * SunOS, we squish out `empty' entries.
! 217: *
! 218: * This is quite ugly, but what do you expect from compatibility code?
! 219: */
! 220:
! 221: int svr4_readdir_callback(void *, struct dirent *, off_t);
! 222: int svr4_readdir64_callback(void *, struct dirent *, off_t);
! 223:
! 224: struct svr4_readdir_callback_args {
! 225: caddr_t outp;
! 226: int resid;
! 227: };
! 228:
! 229: int
! 230: svr4_readdir_callback(arg, bdp, cookie)
! 231: void *arg;
! 232: struct dirent *bdp;
! 233: off_t cookie;
! 234: {
! 235: struct svr4_dirent idb;
! 236: struct svr4_readdir_callback_args *cb = arg;
! 237: int svr4_reclen;
! 238: int error;
! 239:
! 240: svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen);
! 241: if (cb->resid < svr4_reclen)
! 242: return (ENOMEM);
! 243:
! 244: idb.d_ino = (svr4_ino_t)bdp->d_fileno;
! 245: idb.d_off = (svr4_off_t)cookie;
! 246: idb.d_reclen = (u_short)svr4_reclen;
! 247: strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
! 248: if ((error = copyout((caddr_t)&idb, cb->outp, svr4_reclen)))
! 249: return (error);
! 250:
! 251: cb->outp += svr4_reclen;
! 252: cb->resid -= svr4_reclen;
! 253:
! 254: return (0);
! 255: }
! 256:
! 257: int
! 258: svr4_readdir64_callback(arg, bdp, cookie)
! 259: void *arg;
! 260: struct dirent *bdp;
! 261: off_t cookie;
! 262: {
! 263: struct svr4_dirent64 idb;
! 264: struct svr4_readdir_callback_args *cb = arg;
! 265: int svr4_reclen;
! 266: int error;
! 267:
! 268: svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen);
! 269: if (cb->resid < svr4_reclen)
! 270: return (ENOMEM);
! 271:
! 272: /*
! 273: * Massage in place to make a SVR4-shaped dirent (otherwise
! 274: * we have to worry about touching user memory outside of
! 275: * the copyout() call).
! 276: */
! 277: idb.d_ino = (svr4_ino64_t)bdp->d_fileno;
! 278: idb.d_off = (svr4_off64_t)cookie;
! 279: idb.d_reclen = (u_short)svr4_reclen;
! 280: strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
! 281: if ((error = copyout((caddr_t)&idb, cb->outp, svr4_reclen)))
! 282: return (error);
! 283:
! 284: cb->outp += svr4_reclen;
! 285: cb->resid -= svr4_reclen;
! 286:
! 287: return (0);
! 288: }
! 289:
! 290:
! 291: int
! 292: svr4_sys_getdents(p, v, retval)
! 293: register struct proc *p;
! 294: void *v;
! 295: register_t *retval;
! 296: {
! 297: struct svr4_sys_getdents_args *uap = v;
! 298: struct svr4_readdir_callback_args args;
! 299: struct file *fp;
! 300: int error;
! 301:
! 302: if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
! 303: return (error);
! 304:
! 305: args.resid = SCARG(uap, nbytes);
! 306: args.outp = (caddr_t)SCARG(uap, buf);
! 307:
! 308: error = readdir_with_callback(fp, &fp->f_offset, SCARG(uap, nbytes),
! 309: svr4_readdir_callback, &args);
! 310: FRELE(fp);
! 311: if (error)
! 312: return (error);
! 313:
! 314: *retval = SCARG(uap, nbytes) - args.resid;
! 315:
! 316: return (0);
! 317: }
! 318:
! 319: int
! 320: svr4_sys_getdents64(p, v, retval)
! 321: register struct proc *p;
! 322: void *v;
! 323: register_t *retval;
! 324: {
! 325: struct svr4_sys_getdents64_args *uap = v;
! 326: struct svr4_readdir_callback_args args;
! 327: struct file *fp;
! 328: int error;
! 329:
! 330: if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
! 331: return (error);
! 332:
! 333: args.resid = SCARG(uap, nbytes);
! 334: args.outp = (caddr_t)SCARG(uap, dp);
! 335:
! 336: error = readdir_with_callback(fp, &fp->f_offset, SCARG(uap, nbytes),
! 337: svr4_readdir64_callback, &args);
! 338: FRELE(fp);
! 339: if (error)
! 340: return (error);
! 341:
! 342: *retval = SCARG(uap, nbytes) - args.resid;
! 343:
! 344: return (0);
! 345: }
! 346:
! 347: int
! 348: svr4_sys_mmap(p, v, retval)
! 349: register struct proc *p;
! 350: void *v;
! 351: register_t *retval;
! 352: {
! 353: struct svr4_sys_mmap_args *uap = v;
! 354: struct sys_mmap_args mm;
! 355: void *rp;
! 356: #define _MAP_NEW 0x80000000
! 357: /*
! 358: * Verify the arguments.
! 359: */
! 360: if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
! 361: return EINVAL; /* XXX still needed? */
! 362:
! 363: if (SCARG(uap, len) == 0)
! 364: return EINVAL;
! 365:
! 366: SCARG(&mm, prot) = SCARG(uap, prot);
! 367: SCARG(&mm, len) = SCARG(uap, len);
! 368: SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW;
! 369: SCARG(&mm, fd) = SCARG(uap, fd);
! 370: SCARG(&mm, addr) = SCARG(uap, addr);
! 371: SCARG(&mm, pos) = SCARG(uap, pos);
! 372:
! 373: rp = (void *) round_page((vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ);
! 374: if ((SCARG(&mm, flags) & MAP_FIXED) == 0 &&
! 375: SCARG(&mm, addr) != 0 && SCARG(&mm, addr) < rp)
! 376: SCARG(&mm, addr) = rp;
! 377:
! 378: return sys_mmap(p, &mm, retval);
! 379: }
! 380:
! 381: int
! 382: svr4_sys_mmap64(p, v, retval)
! 383: register struct proc *p;
! 384: void *v;
! 385: register_t *retval;
! 386: {
! 387: struct svr4_sys_mmap64_args *uap = v;
! 388: struct sys_mmap_args mm;
! 389: void *rp;
! 390: #define _MAP_NEW 0x80000000
! 391: /*
! 392: * Verify the arguments.
! 393: */
! 394: if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
! 395: return EINVAL; /* XXX still needed? */
! 396:
! 397: if (SCARG(uap, len) == 0)
! 398: return EINVAL;
! 399:
! 400: SCARG(&mm, prot) = SCARG(uap, prot);
! 401: SCARG(&mm, len) = SCARG(uap, len);
! 402: SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW;
! 403: SCARG(&mm, fd) = SCARG(uap, fd);
! 404: SCARG(&mm, addr) = SCARG(uap, addr);
! 405: SCARG(&mm, pos) = SCARG(uap, pos);
! 406:
! 407: rp = (void *) round_page((vaddr_t)p->p_vmspace->vm_daddr + MAXDSIZ);
! 408: if ((SCARG(&mm, flags) & MAP_FIXED) == 0 &&
! 409: SCARG(&mm, addr) != 0 && SCARG(&mm, addr) < rp)
! 410: SCARG(&mm, addr) = rp;
! 411:
! 412: return sys_mmap(p, &mm, retval);
! 413: }
! 414:
! 415: int
! 416: svr4_sys_fchroot(p, v, retval)
! 417: register struct proc *p;
! 418: void *v;
! 419: register_t *retval;
! 420: {
! 421: struct svr4_sys_fchroot_args *uap = v;
! 422: struct filedesc *fdp = p->p_fd;
! 423: struct vnode *vp;
! 424: struct file *fp;
! 425: int error;
! 426:
! 427: if ((error = suser(p, 0)) != 0)
! 428: return error;
! 429: if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
! 430: return error;
! 431:
! 432: vp = (struct vnode *) fp->f_data;
! 433: vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
! 434: if (vp->v_type != VDIR)
! 435: error = ENOTDIR;
! 436: else
! 437: error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
! 438: VOP_UNLOCK(vp, 0, p);
! 439: if (error) {
! 440: FRELE(fp);
! 441: return error;
! 442: }
! 443: VREF(vp);
! 444: if (fdp->fd_rdir != NULL)
! 445: vrele(fdp->fd_rdir);
! 446: fdp->fd_rdir = vp;
! 447: FRELE(fp);
! 448: return 0;
! 449: }
! 450:
! 451: static int
! 452: svr4_mknod(p, retval, path, mode, dev)
! 453: struct proc *p;
! 454: register_t *retval;
! 455: char *path;
! 456: svr4_mode_t mode;
! 457: svr4_dev_t dev;
! 458: {
! 459: caddr_t sg = stackgap_init(p->p_emul);
! 460:
! 461: SVR4_CHECK_ALT_EXIST(p, &sg, path);
! 462:
! 463: if (S_ISFIFO(mode)) {
! 464: struct sys_mkfifo_args ap;
! 465: SCARG(&ap, path) = path;
! 466: SCARG(&ap, mode) = mode;
! 467: return sys_mkfifo(p, &ap, retval);
! 468: } else {
! 469: struct sys_mknod_args ap;
! 470: SCARG(&ap, path) = path;
! 471: SCARG(&ap, mode) = mode;
! 472: SCARG(&ap, dev) = dev;
! 473: return sys_mknod(p, &ap, retval);
! 474: }
! 475: }
! 476:
! 477:
! 478: int
! 479: svr4_sys_mknod(p, v, retval)
! 480: register struct proc *p;
! 481: void *v;
! 482: register_t *retval;
! 483: {
! 484: struct svr4_sys_mknod_args *uap = v;
! 485: return svr4_mknod(p, retval,
! 486: SCARG(uap, path), SCARG(uap, mode),
! 487: svr4_to_bsd_odev_t(SCARG(uap, dev)));
! 488: }
! 489:
! 490:
! 491: int
! 492: svr4_sys_xmknod(p, v, retval)
! 493: register struct proc *p;
! 494: void *v;
! 495: register_t *retval;
! 496: {
! 497: struct svr4_sys_xmknod_args *uap = v;
! 498: return svr4_mknod(p, retval,
! 499: SCARG(uap, path), SCARG(uap, mode),
! 500: svr4_to_bsd_dev_t(SCARG(uap, dev)));
! 501: }
! 502:
! 503:
! 504: int
! 505: svr4_sys_vhangup(p, v, retval)
! 506: struct proc *p;
! 507: void *v;
! 508: register_t *retval;
! 509: {
! 510: return 0;
! 511: }
! 512:
! 513:
! 514: int
! 515: svr4_sys_sysconfig(p, v, retval)
! 516: register struct proc *p;
! 517: void *v;
! 518: register_t *retval;
! 519: {
! 520: struct svr4_sys_sysconfig_args *uap = v;
! 521: extern int maxfiles;
! 522:
! 523: switch (SCARG(uap, name)) {
! 524: case SVR4_CONFIG_UNUSED:
! 525: *retval = 0;
! 526: break;
! 527: case SVR4_CONFIG_NGROUPS:
! 528: *retval = NGROUPS_MAX;
! 529: break;
! 530: case SVR4_CONFIG_CHILD_MAX:
! 531: *retval = maxproc;
! 532: break;
! 533: case SVR4_CONFIG_OPEN_FILES:
! 534: *retval = maxfiles;
! 535: break;
! 536: case SVR4_CONFIG_POSIX_VER:
! 537: *retval = 198808;
! 538: break;
! 539: case SVR4_CONFIG_PAGESIZE:
! 540: *retval = NBPG;
! 541: break;
! 542: case SVR4_CONFIG_CLK_TCK:
! 543: *retval = 60; /* should this be `hz', ie. 100? */
! 544: break;
! 545: case SVR4_CONFIG_XOPEN_VER:
! 546: *retval = 2; /* XXX: What should that be? */
! 547: break;
! 548: case SVR4_CONFIG_PROF_TCK:
! 549: *retval = 60; /* XXX: What should that be? */
! 550: break;
! 551: case SVR4_CONFIG_NPROC_CONF:
! 552: *retval = 1; /* Only one processor for now */
! 553: break;
! 554: case SVR4_CONFIG_NPROC_ONLN:
! 555: *retval = 1; /* And it better be online */
! 556: break;
! 557: case SVR4_CONFIG_AIO_LISTIO_MAX:
! 558: case SVR4_CONFIG_AIO_MAX:
! 559: case SVR4_CONFIG_AIO_PRIO_DELTA_MAX:
! 560: *retval = 0; /* No aio support */
! 561: break;
! 562: case SVR4_CONFIG_DELAYTIMER_MAX:
! 563: *retval = 0; /* No delaytimer support */
! 564: break;
! 565: #ifdef SYSVMSG
! 566: case SVR4_CONFIG_MQ_OPEN_MAX:
! 567: *retval = msginfo.msgmni;
! 568: break;
! 569: #endif
! 570: case SVR4_CONFIG_MQ_PRIO_MAX:
! 571: *retval = 0; /* XXX: Don't know */
! 572: break;
! 573: case SVR4_CONFIG_RTSIG_MAX:
! 574: *retval = 0;
! 575: break;
! 576: #ifdef SYSVSEM
! 577: case SVR4_CONFIG_SEM_NSEMS_MAX:
! 578: *retval = seminfo.semmni;
! 579: break;
! 580: case SVR4_CONFIG_SEM_VALUE_MAX:
! 581: *retval = seminfo.semvmx;
! 582: break;
! 583: #endif
! 584: case SVR4_CONFIG_SIGQUEUE_MAX:
! 585: *retval = 0; /* XXX: Don't know */
! 586: break;
! 587: case SVR4_CONFIG_SIGRT_MIN:
! 588: case SVR4_CONFIG_SIGRT_MAX:
! 589: *retval = 0; /* No real time signals */
! 590: break;
! 591: case SVR4_CONFIG_TIMER_MAX:
! 592: *retval = 3; /* XXX: real, virtual, profiling */
! 593: break;
! 594: case SVR4_CONFIG_PHYS_PAGES:
! 595: *retval = uvmexp.npages;
! 596: break;
! 597: case SVR4_CONFIG_AVPHYS_PAGES:
! 598: *retval = uvmexp.active; /* XXX: active instead of avg */
! 599: break;
! 600: default:
! 601: return EINVAL;
! 602: }
! 603: return 0;
! 604: }
! 605:
! 606: #define SVR4_RLIMIT_NOFILE 5 /* Other RLIMIT_* are the same */
! 607: #define SVR4_RLIMIT_VMEM 6 /* Other RLIMIT_* are the same */
! 608: #define SVR4_RLIM_NLIMITS 7
! 609:
! 610: int
! 611: svr4_sys_getrlimit(p, v, retval)
! 612: register struct proc *p;
! 613: void *v;
! 614: register_t *retval;
! 615: {
! 616: struct svr4_sys_getrlimit_args *uap = v;
! 617: struct compat_43_sys_getrlimit_args ap;
! 618:
! 619: if (SCARG(uap, which) >= SVR4_RLIM_NLIMITS)
! 620: return EINVAL;
! 621:
! 622: if (SCARG(uap, which) == SVR4_RLIMIT_NOFILE)
! 623: SCARG(uap, which) = RLIMIT_NOFILE;
! 624: if (SCARG(uap, which) == SVR4_RLIMIT_VMEM)
! 625: SCARG(uap, which) = RLIMIT_RSS;
! 626:
! 627: SCARG(&ap, which) = SCARG(uap, which);
! 628: SCARG(&ap, rlp) = SCARG(uap, rlp);
! 629:
! 630: return compat_43_sys_getrlimit(p, &ap, retval);
! 631: }
! 632:
! 633: int
! 634: svr4_sys_setrlimit(p, v, retval)
! 635: register struct proc *p;
! 636: void *v;
! 637: register_t *retval;
! 638: {
! 639: struct svr4_sys_setrlimit_args *uap = v;
! 640: struct compat_43_sys_setrlimit_args ap;
! 641:
! 642: if (SCARG(uap, which) >= SVR4_RLIM_NLIMITS)
! 643: return EINVAL;
! 644:
! 645: if (SCARG(uap, which) == SVR4_RLIMIT_NOFILE)
! 646: SCARG(uap, which) = RLIMIT_NOFILE;
! 647: if (SCARG(uap, which) == SVR4_RLIMIT_VMEM)
! 648: SCARG(uap, which) = RLIMIT_RSS;
! 649:
! 650: SCARG(&ap, which) = SCARG(uap, which);
! 651: SCARG(&ap, rlp) = SCARG(uap, rlp);
! 652:
! 653: return compat_43_sys_setrlimit(p, uap, retval);
! 654: }
! 655:
! 656:
! 657: /* ARGSUSED */
! 658: int
! 659: svr4_sys_break(p, v, retval)
! 660: register struct proc *p;
! 661: void *v;
! 662: register_t *retval;
! 663: {
! 664: struct svr4_sys_break_args *uap = v;
! 665: register struct vmspace *vm = p->p_vmspace;
! 666: vaddr_t new, old;
! 667: int error;
! 668: register int diff;
! 669:
! 670: old = (vaddr_t) vm->vm_daddr;
! 671: new = round_page((vaddr_t)SCARG(uap, nsize));
! 672: diff = new - old;
! 673:
! 674: DPRINTF(("break(1): old %lx new %lx diff %x\n", old, new, diff));
! 675:
! 676: if (diff > p->p_rlimit[RLIMIT_DATA].rlim_cur)
! 677: return ENOMEM;
! 678:
! 679: old = round_page(old + ctob(vm->vm_dsize));
! 680: DPRINTF(("break(2): dsize = %x ctob %x\n",
! 681: vm->vm_dsize, ctob(vm->vm_dsize)));
! 682:
! 683: diff = new - old;
! 684: DPRINTF(("break(3): old %lx new %lx diff %x\n", old, new, diff));
! 685:
! 686: if (diff > 0) {
! 687: error = uvm_map(&vm->vm_map, &old, diff, NULL, UVM_UNKNOWN_OFFSET,
! 688: 0, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY,
! 689: UVM_ADV_NORMAL,
! 690: UVM_FLAG_AMAPPAD|UVM_FLAG_FIXED|
! 691: UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW));
! 692: if (error) {
! 693: uprintf("sbrk: grow failed, return = %d\n", error);
! 694: return error;
! 695: }
! 696: vm->vm_dsize += btoc(diff);
! 697: } else if (diff < 0) {
! 698: diff = -diff;
! 699: uvm_deallocate(&vm->vm_map, new, diff);
! 700: vm->vm_dsize -= btoc(diff);
! 701: }
! 702: return 0;
! 703: }
! 704:
! 705: static __inline clock_t
! 706: timeval_to_clock_t(tv)
! 707: struct timeval *tv;
! 708: {
! 709: return tv->tv_sec * hz + tv->tv_usec / (1000000 / hz);
! 710: }
! 711:
! 712: int
! 713: svr4_sys_times(p, v, retval)
! 714: register struct proc *p;
! 715: void *v;
! 716: register_t *retval;
! 717: {
! 718: struct svr4_sys_times_args *uap = v;
! 719: int error;
! 720: struct tms tms;
! 721: struct timeval t;
! 722: struct rusage *ru;
! 723: struct rusage r;
! 724: struct sys_getrusage_args ga;
! 725:
! 726: caddr_t sg = stackgap_init(p->p_emul);
! 727: ru = stackgap_alloc(&sg, sizeof(struct rusage));
! 728:
! 729: SCARG(&ga, who) = RUSAGE_SELF;
! 730: SCARG(&ga, rusage) = ru;
! 731:
! 732: error = sys_getrusage(p, &ga, retval);
! 733: if (error)
! 734: return error;
! 735:
! 736: if ((error = copyin(ru, &r, sizeof r)) != 0)
! 737: return error;
! 738:
! 739: tms.tms_utime = timeval_to_clock_t(&r.ru_utime);
! 740: tms.tms_stime = timeval_to_clock_t(&r.ru_stime);
! 741:
! 742: SCARG(&ga, who) = RUSAGE_CHILDREN;
! 743: error = sys_getrusage(p, &ga, retval);
! 744: if (error)
! 745: return error;
! 746:
! 747: if ((error = copyin(ru, &r, sizeof r)) != 0)
! 748: return error;
! 749:
! 750: tms.tms_cutime = timeval_to_clock_t(&r.ru_utime);
! 751: tms.tms_cstime = timeval_to_clock_t(&r.ru_stime);
! 752:
! 753: microtime(&t);
! 754: *retval = timeval_to_clock_t(&t);
! 755:
! 756: return copyout(&tms, SCARG(uap, tp), sizeof(tms));
! 757: }
! 758:
! 759:
! 760: int
! 761: svr4_sys_ulimit(p, v, retval)
! 762: register struct proc *p;
! 763: void *v;
! 764: register_t *retval;
! 765: {
! 766: struct svr4_sys_ulimit_args *uap = v;
! 767:
! 768: switch (SCARG(uap, cmd)) {
! 769: case SVR4_GFILLIM:
! 770: *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur / 512;
! 771: return 0;
! 772:
! 773: case SVR4_SFILLIM:
! 774: {
! 775: int error;
! 776: struct sys_setrlimit_args srl;
! 777: struct rlimit krl;
! 778: caddr_t sg = stackgap_init(p->p_emul);
! 779: struct rlimit *url = (struct rlimit *)
! 780: stackgap_alloc(&sg, sizeof *url);
! 781:
! 782: krl.rlim_cur = SCARG(uap, newlimit) * 512;
! 783: krl.rlim_max = p->p_rlimit[RLIMIT_FSIZE].rlim_max;
! 784:
! 785: error = copyout(&krl, url, sizeof(*url));
! 786: if (error)
! 787: return error;
! 788:
! 789: SCARG(&srl, which) = RLIMIT_FSIZE;
! 790: SCARG(&srl, rlp) = url;
! 791:
! 792: error = sys_setrlimit(p, &srl, retval);
! 793: if (error)
! 794: return error;
! 795:
! 796: *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
! 797: return 0;
! 798: }
! 799:
! 800: case SVR4_GMEMLIM:
! 801: {
! 802: struct vmspace *vm = p->p_vmspace;
! 803: *retval = (long) vm->vm_daddr +
! 804: p->p_rlimit[RLIMIT_DATA].rlim_cur;
! 805: return 0;
! 806: }
! 807:
! 808: case SVR4_GDESLIM:
! 809: *retval = p->p_rlimit[RLIMIT_NOFILE].rlim_cur;
! 810: return 0;
! 811:
! 812: default:
! 813: return EINVAL;
! 814: }
! 815: }
! 816:
! 817:
! 818: static struct proc *
! 819: svr4_pfind(pid)
! 820: pid_t pid;
! 821: {
! 822: struct proc *p;
! 823:
! 824: /* look in the live processes */
! 825: if ((p = pfind(pid)) != NULL)
! 826: return p;
! 827:
! 828: /* look in the zombies */
! 829: LIST_FOREACH(p, &zombproc, p_list)
! 830: if (p->p_pid == pid)
! 831: return p;
! 832:
! 833: return NULL;
! 834: }
! 835:
! 836:
! 837: int
! 838: svr4_sys_pgrpsys(p, v, retval)
! 839: register struct proc *p;
! 840: void *v;
! 841: register_t *retval;
! 842: {
! 843: struct svr4_sys_pgrpsys_args *uap = v;
! 844: int error;
! 845:
! 846: switch (SCARG(uap, cmd)) {
! 847: case 0: /* getpgrp() */
! 848: *retval = p->p_pgrp->pg_id;
! 849: return 0;
! 850:
! 851: case 1: /* setpgrp() */
! 852: {
! 853: struct sys_setpgid_args sa;
! 854:
! 855: SCARG(&sa, pid) = 0;
! 856: SCARG(&sa, pgid) = 0;
! 857: if ((error = sys_setpgid(p, &sa, retval)) != 0)
! 858: return error;
! 859: *retval = p->p_pgrp->pg_id;
! 860: return 0;
! 861: }
! 862:
! 863: case 2: /* getsid(pid) */
! 864: if (SCARG(uap, pid) != 0 &&
! 865: (p = svr4_pfind(SCARG(uap, pid))) == NULL)
! 866: return ESRCH;
! 867: /*
! 868: * we return the pid of the session leader for this
! 869: * process
! 870: */
! 871: *retval = (register_t) p->p_session->s_leader->p_pid;
! 872: return 0;
! 873:
! 874: case 3: /* setsid() */
! 875: return sys_setsid(p, NULL, retval);
! 876:
! 877: case 4: /* getpgid(pid) */
! 878:
! 879: if (SCARG(uap, pid) != 0 &&
! 880: (p = svr4_pfind(SCARG(uap, pid))) == NULL)
! 881: return ESRCH;
! 882:
! 883: *retval = (int) p->p_pgrp->pg_id;
! 884: return 0;
! 885:
! 886: case 5: /* setpgid(pid, pgid); */
! 887: {
! 888: struct sys_setpgid_args sa;
! 889:
! 890: SCARG(&sa, pid) = SCARG(uap, pid);
! 891: SCARG(&sa, pgid) = SCARG(uap, pgid);
! 892: return sys_setpgid(p, &sa, retval);
! 893: }
! 894:
! 895: default:
! 896: return EINVAL;
! 897: }
! 898: }
! 899:
! 900: struct svr4_hrtcntl_args {
! 901: syscallarg(int) cmd;
! 902: syscallarg(int) fun;
! 903: syscallarg(int) clk;
! 904: syscallarg(svr4_hrt_interval_t *) iv;
! 905: syscallarg(svr4_hrt_time_t *) ti;
! 906: };
! 907:
! 908: static int
! 909: svr4_hrtcntl(p, uap, retval)
! 910: register struct proc *p;
! 911: register struct svr4_hrtcntl_args *uap;
! 912: register_t *retval;
! 913: {
! 914: switch (SCARG(uap, fun)) {
! 915: case SVR4_HRT_CNTL_RES:
! 916: DPRINTF(("htrcntl(RES)\n"));
! 917: *retval = SVR4_HRT_USEC;
! 918: return 0;
! 919:
! 920: case SVR4_HRT_CNTL_TOFD:
! 921: DPRINTF(("htrcntl(TOFD)\n"));
! 922: {
! 923: struct timeval tv;
! 924: svr4_hrt_time_t t;
! 925: if (SCARG(uap, clk) != SVR4_HRT_CLK_STD) {
! 926: DPRINTF(("clk == %d\n", SCARG(uap, clk)));
! 927: return EINVAL;
! 928: }
! 929: if (SCARG(uap, ti) == NULL) {
! 930: DPRINTF(("ti NULL\n"));
! 931: return EINVAL;
! 932: }
! 933: microtime(&tv);
! 934: t.h_sec = tv.tv_sec;
! 935: t.h_rem = tv.tv_usec;
! 936: t.h_res = SVR4_HRT_USEC;
! 937: return copyout(&t, SCARG(uap, ti), sizeof(t));
! 938: }
! 939:
! 940: case SVR4_HRT_CNTL_START:
! 941: DPRINTF(("htrcntl(START)\n"));
! 942: return ENOSYS;
! 943:
! 944: case SVR4_HRT_CNTL_GET:
! 945: DPRINTF(("htrcntl(GET)\n"));
! 946: return ENOSYS;
! 947: default:
! 948: DPRINTF(("Bad htrcntl command %d\n", SCARG(uap, fun)));
! 949: return ENOSYS;
! 950: }
! 951: }
! 952:
! 953: int
! 954: svr4_sys_hrtsys(p, v, retval)
! 955: register struct proc *p;
! 956: void *v;
! 957: register_t *retval;
! 958: {
! 959: struct svr4_sys_hrtsys_args *uap = v;
! 960:
! 961: switch (SCARG(uap, cmd)) {
! 962: case SVR4_HRT_CNTL:
! 963: return svr4_hrtcntl(p, (struct svr4_hrtcntl_args *) uap,
! 964: retval);
! 965:
! 966: case SVR4_HRT_ALRM:
! 967: DPRINTF(("hrtalarm\n"));
! 968: return ENOSYS;
! 969:
! 970: case SVR4_HRT_SLP:
! 971: DPRINTF(("hrtsleep\n"));
! 972: return ENOSYS;
! 973:
! 974: case SVR4_HRT_CAN:
! 975: DPRINTF(("hrtcancel\n"));
! 976: return ENOSYS;
! 977:
! 978: default:
! 979: DPRINTF(("Bad hrtsys command %d\n", SCARG(uap, cmd)));
! 980: return EINVAL;
! 981: }
! 982: }
! 983:
! 984: static int
! 985: svr4_setinfo(p, st, s)
! 986: struct proc *p;
! 987: int st;
! 988: svr4_siginfo_t *s;
! 989: {
! 990: svr4_siginfo_t i;
! 991:
! 992: bzero(&i, sizeof(i));
! 993:
! 994: i.svr4_si_signo = SVR4_SIGCHLD;
! 995: i.svr4_si_errno = 0; /* XXX? */
! 996:
! 997: if (p) {
! 998: i.svr4_si_pid = p->p_pid;
! 999: if (p->p_stat == SZOMB) {
! 1000: i.svr4_si_stime = p->p_ru->ru_stime.tv_sec;
! 1001: i.svr4_si_utime = p->p_ru->ru_utime.tv_sec;
! 1002: } else {
! 1003: i.svr4_si_stime = p->p_stats->p_ru.ru_stime.tv_sec;
! 1004: i.svr4_si_utime = p->p_stats->p_ru.ru_utime.tv_sec;
! 1005: }
! 1006: }
! 1007:
! 1008: if (WIFEXITED(st)) {
! 1009: i.svr4_si_status = WEXITSTATUS(st);
! 1010: i.svr4_si_code = SVR4_CLD_EXITED;
! 1011: }
! 1012: else if (WIFSTOPPED(st)) {
! 1013: i.svr4_si_status = bsd_to_svr4_sig[WSTOPSIG(st)];
! 1014:
! 1015: if (i.svr4_si_status == SVR4_SIGCONT)
! 1016: i.svr4_si_code = SVR4_CLD_CONTINUED;
! 1017: else
! 1018: i.svr4_si_code = SVR4_CLD_STOPPED;
! 1019: } else {
! 1020: i.svr4_si_status = bsd_to_svr4_sig[WTERMSIG(st)];
! 1021:
! 1022: if (WCOREDUMP(st))
! 1023: i.svr4_si_code = SVR4_CLD_DUMPED;
! 1024: else
! 1025: i.svr4_si_code = SVR4_CLD_KILLED;
! 1026: }
! 1027:
! 1028: DPRINTF(("siginfo [pid %ld signo %d code %d errno %d status %d]\n",
! 1029: i.svr4_si_pid, i.svr4_si_signo, i.svr4_si_code,
! 1030: i.svr4_si_errno, i.svr4_si_status));
! 1031:
! 1032: return copyout(&i, s, sizeof(i));
! 1033: }
! 1034:
! 1035:
! 1036: int
! 1037: svr4_sys_waitsys(q, v, retval)
! 1038: struct proc *q;
! 1039: void *v;
! 1040: register_t *retval;
! 1041: {
! 1042: struct svr4_sys_waitsys_args *uap = v;
! 1043: int nfound;
! 1044: int error;
! 1045: struct proc *p, *t;
! 1046:
! 1047: switch (SCARG(uap, grp)) {
! 1048: case SVR4_P_PID:
! 1049: break;
! 1050:
! 1051: case SVR4_P_PGID:
! 1052: SCARG(uap, id) = -q->p_pgid;
! 1053: break;
! 1054:
! 1055: case SVR4_P_ALL:
! 1056: SCARG(uap, id) = WAIT_ANY;
! 1057: break;
! 1058:
! 1059: default:
! 1060: return (EINVAL);
! 1061: }
! 1062:
! 1063: DPRINTF(("waitsys(%d, %d, %p, %x)\n", SCARG(uap, grp), SCARG(uap, id),
! 1064: SCARG(uap, info), SCARG(uap, options)));
! 1065:
! 1066: loop:
! 1067: nfound = 0;
! 1068: LIST_FOREACH(p, &q->p_children, p_sibling) {
! 1069: if (SCARG(uap, id) != WAIT_ANY &&
! 1070: p->p_pid != SCARG(uap, id) &&
! 1071: p->p_pgid != -SCARG(uap, id)) {
! 1072: DPRINTF(("pid %d pgid %d != %d\n", p->p_pid,
! 1073: p->p_pgid, SCARG(uap, id)));
! 1074: continue;
! 1075: }
! 1076: nfound++;
! 1077: if (p->p_stat == SZOMB &&
! 1078: ((SCARG(uap, options) & (SVR4_WEXITED|SVR4_WTRAPPED)))) {
! 1079: *retval = 0;
! 1080: DPRINTF(("found %d\n", p->p_pid));
! 1081: error = svr4_setinfo(p, p->p_xstat, SCARG(uap, info));
! 1082: if (error)
! 1083: return (error);
! 1084:
! 1085: if ((SCARG(uap, options) & SVR4_WNOWAIT)) {
! 1086: DPRINTF(("Don't wait\n"));
! 1087: return (0);
! 1088: }
! 1089:
! 1090: /*
! 1091: * If we got the child via a ptrace 'attach',
! 1092: * we need to give it back to the old parent.
! 1093: */
! 1094: if (p->p_oppid && (t = pfind(p->p_oppid))) {
! 1095: p->p_oppid = 0;
! 1096: proc_reparent(p, t);
! 1097: psignal(t, SIGCHLD);
! 1098: wakeup((caddr_t)t);
! 1099: return (0);
! 1100: }
! 1101:
! 1102: scheduler_wait_hook(q, p);
! 1103: p->p_xstat = 0;
! 1104: ruadd(&q->p_stats->p_cru, p->p_ru);
! 1105:
! 1106: proc_zap(p);
! 1107: return (0);
! 1108: }
! 1109: if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
! 1110: (p->p_flag & P_TRACED ||
! 1111: (SCARG(uap, options) & (SVR4_WSTOPPED|SVR4_WCONTINUED)))) {
! 1112: DPRINTF(("jobcontrol %d\n", p->p_pid));
! 1113: if (((SCARG(uap, options) & SVR4_WNOWAIT)) == 0)
! 1114: atomic_setbits_int(&p->p_flag, P_WAITED);
! 1115: *retval = 0;
! 1116: return (svr4_setinfo(p, W_STOPCODE(p->p_xstat),
! 1117: SCARG(uap, info)));
! 1118: }
! 1119: }
! 1120:
! 1121: if (nfound == 0)
! 1122: return (ECHILD);
! 1123:
! 1124: if (SCARG(uap, options) & SVR4_WNOHANG) {
! 1125: *retval = 0;
! 1126: if ((error = svr4_setinfo(NULL, 0, SCARG(uap, info))) != 0)
! 1127: return (error);
! 1128: return (0);
! 1129: }
! 1130:
! 1131: if ((error = tsleep((caddr_t)q, PWAIT | PCATCH, "svr4_wait", 0)) != 0)
! 1132: return (error);
! 1133: goto loop;
! 1134: }
! 1135:
! 1136: static void
! 1137: bsd_statfs_to_svr4_statvfs(bfs, sfs)
! 1138: const struct statfs *bfs;
! 1139: struct svr4_statvfs *sfs;
! 1140: {
! 1141: sfs->f_bsize = bfs->f_iosize; /* XXX */
! 1142: sfs->f_frsize = bfs->f_bsize;
! 1143: sfs->f_blocks = bfs->f_blocks;
! 1144: sfs->f_bfree = bfs->f_bfree;
! 1145: sfs->f_bavail = bfs->f_bavail;
! 1146: sfs->f_files = bfs->f_files;
! 1147: sfs->f_ffree = bfs->f_ffree;
! 1148: sfs->f_favail = bfs->f_ffree;
! 1149: sfs->f_fsid = bfs->f_fsid.val[0];
! 1150: bcopy(bfs->f_fstypename, sfs->f_basetype, sizeof(sfs->f_basetype));
! 1151: sfs->f_flag = 0;
! 1152: if (bfs->f_flags & MNT_RDONLY)
! 1153: sfs->f_flag |= SVR4_ST_RDONLY;
! 1154: if (bfs->f_flags & MNT_NOSUID)
! 1155: sfs->f_flag |= SVR4_ST_NOSUID;
! 1156: sfs->f_namemax = MAXNAMLEN;
! 1157: bcopy(bfs->f_fstypename, sfs->f_fstr, sizeof(sfs->f_fstr)); /* XXX */
! 1158: bzero(sfs->f_filler, sizeof(sfs->f_filler));
! 1159: }
! 1160:
! 1161:
! 1162: static void
! 1163: bsd_statfs_to_svr4_statvfs64(bfs, sfs)
! 1164: const struct statfs *bfs;
! 1165: struct svr4_statvfs64 *sfs;
! 1166: {
! 1167: sfs->f_bsize = bfs->f_iosize; /* XXX */
! 1168: sfs->f_frsize = bfs->f_bsize;
! 1169: sfs->f_blocks = bfs->f_blocks;
! 1170: sfs->f_bfree = bfs->f_bfree;
! 1171: sfs->f_bavail = bfs->f_bavail;
! 1172: sfs->f_files = bfs->f_files;
! 1173: sfs->f_ffree = bfs->f_ffree;
! 1174: sfs->f_favail = bfs->f_ffree;
! 1175: sfs->f_fsid = bfs->f_fsid.val[0];
! 1176: bcopy(bfs->f_fstypename, sfs->f_basetype, sizeof(sfs->f_basetype));
! 1177: sfs->f_flag = 0;
! 1178: if (bfs->f_flags & MNT_RDONLY)
! 1179: sfs->f_flag |= SVR4_ST_RDONLY;
! 1180: if (bfs->f_flags & MNT_NOSUID)
! 1181: sfs->f_flag |= SVR4_ST_NOSUID;
! 1182: sfs->f_namemax = MAXNAMLEN;
! 1183: bcopy(bfs->f_fstypename, sfs->f_fstr, sizeof(sfs->f_fstr)); /* XXX */
! 1184: bzero(sfs->f_filler, sizeof(sfs->f_filler));
! 1185: }
! 1186:
! 1187:
! 1188: int
! 1189: svr4_sys_statvfs(p, v, retval)
! 1190: register struct proc *p;
! 1191: void *v;
! 1192: register_t *retval;
! 1193: {
! 1194: struct svr4_sys_statvfs_args *uap = v;
! 1195: struct sys_statfs_args fs_args;
! 1196: caddr_t sg = stackgap_init(p->p_emul);
! 1197: struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs));
! 1198: struct statfs bfs;
! 1199: struct svr4_statvfs sfs;
! 1200: int error;
! 1201:
! 1202: SVR4_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 1203: SCARG(&fs_args, path) = SCARG(uap, path);
! 1204: SCARG(&fs_args, buf) = fs;
! 1205:
! 1206: if ((error = sys_statfs(p, &fs_args, retval)) != 0)
! 1207: return error;
! 1208:
! 1209: if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0)
! 1210: return error;
! 1211:
! 1212: bsd_statfs_to_svr4_statvfs(&bfs, &sfs);
! 1213:
! 1214: return copyout(&sfs, SCARG(uap, fs), sizeof(sfs));
! 1215: }
! 1216:
! 1217:
! 1218: int
! 1219: svr4_sys_fstatvfs(p, v, retval)
! 1220: register struct proc *p;
! 1221: void *v;
! 1222: register_t *retval;
! 1223: {
! 1224: struct svr4_sys_fstatvfs_args *uap = v;
! 1225: struct sys_fstatfs_args fs_args;
! 1226: caddr_t sg = stackgap_init(p->p_emul);
! 1227: struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs));
! 1228: struct statfs bfs;
! 1229: struct svr4_statvfs sfs;
! 1230: int error;
! 1231:
! 1232: SCARG(&fs_args, fd) = SCARG(uap, fd);
! 1233: SCARG(&fs_args, buf) = fs;
! 1234:
! 1235: if ((error = sys_fstatfs(p, &fs_args, retval)) != 0)
! 1236: return error;
! 1237:
! 1238: if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0)
! 1239: return error;
! 1240:
! 1241: bsd_statfs_to_svr4_statvfs(&bfs, &sfs);
! 1242:
! 1243: return copyout(&sfs, SCARG(uap, fs), sizeof(sfs));
! 1244: }
! 1245:
! 1246:
! 1247: int
! 1248: svr4_sys_fstatvfs64(p, v, retval)
! 1249: register struct proc *p;
! 1250: void *v;
! 1251: register_t *retval;
! 1252: {
! 1253: struct svr4_sys_fstatvfs64_args *uap = v;
! 1254: struct sys_fstatfs_args fs_args;
! 1255: caddr_t sg = stackgap_init(p->p_emul);
! 1256: struct statfs *fs = stackgap_alloc(&sg, sizeof(struct statfs));
! 1257: struct statfs bfs;
! 1258: struct svr4_statvfs64 sfs;
! 1259: int error;
! 1260:
! 1261: SCARG(&fs_args, fd) = SCARG(uap, fd);
! 1262: SCARG(&fs_args, buf) = fs;
! 1263:
! 1264: if ((error = sys_fstatfs(p, &fs_args, retval)) != 0)
! 1265: return error;
! 1266:
! 1267: if ((error = copyin(fs, &bfs, sizeof(bfs))) != 0)
! 1268: return error;
! 1269:
! 1270: bsd_statfs_to_svr4_statvfs64(&bfs, &sfs);
! 1271:
! 1272: return copyout(&sfs, SCARG(uap, fs), sizeof(sfs));
! 1273: }
! 1274:
! 1275:
! 1276: int
! 1277: svr4_sys_alarm(p, v, retval)
! 1278: register struct proc *p;
! 1279: void *v;
! 1280: register_t *retval;
! 1281: {
! 1282: struct svr4_sys_alarm_args *uap = v;
! 1283: int error;
! 1284: struct itimerval *ntp, *otp, tp;
! 1285: struct sys_setitimer_args sa;
! 1286: caddr_t sg = stackgap_init(p->p_emul);
! 1287:
! 1288: ntp = stackgap_alloc(&sg, sizeof(struct itimerval));
! 1289: otp = stackgap_alloc(&sg, sizeof(struct itimerval));
! 1290:
! 1291: timerclear(&tp.it_interval);
! 1292: tp.it_value.tv_sec = SCARG(uap, sec);
! 1293: tp.it_value.tv_usec = 0;
! 1294:
! 1295: if ((error = copyout(&tp, ntp, sizeof(tp))) != 0)
! 1296: return error;
! 1297:
! 1298: SCARG(&sa, which) = ITIMER_REAL;
! 1299: SCARG(&sa, itv) = ntp;
! 1300: SCARG(&sa, oitv) = otp;
! 1301:
! 1302: if ((error = sys_setitimer(p, &sa, retval)) != 0)
! 1303: return error;
! 1304:
! 1305: if ((error = copyin(otp, &tp, sizeof(tp))) != 0)
! 1306: return error;
! 1307:
! 1308: if (tp.it_value.tv_usec)
! 1309: tp.it_value.tv_sec++;
! 1310:
! 1311: *retval = (register_t) tp.it_value.tv_sec;
! 1312:
! 1313: return 0;
! 1314: }
! 1315:
! 1316:
! 1317: int
! 1318: svr4_sys_gettimeofday(p, v, retval)
! 1319: register struct proc *p;
! 1320: void *v;
! 1321: register_t *retval;
! 1322: {
! 1323: struct svr4_sys_gettimeofday_args *uap = v;
! 1324:
! 1325: if (SCARG(uap, tp)) {
! 1326: struct timeval atv;
! 1327:
! 1328: microtime(&atv);
! 1329: return copyout(&atv, SCARG(uap, tp), sizeof (atv));
! 1330: }
! 1331:
! 1332: return 0;
! 1333: }
! 1334:
! 1335: int
! 1336: svr4_sys_facl(p, v, retval)
! 1337: register struct proc *p;
! 1338: void *v;
! 1339: register_t *retval;
! 1340: {
! 1341: struct svr4_sys_facl_args *uap = v;
! 1342:
! 1343: *retval = 0;
! 1344:
! 1345: switch (SCARG(uap, cmd)) {
! 1346: case SVR4_SYS_SETACL:
! 1347: /* We don't support acls on any filesystem */
! 1348: return ENOSYS;
! 1349:
! 1350: case SVR4_SYS_GETACL:
! 1351: return copyout(retval, &SCARG(uap, num),
! 1352: sizeof(SCARG(uap, num)));
! 1353:
! 1354: case SVR4_SYS_GETACLCNT:
! 1355: return 0;
! 1356:
! 1357: default:
! 1358: return EINVAL;
! 1359: }
! 1360: }
! 1361:
! 1362: int
! 1363: svr4_sys_acl(p, v, retval)
! 1364: register struct proc *p;
! 1365: void *v;
! 1366: register_t *retval;
! 1367: {
! 1368: return svr4_sys_facl(p, v, retval); /* XXX: for now the same */
! 1369: }
! 1370:
! 1371: int
! 1372: svr4_sys_auditsys(p, v, retval)
! 1373: register struct proc *p;
! 1374: void *v;
! 1375: register_t *retval;
! 1376: {
! 1377: /*
! 1378: * XXX: Big brother is *not* watching.
! 1379: */
! 1380: return 0;
! 1381: }
! 1382:
! 1383: int
! 1384: svr4_sys_memcntl(p, v, retval)
! 1385: register struct proc *p;
! 1386: void *v;
! 1387: register_t *retval;
! 1388: {
! 1389: struct svr4_sys_memcntl_args *uap = v;
! 1390: struct sys_mprotect_args ap;
! 1391:
! 1392: SCARG(&ap, addr) = SCARG(uap, addr);
! 1393: SCARG(&ap, len) = SCARG(uap, len);
! 1394: SCARG(&ap, prot) = SCARG(uap, attr);
! 1395:
! 1396: /* XXX: no locking, invalidating, or syncing supported */
! 1397: return sys_mprotect(p, &ap, retval);
! 1398: }
! 1399:
! 1400: int
! 1401: svr4_sys_nice(p, v, retval)
! 1402: register struct proc *p;
! 1403: void *v;
! 1404: register_t *retval;
! 1405: {
! 1406: struct svr4_sys_nice_args *uap = v;
! 1407: struct sys_setpriority_args ap;
! 1408: int error;
! 1409:
! 1410: SCARG(&ap, which) = PRIO_PROCESS;
! 1411: SCARG(&ap, who) = 0;
! 1412: SCARG(&ap, prio) = SCARG(uap, prio);
! 1413:
! 1414: if ((error = sys_setpriority(p, &ap, retval)) != 0)
! 1415: return error;
! 1416:
! 1417: if ((error = sys_getpriority(p, &ap, retval)) != 0)
! 1418: return error;
! 1419:
! 1420: return 0;
! 1421: }
! 1422:
! 1423: /* ARGSUSED */
! 1424: int
! 1425: svr4_sys_setegid(p, v, retval)
! 1426: struct proc *p;
! 1427: void *v;
! 1428: register_t *retval;
! 1429: {
! 1430: struct sys_setegid_args /* {
! 1431: syscallarg(gid_t) egid;
! 1432: } */ *uap = v;
! 1433:
! 1434: #if defined(COMPAT_LINUX) && defined(i386)
! 1435: if (SCARG(uap, egid) > 60000) {
! 1436: /*
! 1437: * One great fuckup deserves another. The Linux people
! 1438: * made this their personality system call. But we can't
! 1439: * tell if a binary is SVR4 or Linux until they do that
! 1440: * system call, in some cases. So when we get it, and the
! 1441: * value is out of some magical range, switch to Linux
! 1442: * emulation and pray.
! 1443: */
! 1444: extern struct emul emul_linux_elf;
! 1445:
! 1446: p->p_emul = &emul_linux_elf;
! 1447: p->p_os = OOS_LINUX;
! 1448: #ifdef KTRACE
! 1449: if (KTRPOINT(p, KTR_EMUL))
! 1450: ktremul(p, p->p_emul->e_name);
! 1451: #endif
! 1452: return (0);
! 1453: }
! 1454: #else
! 1455: (void)uap;
! 1456: #endif
! 1457: return (sys_setegid(p, v, retval));
! 1458: }
! 1459:
! 1460: int
! 1461: svr4_sys_rdebug(p, v, retval)
! 1462: struct proc *p;
! 1463: void *v;
! 1464: register_t *retval;
! 1465: {
! 1466: #ifdef COMPAT_SVR4_NCR
! 1467: return (ENXIO);
! 1468: #else
! 1469: return (p->p_os == OOS_NCR ? ENXIO : sys_nosys(p, v, retval));
! 1470: #endif
! 1471: }
CVSweb