Annotation of Net2/arch/hp300/hpux/hpux_compat.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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