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

Annotation of sys/compat/hpux/hpux_compat.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: hpux_compat.c,v 1.28 2004/07/09 21:33:44 mickey Exp $ */
                      2: /*     $NetBSD: hpux_compat.c,v 1.35 1997/05/08 16:19:48 mycroft Exp $ */
                      3:
                      4: /*
                      5:  * Copyright (c) 1988 University of Utah.
                      6:  * Copyright (c) 1990, 1993
                      7:  *     The Regents of the University of California.  All rights reserved.
                      8:  *
                      9:  * This code is derived from software contributed to Berkeley by
                     10:  * the Systems Programming Group of the University of Utah Computer
                     11:  * Science Department.
                     12:  *
                     13:  * Redistribution and use in source and binary forms, with or without
                     14:  * modification, are permitted provided that the following conditions
                     15:  * are met:
                     16:  * 1. Redistributions of source code must retain the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer.
                     18:  * 2. Redistributions in binary form must reproduce the above copyright
                     19:  *    notice, this list of conditions and the following disclaimer in the
                     20:  *    documentation and/or other materials provided with the distribution.
                     21:  * 3. Neither the name of the University nor the names of its contributors
                     22:  *    may be used to endorse or promote products derived from this software
                     23:  *    without specific prior written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     28:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     29:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     30:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     31:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     32:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     33:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     34:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     35:  * SUCH DAMAGE.
                     36:  *
                     37:  * from: Utah $Hdr: hpux_compat.c 1.64 93/08/05$
                     38:  *
                     39:  *     @(#)hpux_compat.c       8.4 (Berkeley) 2/13/94
                     40:  */
                     41:
                     42: /*
                     43:  * Various HP-UX compatibility routines
                     44:  */
                     45:
                     46: #ifndef COMPAT_43
                     47: #define COMPAT_43
                     48: #endif
                     49:
                     50: #include <sys/param.h>
                     51: #include <sys/systm.h>
                     52: #include <sys/signalvar.h>
                     53: #include <sys/kernel.h>
                     54: #include <sys/filedesc.h>
                     55: #include <sys/proc.h>
                     56: #include <sys/buf.h>
                     57: #include <sys/wait.h>
                     58: #include <sys/file.h>
                     59: #include <sys/namei.h>
                     60: #include <sys/vnode.h>
                     61: #include <sys/ioctl.h>
                     62: #include <sys/ptrace.h>
                     63: #include <sys/stat.h>
                     64: #include <sys/syslog.h>
                     65: #include <sys/malloc.h>
                     66: #include <sys/mount.h>
                     67: #include <sys/ipc.h>
                     68: #include <sys/user.h>
                     69: #include <sys/mman.h>
                     70:
                     71: #include <machine/cpu.h>
                     72: #include <machine/reg.h>
                     73: #include <machine/psl.h>
                     74: #include <machine/vmparam.h>
                     75:
                     76: #include <sys/syscallargs.h>
                     77:
                     78: #include <compat/hpux/hpux.h>
                     79: #include <compat/hpux/hpux_sig.h>
                     80: #include <compat/hpux/hpux_util.h>
                     81: #include <compat/hpux/hpux_termio.h>
                     82: #include <compat/hpux/hpux_syscall.h>
                     83: #include <compat/hpux/hpux_syscallargs.h>
                     84:
                     85: #include <machine/hpux_machdep.h>
                     86:
                     87: #ifdef DEBUG
                     88: int unimpresponse = 0;
                     89: #endif
                     90:
                     91: #define NERR   83
                     92: #define BERR   1000
                     93:
                     94: /* indexed by BSD errno */
                     95: int bsdtohpuxerrnomap[NERR] = {
                     96: /*00*/   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                     97: /*10*/  10,  45,  12,  13,  14,  15,  16,  17,  18,  19,
                     98: /*20*/  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
                     99: /*30*/  30,  31,  32,  33,  34, 246, 245, 244, 216, 217,
                    100: /*40*/ 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
                    101: /*50*/ 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
                    102: /*60*/ 238, 239, 249, 248, 241, 242, 247,BERR,BERR,BERR,
                    103: /*70*/   70,  71,BERR,BERR,BERR,BERR,BERR,  46, 251,BERR,
                    104: /*80*/ BERR,BERR,  11
                    105: };
                    106:
                    107: extern char sigcode[], esigcode[];
                    108: extern struct sysent hpux_sysent[];
                    109: extern char *hpux_syscallnames[];
                    110:
                    111: int    hpux_shmctl1(struct proc *, struct hpux_sys_shmctl_args *,
                    112:            register_t *, int);
                    113: int    hpuxtobsdioctl(u_long);
                    114:
                    115: static int     hpux_scale(struct timeval *);
                    116:
                    117: /*
                    118:  * HP-UX fork and vfork need to map the EAGAIN return value appropriately.
                    119:  */
                    120: int
                    121: hpux_sys_fork(p, v, retval)
                    122:        struct proc *p;
                    123:        void *v;
                    124:        register_t *retval;
                    125: {
                    126:        /* struct hpux_sys_fork_args *uap = v; */
                    127:        int error;
                    128:
                    129:        error = sys_fork(p, v, retval);
                    130:        if (error == EAGAIN)
                    131:                error = OEAGAIN;
                    132:        return (error);
                    133: }
                    134:
                    135: int
                    136: hpux_sys_vfork(p, v, retval)
                    137:        struct proc *p;
                    138:        void *v;
                    139:        register_t *retval;
                    140: {
                    141:        /* struct hpux_sys_vfork_args *uap = v; */
                    142:        int error;
                    143:
                    144:        error = sys_vfork(p, v, retval);
                    145:        if (error == EAGAIN)
                    146:                error = OEAGAIN;
                    147:        return (error);
                    148: }
                    149:
                    150: /*
                    151:  * HP-UX versions of wait and wait3 actually pass the parameters
                    152:  * (status pointer, options, rusage) into the kernel rather than
                    153:  * handling it in the C library stub.  We also need to map any
                    154:  * termination signal from BSD to HP-UX.
                    155:  */
                    156: int
                    157: hpux_sys_wait3(p, v, retval)
                    158:        struct proc *p;
                    159:        void *v;
                    160:        register_t *retval;
                    161: {
                    162:        struct hpux_sys_wait3_args *uap = v;
                    163:
                    164:        /* rusage pointer must be zero */
                    165:        if (SCARG(uap, rusage))
                    166:                return (EINVAL);
                    167: #ifdef m68k
                    168:        p->p_md.md_regs[PS] = PSL_ALLCC;
                    169:        p->p_md.md_regs[R0] = SCARG(uap, options);
                    170:        p->p_md.md_regs[R1] = SCARG(uap, rusage);
                    171: #endif
                    172:
                    173:        return (hpux_sys_wait(p, uap, retval));
                    174: }
                    175:
                    176: int
                    177: hpux_sys_wait(p, v, retval)
                    178:        struct proc *p;
                    179:        void *v;
                    180:        register_t *retval;
                    181: {
                    182:        struct hpux_sys_wait_args *uap = v;
                    183:        struct sys_wait4_args w4;
                    184:        int error;
                    185:        int sig;
                    186:        size_t sz = sizeof(*SCARG(&w4, status));
                    187:        int status;
                    188:
                    189:        SCARG(&w4, rusage) = NULL;
                    190:        SCARG(&w4, options) = 0;
                    191:
                    192:        if (SCARG(uap, status) == NULL) {
                    193:                caddr_t sg = stackgap_init(p->p_emul);
                    194:                SCARG(&w4, status) = stackgap_alloc(&sg, sz);
                    195:        }
                    196:        else
                    197:                SCARG(&w4, status) = SCARG(uap, status);
                    198:
                    199:        SCARG(&w4, pid) = WAIT_ANY;
                    200:
                    201:        error = sys_wait4(p, &w4, retval);
                    202:        /*
                    203:         * HP-UX wait always returns EINTR when interrupted by a signal
                    204:         * (well, unless its emulating a BSD process, but we don't bother...)
                    205:         */
                    206:        if (error == ERESTART)
                    207:                error = EINTR;
                    208:        if (error)
                    209:                return error;
                    210:
                    211:        if ((error = copyin(SCARG(&w4, status), &status, sizeof(status))) != 0)
                    212:                return error;
                    213:
                    214:        sig = status & 0xFF;
                    215:        if (sig == WSTOPPED) {
                    216:                sig = (status >> 8) & 0xFF;
                    217:                retval[1] = (bsdtohpuxsig(sig) << 8) | WSTOPPED;
                    218:        } else if (sig)
                    219:                retval[1] = (status & 0xFF00) |
                    220:                        bsdtohpuxsig(sig & 0x7F) | (sig & 0x80);
                    221:
                    222:        if (SCARG(uap, status) == NULL)
                    223:                return error;
                    224:        else
                    225:                return copyout(&retval[1],
                    226:                               SCARG(uap, status), sizeof(retval[1]));
                    227: }
                    228:
                    229: int
                    230: hpux_sys_waitpid(p, v, retval)
                    231:        struct proc *p;
                    232:        void *v;
                    233:        register_t *retval;
                    234: {
                    235:        struct hpux_sys_waitpid_args *uap = v;
                    236:        int rv, sig, xstat, error;
                    237:
                    238:        SCARG(uap, rusage) = 0;
                    239:        error = sys_wait4(p, uap, retval);
                    240:        /*
                    241:         * HP-UX wait always returns EINTR when interrupted by a signal
                    242:         * (well, unless its emulating a BSD process, but we don't bother...)
                    243:         */
                    244:        if (error == ERESTART)
                    245:                error = EINTR;
                    246:        if (error)
                    247:                return (error);
                    248:
                    249:        if (SCARG(uap, status)) {
                    250:                /*
                    251:                 * Wait4 already wrote the status out to user space,
                    252:                 * pull it back, change the signal portion, and write
                    253:                 * it back out.
                    254:                 */
                    255:                if ((error = copyin((caddr_t)SCARG(uap, status), &rv,
                    256:                    sizeof(int))) != 0)
                    257:                        return error;
                    258:
                    259:                if (WIFSTOPPED(rv)) {
                    260:                        sig = WSTOPSIG(rv);
                    261:                        rv = W_STOPCODE(bsdtohpuxsig(sig));
                    262:                } else if (WIFSIGNALED(rv)) {
                    263:                        sig = WTERMSIG(rv);
                    264:                        xstat = WEXITSTATUS(rv);
                    265:                        rv = W_EXITCODE(xstat, bsdtohpuxsig(sig)) |
                    266:                                WCOREDUMP(rv);
                    267:                }
                    268:                error = copyout(&rv, (caddr_t)SCARG(uap, status), sizeof(int));
                    269:        }
                    270:        return (error);
                    271: }
                    272:
                    273: /*
                    274:  * Read and write calls.  Same as BSD except for non-blocking behavior.
                    275:  * There are three types of non-blocking reads/writes in HP-UX checked
                    276:  * in the following order:
                    277:  *
                    278:  *     O_NONBLOCK: return -1 and errno == EAGAIN
                    279:  *     O_NDELAY:   return 0
                    280:  *     FIOSNBIO:   return -1 and errno == EWOULDBLOCK
                    281:  */
                    282: int
                    283: hpux_sys_read(p, v, retval)
                    284:        struct proc *p;
                    285:        void *v;
                    286:        register_t *retval;
                    287: {
                    288:        struct hpux_sys_read_args *uap = v;
                    289:        int error;
                    290:
                    291:        error = sys_read(p, (struct sys_read_args *) uap, retval);
                    292:        if (error == EWOULDBLOCK) {
                    293:                char *fp = &p->p_fd->fd_ofileflags[SCARG(uap, fd)];
                    294:
                    295:                if (*fp & HPUX_UF_NONBLOCK_ON) {
                    296:                        *retval = -1;
                    297:                        error = OEAGAIN;
                    298:                } else if (*fp & HPUX_UF_FNDELAY_ON) {
                    299:                        *retval = 0;
                    300:                        error = 0;
                    301:                }
                    302:        }
                    303:        return (error);
                    304: }
                    305:
                    306: int
                    307: hpux_sys_write(p, v, retval)
                    308:        struct proc *p;
                    309:        void *v;
                    310:        register_t *retval;
                    311: {
                    312:        struct hpux_sys_write_args *uap = v;
                    313:        int error;
                    314:
                    315:        error = sys_write(p, (struct sys_write_args *) uap, retval);
                    316:        if (error == EWOULDBLOCK) {
                    317:                char *fp = &p->p_fd->fd_ofileflags[SCARG(uap, fd)];
                    318:
                    319:                if (*fp & HPUX_UF_NONBLOCK_ON) {
                    320:                        *retval = -1;
                    321:                        error = OEAGAIN;
                    322:                } else if (*fp & HPUX_UF_FNDELAY_ON) {
                    323:                        *retval = 0;
                    324:                        error = 0;
                    325:                }
                    326:        }
                    327:        return (error);
                    328: }
                    329:
                    330: int
                    331: hpux_sys_readv(p, v, retval)
                    332:        struct proc *p;
                    333:        void *v;
                    334:        register_t *retval;
                    335: {
                    336:        struct hpux_sys_readv_args *uap = v;
                    337:        int error;
                    338:
                    339:        error = sys_readv(p, (struct sys_readv_args *) uap, retval);
                    340:        if (error == EWOULDBLOCK) {
                    341:                char *fp = &p->p_fd->fd_ofileflags[SCARG(uap, fd)];
                    342:
                    343:                if (*fp & HPUX_UF_NONBLOCK_ON) {
                    344:                        *retval = -1;
                    345:                        error = OEAGAIN;
                    346:                } else if (*fp & HPUX_UF_FNDELAY_ON) {
                    347:                        *retval = 0;
                    348:                        error = 0;
                    349:                }
                    350:        }
                    351:        return (error);
                    352: }
                    353:
                    354: int
                    355: hpux_sys_writev(p, v, retval)
                    356:        struct proc *p;
                    357:        void *v;
                    358:        register_t *retval;
                    359: {
                    360:        struct hpux_sys_writev_args *uap = v;
                    361:        int error;
                    362:
                    363:        error = sys_writev(p, (struct sys_writev_args *) uap, retval);
                    364:        if (error == EWOULDBLOCK) {
                    365:                char *fp = &p->p_fd->fd_ofileflags[SCARG(uap, fd)];
                    366:
                    367:                if (*fp & HPUX_UF_NONBLOCK_ON) {
                    368:                        *retval = -1;
                    369:                        error = OEAGAIN;
                    370:                } else if (*fp & HPUX_UF_FNDELAY_ON) {
                    371:                        *retval = 0;
                    372:                        error = 0;
                    373:                }
                    374:        }
                    375:        return (error);
                    376: }
                    377:
                    378: int
                    379: hpux_sys_utssys(p, v, retval)
                    380:        struct proc *p;
                    381:        void *v;
                    382:        register_t *retval;
                    383: {
                    384:        struct hpux_sys_utssys_args *uap = v;
                    385:        int i;
                    386:        int error;
                    387:        struct hpux_utsname     ut;
                    388:        extern char hostname[], machine[];
                    389:
                    390:        switch (SCARG(uap, request)) {
                    391:        /* uname */
                    392:        case 0:
                    393:                bzero(&ut, sizeof(ut));
                    394:
                    395:                strlcpy(ut.sysname, ostype, sizeof(ut.sysname));
                    396:
                    397:                /* copy hostname (sans domain) to nodename */
                    398:                for (i = 0; i < 8 && hostname[i] != '.'; i++)
                    399:                        ut.nodename[i] = hostname[i];
                    400:                ut.nodename[i] = '\0';
                    401:
                    402:                strlcpy(ut.release, osrelease, sizeof(ut.release));
                    403:                strlcpy(ut.version, version, sizeof(ut.version));
                    404:                strlcpy(ut.machine, machine, sizeof(ut.machine));
                    405:
                    406:                error = copyout((caddr_t)&ut,
                    407:                    (caddr_t)SCARG(uap, uts), sizeof(ut));
                    408:                break;
                    409:
                    410:        /* gethostname */
                    411:        case 5:
                    412:                /* SCARG(uap, dev) is length */
                    413:                i = SCARG(uap, dev);
                    414:                if (i < 0) {
                    415:                        error = EINVAL;
                    416:                        break;
                    417:                }
                    418:                if (i > hostnamelen + 1)
                    419:                        i = hostnamelen + 1;
                    420:                error = copyout((caddr_t)hostname, (caddr_t)SCARG(uap, uts), i);
                    421:                break;
                    422:
                    423:        case 1: /* ?? */
                    424:        case 2: /* ustat */
                    425:        case 3: /* ?? */
                    426:        case 4: /* sethostname */
                    427:        default:
                    428:                error = EINVAL;
                    429:                break;
                    430:        }
                    431:        return (error);
                    432: }
                    433:
                    434: int
                    435: hpux_sys_sysconf(p, v, retval)
                    436:        struct proc *p;
                    437:        void *v;
                    438:        register_t *retval;
                    439: {
                    440:        struct hpux_sys_sysconf_args *uap = v;
                    441:        switch (SCARG(uap, name)) {
                    442:
                    443:        /* clock ticks per second */
                    444:        case HPUX_SYSCONF_CLKTICK:
                    445:                *retval = hz;
                    446:                break;
                    447:
                    448:        /* open files */
                    449:        case HPUX_SYSCONF_OPENMAX:
                    450:                *retval = NOFILE;
                    451:                break;
                    452:
                    453:        /* architecture */
                    454:        case HPUX_SYSCONF_CPUTYPE:
                    455:                *retval = hpux_cpu_sysconf_arch();
                    456:                break;
                    457:        default:
                    458:                /* XXX */
                    459:                uprintf("HP-UX sysconf(%d) not implemented\n",
                    460:                    SCARG(uap, name));
                    461:                return (EINVAL);
                    462:        }
                    463:        return (0);
                    464: }
                    465:
                    466: int
                    467: hpux_sys_ulimit(p, v, retval)
                    468:        struct proc *p;
                    469:        void *v;
                    470:        register_t *retval;
                    471: {
                    472:        struct hpux_sys_ulimit_args *uap = v;
                    473:        struct rlimit *limp;
                    474:        int error = 0;
                    475:
                    476:        limp = &p->p_rlimit[RLIMIT_FSIZE];
                    477:        switch (SCARG(uap, cmd)) {
                    478:        case 2:
                    479:                SCARG(uap, newlimit) *= 512;
                    480:                if (SCARG(uap, newlimit) > limp->rlim_max &&
                    481:                    (error = suser(p, 0)))
                    482:                        break;
                    483:                limp->rlim_cur = limp->rlim_max = SCARG(uap, newlimit);
                    484:                /* else fall into... */
                    485:
                    486:        case 1:
                    487:                *retval = limp->rlim_max / 512;
                    488:                break;
                    489:
                    490:        case 3:
                    491:                limp = &p->p_rlimit[RLIMIT_DATA];
                    492:                *retval = ctob(p->p_vmspace->vm_tsize) + limp->rlim_max;
                    493:                break;
                    494:
                    495:        default:
                    496:                error = EINVAL;
                    497:                break;
                    498:        }
                    499:        return (error);
                    500: }
                    501:
                    502: /*
                    503:  * Map "real time" priorities 0 (high) thru 127 (low) into nice
                    504:  * values -16 (high) thru -1 (low).
                    505:  */
                    506: int
                    507: hpux_sys_rtprio(cp, v, retval)
                    508:        struct proc *cp;
                    509:        void *v;
                    510:        register_t *retval;
                    511: {
                    512:        struct hpux_sys_rtprio_args *uap = v;
                    513:        struct proc *p;
                    514:        int nice, error;
                    515:
                    516:        if (SCARG(uap, prio) < RTPRIO_MIN && SCARG(uap, prio) > RTPRIO_MAX &&
                    517:            SCARG(uap, prio) != RTPRIO_NOCHG &&
                    518:            SCARG(uap, prio) != RTPRIO_RTOFF)
                    519:                return (EINVAL);
                    520:        if (SCARG(uap, pid) == 0)
                    521:                p = cp;
                    522:        else if ((p = pfind(SCARG(uap, pid))) == 0)
                    523:                return (ESRCH);
                    524:        nice = p->p_nice;
                    525:        if (nice < NZERO)
                    526:                *retval = (nice + 16) << 3;
                    527:        else
                    528:                *retval = RTPRIO_RTOFF;
                    529:        switch (SCARG(uap, prio)) {
                    530:
                    531:        case RTPRIO_NOCHG:
                    532:                return (0);
                    533:
                    534:        case RTPRIO_RTOFF:
                    535:                if (nice >= NZERO)
                    536:                        return (0);
                    537:                nice = NZERO;
                    538:                break;
                    539:
                    540:        default:
                    541:                nice = (SCARG(uap, prio) >> 3) - 16;
                    542:                break;
                    543:        }
                    544:        error = donice(cp, p, nice);
                    545:        if (error == EACCES)
                    546:                error = EPERM;
                    547:        return (error);
                    548: }
                    549:
                    550: /* hpux_sys_advise() is found in hpux_machdep.c */
                    551:
                    552: #ifdef PTRACE
                    553:
                    554: int
                    555: hpux_sys_ptrace(p, v, retval)
                    556:        struct proc *p;
                    557:        void *v;
                    558:        register_t *retval;
                    559: {
                    560:        struct hpux_sys_ptrace_args *uap = v;
                    561:        int error;
                    562: #if defined(PT_READ_U) || defined(PT_WRITE_U)
                    563:        int isps = 0;
                    564:        struct proc *cp;
                    565: #endif
                    566:
                    567:        switch (SCARG(uap, req)) {
                    568:        /* map signal */
                    569: #if defined(PT_STEP) || defined(PT_CONTINUE)
                    570: # ifdef PT_STEP
                    571:        case PT_STEP:
                    572: # endif
                    573: # ifdef PT_CONTINUE
                    574:        case PT_CONTINUE:
                    575: # endif
                    576:                if (SCARG(uap, data)) {
                    577:                        SCARG(uap, data) = hpuxtobsdsig(SCARG(uap, data));
                    578:                        if (SCARG(uap, data) == 0)
                    579:                                SCARG(uap, data) = NSIG;
                    580:                }
                    581:                break;
                    582: #endif
                    583:        /* map u-area offset */
                    584: #if defined(PT_READ_U) || defined(PT_WRITE_U)
                    585: # ifdef PT_READ_U
                    586:        case PT_READ_U:
                    587: # endif
                    588: # ifdef PT_WRITE_U
                    589:        case PT_WRITE_U:
                    590: # endif
                    591:                /*
                    592:                 * Big, cheezy hack: hpux_to_bsd_uoff is really intended
                    593:                 * to be called in the child context (procxmt) but we
                    594:                 * do it here in the parent context to avoid hacks in
                    595:                 * the MI sys_process.c file.  This works only because
                    596:                 * we can access the child's md_regs pointer and it
                    597:                 * has the correct value (the child has already trapped
                    598:                 * into the kernel).
                    599:                 */
                    600:                if ((cp = pfind(SCARG(uap, pid))) == 0)
                    601:                        return (ESRCH);
                    602:                SCARG(uap, addr) =
                    603:                    (int *)hpux_to_bsd_uoff(SCARG(uap, addr), &isps, cp);
                    604:
                    605:                /*
                    606:                 * Since HP-UX PS is only 16-bits in ar0, requests
                    607:                 * to write PS actually contain the PS in the high word
                    608:                 * and the high half of the PC (the following register)
                    609:                 * in the low word.  Move the PS value to where BSD
                    610:                 * expects it.
                    611:                 */
                    612:                if (isps && SCARG(uap, req) == PT_WRITE_U)
                    613:                        SCARG(uap, data) >>= 16;
                    614:                break;
                    615: #endif
                    616:        }
                    617:
                    618:        error = sys_ptrace(p, uap, retval);
                    619:        /*
                    620:         * Align PS as HP-UX expects it (see WRITE_U comment above).
                    621:         * Note that we do not return the high part of PC like HP-UX
                    622:         * would, but the HP-UX debuggers don't require it.
                    623:         */
                    624: #ifdef PT_READ_U
                    625:        if (isps && error == 0 && SCARG(uap, req) == PT_READ_U)
                    626:                *retval <<= 16;
                    627: #endif
                    628:        return (error);
                    629: }
                    630:
                    631: #endif /* PTRACE */
                    632:
                    633: #ifdef SYSVSHM
                    634: #include <sys/shm.h>
                    635:
                    636: int
                    637: hpux_sys_shmctl(p, v, retval)
                    638:        struct proc *p;
                    639:        void *v;
                    640:        register_t *retval;
                    641: {
                    642:        struct hpux_sys_shmctl_args *uap = v;
                    643:
                    644:        return (hpux_shmctl1(p, (struct hpux_sys_shmctl_args *)uap, retval, 0));
                    645: }
                    646:
                    647: int
                    648: hpux_sys_nshmctl(p, v, retval)
                    649:        struct proc *p;
                    650:        void *v;
                    651:        register_t *retval;     /* struct hpux_nshmctl_args * */
                    652: {
                    653:        struct hpux_sys_nshmctl_args *uap = v;
                    654:
                    655:        return (hpux_shmctl1(p, (struct hpux_sys_shmctl_args *)uap, retval, 1));
                    656: }
                    657:
                    658: /*
                    659:  * Handle HP-UX specific commands.
                    660:  */
                    661: int
                    662: hpux_shmctl1(p, uap, retval, isnew)
                    663:        struct proc *p;
                    664:        struct hpux_sys_shmctl_args *uap;
                    665:        register_t *retval;
                    666:        int isnew;
                    667: {
                    668:        struct shmid_ds *shp;
                    669:        struct ucred *cred = p->p_ucred;
                    670:        struct hpux_shmid_ds sbuf;
                    671:        int error;
                    672:        extern struct shmid_ds *shm_find_segment_by_shmid(int);
                    673:
                    674:        if ((shp = shm_find_segment_by_shmid(SCARG(uap, shmid))) == NULL)
                    675:                return EINVAL;
                    676:
                    677:        switch (SCARG(uap, cmd)) {
                    678:        case SHM_LOCK:
                    679:        case SHM_UNLOCK:
                    680:                /* don't really do anything, but make them think we did */
                    681:                if (cred->cr_uid && cred->cr_uid != shp->shm_perm.uid &&
                    682:                    cred->cr_uid != shp->shm_perm.cuid)
                    683:                        return (EPERM);
                    684:                return (0);
                    685:
                    686:        case IPC_STAT:
                    687:                if (!isnew)
                    688:                        break;
                    689:                error = ipcperm(cred, &shp->shm_perm, IPC_R);
                    690:                if (error == 0) {
                    691:                        sbuf.shm_perm.uid = shp->shm_perm.uid;
                    692:                        sbuf.shm_perm.gid = shp->shm_perm.gid;
                    693:                        sbuf.shm_perm.cuid = shp->shm_perm.cuid;
                    694:                        sbuf.shm_perm.cgid = shp->shm_perm.cgid;
                    695:                        sbuf.shm_perm.mode = shp->shm_perm.mode;
                    696:                        sbuf.shm_perm.seq = shp->shm_perm.seq;
                    697:                        sbuf.shm_perm.key = shp->shm_perm.key;
                    698:                        sbuf.shm_segsz = shp->shm_segsz;
                    699:                        sbuf.shm_ptbl = shp->shm_internal;      /* XXX */
                    700:                        sbuf.shm_lpid = shp->shm_lpid;
                    701:                        sbuf.shm_cpid = shp->shm_cpid;
                    702:                        sbuf.shm_nattch = shp->shm_nattch;
                    703:                        sbuf.shm_cnattch = shp->shm_nattch;     /* XXX */
                    704:                        sbuf.shm_atime = shp->shm_atime;
                    705:                        sbuf.shm_dtime = shp->shm_dtime;
                    706:                        sbuf.shm_ctime = shp->shm_ctime;
                    707:                        error = copyout((caddr_t)&sbuf, SCARG(uap, buf),
                    708:                            sizeof sbuf);
                    709:                }
                    710:                return (error);
                    711:
                    712:        case IPC_SET:
                    713:                if (!isnew)
                    714:                        break;
                    715:                if (cred->cr_uid && cred->cr_uid != shp->shm_perm.uid &&
                    716:                    cred->cr_uid != shp->shm_perm.cuid) {
                    717:                        return (EPERM);
                    718:                }
                    719:                error = copyin(SCARG(uap, buf), (caddr_t)&sbuf, sizeof sbuf);
                    720:                if (error == 0) {
                    721:                        shp->shm_perm.uid = sbuf.shm_perm.uid;
                    722:                        shp->shm_perm.gid = sbuf.shm_perm.gid;
                    723:                        shp->shm_perm.mode = (shp->shm_perm.mode & ~0777)
                    724:                                | (sbuf.shm_perm.mode & 0777);
                    725:                        shp->shm_ctime = time_second;
                    726:                }
                    727:                return (error);
                    728:        }
                    729:        return (sys_shmctl(p, uap, retval));
                    730: }
                    731: #endif
                    732:
                    733: /*
                    734:  * HP-UX mmap() emulation (mainly for shared library support).
                    735:  */
                    736: int
                    737: hpux_sys_mmap(p, v, retval)
                    738:        struct proc *p;
                    739:        void *v;
                    740:        register_t *retval;
                    741: {
                    742:        struct hpux_sys_mmap_args *uap = v;
                    743:        struct sys_mmap_args /* {
                    744:                syscallarg(caddr_t) addr;
                    745:                syscallarg(size_t) len;
                    746:                syscallarg(int) prot;
                    747:                syscallarg(int) flags;
                    748:                syscallarg(int) fd;
                    749:                syscallarg(long) pad;
                    750:                syscallarg(off_t) pos;
                    751:        } */ nargs;
                    752:
                    753:        SCARG(&nargs, addr) = SCARG(uap, addr);
                    754:        SCARG(&nargs, len) = SCARG(uap, len);
                    755:        SCARG(&nargs, prot) = SCARG(uap, prot);
                    756:        SCARG(&nargs, flags) = SCARG(uap, flags) &
                    757:                ~(HPUXMAP_FIXED|HPUXMAP_REPLACE|HPUXMAP_ANON);
                    758:        if (SCARG(uap, flags) & HPUXMAP_FIXED)
                    759:                SCARG(&nargs, flags) |= MAP_FIXED;
                    760:        if (SCARG(uap, flags) & HPUXMAP_ANON)
                    761:                SCARG(&nargs, flags) |= MAP_ANON;
                    762:        SCARG(&nargs, fd) = (SCARG(&nargs, flags) & MAP_ANON) ? -1 : SCARG(uap, fd);
                    763:        SCARG(&nargs, pos) = SCARG(uap, pos);
                    764:
                    765:        return (sys_mmap(p, &nargs, retval));
                    766: }
                    767:
                    768: int
                    769: hpuxtobsdioctl(com)
                    770:        u_long com;
                    771: {
                    772:        switch (com) {
                    773:        case HPUXTIOCSLTC:
                    774:                com = TIOCSLTC; break;
                    775:        case HPUXTIOCGLTC:
                    776:                com = TIOCGLTC; break;
                    777:        case HPUXTIOCSPGRP:
                    778:                com = TIOCSPGRP; break;
                    779:        case HPUXTIOCGPGRP:
                    780:                com = TIOCGPGRP; break;
                    781:        case HPUXTIOCLBIS:
                    782:                com = TIOCLBIS; break;
                    783:        case HPUXTIOCLBIC:
                    784:                com = TIOCLBIC; break;
                    785:        case HPUXTIOCLSET:
                    786:                com = TIOCLSET; break;
                    787:        case HPUXTIOCLGET:
                    788:                com = TIOCLGET; break;
                    789:        case HPUXTIOCGWINSZ:
                    790:                com = TIOCGWINSZ; break;
                    791:        case HPUXTIOCSWINSZ:
                    792:                com = TIOCSWINSZ; break;
                    793:        }
                    794:        return(com);
                    795: }
                    796:
                    797: /*
                    798:  * HP-UX ioctl system call.  The differences here are:
                    799:  *     IOC_IN also means IOC_VOID if the size portion is zero.
                    800:  *     no FIOCLEX/FIONCLEX/FIOASYNC/FIOGETOWN/FIOSETOWN
                    801:  *     the sgttyb struct is 2 bytes longer
                    802:  */
                    803: int
                    804: hpux_sys_ioctl(p, v, retval)
                    805:        struct proc *p;
                    806:        void *v;
                    807:        register_t *retval;
                    808: {
                    809:        struct hpux_sys_ioctl_args /* {
                    810:                syscallarg(int) fd;
                    811:                syscallarg(int) com;
                    812:                syscallarg(caddr_t) data;
                    813:        } */ *uap = v;
                    814:        struct filedesc *fdp = p->p_fd;
                    815:        struct file *fp;
                    816:        int com, error = 0;
                    817:        u_int size;
                    818:        caddr_t memp = 0;
                    819: #define STK_PARAMS     128
                    820:        char stkbuf[STK_PARAMS];
                    821:        caddr_t dt = stkbuf;
                    822:
                    823:        com = SCARG(uap, com);
                    824:
                    825:        /* XXX */
                    826:        if (com == HPUXTIOCGETP || com == HPUXTIOCSETP)
                    827:                return (getsettty(p, SCARG(uap, fd), com, SCARG(uap, data)));
                    828:
                    829:        if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
                    830:                return (EBADF);
                    831:        if ((fp->f_flag & (FREAD|FWRITE)) == 0)
                    832:                return (EBADF);
                    833:
                    834:        /*
                    835:         * Interpret high order word to find
                    836:         * amount of data to be copied to/from the
                    837:         * user's address space.
                    838:         */
                    839:        size = IOCPARM_LEN(com);
                    840:        if (size > IOCPARM_MAX)
                    841:                return (ENOTTY);
                    842:        FREF(fp);
                    843:        if (size > sizeof (stkbuf)) {
                    844:                memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
                    845:                dt = memp;
                    846:        }
                    847:        if (com&IOC_IN) {
                    848:                if (size) {
                    849:                        error = copyin(SCARG(uap, data), dt, (u_int)size);
                    850:                        if (error) {
                    851:                                goto out;
                    852:                        }
                    853:                } else
                    854:                        *(caddr_t *)dt = SCARG(uap, data);
                    855:        } else if ((com&IOC_OUT) && size)
                    856:                /*
                    857:                 * Zero the buffer so the user always
                    858:                 * gets back something deterministic.
                    859:                 */
                    860:                bzero(dt, size);
                    861:        else if (com&IOC_VOID)
                    862:                *(caddr_t *)dt = SCARG(uap, data);
                    863:
                    864:        switch (com) {
                    865:
                    866:        case HPUXFIOSNBIO:
                    867:        {
                    868:                char *ofp = &fdp->fd_ofileflags[SCARG(uap, fd)];
                    869:                int tmp;
                    870:
                    871:                if (*(int *)dt)
                    872:                        *ofp |= HPUX_UF_FIONBIO_ON;
                    873:                else
                    874:                        *ofp &= ~HPUX_UF_FIONBIO_ON;
                    875:                /*
                    876:                 * Only set/clear if O_NONBLOCK/FNDELAY not in effect
                    877:                 */
                    878:                if ((*ofp & (HPUX_UF_NONBLOCK_ON|HPUX_UF_FNDELAY_ON)) == 0) {
                    879:                        tmp = *ofp & HPUX_UF_FIONBIO_ON;
                    880:                        error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO,
                    881:                                                       (caddr_t)&tmp, p);
                    882:                }
                    883:                break;
                    884:        }
                    885:
                    886:        case HPUXTIOCCONS:
                    887:                *(int *)dt = 1;
                    888:                error = (*fp->f_ops->fo_ioctl)(fp, TIOCCONS, dt, p);
                    889:                break;
                    890:
                    891:        /* BSD-style job control ioctls */
                    892:        case HPUXTIOCLBIS:
                    893:        case HPUXTIOCLBIC:
                    894:        case HPUXTIOCLSET:
                    895:                *(int *)dt &= HPUXLTOSTOP;
                    896:                if (*(int *)dt & HPUXLTOSTOP)
                    897:                        *(int *)dt = LTOSTOP;
                    898:                /* fall into */
                    899:
                    900:        /* simple mapping cases */
                    901:        case HPUXTIOCLGET:
                    902:        case HPUXTIOCSLTC:
                    903:        case HPUXTIOCGLTC:
                    904:        case HPUXTIOCSPGRP:
                    905:        case HPUXTIOCGPGRP:
                    906:        case HPUXTIOCGWINSZ:
                    907:        case HPUXTIOCSWINSZ:
                    908:                error = (*fp->f_ops->fo_ioctl)
                    909:                        (fp, hpuxtobsdioctl(com), dt, p);
                    910:                if (error == 0 && com == HPUXTIOCLGET) {
                    911:                        *(int *)dt &= LTOSTOP;
                    912:                        if (*(int *)dt & LTOSTOP)
                    913:                                *(int *)dt = HPUXLTOSTOP;
                    914:                }
                    915:                break;
                    916:
                    917:        /* SYS 5 termio and POSIX termios */
                    918:        case HPUXTCGETA:
                    919:        case HPUXTCSETA:
                    920:        case HPUXTCSETAW:
                    921:        case HPUXTCSETAF:
                    922:        case HPUXTCGETATTR:
                    923:        case HPUXTCSETATTR:
                    924:        case HPUXTCSETATTRD:
                    925:        case HPUXTCSETATTRF:
                    926:                error = hpux_termio(SCARG(uap, fd), com, dt, p);
                    927:                break;
                    928:
                    929:        default:
                    930:                error = (*fp->f_ops->fo_ioctl)(fp, com, dt, p);
                    931:                break;
                    932:        }
                    933:        /*
                    934:         * Copy any data to user, size was
                    935:         * already set and checked above.
                    936:         */
                    937:        if (error == 0 && (com&IOC_OUT) && size)
                    938:                error = copyout(dt, SCARG(uap, data), (u_int)size);
                    939:
                    940: out:
                    941:        FRELE(fp);
                    942:        if (memp)
                    943:                free(memp, M_IOCTLOPS);
                    944:        return (error);
                    945: }
                    946:
                    947: /* hpux_sys_getcontext() is found in hpux_machdep.c */
                    948:
                    949: /*
                    950:  * This is the equivalent of BSD getpgrp but with more restrictions.
                    951:  * Note we do not check the real uid or "saved" uid.
                    952:  */
                    953: int
                    954: hpux_sys_getpgrp2(cp, v, retval)
                    955:        struct proc *cp;
                    956:        void *v;
                    957:        register_t *retval;
                    958: {
                    959:        struct hpux_sys_getpgrp2_args *uap = v;
                    960:        struct proc *p;
                    961:
                    962:        if (SCARG(uap, pid) == 0)
                    963:                SCARG(uap, pid) = cp->p_pid;
                    964:        p = pfind(SCARG(uap, pid));
                    965:        if (p == 0)
                    966:                return (ESRCH);
                    967:        if (cp->p_ucred->cr_uid && p->p_ucred->cr_uid != cp->p_ucred->cr_uid &&
                    968:            !inferior(p))
                    969:                return (EPERM);
                    970:        *retval = p->p_pgid;
                    971:        return (0);
                    972: }
                    973:
                    974: /*
                    975:  * This is the equivalent of BSD setpgrp but with more restrictions.
                    976:  * Note we do not check the real uid or "saved" uid or pgrp.
                    977:  */
                    978: int
                    979: hpux_sys_setpgrp2(p, v, retval)
                    980:        struct proc *p;
                    981:        void *v;
                    982:        register_t *retval;
                    983: {
                    984:        struct hpux_sys_setpgrp2_args *uap = v;
                    985:
                    986:        /* empirically determined */
                    987:        if (SCARG(uap, pgid) < 0 || SCARG(uap, pgid) >= 30000)
                    988:                return (EINVAL);
                    989:        return (sys_setpgid(p, uap, retval));
                    990: }
                    991:
                    992: int
                    993: hpux_sys_getrlimit(p, v, retval)
                    994:        struct proc *p;
                    995:        void *v;
                    996:        register_t *retval;
                    997: {
                    998:        struct hpux_sys_getrlimit_args *uap = v;
                    999:        struct compat_43_sys_getrlimit_args ap;
                   1000:
                   1001:        if (SCARG(uap, which) > HPUXRLIMIT_NOFILE)
                   1002:                return (EINVAL);
                   1003:        if (SCARG(uap, which) == HPUXRLIMIT_NOFILE)
                   1004:                SCARG(uap, which) = RLIMIT_NOFILE;
                   1005:
                   1006:        SCARG(&ap, which) = SCARG(uap, which);
                   1007:        SCARG(&ap, rlp) = SCARG(uap, rlp);
                   1008:
                   1009:        return (compat_43_sys_getrlimit(p, uap, retval));
                   1010: }
                   1011:
                   1012: int
                   1013: hpux_sys_setrlimit(p, v, retval)
                   1014:        struct proc *p;
                   1015:        void *v;
                   1016:        register_t *retval;
                   1017: {
                   1018:        struct hpux_sys_setrlimit_args *uap = v;
                   1019:        struct compat_43_sys_setrlimit_args ap;
                   1020:
                   1021:        if (SCARG(uap, which) > HPUXRLIMIT_NOFILE)
                   1022:                return (EINVAL);
                   1023:        if (SCARG(uap, which) == HPUXRLIMIT_NOFILE)
                   1024:                SCARG(uap, which) = RLIMIT_NOFILE;
                   1025:
                   1026:        SCARG(&ap, which) = SCARG(uap, which);
                   1027:        SCARG(&ap, rlp) = SCARG(uap, rlp);
                   1028:
                   1029:        return (compat_43_sys_setrlimit(p, uap, retval));
                   1030: }
                   1031:
                   1032: /*
                   1033:  * XXX: simple recognition hack to see if we can make grmd work.
                   1034:  */
                   1035: int
                   1036: hpux_sys_lockf(p, v, retval)
                   1037:        struct proc *p;
                   1038:        void *v;
                   1039:        register_t *retval;
                   1040: {
                   1041:        /* struct hpux_sys_lockf_args *uap = v; */
                   1042:
                   1043:        return (0);
                   1044: }
                   1045:
                   1046:
                   1047: #ifndef __hppa__
                   1048: int
                   1049: hpux_sys_getaccess(p, v, retval)
                   1050:        struct proc *p;
                   1051:        void *v;
                   1052:        register_t *retval;
                   1053: {
                   1054:        struct hpux_sys_getaccess_args *uap = v;
                   1055:        int lgroups[NGROUPS];
                   1056:        int error = 0;
                   1057:        struct ucred *cred;
                   1058:        struct vnode *vp;
                   1059:        struct nameidata nd;
                   1060:
                   1061:        /*
                   1062:         * Build an appropriate credential structure
                   1063:         */
                   1064:        cred = crdup(p->p_ucred);
                   1065:        switch (SCARG(uap, uid)) {
                   1066:        case 65502:     /* UID_EUID */
                   1067:                break;
                   1068:        case 65503:     /* UID_RUID */
                   1069:                cred->cr_uid = p->p_cred->p_ruid;
                   1070:                break;
                   1071:        case 65504:     /* UID_SUID */
                   1072:                error = EINVAL;
                   1073:                break;
                   1074:        default:
                   1075:                if (SCARG(uap, uid) > 65504)
                   1076:                        error = EINVAL;
                   1077:                cred->cr_uid = SCARG(uap, uid);
                   1078:                break;
                   1079:        }
                   1080:        switch (SCARG(uap, ngroups)) {
                   1081:        case -1:        /* NGROUPS_EGID */
                   1082:                cred->cr_ngroups = 1;
                   1083:                break;
                   1084:        case -5:        /* NGROUPS_EGID_SUPP */
                   1085:                break;
                   1086:        case -2:        /* NGROUPS_RGID */
                   1087:                cred->cr_ngroups = 1;
                   1088:                cred->cr_gid = p->p_cred->p_rgid;
                   1089:                break;
                   1090:        case -6:        /* NGROUPS_RGID_SUPP */
                   1091:                cred->cr_gid = p->p_cred->p_rgid;
                   1092:                break;
                   1093:        case -3:        /* NGROUPS_SGID */
                   1094:        case -7:        /* NGROUPS_SGID_SUPP */
                   1095:                error = EINVAL;
                   1096:                break;
                   1097:        case -4:        /* NGROUPS_SUPP */
                   1098:                if (cred->cr_ngroups > 1)
                   1099:                        cred->cr_gid = cred->cr_groups[1];
                   1100:                else
                   1101:                        error = EINVAL;
                   1102:                break;
                   1103:        default:
                   1104:                if (SCARG(uap, ngroups) > 0 && SCARG(uap, ngroups) <= NGROUPS)
                   1105:                        error = copyin((caddr_t)SCARG(uap, gidset),
                   1106:                                       (caddr_t)&lgroups[0],
                   1107:                                       SCARG(uap, ngroups) *
                   1108:                                           sizeof(lgroups[0]));
                   1109:                else
                   1110:                        error = EINVAL;
                   1111:                if (error == 0) {
                   1112:                        int gid;
                   1113:
                   1114:                        for (gid = 0; gid < SCARG(uap, ngroups); gid++)
                   1115:                                cred->cr_groups[gid] = lgroups[gid];
                   1116:                        cred->cr_ngroups = SCARG(uap, ngroups);
                   1117:                }
                   1118:                break;
                   1119:        }
                   1120:        /*
                   1121:         * Lookup file using caller's effective IDs.
                   1122:         */
                   1123:        if (error == 0) {
                   1124:                NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
                   1125:                        SCARG(uap, path), p);
                   1126:                error = namei(&nd);
                   1127:        }
                   1128:        if (error) {
                   1129:                crfree(cred);
                   1130:                return (error);
                   1131:        }
                   1132:        /*
                   1133:         * Use the constructed credentials for access checks.
                   1134:         */
                   1135:        vp = nd.ni_vp;
                   1136:        *retval = 0;
                   1137:        if (VOP_ACCESS(vp, VREAD, cred, p) == 0)
                   1138:                *retval |= R_OK;
                   1139:        if (vn_writechk(vp) == 0 && VOP_ACCESS(vp, VWRITE, cred, p) == 0)
                   1140:                *retval |= W_OK;
                   1141:        if (VOP_ACCESS(vp, VEXEC, cred, p) == 0)
                   1142:                *retval |= X_OK;
                   1143:        vput(vp);
                   1144:        crfree(cred);
                   1145:        return (error);
                   1146: }
                   1147: #endif
                   1148:
                   1149: /*
                   1150:  * Ancient HP-UX system calls.  Some 9.x executables even use them!
                   1151:  */
                   1152: #define HPUX_HZ        50
                   1153:
                   1154: #include <sys/times.h>
                   1155:
                   1156:
                   1157: /*
                   1158:  * SYS V style setpgrp()
                   1159:  */
                   1160: int
                   1161: hpux_sys_setpgrp_6x(p, v, retval)
                   1162:        struct proc *p;
                   1163:        void *v;
                   1164:        register_t *retval;
                   1165: {
                   1166:
                   1167:        if (p->p_pid != p->p_pgid)
                   1168:                enterpgrp(p, p->p_pid, 0);
                   1169:        *retval = p->p_pgid;
                   1170:        return (0);
                   1171: }
                   1172:
                   1173: int
                   1174: hpux_sys_time_6x(p, v, retval)
                   1175:        struct proc *p;
                   1176:        void *v;
                   1177:        register_t *retval;
                   1178: {
                   1179:        struct hpux_sys_time_6x_args /* {
                   1180:                syscallarg(time_t *) t;
                   1181:        } */ *uap = v;
                   1182:        int error = 0;
                   1183:        struct timeval tv;
                   1184:
                   1185:        microtime(&tv);
                   1186:         if (SCARG(uap, t) != NULL)
                   1187:                error = copyout(&tv.tv_sec, SCARG(uap, t), sizeof(time_t));
                   1188:
                   1189:        *retval = (register_t)tv.tv_sec;
                   1190:        return (error);
                   1191: }
                   1192:
                   1193: int
                   1194: hpux_sys_stime_6x(p, v, retval)
                   1195:        struct proc *p;
                   1196:        void *v;
                   1197:        register_t *retval;
                   1198: {
                   1199:        struct hpux_sys_stime_6x_args /* {
                   1200:                syscallarg(int) time;
                   1201:        } */ *uap = v;
                   1202:        struct timespec ts;
                   1203:        int error;
                   1204:
                   1205:        ts.tv_sec = SCARG(uap, time);
                   1206:        ts.tv_nsec = 0;
                   1207:        if ((error = suser(p, 0)))
                   1208:                return (error);
                   1209:
                   1210:        settime(&ts);
                   1211:
                   1212:        return (0);
                   1213: }
                   1214:
                   1215: int
                   1216: hpux_sys_ftime_6x(p, v, retval)
                   1217:        struct proc *p;
                   1218:        void *v;
                   1219:        register_t *retval;
                   1220: {
                   1221:        struct hpux_sys_ftime_6x_args /* {
                   1222:                syscallarg(struct hpux_timeb *) tp;
                   1223:        } */ *uap = v;
                   1224:        struct hpux_otimeb tb;
                   1225:        struct timeval tv;
                   1226:
                   1227:        microtime(&tv);
                   1228:        tb.time = tv.tv_sec;
                   1229:        tb.millitm = tv.tv_usec / 1000;
                   1230:        tb.timezone = tz.tz_minuteswest;
                   1231:        tb.dstflag = tz.tz_dsttime;
                   1232:        return (copyout((caddr_t)&tb, (caddr_t)SCARG(uap, tp), sizeof (tb)));
                   1233: }
                   1234:
                   1235: int
                   1236: hpux_sys_alarm_6x(p, v, retval)
                   1237:        struct proc *p;
                   1238:        void *v;
                   1239:        register_t *retval;
                   1240: {
                   1241:        struct hpux_sys_alarm_6x_args /* {
                   1242:                syscallarg(int) deltat;
                   1243:        } */ *uap = v;
                   1244:        int timo;
                   1245:        struct timeval tv, atv;
                   1246:
                   1247:        timeout_del(&p->p_realit_to);
                   1248:        timerclear(&p->p_realtimer.it_interval);
                   1249:        *retval = 0;
                   1250:        getmicrouptime(&tv);
                   1251:        if (timerisset(&p->p_realtimer.it_value) &&
                   1252:            timercmp(&p->p_realtimer.it_value, &tv, >))
                   1253:                *retval = p->p_realtimer.it_value.tv_sec - tv.tv_sec;
                   1254:        if (SCARG(uap, deltat) == 0) {
                   1255:                timerclear(&p->p_realtimer.it_value);
                   1256:                return (0);
                   1257:        }
                   1258:        atv.tv_sec = SCARG(uap, deltat);
                   1259:        atv.tv_usec = 0;
                   1260:        p->p_realtimer.it_value = tv;
                   1261:        p->p_realtimer.it_value.tv_sec += SCARG(uap, deltat);
                   1262:        timo = tvtohz(&atv);
                   1263:        if (timo <= 0)
                   1264:                timo = 1;
                   1265:        timeout_add(&p->p_realit_to, timo);
                   1266:        return (0);
                   1267: }
                   1268:
                   1269: int
                   1270: hpux_sys_nice_6x(p, v, retval)
                   1271:        struct proc *p;
                   1272:        void *v;
                   1273:        register_t *retval;
                   1274: {
                   1275:        struct hpux_sys_nice_6x_args /* {
                   1276:                syscallarg(int) nval;
                   1277:        } */ *uap = v;
                   1278:        int error;
                   1279:
                   1280:        error = donice(p, p, (p->p_nice-NZERO)+SCARG(uap, nval));
                   1281:        if (error == 0)
                   1282:                *retval = p->p_nice - NZERO;
                   1283:        return (error);
                   1284: }
                   1285:
                   1286: int
                   1287: hpux_sys_times_6x(p, v, retval)
                   1288:        struct proc *p;
                   1289:        void *v;
                   1290:        register_t *retval;
                   1291: {
                   1292:        struct hpux_sys_times_6x_args /* {
                   1293:                syscallarg(struct tms *) tms;
                   1294:        } */ *uap = v;
                   1295:        struct timeval ru, rs;
                   1296:        struct tms atms;
                   1297:        int error;
                   1298:
                   1299:        calcru(p, &ru, &rs, NULL);
                   1300:        atms.tms_utime = hpux_scale(&ru);
                   1301:        atms.tms_stime = hpux_scale(&rs);
                   1302:        atms.tms_cutime = hpux_scale(&p->p_stats->p_cru.ru_utime);
                   1303:        atms.tms_cstime = hpux_scale(&p->p_stats->p_cru.ru_stime);
                   1304:        error = copyout((caddr_t)&atms, (caddr_t)SCARG(uap, tms),
                   1305:            sizeof (atms));
                   1306:        if (error == 0) {
                   1307:                struct timeval tv;
                   1308:                getmicrouptime(&tv);
                   1309:                *(time_t *)retval = hpux_scale(&tv);
                   1310:        }
                   1311:        return (error);
                   1312: }
                   1313:
                   1314: /*
                   1315:  * Doesn't exactly do what the documentation says.
                   1316:  * What we really do is return 1/HPUX_HZ-th of a second since that
                   1317:  * is what HP-UX returns.
                   1318:  */
                   1319: static int
                   1320: hpux_scale(tvp)
                   1321:        struct timeval *tvp;
                   1322: {
                   1323:        return (tvp->tv_sec * HPUX_HZ + tvp->tv_usec * HPUX_HZ / 1000000);
                   1324: }
                   1325:
                   1326: /*
                   1327:  * Set IUPD and IACC times on file.
                   1328:  * Can't set ICHG.
                   1329:  */
                   1330: int
                   1331: hpux_sys_utime_6x(p, v, retval)
                   1332:        struct proc *p;
                   1333:        void *v;
                   1334:        register_t *retval;
                   1335: {
                   1336:        struct hpux_sys_utime_6x_args /* {
                   1337:                syscallarg(char *) fname;
                   1338:                syscallarg(time_t *) tptr;
                   1339:        } */ *uap = v;
                   1340:        struct vnode *vp;
                   1341:        struct vattr vattr;
                   1342:        time_t tv[2];
                   1343:        int error;
                   1344:        struct nameidata nd;
                   1345:
                   1346:        if (SCARG(uap, tptr)) {
                   1347:                error = copyin((caddr_t)SCARG(uap, tptr), (caddr_t)tv,
                   1348:                    sizeof (tv));
                   1349:                if (error)
                   1350:                        return (error);
                   1351:        } else
                   1352:                tv[0] = tv[1] = time_second;
                   1353:        vattr_null(&vattr);
                   1354:        vattr.va_atime.tv_sec = tv[0];
                   1355:        vattr.va_atime.tv_nsec = 0;
                   1356:        vattr.va_mtime.tv_sec = tv[1];
                   1357:        vattr.va_mtime.tv_nsec = 0;
                   1358:        NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
                   1359:            SCARG(uap, fname), p);
                   1360:        if ((error = namei(&nd)))
                   1361:                return (error);
                   1362:        vp = nd.ni_vp;
                   1363:        if (vp->v_mount->mnt_flag & MNT_RDONLY)
                   1364:                error = EROFS;
                   1365:        else
                   1366:                error = VOP_SETATTR(vp, &vattr, nd.ni_cnd.cn_cred, p);
                   1367:        vput(vp);
                   1368:        return (error);
                   1369: }
                   1370:
                   1371: int
                   1372: hpux_sys_pause_6x(p, v, retval)
                   1373:        struct proc *p;
                   1374:        void *v;
                   1375:        register_t *retval;
                   1376: {
                   1377:        struct sys_sigsuspend_args bsa;
                   1378:
                   1379:        SCARG(&bsa, mask) = p->p_sigmask;
                   1380:        return (sys_sigsuspend(p, &bsa, retval));
                   1381: }

CVSweb