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

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

unix.superglobalmegacorp.com

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