Annotation of 43BSDReno/sys/hpux/hpux_compat.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 University of Utah.
                      3:  * Copyright (c) 1990 The Regents of the University of California.
                      4:  * All rights reserved.
                      5:  *
                      6:  * This code is derived from software contributed to Berkeley by
                      7:  * the Systems Programming Group of the University of Utah Computer
                      8:  * Science Department.
                      9:  *
                     10:  * Redistribution is only permitted until one year after the first shipment
                     11:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                     12:  * binary forms are permitted provided that: (1) source distributions retain
                     13:  * this entire copyright notice and comment, and (2) distributions including
                     14:  * binaries display the following acknowledgement:  This product includes
                     15:  * software developed by the University of California, Berkeley and its
                     16:  * contributors'' in the documentation or other materials provided with the
                     17:  * distribution and in all advertising materials mentioning features or use
                     18:  * of this software.  Neither the name of the University nor the names of
                     19:  * its contributors may be used to endorse or promote products derived from
                     20:  * this software without specific prior written permission.
                     21:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     22:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     23:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     24:  *
                     25:  * from: Utah $Hdr: hpux_compat.c 1.33 89/08/23$
                     26:  *
                     27:  *     @(#)hpux_compat.c       7.9 (Berkeley) 6/28/90
                     28:  */
                     29: 
                     30: /*
                     31:  * Various HPUX compatibility routines
                     32:  */
                     33: 
                     34: #ifdef HPUXCOMPAT
                     35: 
                     36: #include "param.h"
                     37: #include "systm.h"
                     38: #include "user.h"
                     39: #include "kernel.h"
                     40: #include "proc.h"
                     41: #include "buf.h"
                     42: #include "wait.h"
                     43: #include "file.h"
                     44: #include "vnode.h"
                     45: #include "ioctl.h"
                     46: #include "uio.h"
                     47: #include "ptrace.h"
                     48: #include "stat.h"
                     49: #include "syslog.h"
                     50: #include "malloc.h"
                     51: #include "mount.h"
                     52: #include "ipc.h"
                     53: 
                     54: #include "machine/cpu.h"
                     55: #include "machine/reg.h"
                     56: #include "machine/psl.h"
                     57: #include "machine/vmparam.h"
                     58: #include "hpux.h"
                     59: #include "hpux_termio.h"
                     60: 
                     61: #ifdef DEBUG
                     62: int unimpresponse = 0;
                     63: #endif
                     64: 
                     65: /* "tick" value for HZ==50 */
                     66: int hpuxtick = 1000000 / 50;
                     67: 
                     68: /* SYS5 style UTSNAME info */
                     69: struct hpuxutsname protoutsname = {
                     70:        "4.4bsd", "", "2.0", "B", "9000/3?0", ""
                     71: };
                     72: 
                     73: /* 6.0 and later style context */
                     74: #ifdef FPCOPROC
                     75: char hpuxcontext[] =
                     76:        "standalone HP-MC68881 HP-MC68020 HP-MC68010 localroot default";
                     77: #else
                     78: char hpuxcontext[] =
                     79:        "standalone HP-MC68020 HP-MC68010 localroot default";
                     80: #endif
                     81: 
                     82: /* YP domainname */
                     83: char   domainname[MAXHOSTNAMELEN] = "unknown";
                     84: int    domainnamelen = 7;
                     85: 
                     86: #define NERR   79
                     87: #define BERR   1000
                     88: 
                     89: /* indexed by BSD errno */
                     90: short bsdtohpuxerrnomap[NERR] = {
                     91: /*00*/   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
                     92: /*10*/  10,  45,  12,  13,  14,  15,  16,  17,  18,  19,
                     93: /*20*/  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
                     94: /*30*/  30,  31,  32,  33,  34, 246, 245, 244, 216, 217,
                     95: /*40*/ 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
                     96: /*50*/ 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
                     97: /*60*/ 238, 239, 249, 248, 241, 242, 247,BERR,BERR,BERR,
                     98: /*70*/   70,  71,BERR,BERR,BERR,BERR,BERR,  46,BERR
                     99: };
                    100: 
                    101: notimp(p, uap, retval, code, nargs)
                    102:        struct proc *p;
                    103:        int *uap, *retval;
                    104:        int code, nargs;
                    105: {
                    106:        int error = 0;
                    107: #ifdef DEBUG
                    108:        register int *argp = uap;
                    109:        extern char *hpuxsyscallnames[];
                    110: 
                    111:        printf("HPUX %s(", hpuxsyscallnames[code]);
                    112:        if (nargs)
                    113:                while (nargs--)
                    114:                        printf("%x%c", *argp++, nargs? ',' : ')');
                    115:        else
                    116:                printf(")");
                    117:        printf("\n");
                    118:        switch (unimpresponse) {
                    119:        case 0:
                    120:                error = nosys(p, uap, retval);
                    121:                break;
                    122:        case 1:
                    123:                error = EINVAL;
                    124:                break;
                    125:        }
                    126: #else
                    127:        error = nosys(p, uap, retval);
                    128: #endif
                    129:        uprintf("HP-UX system call %d not implemented\n", code);
                    130:        return (error);
                    131: }
                    132: 
                    133: /*
                    134:  * HPUX versions of wait and wait3 actually pass the parameters
                    135:  * (status pointer, options, rusage) into the kernel rather than
                    136:  * handling it in the C library stub.  We also need to map any
                    137:  * termination signal from BSD to HPUX.
                    138:  */
                    139: hpuxwait3(p, uap, retval)
                    140:        struct proc *p;
                    141:        struct args {
                    142:                int     *status;
                    143:                int     options;
                    144:                int     rusage;
                    145:        } *uap;
                    146:        int *retval;
                    147: {
                    148:        /* rusage pointer must be zero */
                    149:        if (uap->rusage)
                    150:                return (EINVAL);
                    151:        u.u_ar0[PS] = PSL_ALLCC;
                    152:        u.u_ar0[R0] = uap->options;
                    153:        u.u_ar0[R1] = uap->rusage;
                    154:        return (hpuxwait(p, uap, retval));
                    155: }
                    156: 
                    157: hpuxwait(p, uap, retval)
                    158:        struct proc *p;
                    159:        struct args {
                    160:                int     *status;
                    161:        } *uap;
                    162:        int *retval;
                    163: {
                    164:        int sig, *statp, error;
                    165: 
                    166:        statp = uap->status;    /* owait clobbers first arg */
                    167:        error = owait(p, uap, retval);
                    168:        /*
                    169:         * HP-UX wait always returns EINTR when interrupted by a signal
                    170:         * (well, unless its emulating a BSD process, but we don't bother...)
                    171:         */
                    172:        if (error == ERESTART)
                    173:                error = EINTR;
                    174:        if (error)
                    175:                return (error);
                    176:        sig = retval[1] & 0xFF;
                    177:        if (sig == WSTOPPED) {
                    178:                sig = (retval[1] >> 8) & 0xFF;
                    179:                retval[1] = (bsdtohpuxsig(sig) << 8) | WSTOPPED;
                    180:        } else if (sig)
                    181:                retval[1] = (retval[1] & 0xFF00) |
                    182:                        bsdtohpuxsig(sig & 0x7F) | (sig & 0x80);
                    183:        if (statp)
                    184:                if (suword((caddr_t)statp, retval[1]))
                    185:                        error = EFAULT;
                    186:        return (error);
                    187: }
                    188: 
                    189: hpuxwaitpid(p, uap, retval)
                    190:        struct proc *p;
                    191:        struct args {
                    192:                int     pid;
                    193:                int     *status;
                    194:                int     options;
                    195:                struct  rusage *rusage; /* wait4 arg */
                    196:        } *uap;
                    197:        int *retval;
                    198: {
                    199:        int sig, *statp, error;
                    200: 
                    201:        uap->rusage = 0;
                    202:        error = wait4(p, uap, retval);
                    203:        /*
                    204:         * HP-UX wait always returns EINTR when interrupted by a signal
                    205:         * (well, unless its emulating a BSD process, but we don't bother...)
                    206:         */
                    207:        if (error == ERESTART)
                    208:                error = EINTR;
                    209:        if (error)
                    210:                return (error);
                    211:        sig = retval[1] & 0xFF;
                    212:        if (sig == WSTOPPED) {
                    213:                sig = (retval[1] >> 8) & 0xFF;
                    214:                retval[1] = (bsdtohpuxsig(sig) << 8) | WSTOPPED;
                    215:        } else if (sig)
                    216:                retval[1] = (retval[1] & 0xFF00) |
                    217:                        bsdtohpuxsig(sig & 0x7F) | (sig & 0x80);
                    218:        if (statp)
                    219:                if (suword((caddr_t)statp, retval[1]))
                    220:                        error = EFAULT;
                    221:        return (error);
                    222: }
                    223: 
                    224: /*
                    225:  * Must remap some bits in the mode mask.
                    226:  * O_CREAT, O_TRUNC, and O_EXCL must be remapped,
                    227:  * O_SYNCIO (0100000) is removed entirely.
                    228:  */
                    229: hpuxopen(p, uap, retval)
                    230:        struct proc *p;
                    231:        register struct args {
                    232:                char    *fname;
                    233:                int     mode;
                    234:                int     crtmode;
                    235:        } *uap;
                    236:        int *retval;
                    237: {
                    238:        int mode;
                    239: 
                    240:        mode = uap->mode;
                    241:        uap->mode &= ~(HPUXFSYNCIO|HPUXFEXCL|HPUXFTRUNC|HPUXFCREAT);
                    242:        if (mode & HPUXFCREAT) {
                    243:                /*
                    244:                 * simulate the pre-NFS behavior that opening a
                    245:                 * file for READ+CREATE ignores the CREATE (unless
                    246:                 * EXCL is set in which case we will return the
                    247:                 * proper error).
                    248:                 */
                    249:                if ((mode & HPUXFEXCL) || ((mode-FOPEN) & FWRITE))
                    250:                        uap->mode |= FCREAT;
                    251:        }
                    252:        if (mode & HPUXFTRUNC)
                    253:                uap->mode |= FTRUNC;
                    254:        if (mode & HPUXFEXCL)
                    255:                uap->mode |= FEXCL;
                    256:        return (open(p, uap, retval));
                    257: }
                    258: 
                    259: hpuxfcntl(p, uap, retval)
                    260:        struct proc *p;
                    261:        register struct args {
                    262:                int     fdes;
                    263:                int     cmd;
                    264:                int     arg;
                    265:        } *uap;
                    266:        int *retval;
                    267: {
                    268:        int mode, error;
                    269: 
                    270:        switch (uap->cmd) {
                    271:        case F_SETFL:
                    272:                uap->arg &= ~(HPUXFSYNCIO|HPUXFREMOTE|FUSECACHE);
                    273:                break;
                    274:        case F_GETFL:
                    275:        case F_DUPFD:
                    276:        case F_GETFD:
                    277:        case F_SETFD:
                    278:                break;
                    279:        default:
                    280:                return (EINVAL);
                    281:        }
                    282:        error = fcntl(p, uap, retval);
                    283:        if (error == 0 && uap->arg == F_GETFL) {
                    284:                mode = *retval;
                    285:                *retval &= ~(FCREAT|FTRUNC|FEXCL|FUSECACHE);
                    286:                if (mode & FCREAT)
                    287:                        *retval |= HPUXFCREAT;
                    288:                if (mode & FTRUNC)
                    289:                        *retval |= HPUXFTRUNC;
                    290:                if (mode & FEXCL)
                    291:                        *retval |= HPUXFEXCL;
                    292:        }
                    293:        return (error);
                    294: }
                    295: 
                    296: /*
                    297:  * Read and write should return a 0 count when an operation
                    298:  * on a VNODE would block, not an error.  Sockets appear to
                    299:  * return EWOULDBLOCK (at least in 6.2).  This is probably
                    300:  * not entirely correct, since the behavior is only defined
                    301:  * for pipes and tty type devices.
                    302:  */
                    303: hpuxread(p, uap, retval)
                    304:        struct proc *p;
                    305:        struct args {
                    306:                int     fd;
                    307:        } *uap;
                    308:        int *retval;
                    309: {
                    310:        int error;
                    311: 
                    312:        error = read(p, uap, retval);
                    313:        if (error == EWOULDBLOCK &&
                    314:            u.u_ofile[uap->fd]->f_type == DTYPE_VNODE) {
                    315:                error = 0;
                    316:                *retval = 0;
                    317:        }
                    318:        return (error);
                    319: }
                    320: 
                    321: hpuxwrite(p, uap, retval)
                    322:        struct proc *p;
                    323:        struct args {
                    324:                int     fd;
                    325:        } *uap;
                    326:        int *retval;
                    327: {
                    328:        int error;
                    329: 
                    330:        error = write(p, uap, retval);
                    331:        if (error == EWOULDBLOCK &&
                    332:            u.u_ofile[uap->fd]->f_type == DTYPE_VNODE) {
                    333:                error = 0;
                    334:                *retval = 0;
                    335:        }
                    336:        return (error);
                    337: }
                    338: 
                    339: hpuxreadv(p, uap, retval)
                    340:        struct proc *p;
                    341:        struct args {
                    342:                int     fd;
                    343:        } *uap;
                    344:        int *retval;
                    345: {
                    346:        int error;
                    347: 
                    348:        error = readv(p, uap, retval);
                    349:        if (error == EWOULDBLOCK &&
                    350:            u.u_ofile[uap->fd]->f_type == DTYPE_VNODE) {
                    351:                error = 0;
                    352:                *retval = 0;
                    353:        }
                    354:        return (error);
                    355: }
                    356: 
                    357: hpuxwritev(p, uap, retval)
                    358:        struct proc *p;
                    359:        struct args {
                    360:                int     fd;
                    361:        } *uap;
                    362:        int *retval;
                    363: {
                    364:        int error;
                    365: 
                    366:        error = writev(p, uap, retval);
                    367:        if (error == EWOULDBLOCK &&
                    368:            u.u_ofile[uap->fd]->f_type == DTYPE_VNODE) {
                    369:                error = 0;
                    370:                *retval = 0;
                    371:        }
                    372:        return (error);
                    373: }
                    374: 
                    375: /*
                    376:  * 4.3bsd dup allows dup2 to come in on the same syscall entry
                    377:  * and hence allows two arguments.  HPUX dup has only one arg.
                    378:  */
                    379: hpuxdup(p, uap, retval)
                    380:        struct proc *p;
                    381:        register struct args {
                    382:                int     i;
                    383:        } *uap;
                    384:        int *retval;
                    385: {
                    386:        struct file *fp;
                    387:        int fd, error;
                    388: 
                    389:        if ((unsigned)uap->i >= NOFILE || (fp = u.u_ofile[uap->i]) == NULL)
                    390:                return (EBADF);
                    391:        if (error = ufalloc(0, &fd))
                    392:                return (error);
                    393:        *retval = fd;
                    394:        u.u_ofile[fd] = fp;
                    395:        u.u_pofile[fd] = u.u_pofile[uap->i] &~ UF_EXCLOSE;
                    396:        fp->f_count++;
                    397:        if (fd > u.u_lastfile)
                    398:                u.u_lastfile = fd;
                    399:        return (0);
                    400: }
                    401: 
                    402: hpuxuname(p, uap, retval)
                    403:        struct proc *p;
                    404:        register struct args {
                    405:                struct hpuxutsname *uts;
                    406:                int dev;
                    407:                int request;
                    408:        } *uap;
                    409:        int *retval;
                    410: {
                    411:        register int i;
                    412:        int error;
                    413: 
                    414:        switch (uap->request) {
                    415:        /* uname */
                    416:        case 0:
                    417:                /* fill in machine type */
                    418:                switch (machineid) {
                    419:                case HP_320:
                    420:                        protoutsname.machine[6] = '2';
                    421:                        break;
                    422:                /* includes 318 and 319 */
                    423:                case HP_330:
                    424:                        protoutsname.machine[6] = '3';
                    425:                        break;
                    426:                case HP_340:
                    427:                        protoutsname.machine[6] = '4';
                    428:                        break;
                    429:                case HP_350:
                    430:                        protoutsname.machine[6] = '5';
                    431:                        break;
                    432:                case HP_360:
                    433:                        protoutsname.machine[6] = '6';
                    434:                        break;
                    435:                case HP_370:
                    436:                        protoutsname.machine[6] = '7';
                    437:                        break;
                    438:                /* includes 345 */
                    439:                case HP_375:
                    440:                        protoutsname.machine[6] = '7';
                    441:                        protoutsname.machine[7] = '5';
                    442:                        break;
                    443:                }
                    444:                /* copy hostname (sans domain) to nodename */
                    445:                for (i = 0; i < 9 && hostname[i] != '.'; i++)
                    446:                        protoutsname.nodename[i] = hostname[i];
                    447:                error = copyout((caddr_t)&protoutsname, (caddr_t)uap->uts,
                    448:                                sizeof(struct hpuxutsname));
                    449:                break;
                    450:        /* ustat - who cares? */
                    451:        case 2:
                    452:        default:
                    453:                error = EINVAL;
                    454:                break;
                    455:        }
                    456:        return (error);
                    457: }
                    458: 
                    459: hpuxstat(p, uap, retval)
                    460:        struct proc *p;
                    461:        struct args {
                    462:                char    *fname;
                    463:                struct hpuxstat *hsb;
                    464:        } *uap;
                    465:        int *retval;
                    466: {
                    467:        return (hpuxstat1(uap->fname, uap->hsb, FOLLOW));
                    468: }
                    469: 
                    470: hpuxlstat(p, uap, retval)
                    471:        struct proc *p;
                    472:        struct args {
                    473:                char    *fname;
                    474:                struct hpuxstat *hsb;
                    475:        } *uap;
                    476:        int *retval;
                    477: {
                    478:        return (hpuxstat1(uap->fname, uap->hsb, NOFOLLOW));
                    479: }
                    480: 
                    481: hpuxfstat(p, uap, retval)
                    482:        struct proc *p;
                    483:        register struct args {
                    484:                int     fdes;
                    485:                struct  hpuxstat *hsb;
                    486:        } *uap;
                    487:        int *retval;
                    488: {
                    489:        register struct file *fp;
                    490:        struct stat sb;
                    491:        int error;
                    492: 
                    493:        if ((unsigned)uap->fdes >= NOFILE ||
                    494:            (fp = u.u_ofile[uap->fdes]) == NULL)
                    495:                return (EBADF);
                    496: 
                    497:        switch (fp->f_type) {
                    498: 
                    499:        case DTYPE_VNODE:
                    500:                error = vn_stat((struct vnode *)fp->f_data, &sb);
                    501:                break;
                    502: 
                    503:        case DTYPE_SOCKET:
                    504:                error = soo_stat((struct socket *)fp->f_data, &sb);
                    505:                break;
                    506: 
                    507:        default:
                    508:                panic("fstat");
                    509:                /*NOTREACHED*/
                    510:        }
                    511:        /* is this right for sockets?? */
                    512:        if (error == 0)
                    513:                error = bsdtohpuxstat(&sb, uap->hsb);
                    514:        return (error);
                    515: }
                    516: 
                    517: hpuxulimit(p, uap, retval)
                    518:        struct proc *p;
                    519:        register struct args {
                    520:                int     cmd;
                    521:                long    newlimit;
                    522:        } *uap;
                    523:        off_t *retval;
                    524: {
                    525:        struct rlimit *limp;
                    526:        int error = 0;
                    527: 
                    528:        limp = &u.u_rlimit[RLIMIT_FSIZE];
                    529:        switch (uap->cmd) {
                    530:        case 2:
                    531:                uap->newlimit *= 512;
                    532:                if (uap->newlimit > limp->rlim_max &&
                    533:                    (error = suser(u.u_cred, &u.u_acflag)))
                    534:                        break;
                    535:                limp->rlim_cur = limp->rlim_max = uap->newlimit;
                    536:                /* else fall into... */
                    537: 
                    538:        case 1:
                    539:                *retval = limp->rlim_max / 512;         /* XXX */
                    540:                break;
                    541: 
                    542:        case 3:
                    543:                limp = &u.u_rlimit[RLIMIT_DATA];
                    544:                *retval = ctob(u.u_tsize) + limp->rlim_max;     /* XXX */
                    545:                break;
                    546: 
                    547:        default:
                    548:                error = EINVAL;
                    549:                break;
                    550:        }
                    551:        return (error);
                    552: }
                    553: 
                    554: /*
                    555:  * Map "real time" priorities 0 (high) thru 127 (low) into nice
                    556:  * values -16 (high) thru -1 (low).
                    557:  */
                    558: hpuxrtprio(cp, uap, retval)
                    559:        struct proc *cp;
                    560:        register struct args {
                    561:                int pid;
                    562:                int prio;
                    563:        } *uap;
                    564:        int *retval;
                    565: {
                    566:        struct proc *p;
                    567:        int nice, error;
                    568: 
                    569:        if (uap->prio < RTPRIO_MIN && uap->prio > RTPRIO_MAX &&
                    570:            uap->prio != RTPRIO_NOCHG && uap->prio != RTPRIO_RTOFF)
                    571:                return (EINVAL);
                    572:        if (uap->pid == 0)
                    573:                p = cp;
                    574:        else if ((p = pfind(uap->pid)) == 0)
                    575:                return (ESRCH);
                    576:        nice = p->p_nice;
                    577:        if (nice < NZERO)
                    578:                *retval = (nice + 16) << 3;
                    579:        else
                    580:                *retval = RTPRIO_RTOFF;
                    581:        switch (uap->prio) {
                    582: 
                    583:        case RTPRIO_NOCHG:
                    584:                return (0);
                    585: 
                    586:        case RTPRIO_RTOFF:
                    587:                if (nice >= NZERO)
                    588:                        return (0);
                    589:                nice = NZERO;
                    590:                break;
                    591: 
                    592:        default:
                    593:                nice = (uap->prio >> 3) - 16;
                    594:                break;
                    595:        }
                    596:        error = donice(cp, p, nice);
                    597:        if (error == EACCES)
                    598:                error = EPERM;
                    599:        return (error);
                    600: }
                    601: 
                    602: hpuxadvise(p, uap, retval)
                    603:        struct proc *p;
                    604:        struct args {
                    605:                int     arg;
                    606:        } *uap;
                    607:        int *retval;
                    608: {
                    609:        int error = 0;
                    610: 
                    611:        switch (uap->arg) {
                    612:        case 0:
                    613:                u.u_pcb.pcb_flags |= PCB_HPUXMMAP;
                    614:                break;
                    615:        case 1:
                    616:                ICIA();
                    617:                break;
                    618:        case 2:
                    619:                DCIA();
                    620:                break;
                    621:        default:
                    622:                error = EINVAL;
                    623:                break;
                    624:        }
                    625:        return (error);
                    626: }
                    627: 
                    628: hpuxptrace(p, uap, retval)
                    629:        struct proc *p;
                    630:        struct args {
                    631:                int     req;
                    632:                int     pid;
                    633:                int     *addr;
                    634:                int     data;
                    635:        } *uap;
                    636:        int *retval;
                    637: {
                    638:        int error;
                    639: 
                    640:        if (uap->req == PT_STEP || uap->req == PT_CONTINUE) {
                    641:                if (uap->data) {
                    642:                        uap->data = hpuxtobsdsig(uap->data);
                    643:                        if (uap->data == 0)
                    644:                                uap->data = NSIG;
                    645:                }
                    646:        }
                    647:        error = ptrace(p, uap, retval);
                    648:        return (error);
                    649: }
                    650: 
                    651: hpuxgetdomainname(p, uap, retval)
                    652:        struct proc *p;
                    653:        register struct args {
                    654:                char    *domainname;
                    655:                u_int   len;
                    656:        } *uap;
                    657:        int *retval;
                    658: {
                    659:        if (uap->len > domainnamelen + 1)
                    660:                uap->len = domainnamelen + 1;
                    661:        return (copyout(domainname, uap->domainname, uap->len));
                    662: }
                    663: 
                    664: hpuxsetdomainname(p, uap, retval)
                    665:        struct proc *p;
                    666:        register struct args {
                    667:                char    *domainname;
                    668:                u_int   len;
                    669:        } *uap;
                    670:        int *retval;
                    671: {
                    672:        int error;
                    673: 
                    674:        if (error = suser(u.u_cred, &u.u_acflag))
                    675:                return (error);
                    676:        if (uap->len > sizeof (domainname) - 1)
                    677:                return (EINVAL);
                    678:        domainnamelen = uap->len;
                    679:        error = copyin(uap->domainname, domainname, uap->len);
                    680:        domainname[domainnamelen] = 0;
                    681:        return (error);
                    682: }
                    683: 
                    684: #ifdef SYSVSHM
                    685: hpuxshmat(p, uap, retval)
                    686:        struct proc *p;
                    687:        int *uap, *retval;
                    688: {
                    689:        return (shmat(p, uap, retval));
                    690: }
                    691: 
                    692: hpuxshmctl(p, uap, retval)
                    693:        struct proc *p;
                    694:        int *uap, *retval;
                    695: {
                    696:        return (shmctl(p, uap, retval));
                    697: }
                    698: 
                    699: hpuxshmdt(p, uap, retval)
                    700:        struct proc *p;
                    701:        int *uap, *retval;
                    702: {
                    703:        return (shmdt(p, uap, retval));
                    704: }
                    705: 
                    706: hpuxshmget(p, uap, retval)
                    707:        struct proc *p;
                    708:        int *uap, *retval;
                    709: {
                    710:        return (shmget(p, uap, retval));
                    711: }
                    712: #endif
                    713: 
                    714: /*
                    715:  * Fake semaphore routines, just don't return an error.
                    716:  * Should be adequate for starbase to run.
                    717:  */
                    718: hpuxsemctl(p, uap, retval)
                    719:        struct proc *p;
                    720:        struct args {
                    721:                int semid;
                    722:                u_int semnum;
                    723:                int cmd;
                    724:                int arg;
                    725:        } *uap;
                    726:        int *retval;
                    727: {
                    728:        /* XXX: should do something here */
                    729:        return (0);
                    730: }
                    731: 
                    732: hpuxsemget(p, uap, retval)
                    733:        struct proc *p;
                    734:        struct args {
                    735:                key_t key;
                    736:                int nsems;
                    737:                int semflg;
                    738:        } *uap;
                    739:        int *retval;
                    740: {
                    741:        /* XXX: should do something here */
                    742:        return (0);
                    743: }
                    744: 
                    745: hpuxsemop(p, uap, retval)
                    746:        struct proc *p;
                    747:        struct args {
                    748:                int semid;
                    749:                struct sembuf *sops;
                    750:                u_int nsops;
                    751:        } *uap;
                    752:        int *retval;
                    753: {
                    754:        /* XXX: should do something here */
                    755:        return (0);
                    756: }
                    757: 
                    758: /* convert from BSD to HPUX errno */
                    759: bsdtohpuxerrno(err)
                    760:        int err;
                    761: {
                    762:        if (err < 0 || err >= NERR)
                    763:                return(BERR);
                    764:        return((int)bsdtohpuxerrnomap[err]);
                    765: }
                    766: 
                    767: hpuxstat1(fname, hsb, follow)
                    768:        char *fname;
                    769:        struct hpuxstat *hsb;
                    770:        int follow;
                    771: {
                    772:        register struct nameidata *ndp = &u.u_nd;
                    773:        struct stat sb;
                    774:        int error;
                    775: 
                    776:        ndp->ni_nameiop = LOOKUP | LOCKLEAF | follow;
                    777:        ndp->ni_segflg = UIO_USERSPACE;
                    778:        ndp->ni_dirp = fname;
                    779:        if (error = namei(ndp))
                    780:                return (error);
                    781:        error = vn_stat(ndp->ni_vp, &sb);
                    782:        vput(ndp->ni_vp);
                    783:        if (error == 0)
                    784:                error = bsdtohpuxstat(&sb, hsb);
                    785:        return (error);
                    786: }
                    787: 
                    788: #include "grf.h"
                    789: 
                    790: bsdtohpuxstat(sb, hsb)
                    791:        struct stat *sb;
                    792:        struct hpuxstat *hsb;
                    793: {
                    794:        struct hpuxstat ds;
                    795: 
                    796:        bzero((caddr_t)&ds, sizeof(ds));
                    797:        ds.hst_dev = sb->st_dev;
                    798:        ds.hst_ino = (u_long)sb->st_ino;
                    799:        ds.hst_mode = sb->st_mode;
                    800:        ds.hst_nlink = sb->st_nlink;
                    801:        ds.hst_uid = (u_short)sb->st_uid;
                    802:        ds.hst_gid = (u_short)sb->st_gid;
                    803: #if NGRF > 0
                    804:        /* XXX: I don't want to talk about it... */
                    805:        if ((sb->st_mode & S_IFMT) == S_IFCHR && major(sb->st_rdev) == 10)
                    806:                ds.hst_rdev = grfdevno(sb->st_rdev);
                    807:        else
                    808: #endif
                    809:                ds.hst_rdev = bsdtohpuxdev(sb->st_rdev);
                    810:        ds.hst_size = sb->st_size;
                    811:        ds.hst_atime = sb->st_atime;
                    812:        ds.hst_mtime = sb->st_mtime;
                    813:        ds.hst_ctime = sb->st_ctime;
                    814:        ds.hst_blksize = sb->st_blksize;
                    815:        ds.hst_blocks = sb->st_blocks;
                    816:        return(copyout((caddr_t)&ds, (caddr_t)hsb, sizeof(ds)));
                    817: }
                    818: 
                    819: hpuxtobsdioctl(com)
                    820:        int com;
                    821: {
                    822:        switch (com) {
                    823:        case HPUXTIOCSLTC:
                    824:                com = TIOCSLTC; break;
                    825:        case HPUXTIOCGLTC:
                    826:                com = TIOCGLTC; break;
                    827:        case HPUXTIOCSPGRP:
                    828:                com = TIOCSPGRP; break;
                    829:        case HPUXTIOCGPGRP:
                    830:                com = TIOCGPGRP; break;
                    831:        case HPUXTIOCLBIS:
                    832:                com = TIOCLBIS; break;
                    833:        case HPUXTIOCLBIC:
                    834:                com = TIOCLBIC; break;
                    835:        case HPUXTIOCLSET:
                    836:                com = TIOCLSET; break;
                    837:        case HPUXTIOCLGET:
                    838:                com = TIOCLGET; break;
                    839:        }
                    840:        return(com);
                    841: }
                    842: 
                    843: /*
                    844:  * HPUX ioctl system call.  The differences here are:
                    845:  *     IOC_IN also means IOC_VOID if the size portion is zero.
                    846:  *     no FIOCLEX/FIONCLEX/FIONBIO/FIOASYNC/FIOGETOWN/FIOSETOWN
                    847:  *     the sgttyb struct is 2 bytes longer
                    848:  */
                    849: hpuxioctl(p, uap, retval)
                    850:        struct proc *p;
                    851:        register struct args {
                    852:                int     fdes;
                    853:                int     cmd;
                    854:                caddr_t cmarg;
                    855:        } *uap;
                    856:        int *retval;
                    857: {
                    858:        register struct file *fp;
                    859:        register int com, error;
                    860:        register u_int size;
                    861:        caddr_t memp = 0;
                    862: #define STK_PARAMS     128
                    863:        char stkbuf[STK_PARAMS];
                    864:        caddr_t data = stkbuf;
                    865: 
                    866:        com = uap->cmd;
                    867: 
                    868:        /* XXX */
                    869:        if (com == HPUXTIOCGETP || com == HPUXTIOCSETP)
                    870:                return (getsettty(uap->fdes, com, uap->cmarg));
                    871: 
                    872:        if ((unsigned)uap->fdes >= NOFILE ||
                    873:            (fp = u.u_ofile[uap->fdes]) == NULL)
                    874:                return (EBADF);
                    875:        if ((fp->f_flag & (FREAD|FWRITE)) == 0)
                    876:                return (EBADF);
                    877: 
                    878:        /*
                    879:         * Interpret high order word to find
                    880:         * amount of data to be copied to/from the
                    881:         * user's address space.
                    882:         */
                    883:        size = IOCPARM_LEN(com);
                    884:        if (size > IOCPARM_MAX)
                    885:                return (ENOTTY);
                    886:        if (size > sizeof (stkbuf)) {
                    887:                memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
                    888:                data = memp;
                    889:        }
                    890:        if (com&IOC_IN) {
                    891:                if (size) {
                    892:                        error = copyin(uap->cmarg, data, (u_int)size);
                    893:                        if (error) {
                    894:                                if (memp)
                    895:                                        free(memp, M_IOCTLOPS);
                    896:                                return (error);
                    897:                        }
                    898:                } else
                    899:                        *(caddr_t *)data = uap->cmarg;
                    900:        } else if ((com&IOC_OUT) && size)
                    901:                /*
                    902:                 * Zero the buffer so the user always
                    903:                 * gets back something deterministic.
                    904:                 */
                    905:                bzero(data, size);
                    906:        else if (com&IOC_VOID)
                    907:                *(caddr_t *)data = uap->cmarg;
                    908: 
                    909:        switch (com) {
                    910: 
                    911:        case HPUXTIOCCONS:
                    912:                *(int *)data = 1;
                    913:                error = (*fp->f_ops->fo_ioctl)(fp, TIOCCONS, data);
                    914:                break;
                    915: 
                    916:        /* BSD-style job control ioctls */
                    917:        case HPUXTIOCLBIS:
                    918:        case HPUXTIOCLBIC:
                    919:        case HPUXTIOCLSET:
                    920:                *(int *)data &= HPUXLTOSTOP;
                    921:                if (*(int *)data & HPUXLTOSTOP)
                    922:                        *(int *)data = LTOSTOP;
                    923:                /* fall into */
                    924:        case HPUXTIOCLGET:
                    925:        case HPUXTIOCSLTC:
                    926:        case HPUXTIOCGLTC:
                    927:        case HPUXTIOCSPGRP:
                    928:        case HPUXTIOCGPGRP:
                    929:                error = (*fp->f_ops->fo_ioctl)(fp, hpuxtobsdioctl(com), data);
                    930:                if (error == 0 && com == HPUXTIOCLGET) {
                    931:                        *(int *)data &= LTOSTOP;
                    932:                        if (*(int *)data & LTOSTOP)
                    933:                                *(int *)data = HPUXLTOSTOP;
                    934:                }
                    935:                break;
                    936: 
                    937:        /* SYS 5 termio */
                    938:        case HPUXTCGETA:
                    939:        case HPUXTCSETA:
                    940:        case HPUXTCSETAW:
                    941:        case HPUXTCSETAF:
                    942:                error = hpuxtermio(fp, com, data);
                    943:                break;
                    944: 
                    945:        default:
                    946:                error = (*fp->f_ops->fo_ioctl)(fp, com, data);
                    947:                break;
                    948:        }
                    949:        /*
                    950:         * Copy any data to user, size was
                    951:         * already set and checked above.
                    952:         */
                    953:        if (error == 0 && (com&IOC_OUT) && size)
                    954:                error = copyout(data, uap->cmarg, (u_int)size);
                    955:        if (memp)
                    956:                free(memp, M_IOCTLOPS);
                    957:        return (error);
                    958: }
                    959: 
                    960: /*
                    961:  * Man page lies, behaviour here is based on observed behaviour.
                    962:  */
                    963: hpuxgetcontext(p, uap, retval)
                    964:        struct proc *p;
                    965:        struct args {
                    966:                char *buf;
                    967:                int len;
                    968:        } *uap;
                    969:        int *retval;
                    970: {
                    971:        int error = 0;
                    972:        register int len;
                    973: 
                    974:        len = MIN(uap->len, sizeof(hpuxcontext));
                    975:        if (len)
                    976:                error = copyout(hpuxcontext, uap->buf, (u_int)len);
                    977:        if (error == 0)
                    978:                *retval = sizeof(hpuxcontext);
                    979:        return (error);
                    980: }
                    981: 
                    982: /*
                    983:  * XXX: simple recognition hack to see if we can make grmd work.
                    984:  */
                    985: hpuxlockf(p, uap, retval)
                    986:        struct proc *p;
                    987:        struct args {
                    988:                int fd;
                    989:                int func;
                    990:                long size;
                    991:        } *uap;
                    992:        int *retval;
                    993: {
                    994: #ifdef DEBUG
                    995:        log(LOG_DEBUG, "%d: lockf(%d, %d, %d)\n",
                    996:            p->p_pid, uap->fd, uap->func, uap->size);
                    997: #endif
                    998:        return (0);
                    999: }
                   1000: 
                   1001: /*
                   1002:  * This is the equivalent of BSD getpgrp but with more restrictions.
                   1003:  * Note we do not check the real uid or "saved" uid.
                   1004:  */
                   1005: hpuxgetpgrp2(cp, uap, retval)
                   1006:        struct proc *cp;
                   1007:        register struct args {
                   1008:                int pid;
                   1009:        } *uap;
                   1010:        int *retval;
                   1011: {
                   1012:        register struct proc *p;
                   1013: 
                   1014:        if (uap->pid == 0)
                   1015:                uap->pid = cp->p_pid;
                   1016:        p = pfind(uap->pid);
                   1017:        if (p == 0)
                   1018:                return (ESRCH);
                   1019:        if (u.u_uid && p->p_uid != u.u_uid && !inferior(p))
                   1020:                return (EPERM);
                   1021:        *retval = p->p_pgid;
                   1022:        return (0);
                   1023: }
                   1024: 
                   1025: /*
                   1026:  * This is the equivalent of BSD setpgrp but with more restrictions.
                   1027:  * Note we do not check the real uid or "saved" uid or pgrp.
                   1028:  */
                   1029: hpuxsetpgrp2(p, uap, retval)
                   1030:        struct proc *p;
                   1031:        struct args {
                   1032:                int     pid;
                   1033:                int     pgrp;
                   1034:        } *uap;
                   1035:        int *retval;
                   1036: {
                   1037:        /* empirically determined */
                   1038:        if (uap->pgrp < 0 || uap->pgrp >= 30000)
                   1039:                return (EINVAL);
                   1040:        return (setpgrp(p, uap, retval));
                   1041: }
                   1042: 
                   1043: /*
                   1044:  * Brutal hack!  Map HPUX u-area offsets into BSD u offsets.
                   1045:  * No apologies offered, if you don't like it, rewrite it!
                   1046:  */
                   1047: 
                   1048: #define UOFF(f)                ((int)&((struct user *)0)->f)
                   1049: #define HPUOFF(f)      ((int)&((struct hpuxuser *)0)->f)
                   1050: 
                   1051: /* simplified FP structure */
                   1052: struct bsdfp {
                   1053:        int save[54];
                   1054:        int reg[24];
                   1055:        int ctrl[3];
                   1056: };
                   1057: 
                   1058: hpuxtobsduoff(off)
                   1059:        int *off;
                   1060: {
                   1061:        struct hpuxfp *hp;
                   1062:        struct bsdfp *bp;
                   1063:        register u_int raddr;
                   1064: 
                   1065:        /* u_ar0 field */
                   1066:        if ((int)off == HPUOFF(hpuxu_ar0))
                   1067:                return(UOFF(u_ar0));
                   1068: 
                   1069: #ifdef FPCOPROC
                   1070:        /* 68881 registers from PCB */
                   1071:        hp = (struct hpuxfp *)HPUOFF(hpuxu_fp);
                   1072:        bp = (struct bsdfp *)UOFF(u_pcb.pcb_fpregs);
                   1073:        if (off >= hp->hpfp_ctrl && off < &hp->hpfp_ctrl[3])
                   1074:                return((int)&bp->ctrl[off - hp->hpfp_ctrl]);
                   1075:        if (off >= hp->hpfp_reg && off < &hp->hpfp_reg[24])
                   1076:                return((int)&bp->reg[off - hp->hpfp_reg]);
                   1077: #endif
                   1078: 
                   1079:        /*
                   1080:         * Everything else we recognize comes from the kernel stack,
                   1081:         * so we convert off to an absolute address (if not already)
                   1082:         * for simplicity.
                   1083:         */
                   1084:        if (off < (int *)ctob(UPAGES))
                   1085:                off = (int *)((u_int)off + (u_int)&u);
                   1086: 
                   1087:        /*
                   1088:         * 68020 registers.
                   1089:         * We know that the HPUX registers are in the same order as ours.
                   1090:         * The only difference is that their PS is 2 bytes instead of a
                   1091:         * padded 4 like ours throwing the alignment off.
                   1092:         */
                   1093:        if (off >= u.u_ar0 && off < &u.u_ar0[18]) {
                   1094:                /*
                   1095:                 * PS: return low word and high word of PC as HP-UX would
                   1096:                 * (e.g. &u.u_ar0[16.5]).
                   1097:                 */
                   1098:                if (off == &u.u_ar0[PS])
                   1099:                        raddr = (u_int) &((short *)u.u_ar0)[PS*2+1];
                   1100:                /*
                   1101:                 * PC: off will be &u.u_ar0[16.5]
                   1102:                 */
                   1103:                else if (off == (int *)&(((short *)u.u_ar0)[PS*2+1]))
                   1104:                        raddr = (u_int) &u.u_ar0[PC];
                   1105:                /*
                   1106:                 * D0-D7, A0-A7: easy
                   1107:                 */
                   1108:                else
                   1109:                        raddr = (u_int) &u.u_ar0[(int)(off - u.u_ar0)];
                   1110:                return((int)(raddr - (u_int)&u));
                   1111:        }
                   1112: 
                   1113:        /* everything else */
                   1114:        return(-1);
                   1115: }
                   1116: 
                   1117: /*
                   1118:  * Kludge up a uarea dump so that HPUX debuggers can find out
                   1119:  * what they need.  IMPORTANT NOTE: we do not EVEN attempt to
                   1120:  * convert the entire user struct.
                   1121:  */
                   1122: hpuxdumpu(vp, cred)
                   1123:        struct vnode *vp;
                   1124:        struct ucred *cred;
                   1125: {
                   1126:        int error;
                   1127:        struct hpuxuser *faku;
                   1128:        struct bsdfp *bp;
                   1129:        short *foop;
                   1130: 
                   1131:        faku = (struct hpuxuser *)malloc((u_long)ctob(1), M_TEMP, M_WAITOK);
                   1132:        /*
                   1133:         * Make sure there is no mistake about this
                   1134:         * being a real user structure.
                   1135:         */
                   1136:        bzero((caddr_t)faku, ctob(1));
                   1137:        /*
                   1138:         * Fill in the process sizes.
                   1139:         */
                   1140:        faku->hpuxu_tsize = u.u_tsize;
                   1141:        faku->hpuxu_dsize = u.u_dsize;
                   1142:        faku->hpuxu_ssize = u.u_ssize;
                   1143:        /*
                   1144:         * Fill in the exec header for CDB.
                   1145:         * This was saved back in exec().  As far as I can tell CDB
                   1146:         * only uses this information to verify that a particular
                   1147:         * core file goes with a particular binary.
                   1148:         */
                   1149:        bcopy((caddr_t)u.u_pcb.pcb_exec,
                   1150:              (caddr_t)&faku->hpuxu_exdata, sizeof (struct hpux_exec));
                   1151:        /*
                   1152:         * Adjust user's saved registers (on kernel stack) to reflect
                   1153:         * HPUX order.  Note that HPUX saves the SR as 2 bytes not 4
                   1154:         * so we have to move it up.
                   1155:         */
                   1156:        faku->hpuxu_ar0 = u.u_ar0;
                   1157:        foop = (short *) u.u_ar0;
                   1158:        foop[32] = foop[33];
                   1159:        foop[33] = foop[34];
                   1160:        foop[34] = foop[35];
                   1161: #ifdef FPCOPROC
                   1162:        /*
                   1163:         * Copy 68881 registers from our PCB format to HPUX format
                   1164:         */
                   1165:        bp = (struct bsdfp *) &u.u_pcb.pcb_fpregs;
                   1166:        bcopy((caddr_t)bp->save, (caddr_t)faku->hpuxu_fp.hpfp_save,
                   1167:              sizeof(bp->save));
                   1168:        bcopy((caddr_t)bp->ctrl, (caddr_t)faku->hpuxu_fp.hpfp_ctrl,
                   1169:              sizeof(bp->ctrl));
                   1170:        bcopy((caddr_t)bp->reg, (caddr_t)faku->hpuxu_fp.hpfp_reg,
                   1171:              sizeof(bp->reg));
                   1172: #endif
                   1173:        /*
                   1174:         * Slay the dragon
                   1175:         */
                   1176:        faku->hpuxu_dragon = -1;
                   1177:        /*
                   1178:         * Dump this artfully constructed page in place of the
                   1179:         * user struct page.
                   1180:         */
                   1181:        error = vn_rdwr(UIO_WRITE, vp,
                   1182:                        (caddr_t)faku, ctob(1), (off_t)0,
                   1183:                        UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)0);
                   1184:        /*
                   1185:         * Dump the remaining UPAGES-1 pages normally
                   1186:         */
                   1187:        if (!error) 
                   1188:                error = vn_rdwr(UIO_WRITE, vp, ((caddr_t)&u)+ctob(1),
                   1189:                                ctob(UPAGES-1), (off_t)ctob(1), UIO_SYSSPACE,
                   1190:                                IO_NODELOCKED|IO_UNIT, cred, (int *)0);
                   1191:        free((caddr_t)faku, M_TEMP);
                   1192:        return(error);
                   1193: }
                   1194: 
                   1195: /*
                   1196:  * The remaining routines are essentially the same as those in kern_xxx.c
                   1197:  * and vfs_xxx.c as defined under "#ifdef COMPAT".  We replicate them here
                   1198:  * to avoid HPUXCOMPAT dependencies in those files and to make sure that
                   1199:  * HP-UX compatibility still works even when COMPAT is not defined.
                   1200:  */
                   1201: /* #ifdef COMPAT */
                   1202: 
                   1203: #include "../sys/times.h"
                   1204: 
                   1205: /* from old timeb.h */
                   1206: struct hpuxtimeb {
                   1207:        time_t  time;
                   1208:        u_short millitm;
                   1209:        short   timezone;
                   1210:        short   dstflag;
                   1211: };
                   1212: 
                   1213: /* ye ole stat structure */
                   1214: struct ohpuxstat {
                   1215:        dev_t   ohst_dev;
                   1216:        u_short ohst_ino;
                   1217:        u_short ohst_mode;
                   1218:        short   ohst_nlink;
                   1219:        short   ohst_uid;
                   1220:        short   ohst_gid;
                   1221:        dev_t   ohst_rdev;
                   1222:        int     ohst_size;
                   1223:        int     ohst_atime;
                   1224:        int     ohst_mtime;
                   1225:        int     ohst_ctime;
                   1226: };
                   1227: 
                   1228: /*
                   1229:  * SYS V style setpgrp()
                   1230:  */
                   1231: ohpuxsetpgrp(p, uap, retval)
                   1232:        register struct proc *p;
                   1233:        int *uap, *retval;
                   1234: {
                   1235:        if (p->p_pid != p->p_pgid)
                   1236:                pgmv(p, p->p_pid, 0);
                   1237:        *retval = p->p_pgid;
                   1238: }
                   1239: 
                   1240: ohpuxtime(p, uap, retval)
                   1241:        struct proc *p;
                   1242:        register struct args {
                   1243:                long    *tp;
                   1244:        } *uap;
                   1245:        time_t *retval;
                   1246: {
                   1247:        int error;
                   1248: 
                   1249:        if (uap->tp)
                   1250:                error = copyout((caddr_t)&time.tv_sec, (caddr_t)uap->tp,
                   1251:                                sizeof (long));
                   1252:        *retval = time.tv_sec;          /* XXX */
                   1253:        return (error);
                   1254: }
                   1255: 
                   1256: ohpuxstime(p, uap, retval)
                   1257:        struct proc *p;
                   1258:        register struct args {
                   1259:                int     time;
                   1260:        } *uap;
                   1261:        int *retval;
                   1262: {
                   1263:        struct timeval tv;
                   1264:        int s, error;
                   1265: 
                   1266:        tv.tv_sec = uap->time;
                   1267:        tv.tv_usec = 0;
                   1268:        if (error = suser(u.u_cred, &u.u_acflag))
                   1269:                return (error);
                   1270: 
                   1271:        /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
                   1272:        boottime.tv_sec += tv.tv_sec - time.tv_sec;
                   1273:        s = splhigh(); time = tv; splx(s);
                   1274:        resettodr();
                   1275:        return (0);
                   1276: }
                   1277: 
                   1278: ohpuxftime(p, uap, retval)
                   1279:        struct proc *p;
                   1280:        register struct args {
                   1281:                struct  hpuxtimeb *tp;
                   1282:        } *uap;
                   1283:        int *retval;
                   1284: {
                   1285:        struct hpuxtimeb tb;
                   1286:        int s;
                   1287: 
                   1288:        s = splhigh();
                   1289:        tb.time = time.tv_sec;
                   1290:        tb.millitm = time.tv_usec / 1000;
                   1291:        splx(s);
                   1292:        tb.timezone = tz.tz_minuteswest;
                   1293:        tb.dstflag = tz.tz_dsttime;
                   1294:        return (copyout((caddr_t)&tb, (caddr_t)uap->tp, sizeof (tb)));
                   1295: }
                   1296: 
                   1297: ohpuxalarm(p, uap, retval)
                   1298:        register struct proc *p;
                   1299:        register struct args {
                   1300:                int     deltat;
                   1301:        } *uap;
                   1302:        int *retval;
                   1303: {
                   1304:        int s = splhigh();
                   1305: 
                   1306:        untimeout(realitexpire, (caddr_t)p);
                   1307:        timerclear(&p->p_realtimer.it_interval);
                   1308:        *retval = 0;
                   1309:        if (timerisset(&p->p_realtimer.it_value) &&
                   1310:            timercmp(&p->p_realtimer.it_value, &time, >))
                   1311:                *retval = p->p_realtimer.it_value.tv_sec - time.tv_sec;
                   1312:        if (uap->deltat == 0) {
                   1313:                timerclear(&p->p_realtimer.it_value);
                   1314:                splx(s);
                   1315:                return (0);
                   1316:        }
                   1317:        p->p_realtimer.it_value = time;
                   1318:        p->p_realtimer.it_value.tv_sec += uap->deltat;
                   1319:        timeout(realitexpire, (caddr_t)p, hzto(&p->p_realtimer.it_value));
                   1320:        splx(s);
                   1321:        return (0);
                   1322: }
                   1323: 
                   1324: ohpuxnice(p, uap, retval)
                   1325:        register struct proc *p;
                   1326:        register struct args {
                   1327:                int     niceness;
                   1328:        } *uap;
                   1329:        int *retval;
                   1330: {
                   1331:        int error;
                   1332: 
                   1333:        error = donice(p, p, (p->p_nice-NZERO)+uap->niceness);
                   1334:        if (error == 0)
                   1335:                *retval = p->p_nice - NZERO;
                   1336:        return (error);
                   1337: }
                   1338: 
                   1339: ohpuxtimes(p, uap, retval)
                   1340:        struct proc *p;
                   1341:        register struct args {
                   1342:                struct  tms *tmsb;
                   1343:        } *uap;
                   1344:        time_t *retval;
                   1345: {
                   1346:        struct tms atms;
                   1347:        int error;
                   1348: 
                   1349:        atms.tms_utime = scale50(&u.u_ru.ru_utime);
                   1350:        atms.tms_stime = scale50(&u.u_ru.ru_stime);
                   1351:        atms.tms_cutime = scale50(&u.u_cru.ru_utime);
                   1352:        atms.tms_cstime = scale50(&u.u_cru.ru_stime);
                   1353:        error = copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms));
                   1354:        if (error == 0)
                   1355:                *retval = scale50(&time) - scale50(&boottime); /* XXX */
                   1356:        return (error);
                   1357: }
                   1358: 
                   1359: scale50(tvp)
                   1360:        register struct timeval *tvp;
                   1361: {
                   1362:        extern int hpuxtick;
                   1363: 
                   1364:        /*
                   1365:         * Doesn't exactly do what the documentation says.
                   1366:         * What we really do is return 50th of a second since that
                   1367:         * is what HZ is on all bobcats I know of.
                   1368:         */
                   1369:        return ((tvp->tv_sec * 50 + tvp->tv_usec / hpuxtick));
                   1370: }
                   1371: 
                   1372: /*
                   1373:  * Set IUPD and IACC times on file.
                   1374:  * Can't set ICHG.
                   1375:  */
                   1376: ohpuxutime(p, uap, retval)
                   1377:        struct proc *p;
                   1378:        register struct a {
                   1379:                char    *fname;
                   1380:                time_t  *tptr;
                   1381:        } *uap;
                   1382:        int *retval;
                   1383: {
                   1384:        struct vattr vattr;
                   1385:        time_t tv[2];
                   1386:        register struct vnode *vp;
                   1387:        register struct nameidata *ndp = &u.u_nd;
                   1388:        int error;
                   1389: 
                   1390:        if (uap->tptr) {
                   1391:                error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv));
                   1392:                if (error)
                   1393:                        return (error);
                   1394:        } else
                   1395:                tv[0] = tv[1] = time.tv_sec;
                   1396:        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
                   1397:        ndp->ni_segflg = UIO_USERSPACE;
                   1398:        ndp->ni_dirp = uap->fname;
                   1399:        vattr_null(&vattr);
                   1400:        vattr.va_atime.tv_sec = tv[0];
                   1401:        vattr.va_atime.tv_usec = 0;
                   1402:        vattr.va_mtime.tv_sec = tv[1];
                   1403:        vattr.va_mtime.tv_usec = 0;
                   1404:        if (error = namei(ndp))
                   1405:                return (error);
                   1406:        vp = ndp->ni_vp;
                   1407:        if (vp->v_mount->mnt_flag & MNT_RDONLY)
                   1408:                error = EROFS;
                   1409:        else
                   1410:                error = VOP_SETATTR(vp, &vattr, ndp->ni_cred);
                   1411:        vput(vp);
                   1412:        return (error);
                   1413: }
                   1414: 
                   1415: ohpuxpause(p, uap, retval)
                   1416:        struct proc *p;
                   1417:        int *uap, *retval;
                   1418: {
                   1419:        (void) tsleep((caddr_t)&u, PPAUSE | PCATCH, "pause", 0);
                   1420:        /* always return EINTR rather than ERESTART... */
                   1421:        return (EINTR);
                   1422: }
                   1423: 
                   1424: /*
                   1425:  * The old fstat system call.
                   1426:  */
                   1427: ohpuxfstat(p, uap, retval)
                   1428:        struct proc *p;
                   1429:        register struct args {
                   1430:                int     fd;
                   1431:                struct ohpuxstat *sb;
                   1432:        } *uap;
                   1433:        int *retval;
                   1434: {
                   1435:        struct file *fp;
                   1436: 
                   1437:        if ((unsigned)uap->fd >= NOFILE || (fp = u.u_ofile[uap->fd]) == NULL)
                   1438:                return (EBADF);
                   1439:        if (fp->f_type != DTYPE_VNODE)
                   1440:                return (EINVAL);
                   1441:        return (ohpuxstat1((struct vnode *)fp->f_data, uap->sb));
                   1442: }
                   1443: 
                   1444: /*
                   1445:  * Old stat system call.  This version follows links.
                   1446:  */
                   1447: ohpuxstat(p, uap, retval)
                   1448:        struct proc *p;
                   1449:        register struct args {
                   1450:                char    *fname;
                   1451:                struct ohpuxstat *sb;
                   1452:        } *uap;
                   1453:        int *retval;
                   1454: {
                   1455:        register struct nameidata *ndp = &u.u_nd;
                   1456:        int error;
                   1457: 
                   1458:        ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW;
                   1459:        ndp->ni_segflg = UIO_USERSPACE;
                   1460:        ndp->ni_dirp = uap->fname;
                   1461:        if (error = namei(ndp))
                   1462:                return (error);
                   1463:        error = ohpuxstat1(ndp->ni_vp, uap->sb);
                   1464:        vput(ndp->ni_vp);
                   1465:        return (error);
                   1466: }
                   1467: 
                   1468: int
                   1469: ohpuxstat1(vp, ub)
                   1470:        register struct vnode *vp;
                   1471:        struct ohpuxstat *ub;
                   1472: {
                   1473:        struct ohpuxstat ds;
                   1474:        struct vattr vattr;
                   1475:        register int error;
                   1476: 
                   1477:        error = VOP_GETATTR(vp, &vattr, u.u_cred);
                   1478:        if (error)
                   1479:                return(error);
                   1480:        /*
                   1481:         * Copy from inode table
                   1482:         */
                   1483:        ds.ohst_dev = vattr.va_fsid;
                   1484:        ds.ohst_ino = (short)vattr.va_fileid;
                   1485:        ds.ohst_mode = (u_short)vattr.va_mode;
                   1486:        ds.ohst_nlink = vattr.va_nlink;
                   1487:        ds.ohst_uid = (short)vattr.va_uid;
                   1488:        ds.ohst_gid = (short)vattr.va_gid;
                   1489:        ds.ohst_rdev = (dev_t)vattr.va_rdev;
                   1490:        ds.ohst_size = (int)vattr.va_size;
                   1491:        ds.ohst_atime = (int)vattr.va_atime.tv_sec;
                   1492:        ds.ohst_mtime = (int)vattr.va_mtime.tv_sec;
                   1493:        ds.ohst_ctime = (int)vattr.va_ctime.tv_sec;
                   1494:        return (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)));
                   1495: }
                   1496: /* #endif */
                   1497: 
                   1498: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.