Annotation of sys/compat/sunos/sunos_misc.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: sunos_misc.c,v 1.46 2004/06/24 19:35:23 tholo Exp $ */
! 2: /* $NetBSD: sunos_misc.c,v 1.65 1996/04/22 01:44:31 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1992, 1993
! 6: * The Regents of the University of California. All rights reserved.
! 7: *
! 8: * This software was developed by the Computer Systems Engineering group
! 9: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
! 10: * contributed to Berkeley.
! 11: *
! 12: * All advertising materials mentioning features or use of this software
! 13: * must display the following acknowledgement:
! 14: * This product includes software developed by the University of
! 15: * California, Lawrence Berkeley Laboratory.
! 16: *
! 17: * Redistribution and use in source and binary forms, with or without
! 18: * modification, are permitted provided that the following conditions
! 19: * are met:
! 20: * 1. Redistributions of source code must retain the above copyright
! 21: * notice, this list of conditions and the following disclaimer.
! 22: * 2. Redistributions in binary form must reproduce the above copyright
! 23: * notice, this list of conditions and the following disclaimer in the
! 24: * documentation and/or other materials provided with the distribution.
! 25: * 3. Neither the name of the University nor the names of its contributors
! 26: * may be used to endorse or promote products derived from this software
! 27: * without specific prior written permission.
! 28: *
! 29: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 30: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 31: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 32: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 33: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 34: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 35: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 36: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 37: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 38: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 39: * SUCH DAMAGE.
! 40: *
! 41: * @(#)sunos_misc.c 8.1 (Berkeley) 6/18/93
! 42: *
! 43: * Header: sunos_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
! 44: */
! 45:
! 46: /*
! 47: * SunOS compatibility module.
! 48: *
! 49: * SunOS system calls that are implemented differently in BSD are
! 50: * handled here.
! 51: */
! 52:
! 53: #include <sys/param.h>
! 54: #include <sys/systm.h>
! 55: #include <sys/namei.h>
! 56: #include <sys/proc.h>
! 57: #include <sys/dirent.h>
! 58: #include <sys/file.h>
! 59: #include <sys/stat.h>
! 60: #include <sys/filedesc.h>
! 61: #include <sys/ioctl.h>
! 62: #include <sys/kernel.h>
! 63: #include <sys/reboot.h>
! 64: #include <sys/malloc.h>
! 65: #include <sys/mbuf.h>
! 66: #include <sys/mman.h>
! 67: #include <sys/mount.h>
! 68: #include <sys/ptrace.h>
! 69: #include <sys/resource.h>
! 70: #include <sys/resourcevar.h>
! 71: #include <sys/signal.h>
! 72: #include <sys/signalvar.h>
! 73: #include <sys/socket.h>
! 74: #include <sys/tty.h>
! 75: #include <sys/vnode.h>
! 76: #include <sys/uio.h>
! 77: #include <sys/wait.h>
! 78: #include <sys/utsname.h>
! 79: #include <sys/unistd.h>
! 80: #include <sys/syscallargs.h>
! 81: #include <sys/conf.h>
! 82: #include <sys/socketvar.h>
! 83: #include <sys/times.h>
! 84:
! 85: #include <compat/sunos/sunos.h>
! 86: #include <compat/sunos/sunos_syscallargs.h>
! 87: #include <compat/sunos/sunos_util.h>
! 88: #include <compat/sunos/sunos_dirent.h>
! 89:
! 90: #include <compat/common/compat_dir.h>
! 91:
! 92: #include <netinet/in.h>
! 93:
! 94: #include <miscfs/specfs/specdev.h>
! 95:
! 96: #include <nfs/rpcv2.h>
! 97: #include <nfs/nfsproto.h>
! 98: #include <nfs/nfs.h>
! 99:
! 100: #include <uvm/uvm_extern.h>
! 101:
! 102: #ifdef sun3
! 103: # include <machine/machdep.h> /* for prototype of reboot2() */
! 104: #endif
! 105:
! 106: static int sunstatfs(struct statfs *, caddr_t);
! 107:
! 108: int
! 109: sunos_sys_wait4(p, v, retval)
! 110: struct proc *p;
! 111: void *v;
! 112: register_t *retval;
! 113: {
! 114: struct sunos_sys_wait4_args *uap = v;
! 115: if (SCARG(uap, pid) == 0)
! 116: SCARG(uap, pid) = WAIT_ANY;
! 117: return (sys_wait4(p, uap, retval));
! 118: }
! 119:
! 120: int
! 121: sunos_sys_creat(p, v, retval)
! 122: struct proc *p;
! 123: void *v;
! 124: register_t *retval;
! 125: {
! 126: struct sunos_sys_creat_args *uap = v;
! 127: struct sys_open_args ouap;
! 128:
! 129: caddr_t sg = stackgap_init(p->p_emul);
! 130: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 131:
! 132: SCARG(&ouap, path) = SCARG(uap, path);
! 133: SCARG(&ouap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
! 134: SCARG(&ouap, mode) = SCARG(uap, mode);
! 135:
! 136: return (sys_open(p, &ouap, retval));
! 137: }
! 138:
! 139: int
! 140: sunos_sys_access(p, v, retval)
! 141: struct proc *p;
! 142: void *v;
! 143: register_t *retval;
! 144: {
! 145: struct sunos_sys_access_args *uap = v;
! 146: caddr_t sg = stackgap_init(p->p_emul);
! 147: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 148:
! 149: return (sys_access(p, uap, retval));
! 150: }
! 151:
! 152: int
! 153: sunos_sys_stat(p, v, retval)
! 154: struct proc *p;
! 155: void *v;
! 156: register_t *retval;
! 157: {
! 158: struct sunos_sys_stat_args *uap = v;
! 159: caddr_t sg = stackgap_init(p->p_emul);
! 160: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 161:
! 162: return (compat_43_sys_stat(p, uap, retval));
! 163: }
! 164:
! 165: int
! 166: sunos_sys_lstat(p, v, retval)
! 167: struct proc *p;
! 168: void *v;
! 169: register_t *retval;
! 170: {
! 171: struct sunos_sys_lstat_args *uap = v;
! 172: caddr_t sg = stackgap_init(p->p_emul);
! 173: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 174:
! 175: return (compat_43_sys_lstat(p, uap, retval));
! 176: }
! 177:
! 178: int
! 179: sunos_sys_execve(p, v, retval)
! 180: struct proc *p;
! 181: void *v;
! 182: register_t *retval;
! 183: {
! 184: struct sunos_sys_execve_args /* {
! 185: syscallarg(char *) path;
! 186: syscallarg(char **) argv;
! 187: syscallarg(char **) envp;
! 188: } */ *uap = v;
! 189: struct sys_execve_args ap;
! 190: caddr_t sg;
! 191:
! 192: sg = stackgap_init(p->p_emul);
! 193: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 194:
! 195: SCARG(&ap, path) = SCARG(uap, path);
! 196: SCARG(&ap, argp) = SCARG(uap, argp);
! 197: SCARG(&ap, envp) = SCARG(uap, envp);
! 198:
! 199: return (sys_execve(p, &ap, retval));
! 200: }
! 201:
! 202: int
! 203: sunos_sys_execv(p, v, retval)
! 204: struct proc *p;
! 205: void *v;
! 206: register_t *retval;
! 207: {
! 208: struct sunos_sys_execv_args *uap = v;
! 209: struct sys_execve_args ouap;
! 210:
! 211: caddr_t sg = stackgap_init(p->p_emul);
! 212: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 213:
! 214: SCARG(&ouap, path) = SCARG(uap, path);
! 215: SCARG(&ouap, argp) = SCARG(uap, argp);
! 216: SCARG(&ouap, envp) = NULL;
! 217:
! 218: return (sys_execve(p, &ouap, retval));
! 219: }
! 220:
! 221: int
! 222: sunos_sys_unmount(p, v, retval)
! 223: struct proc *p;
! 224: void *v;
! 225: register_t *retval;
! 226: {
! 227: struct sunos_sys_unmount_args *uap = v;
! 228: struct sys_unmount_args ouap;
! 229:
! 230: SCARG(&ouap, path) = SCARG(uap, path);
! 231: SCARG(&ouap, flags) = 0;
! 232:
! 233: return (sys_unmount(p, &ouap, retval));
! 234: }
! 235:
! 236: /*
! 237: * Conversion table for SunOS NFS mount flags.
! 238: */
! 239: static struct {
! 240: int sun_flg;
! 241: int bsd_flg;
! 242: } sunnfs_flgtab[] = {
! 243: { SUNNFS_SOFT, NFSMNT_SOFT },
! 244: { SUNNFS_WSIZE, NFSMNT_WSIZE },
! 245: { SUNNFS_RSIZE, NFSMNT_RSIZE },
! 246: { SUNNFS_TIMEO, NFSMNT_TIMEO },
! 247: { SUNNFS_RETRANS, NFSMNT_RETRANS },
! 248: { SUNNFS_HOSTNAME, 0 }, /* Ignored */
! 249: { SUNNFS_INT, NFSMNT_INT },
! 250: { SUNNFS_NOAC, 0 }, /* Ignored */
! 251: { SUNNFS_ACREGMIN, 0 }, /* Ignored */
! 252: { SUNNFS_ACREGMAX, 0 }, /* Ignored */
! 253: { SUNNFS_ACDIRMIN, 0 }, /* Ignored */
! 254: { SUNNFS_ACDIRMAX, 0 }, /* Ignored */
! 255: { SUNNFS_SECURE, 0 }, /* Ignored */
! 256: { SUNNFS_NOCTO, 0 }, /* Ignored */
! 257: { SUNNFS_POSIX, 0 } /* Ignored */
! 258: };
! 259:
! 260: int
! 261: sunos_sys_mount(p, v, retval)
! 262: struct proc *p;
! 263: void *v;
! 264: register_t *retval;
! 265: {
! 266: struct sunos_sys_mount_args *uap = v;
! 267: int oflags = SCARG(uap, flags), nflags, error;
! 268: char fsname[MFSNAMELEN];
! 269: caddr_t sg = stackgap_init(p->p_emul);
! 270:
! 271: if (oflags & (SUNM_NOSUB | SUNM_SYS5))
! 272: return (EINVAL);
! 273: if ((oflags & SUNM_NEWTYPE) == 0)
! 274: return (EINVAL);
! 275: nflags = 0;
! 276: if (oflags & SUNM_RDONLY)
! 277: nflags |= MNT_RDONLY;
! 278: if (oflags & SUNM_NOSUID)
! 279: nflags |= MNT_NOSUID;
! 280: if (oflags & SUNM_REMOUNT)
! 281: nflags |= MNT_UPDATE;
! 282: SCARG(uap, flags) = nflags;
! 283:
! 284: error = copyinstr((caddr_t)SCARG(uap, type), fsname,
! 285: sizeof fsname, (size_t *)0);
! 286: if (error)
! 287: return (error);
! 288:
! 289: if (strncmp(fsname, "4.2", sizeof fsname) == 0) {
! 290: SCARG(uap, type) = stackgap_alloc(&sg, sizeof("ffs"));
! 291: error = copyout("ffs", SCARG(uap, type), sizeof("ffs"));
! 292: if (error)
! 293: return (error);
! 294: } else if (strncmp(fsname, "nfs", sizeof fsname) == 0) {
! 295: struct sunos_nfs_args sna;
! 296: struct sockaddr_in sain;
! 297: struct nfs_args na;
! 298: struct sockaddr sa;
! 299: int n;
! 300:
! 301: error = copyin(SCARG(uap, data), &sna, sizeof sna);
! 302: if (error)
! 303: return (error);
! 304: error = copyin(sna.addr, &sain, sizeof sain);
! 305: if (error)
! 306: return (error);
! 307: bcopy(&sain, &sa, sizeof sa);
! 308: sa.sa_len = sizeof(sain);
! 309: SCARG(uap, data) = stackgap_alloc(&sg, sizeof(na));
! 310: na.version = NFS_ARGSVERSION;
! 311: na.addr = stackgap_alloc(&sg, sizeof(struct sockaddr));
! 312: na.addrlen = sizeof(struct sockaddr);
! 313: na.sotype = SOCK_DGRAM;
! 314: na.proto = IPPROTO_UDP;
! 315: na.fh = (void *)sna.fh;
! 316: na.fhsize = NFSX_V2FH;
! 317: na.flags = 0;
! 318: n = sizeof(sunnfs_flgtab) / sizeof(sunnfs_flgtab[0]);
! 319: while (--n >= 0)
! 320: if (sna.flags & sunnfs_flgtab[n].sun_flg)
! 321: na.flags |= sunnfs_flgtab[n].bsd_flg;
! 322: na.wsize = sna.wsize;
! 323: na.rsize = sna.rsize;
! 324: if (na.flags & NFSMNT_RSIZE) {
! 325: na.flags |= NFSMNT_READDIRSIZE;
! 326: na.readdirsize = na.rsize;
! 327: }
! 328: na.timeo = sna.timeo;
! 329: na.retrans = sna.retrans;
! 330: na.hostname = sna.hostname;
! 331:
! 332: error = copyout(&sa, na.addr, sizeof sa);
! 333: if (error)
! 334: return (error);
! 335: error = copyout(&na, SCARG(uap, data), sizeof na);
! 336: if (error)
! 337: return (error);
! 338: }
! 339: return (sys_mount(p, (struct sys_mount_args *)uap, retval));
! 340: }
! 341:
! 342: #if defined(NFSCLIENT)
! 343: int
! 344: async_daemon(p, v, retval)
! 345: struct proc *p;
! 346: void *v;
! 347: register_t *retval;
! 348: {
! 349: struct sys_nfssvc_args ouap;
! 350:
! 351: SCARG(&ouap, flag) = NFSSVC_BIOD;
! 352: SCARG(&ouap, argp) = NULL;
! 353:
! 354: return (sys_nfssvc(p, &ouap, retval));
! 355: }
! 356: #endif /* NFSCLIENT */
! 357:
! 358: int
! 359: sunos_sys_sigpending(p, v, retval)
! 360: struct proc *p;
! 361: void *v;
! 362: register_t *retval;
! 363: {
! 364: struct sunos_sys_sigpending_args *uap = v;
! 365: int mask = p->p_siglist & p->p_sigmask;
! 366:
! 367: return (copyout((caddr_t)&mask, (caddr_t)SCARG(uap, mask), sizeof(int)));
! 368: }
! 369:
! 370: /*
! 371: * Read Sun-style directory entries. We suck them into kernel space so
! 372: * that they can be massaged before being copied out to user code. Like
! 373: * SunOS, we squish out `empty' entries.
! 374: *
! 375: * This is quite ugly, but what do you expect from compatibility code?
! 376: */
! 377: int sunos_readdir_callback(void *, struct dirent *, off_t);
! 378:
! 379: struct sunos_readdir_callback_args {
! 380: caddr_t outp;
! 381: int resid;
! 382: };
! 383:
! 384: int
! 385: sunos_readdir_callback(arg, bdp, cookie)
! 386: void *arg;
! 387: struct dirent *bdp;
! 388: off_t cookie;
! 389: {
! 390: struct sunos_dirent idb;
! 391: struct sunos_readdir_callback_args *cb = arg;
! 392: int sunos_reclen;
! 393: int error;
! 394:
! 395: sunos_reclen = SUNOS_RECLEN(&idb, bdp->d_namlen);
! 396: if (cb->resid < sunos_reclen)
! 397: return (ENOMEM);
! 398:
! 399: idb.d_fileno = bdp->d_fileno;
! 400: idb.d_off = cookie;
! 401: idb.d_reclen = sunos_reclen;
! 402: idb.d_namlen = bdp->d_namlen;
! 403: strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
! 404:
! 405: if ((error = copyout((caddr_t)&idb, cb->outp, sunos_reclen)))
! 406: return (error);
! 407:
! 408: cb->outp += sunos_reclen;
! 409: cb->resid -= sunos_reclen;
! 410:
! 411: return (0);
! 412: }
! 413:
! 414: int
! 415: sunos_sys_getdents(p, v, retval)
! 416: struct proc *p;
! 417: void *v;
! 418: register_t *retval;
! 419: {
! 420: struct sunos_sys_getdents_args /* {
! 421: syscallarg(int) fd;
! 422: syscallarg(char *) buf;
! 423: syscallarg(int) nbytes;
! 424: } */ *uap = v;
! 425: struct vnode *vp;
! 426: struct file *fp;
! 427: int error;
! 428: struct sunos_readdir_callback_args args;
! 429:
! 430: if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
! 431: return (error);
! 432:
! 433: vp = (struct vnode *)fp->f_data;
! 434: /* SunOS returns ENOTDIR here, BSD would use EINVAL */
! 435: if (vp->v_type != VDIR) {
! 436: error = ENOTDIR;
! 437: goto bad;
! 438: }
! 439:
! 440: args.resid = SCARG(uap, nbytes);
! 441: args.outp = (caddr_t)SCARG(uap, buf);
! 442:
! 443: error = readdir_with_callback(fp, &fp->f_offset, args.resid,
! 444: sunos_readdir_callback, &args);
! 445: bad:
! 446: FRELE(fp);
! 447: if (error)
! 448: return (error);
! 449:
! 450: *retval = SCARG(uap, nbytes) - args.resid;
! 451:
! 452: return (0);
! 453: }
! 454:
! 455:
! 456: #define SUNOS__MAP_NEW 0x80000000 /* if not, old mmap & cannot handle */
! 457:
! 458: int
! 459: sunos_sys_mmap(p, v, retval)
! 460: struct proc *p;
! 461: void *v;
! 462: register_t *retval;
! 463: {
! 464: struct sunos_sys_mmap_args *uap = v;
! 465: struct sys_mmap_args ouap;
! 466:
! 467: /*
! 468: * Verify the arguments.
! 469: */
! 470: if (SCARG(uap, prot) & ~(PROT_READ|PROT_WRITE|PROT_EXEC))
! 471: return (EINVAL); /* XXX still needed? */
! 472:
! 473: if ((SCARG(uap, flags) & SUNOS__MAP_NEW) == 0)
! 474: return (EINVAL);
! 475:
! 476: SCARG(&ouap, flags) = SCARG(uap, flags) & ~SUNOS__MAP_NEW;
! 477: SCARG(&ouap, addr) = SCARG(uap, addr);
! 478:
! 479: if ((SCARG(&ouap, flags) & MAP_FIXED) == 0 &&
! 480: SCARG(&ouap, addr) != 0 &&
! 481: SCARG(&ouap, addr) < (void *)round_page((vaddr_t)p->p_vmspace->vm_daddr+MAXDSIZ))
! 482: SCARG(&ouap, addr) = (void *)round_page((vaddr_t)p->p_vmspace->vm_daddr+MAXDSIZ);
! 483:
! 484: SCARG(&ouap, len) = SCARG(uap, len);
! 485: SCARG(&ouap, prot) = SCARG(uap, prot);
! 486: SCARG(&ouap, fd) = SCARG(uap, fd);
! 487: SCARG(&ouap, pos) = SCARG(uap, pos);
! 488:
! 489: return (sys_mmap(p, &ouap, retval));
! 490: }
! 491:
! 492: #define MC_SYNC 1
! 493: #define MC_LOCK 2
! 494: #define MC_UNLOCK 3
! 495: #define MC_ADVISE 4
! 496: #define MC_LOCKAS 5
! 497: #define MC_UNLOCKAS 6
! 498:
! 499: int
! 500: sunos_sys_mctl(p, v, retval)
! 501: register struct proc *p;
! 502: void *v;
! 503: register_t *retval;
! 504: {
! 505: register struct sunos_sys_mctl_args *uap = v;
! 506:
! 507: switch (SCARG(uap, func)) {
! 508: case MC_ADVISE: /* ignore for now */
! 509: return (0);
! 510: case MC_SYNC: /* translate to msync */
! 511: return (sys_msync(p, uap, retval));
! 512: default:
! 513: return (EINVAL);
! 514: }
! 515: }
! 516:
! 517: int
! 518: sunos_sys_setsockopt(p, v, retval)
! 519: struct proc *p;
! 520: void *v;
! 521: register_t *retval;
! 522: {
! 523: struct sunos_sys_setsockopt_args *uap = v;
! 524: struct file *fp;
! 525: struct mbuf *m = NULL;
! 526: int error;
! 527:
! 528: if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
! 529: return (error);
! 530: #define SO_DONTLINGER (~SO_LINGER)
! 531: if (SCARG(uap, name) == SO_DONTLINGER) {
! 532: m = m_get(M_WAIT, MT_SOOPTS);
! 533: mtod(m, struct linger *)->l_onoff = 0;
! 534: m->m_len = sizeof(struct linger);
! 535: error = (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
! 536: SO_LINGER, m));
! 537: goto bad;
! 538: }
! 539: if (SCARG(uap, level) == IPPROTO_IP) {
! 540: #define SUNOS_IP_MULTICAST_IF 2
! 541: #define SUNOS_IP_MULTICAST_TTL 3
! 542: #define SUNOS_IP_MULTICAST_LOOP 4
! 543: #define SUNOS_IP_ADD_MEMBERSHIP 5
! 544: #define SUNOS_IP_DROP_MEMBERSHIP 6
! 545: static int ipoptxlat[] = {
! 546: IP_MULTICAST_IF,
! 547: IP_MULTICAST_TTL,
! 548: IP_MULTICAST_LOOP,
! 549: IP_ADD_MEMBERSHIP,
! 550: IP_DROP_MEMBERSHIP
! 551: };
! 552: if (SCARG(uap, name) >= SUNOS_IP_MULTICAST_IF &&
! 553: SCARG(uap, name) <= SUNOS_IP_DROP_MEMBERSHIP) {
! 554: SCARG(uap, name) =
! 555: ipoptxlat[SCARG(uap, name) - SUNOS_IP_MULTICAST_IF];
! 556: }
! 557: }
! 558: if (SCARG(uap, valsize) > MLEN) {
! 559: error = EINVAL;
! 560: goto bad;
! 561: }
! 562: if (SCARG(uap, val)) {
! 563: m = m_get(M_WAIT, MT_SOOPTS);
! 564: error = copyin(SCARG(uap, val), mtod(m, caddr_t),
! 565: (u_int)SCARG(uap, valsize));
! 566: if (error) {
! 567: (void) m_free(m);
! 568: goto bad;
! 569: }
! 570: m->m_len = SCARG(uap, valsize);
! 571: }
! 572: error = (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
! 573: SCARG(uap, name), m));
! 574: bad:
! 575: FRELE(fp);
! 576: return (error);
! 577: }
! 578:
! 579: int
! 580: sunos_sys_fchroot(p, v, retval)
! 581: register struct proc *p;
! 582: void *v;
! 583: register_t *retval;
! 584: {
! 585: register struct sunos_sys_fchroot_args *uap = v;
! 586: register struct filedesc *fdp = p->p_fd;
! 587: register struct vnode *vp;
! 588: struct file *fp;
! 589: int error;
! 590:
! 591: if ((error = suser(p, 0)) != 0)
! 592: return (error);
! 593: if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
! 594: return (error);
! 595: vp = (struct vnode *)fp->f_data;
! 596: vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
! 597: if (vp->v_type != VDIR)
! 598: error = ENOTDIR;
! 599: else
! 600: error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
! 601: VOP_UNLOCK(vp, 0, p);
! 602: if (error) {
! 603: FRELE(fp);
! 604: return (error);
! 605: }
! 606: VREF(vp);
! 607: if (fdp->fd_rdir != NULL)
! 608: vrele(fdp->fd_rdir);
! 609: fdp->fd_rdir = vp;
! 610: FRELE(fp);
! 611: return (0);
! 612: }
! 613:
! 614: /*
! 615: * XXX: This needs cleaning up.
! 616: */
! 617: int
! 618: sunos_sys_auditsys(p, v, retval)
! 619: struct proc *p;
! 620: void *v;
! 621: register_t *retval;
! 622: {
! 623: return 0;
! 624: }
! 625:
! 626: int
! 627: sunos_sys_uname(p, v, retval)
! 628: struct proc *p;
! 629: void *v;
! 630: register_t *retval;
! 631: {
! 632: struct sunos_sys_uname_args *uap = v;
! 633: struct sunos_utsname sut;
! 634: extern char machine[];
! 635:
! 636: bzero(&sut, sizeof(sut));
! 637:
! 638: bcopy(ostype, sut.sysname, sizeof(sut.sysname) - 1);
! 639: bcopy(hostname, sut.nodename, sizeof(sut.nodename));
! 640: sut.nodename[sizeof(sut.nodename)-1] = '\0';
! 641: bcopy(osrelease, sut.release, sizeof(sut.release) - 1);
! 642: strlcpy(sut.version, "1", sizeof(sut.version));
! 643: bcopy(machine, sut.machine, sizeof(sut.machine) - 1);
! 644:
! 645: return copyout((caddr_t)&sut, (caddr_t)SCARG(uap, name),
! 646: sizeof(struct sunos_utsname));
! 647: }
! 648:
! 649: int
! 650: sunos_sys_setpgrp(p, v, retval)
! 651: struct proc *p;
! 652: void *v;
! 653: register_t *retval;
! 654: {
! 655: struct sunos_sys_setpgrp_args *uap = v;
! 656:
! 657: /*
! 658: * difference to our setpgid call is to include backwards
! 659: * compatibility to pre-setsid() binaries. Do setsid()
! 660: * instead of setpgid() in those cases where the process
! 661: * tries to create a new session the old way.
! 662: */
! 663: if (!SCARG(uap, pgid) &&
! 664: (!SCARG(uap, pid) || SCARG(uap, pid) == p->p_pid))
! 665: return sys_setsid(p, uap, retval);
! 666: else
! 667: return sys_setpgid(p, uap, retval);
! 668: }
! 669:
! 670: int
! 671: sunos_sys_open(p, v, retval)
! 672: struct proc *p;
! 673: void *v;
! 674: register_t *retval;
! 675: {
! 676: struct sunos_sys_open_args *uap = v;
! 677: int l, r;
! 678: int noctty;
! 679: int ret;
! 680:
! 681: caddr_t sg = stackgap_init(p->p_emul);
! 682: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 683:
! 684: /* convert mode into NetBSD mode */
! 685: l = SCARG(uap, flags);
! 686: noctty = l & 0x8000;
! 687: r = (l & (0x0001 | 0x0002 | 0x0008 | 0x0040 | 0x0200 | 0x0400 | 0x0800));
! 688: r |= ((l & (0x0004 | 0x1000 | 0x4000)) ? O_NONBLOCK : 0);
! 689: r |= ((l & 0x0080) ? O_SHLOCK : 0);
! 690: r |= ((l & 0x0100) ? O_EXLOCK : 0);
! 691: r |= ((l & 0x2000) ? O_SYNC : 0);
! 692:
! 693: SCARG(uap, flags) = r;
! 694: ret = sys_open(p, (struct sys_open_args *)uap, retval);
! 695:
! 696: if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
! 697: struct filedesc *fdp = p->p_fd;
! 698: struct file *fp;
! 699:
! 700: if ((fp = fd_getfile(fdp, *retval)) == NULL)
! 701: return (EBADF);
! 702: FREF(fp);
! 703: /* ignore any error, just give it a try */
! 704: if (fp->f_type == DTYPE_VNODE)
! 705: (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t)0, p);
! 706: FRELE(fp);
! 707: }
! 708: return ret;
! 709: }
! 710:
! 711: #if defined (NFSSERVER)
! 712: int
! 713: sunos_sys_nfssvc(p, v, retval)
! 714: struct proc *p;
! 715: void *v;
! 716: register_t *retval;
! 717: {
! 718: #if 0
! 719: struct sunos_sys_nfssvc_args *uap = v;
! 720: struct emul *e = p->p_emul;
! 721: struct sys_nfssvc_args outuap;
! 722: struct sockaddr sa;
! 723: int error;
! 724:
! 725: bzero(&outuap, sizeof outuap);
! 726: SCARG(&outuap, fd) = SCARG(uap, fd);
! 727: SCARG(&outuap, mskval) = STACKGAPBASE;
! 728: SCARG(&outuap, msklen) = sizeof sa;
! 729: SCARG(&outuap, mtchval) = SCARG(&outuap, mskval) + sizeof sa;
! 730: SCARG(&outuap, mtchlen) = sizeof sa;
! 731:
! 732: bzero(&sa, sizeof sa);
! 733: if (error = copyout(&sa, SCARG(&outuap, mskval), SCARG(&outuap, msklen)))
! 734: return (error);
! 735: if (error = copyout(&sa, SCARG(&outuap, mtchval), SCARG(&outuap, mtchlen)))
! 736: return (error);
! 737:
! 738: return nfssvc(p, &outuap, retval);
! 739: #else
! 740: return (ENOSYS);
! 741: #endif
! 742: }
! 743: #endif /* NFSSERVER */
! 744:
! 745: int
! 746: sunos_sys_ustat(p, v, retval)
! 747: struct proc *p;
! 748: void *v;
! 749: register_t *retval;
! 750: {
! 751: struct sunos_sys_ustat_args *uap = v;
! 752: struct sunos_ustat us;
! 753: int error;
! 754:
! 755: bzero(&us, sizeof us);
! 756:
! 757: /*
! 758: * XXX: should set f_tfree and f_tinode at least
! 759: * How do we translate dev -> fstat? (and then to sunos_ustat)
! 760: */
! 761:
! 762: if ((error = copyout(&us, SCARG(uap, buf), sizeof us)) != 0)
! 763: return (error);
! 764: return 0;
! 765: }
! 766:
! 767: int
! 768: sunos_sys_quotactl(p, v, retval)
! 769: struct proc *p;
! 770: void *v;
! 771: register_t *retval;
! 772: {
! 773:
! 774: return EINVAL;
! 775: }
! 776:
! 777: int
! 778: sunos_sys_vhangup(p, v, retval)
! 779: struct proc *p;
! 780: void *v;
! 781: register_t *retval;
! 782: {
! 783: struct session *sp = p->p_session;
! 784:
! 785: if (sp->s_ttyvp == 0)
! 786: return 0;
! 787:
! 788: if (sp->s_ttyp && sp->s_ttyp->t_session == sp && sp->s_ttyp->t_pgrp)
! 789: pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
! 790:
! 791: (void) ttywait(sp->s_ttyp);
! 792: if (sp->s_ttyvp)
! 793: VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
! 794: if (sp->s_ttyvp)
! 795: vrele(sp->s_ttyvp);
! 796: sp->s_ttyvp = NULL;
! 797:
! 798: return 0;
! 799: }
! 800:
! 801: static int
! 802: sunstatfs(sp, buf)
! 803: struct statfs *sp;
! 804: caddr_t buf;
! 805: {
! 806: struct sunos_statfs ssfs;
! 807:
! 808: bzero(&ssfs, sizeof ssfs);
! 809: ssfs.f_type = 0;
! 810: ssfs.f_bsize = sp->f_bsize;
! 811: ssfs.f_blocks = sp->f_blocks;
! 812: ssfs.f_bfree = sp->f_bfree;
! 813: ssfs.f_bavail = sp->f_bavail;
! 814: ssfs.f_files = sp->f_files;
! 815: ssfs.f_ffree = sp->f_ffree;
! 816: ssfs.f_fsid = sp->f_fsid;
! 817: return copyout((caddr_t)&ssfs, buf, sizeof ssfs);
! 818: }
! 819:
! 820: int
! 821: sunos_sys_statfs(p, v, retval)
! 822: struct proc *p;
! 823: void *v;
! 824: register_t *retval;
! 825: {
! 826: struct sunos_sys_statfs_args *uap = v;
! 827: register struct mount *mp;
! 828: register struct statfs *sp;
! 829: int error;
! 830: struct nameidata nd;
! 831:
! 832: caddr_t sg = stackgap_init(p->p_emul);
! 833: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 834:
! 835: NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
! 836: if ((error = namei(&nd)) != 0)
! 837: return (error);
! 838: mp = nd.ni_vp->v_mount;
! 839: sp = &mp->mnt_stat;
! 840: vrele(nd.ni_vp);
! 841: if ((error = VFS_STATFS(mp, sp, p)) != 0)
! 842: return (error);
! 843: sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
! 844: return sunstatfs(sp, (caddr_t)SCARG(uap, buf));
! 845: }
! 846:
! 847: int
! 848: sunos_sys_fstatfs(p, v, retval)
! 849: struct proc *p;
! 850: void *v;
! 851: register_t *retval;
! 852: {
! 853: struct sunos_sys_fstatfs_args *uap = v;
! 854: struct file *fp;
! 855: struct mount *mp;
! 856: struct statfs *sp;
! 857: int error;
! 858:
! 859: if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
! 860: return (error);
! 861: mp = ((struct vnode *)fp->f_data)->v_mount;
! 862: sp = &mp->mnt_stat;
! 863: error = VFS_STATFS(mp, sp, p);
! 864: FRELE(fp);
! 865: if (error)
! 866: return (error);
! 867: sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
! 868: return sunstatfs(sp, (caddr_t)SCARG(uap, buf));
! 869: }
! 870:
! 871: int
! 872: sunos_sys_exportfs(p, v, retval)
! 873: struct proc *p;
! 874: void *v;
! 875: register_t *retval;
! 876: {
! 877: /*
! 878: * XXX: should perhaps translate into a mount(2)
! 879: * with MOUNT_EXPORT?
! 880: */
! 881: return 0;
! 882: }
! 883:
! 884: int
! 885: sunos_sys_mknod(p, v, retval)
! 886: struct proc *p;
! 887: void *v;
! 888: register_t *retval;
! 889: {
! 890: struct sunos_sys_mknod_args *uap = v;
! 891:
! 892: caddr_t sg = stackgap_init(p->p_emul);
! 893: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
! 894:
! 895: if (S_ISFIFO(SCARG(uap, mode)))
! 896: return sys_mkfifo(p, uap, retval);
! 897:
! 898: return sys_mknod(p, (struct sys_mknod_args *)uap, retval);
! 899: }
! 900:
! 901: #define SUNOS_SC_ARG_MAX 1
! 902: #define SUNOS_SC_CHILD_MAX 2
! 903: #define SUNOS_SC_CLK_TCK 3
! 904: #define SUNOS_SC_NGROUPS_MAX 4
! 905: #define SUNOS_SC_OPEN_MAX 5
! 906: #define SUNOS_SC_JOB_CONTROL 6
! 907: #define SUNOS_SC_SAVED_IDS 7
! 908: #define SUNOS_SC_VERSION 8
! 909:
! 910: int
! 911: sunos_sys_sysconf(p, v, retval)
! 912: struct proc *p;
! 913: void *v;
! 914: register_t *retval;
! 915: {
! 916: struct sunos_sys_sysconf_args *uap = v;
! 917: extern int maxfiles;
! 918:
! 919: switch(SCARG(uap, name)) {
! 920: case SUNOS_SC_ARG_MAX:
! 921: *retval = ARG_MAX;
! 922: break;
! 923: case SUNOS_SC_CHILD_MAX:
! 924: *retval = maxproc;
! 925: break;
! 926: case SUNOS_SC_CLK_TCK:
! 927: *retval = 60; /* should this be `hz', ie. 100? */
! 928: break;
! 929: case SUNOS_SC_NGROUPS_MAX:
! 930: *retval = NGROUPS_MAX;
! 931: break;
! 932: case SUNOS_SC_OPEN_MAX:
! 933: *retval = maxfiles;
! 934: break;
! 935: case SUNOS_SC_JOB_CONTROL:
! 936: *retval = 1;
! 937: break;
! 938: case SUNOS_SC_SAVED_IDS:
! 939: #ifdef _POSIX_SAVED_IDS
! 940: *retval = 1;
! 941: #else
! 942: *retval = 0;
! 943: #endif
! 944: break;
! 945: case SUNOS_SC_VERSION:
! 946: *retval = 198808;
! 947: break;
! 948: default:
! 949: return EINVAL;
! 950: }
! 951: return 0;
! 952: }
! 953:
! 954: #define SUNOS_RLIMIT_NOFILE 6 /* Other RLIMIT_* are the same */
! 955: #define SUNOS_RLIM_NLIMITS 7
! 956:
! 957: int
! 958: sunos_sys_getrlimit(p, v, retval)
! 959: struct proc *p;
! 960: void *v;
! 961: register_t *retval;
! 962: {
! 963: struct sunos_sys_getrlimit_args *uap = v;
! 964:
! 965: if (SCARG(uap, which) >= SUNOS_RLIM_NLIMITS)
! 966: return EINVAL;
! 967:
! 968: if (SCARG(uap, which) == SUNOS_RLIMIT_NOFILE)
! 969: SCARG(uap, which) = RLIMIT_NOFILE;
! 970:
! 971: return compat_43_sys_getrlimit(p, uap, retval);
! 972: }
! 973:
! 974: int
! 975: sunos_sys_setrlimit(p, v, retval)
! 976: struct proc *p;
! 977: void *v;
! 978: register_t *retval;
! 979: {
! 980: struct sunos_sys_getrlimit_args *uap = v;
! 981:
! 982: if (SCARG(uap, which) >= SUNOS_RLIM_NLIMITS)
! 983: return EINVAL;
! 984:
! 985: if (SCARG(uap, which) == SUNOS_RLIMIT_NOFILE)
! 986: SCARG(uap, which) = RLIMIT_NOFILE;
! 987:
! 988: return compat_43_sys_setrlimit(p, uap, retval);
! 989: }
! 990:
! 991: #ifdef PTRACE
! 992:
! 993: static int sreq2breq[] = {
! 994: PT_TRACE_ME, PT_READ_I, PT_READ_D, -1,
! 995: PT_WRITE_I, PT_WRITE_D, -1, PT_CONTINUE,
! 996: PT_KILL, -1, PT_ATTACH, PT_DETACH,
! 997: PT_GETREGS, PT_SETREGS, PT_GETFPREGS, PT_SETFPREGS
! 998: };
! 999: static int nreqs = sizeof(sreq2breq) / sizeof(sreq2breq[0]);
! 1000:
! 1001: int
! 1002: sunos_sys_ptrace(p, v, retval)
! 1003: struct proc *p;
! 1004: void *v;
! 1005: register_t *retval;
! 1006: {
! 1007: struct sunos_sys_ptrace_args *uap = v;
! 1008: struct sys_ptrace_args pa;
! 1009: int req;
! 1010:
! 1011: req = SCARG(uap, req);
! 1012:
! 1013: if (req < 0 || req >= nreqs)
! 1014: return (EINVAL);
! 1015:
! 1016: req = sreq2breq[req];
! 1017: if (req == -1)
! 1018: return (EINVAL);
! 1019:
! 1020: SCARG(&pa, req) = req;
! 1021: SCARG(&pa, pid) = (pid_t)SCARG(uap, pid);
! 1022: SCARG(&pa, addr) = (caddr_t)SCARG(uap, addr);
! 1023: SCARG(&pa, data) = SCARG(uap, data);
! 1024:
! 1025: return sys_ptrace(p, &pa, retval);
! 1026: }
! 1027:
! 1028: #endif /* PTRACE */
! 1029:
! 1030: /*
! 1031: * SunOS reboot system call (for compatibility).
! 1032: * Sun lets you pass in a boot string which the PROM
! 1033: * saves and provides to the next boot program.
! 1034: */
! 1035: static struct sunos_howto_conv {
! 1036: int sun_howto;
! 1037: int bsd_howto;
! 1038: } sunos_howto_conv[] = {
! 1039: { 0x001, RB_ASKNAME },
! 1040: { 0x002, RB_SINGLE },
! 1041: { 0x004, RB_NOSYNC },
! 1042: { 0x008, RB_HALT },
! 1043: { 0x080, RB_DUMP },
! 1044: { 0x000, 0 },
! 1045: };
! 1046: #define SUNOS_RB_STRING 0x200
! 1047:
! 1048: int
! 1049: sunos_sys_reboot(p, v, retval)
! 1050: struct proc *p;
! 1051: void *v;
! 1052: register_t *retval;
! 1053: {
! 1054: struct sunos_sys_reboot_args *uap = v;
! 1055: struct sunos_howto_conv *convp;
! 1056: int error, bsd_howto, sun_howto;
! 1057:
! 1058: if ((error = suser(p, 0)) != 0)
! 1059: return (error);
! 1060:
! 1061: /*
! 1062: * Convert howto bits to BSD format.
! 1063: */
! 1064: sun_howto = SCARG(uap, howto);
! 1065: bsd_howto = 0;
! 1066: convp = sunos_howto_conv;
! 1067: while (convp->sun_howto) {
! 1068: if (sun_howto & convp->sun_howto)
! 1069: bsd_howto |= convp->bsd_howto;
! 1070: convp++;
! 1071: }
! 1072:
! 1073: #ifdef sun3
! 1074: /*
! 1075: * Sun RB_STRING (Get user supplied bootstring.)
! 1076: * If the machine supports passing a string to the
! 1077: * next booted kernel, add the machine name above
! 1078: * and provide a reboot2() function (see sun3).
! 1079: */
! 1080: if (sun_howto & SUNOS_RB_STRING) {
! 1081: char bs[128];
! 1082:
! 1083: error = copyinstr(SCARG(uap, bootstr), bs, sizeof(bs), 0);
! 1084: if (error)
! 1085: return error;
! 1086:
! 1087: return (reboot2(bsd_howto, bs));
! 1088: }
! 1089: #endif /* sun3 */
! 1090:
! 1091: boot(bsd_howto);
! 1092: return 0;
! 1093: }
! 1094:
! 1095: /*
! 1096: * Generalized interface signal handler, 4.3-compatible.
! 1097: */
! 1098: /* ARGSUSED */
! 1099: int
! 1100: sunos_sys_sigvec(p, v, retval)
! 1101: struct proc *p;
! 1102: void *v;
! 1103: register_t *retval;
! 1104: {
! 1105: register struct sunos_sys_sigvec_args /* {
! 1106: syscallarg(int) signum;
! 1107: syscallarg(struct sigvec *) nsv;
! 1108: syscallarg(struct sigvec *) osv;
! 1109: } */ *uap = v;
! 1110: struct sigvec vec;
! 1111: register struct sigacts *ps = p->p_sigacts;
! 1112: register struct sigvec *sv;
! 1113: register int signum;
! 1114: int bit, error;
! 1115:
! 1116: signum = SCARG(uap, signum);
! 1117: if (signum <= 0 || signum >= NSIG ||
! 1118: signum == SIGKILL || signum == SIGSTOP)
! 1119: return (EINVAL);
! 1120: sv = &vec;
! 1121: if (SCARG(uap, osv)) {
! 1122: *(sig_t *)&sv->sv_handler = ps->ps_sigact[signum];
! 1123: sv->sv_mask = ps->ps_catchmask[signum];
! 1124: bit = sigmask(signum);
! 1125: sv->sv_flags = 0;
! 1126: if ((ps->ps_sigonstack & bit) != 0)
! 1127: sv->sv_flags |= SV_ONSTACK;
! 1128: if ((ps->ps_sigintr & bit) != 0)
! 1129: sv->sv_flags |= SV_INTERRUPT;
! 1130: if ((ps->ps_sigreset & bit) != 0)
! 1131: sv->sv_flags |= SA_RESETHAND;
! 1132: sv->sv_mask &= ~bit;
! 1133: error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, osv),
! 1134: sizeof (vec));
! 1135: if (error)
! 1136: return (error);
! 1137: }
! 1138: if (SCARG(uap, nsv)) {
! 1139: error = copyin((caddr_t)SCARG(uap, nsv), (caddr_t)sv,
! 1140: sizeof (vec));
! 1141: if (error)
! 1142: return (error);
! 1143: /*
! 1144: * SunOS uses the mask 0x0004 as SV_RESETHAND
! 1145: * meaning: `reset to SIG_DFL on delivery'.
! 1146: * We support only the bits in: 0xF
! 1147: * (those bits are the same as ours)
! 1148: */
! 1149: if (sv->sv_flags & ~0xF)
! 1150: return (EINVAL);
! 1151: /* SunOS binaries have a user-mode trampoline. */
! 1152: sv->sv_flags |= SA_USERTRAMP;
! 1153: /* Convert sigvec:SV_INTERRUPT to sigaction:SA_RESTART */
! 1154: sv->sv_flags ^= SA_RESTART; /* same bit, inverted */
! 1155: setsigvec(p, signum, (struct sigaction *)sv);
! 1156: }
! 1157: return (0);
! 1158: }
! 1159:
! 1160: int
! 1161: sunos_sys_ostime(p, v, retval)
! 1162: struct proc *p;
! 1163: void *v;
! 1164: register_t *retval;
! 1165: {
! 1166: struct sunos_sys_ostime_args /* {
! 1167: syscallarg(int) time;
! 1168: } */ *uap = v;
! 1169: struct timespec ts;
! 1170: int error;
! 1171:
! 1172: if ((error = suser(p, 0)) != 0)
! 1173: return (error);
! 1174:
! 1175: ts.tv_sec = SCARG(uap, time);
! 1176: ts.tv_nsec = 0;
! 1177: error = settime(&ts);
! 1178: return (error);
! 1179: }
! 1180:
! 1181: /*
! 1182: * This code is partly stolen from src/lib/libc/gen/times.c
! 1183: * XXX - CLK_TCK isn't declared in /sys, just in <time.h>, done here
! 1184: */
! 1185:
! 1186: #define CLK_TCK 100
! 1187: #define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
! 1188:
! 1189: int
! 1190: sunos_sys_otimes(p, v, retval)
! 1191: struct proc *p;
! 1192: void *v;
! 1193: register_t *retval;
! 1194: {
! 1195: struct sunos_sys_otimes_args /* {
! 1196: syscallarg(struct tms *) tp;
! 1197: } */ *uap = v;
! 1198: struct tms tms;
! 1199: struct rusage ru, *rup;
! 1200:
! 1201: /* RUSAGE_SELF */
! 1202: calcru(p, &ru.ru_utime, &ru.ru_stime, NULL);
! 1203: tms.tms_utime = CONVTCK(ru.ru_utime);
! 1204: tms.tms_stime = CONVTCK(ru.ru_stime);
! 1205:
! 1206: /* RUSAGE_CHILDREN */
! 1207: rup = &p->p_stats->p_cru;
! 1208: tms.tms_cutime = CONVTCK(rup->ru_utime);
! 1209: tms.tms_cstime = CONVTCK(rup->ru_stime);
! 1210:
! 1211: return copyout(&tms, SCARG(uap, tp), sizeof(*(SCARG(uap, tp))));
! 1212: }
CVSweb