[BACK]Return to sunos_misc.c CVS log [TXT][DIR] Up to [local] / sys / compat / sunos

Annotation of sys/compat/sunos/sunos_misc.c, Revision 1.1.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