Annotation of 43BSDReno/sys/hpux/hpux_compat.c, revision 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.