[BACK]Return to sysv_msg.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Annotation of src/sys/kern/sysv_msg.c, Revision 1.12

1.12    ! mycroft     1: /*     $NetBSD: sysv_msg.c,v 1.11 1994/10/23 23:11:27 cgd Exp $        */
1.9       cgd         2:
1.1       cgd         3: /*
                      4:  * Implementation of SVID messages
                      5:  *
                      6:  * Author:  Daniel Boulet
                      7:  *
                      8:  * Copyright 1993 Daniel Boulet and RTMX Inc.
                      9:  *
                     10:  * This system call was implemented by Daniel Boulet under contract from RTMX.
                     11:  *
                     12:  * Redistribution and use in source forms, with and without modification,
                     13:  * are permitted provided that this entire comment appears intact.
                     14:  *
                     15:  * Redistribution in binary form may occur without any restrictions.
                     16:  * Obviously, it would be nice if you gave credit where credit is due
                     17:  * but requiring it would be too onerous.
                     18:  *
                     19:  * This software is provided ``AS IS'' without any warranties of any kind.
                     20:  */
                     21:
1.2       mycroft    22: #include <sys/param.h>
                     23: #include <sys/systm.h>
                     24: #include <sys/kernel.h>
                     25: #include <sys/proc.h>
                     26: #include <sys/msg.h>
                     27: #include <sys/malloc.h>
1.1       cgd        28:
1.10      cgd        29: #include <sys/mount.h>
                     30: #include <sys/syscallargs.h>
                     31:
1.1       cgd        32: #define MSG_DEBUG
                     33: #undef MSG_DEBUG_OK
                     34:
                     35: int nfree_msgmaps;             /* # of free map entries */
                     36: short free_msgmaps;            /* head of linked list of free map entries */
                     37: struct msg *free_msghdrs;      /* list of free msg headers */
                     38:
                     39: int
                     40: msginit()
                     41: {
1.3       mycroft    42:        register int i;
                     43:        vm_offset_t whocares1, whocares2;
1.1       cgd        44:
1.3       mycroft    45:        /*
                     46:         * msginfo.msgssz should be a power of two for efficiency reasons.
                     47:         * It is also pretty silly if msginfo.msgssz is less than 8
                     48:         * or greater than about 256 so ...
                     49:         */
1.1       cgd        50:
1.3       mycroft    51:        i = 8;
                     52:        while (i < 1024 && i != msginfo.msgssz)
                     53:                i <<= 1;
                     54:        if (i != msginfo.msgssz) {
                     55:                printf("msginfo.msgssz=%d (0x%x)\n", msginfo.msgssz,
                     56:                    msginfo.msgssz);
                     57:                panic("msginfo.msgssz not a small power of 2");
                     58:        }
                     59:
                     60:        if (msginfo.msgseg > 32767) {
                     61:                printf("msginfo.msgseg=%d\n", msginfo.msgseg);
                     62:                panic("msginfo.msgseg > 32767");
                     63:        }
                     64:
                     65:        if (msgmaps == NULL)
                     66:                panic("msgmaps is NULL");
                     67:
                     68:        for (i = 0; i < msginfo.msgseg; i++) {
                     69:                if (i > 0)
                     70:                        msgmaps[i-1].next = i;
                     71:                msgmaps[i].next = -1;   /* implies entry is available */
                     72:        }
                     73:        free_msgmaps = 0;
                     74:        nfree_msgmaps = msginfo.msgseg;
                     75:
                     76:        if (msghdrs == NULL)
                     77:                panic("msghdrs is NULL");
                     78:
                     79:        for (i = 0; i < msginfo.msgtql; i++) {
                     80:                msghdrs[i].msg_type = 0;
                     81:                if (i > 0)
                     82:                        msghdrs[i-1].msg_next = &msghdrs[i];
                     83:                msghdrs[i].msg_next = NULL;
                     84:        }
                     85:        free_msghdrs = &msghdrs[0];
                     86:
                     87:        if (msqids == NULL)
                     88:                panic("msqids is NULL");
                     89:
1.4       mycroft    90:        for (i = 0; i < msginfo.msgmni; i++) {
1.3       mycroft    91:                msqids[i].msg_qbytes = 0;       /* implies entry is available */
                     92:                msqids[i].msg_perm.seq = 0;     /* reset to a known value */
                     93:        }
1.1       cgd        94: }
                     95:
1.3       mycroft    96: static void
1.1       cgd        97: msg_freehdr(msghdr)
1.3       mycroft    98:        struct msg *msghdr;
1.1       cgd        99: {
1.3       mycroft   100:        while (msghdr->msg_ts > 0) {
                    101:                short next;
                    102:                if (msghdr->msg_spot < 0 || msghdr->msg_spot >= msginfo.msgseg)
                    103:                        panic("msghdr->msg_spot out of range");
                    104:                next = msgmaps[msghdr->msg_spot].next;
                    105:                msgmaps[msghdr->msg_spot].next = free_msgmaps;
                    106:                free_msgmaps = msghdr->msg_spot;
1.5       mycroft   107:                nfree_msgmaps++;
1.3       mycroft   108:                msghdr->msg_spot = next;
                    109:                if (msghdr->msg_ts >= msginfo.msgssz)
                    110:                        msghdr->msg_ts -= msginfo.msgssz;
                    111:                else
                    112:                        msghdr->msg_ts = 0;
                    113:        }
                    114:        if (msghdr->msg_spot != -1)
                    115:                panic("msghdr->msg_spot != -1");
                    116:        msghdr->msg_next = free_msghdrs;
                    117:        free_msghdrs = msghdr;
1.1       cgd       118: }
                    119:
                    120: int
                    121: msgctl(p, uap, retval)
                    122:        struct proc *p;
1.10      cgd       123:        register struct msgctl_args /* {
                    124:                syscallarg(int) msqid;
                    125:                syscallarg(int) cmd;
                    126:                syscallarg(struct msqid_ds *) buf;
                    127:        } */ *uap;
                    128:        register_t *retval;
1.1       cgd       129: {
1.10      cgd       130:        int msqid = SCARG(uap, msqid);
                    131:        int cmd = SCARG(uap, cmd);
                    132:        struct msqid_ds *user_msqptr = SCARG(uap, buf);
1.3       mycroft   133:        struct ucred *cred = p->p_ucred;
                    134:        int i, rval, eval;
                    135:        struct msqid_ds msqbuf;
                    136:        register struct msqid_ds *msqptr;
1.1       cgd       137:
                    138: #ifdef MSG_DEBUG_OK
1.3       mycroft   139:        printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr);
1.1       cgd       140: #endif
                    141:
1.3       mycroft   142:        msqid = IPCID_TO_IX(msqid);
1.1       cgd       143:
1.3       mycroft   144:        if (msqid < 0 || msqid >= msginfo.msgmni) {
1.1       cgd       145: #ifdef MSG_DEBUG_OK
1.3       mycroft   146:                printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
                    147:                    msginfo.msgmni);
1.1       cgd       148: #endif
1.3       mycroft   149:                return(EINVAL);
                    150:        }
1.1       cgd       151:
1.3       mycroft   152:        msqptr = &msqids[msqid];
1.1       cgd       153:
1.3       mycroft   154:        if (msqptr->msg_qbytes == 0) {
1.1       cgd       155: #ifdef MSG_DEBUG_OK
1.3       mycroft   156:                printf("no such msqid\n");
1.1       cgd       157: #endif
1.3       mycroft   158:                return(EINVAL);
                    159:        }
1.10      cgd       160:        if (msqptr->msg_perm.seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
1.1       cgd       161: #ifdef MSG_DEBUG_OK
1.3       mycroft   162:                printf("wrong sequence number\n");
1.1       cgd       163: #endif
1.3       mycroft   164:                return(EINVAL);
                    165:        }
1.1       cgd       166:
1.3       mycroft   167:        eval = 0;
                    168:        rval = 0;
1.1       cgd       169:
1.3       mycroft   170:        switch (cmd) {
1.1       cgd       171:
1.3       mycroft   172:        case IPC_RMID:
1.1       cgd       173:        {
1.3       mycroft   174:                struct msg *msghdr;
1.8       mycroft   175:                if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M)))
1.7       mycroft   176:                        return(eval);
1.3       mycroft   177:                /* Free the message headers */
                    178:                msghdr = msqptr->msg_first;
                    179:                while (msghdr != NULL) {
                    180:                        struct msg *msghdr_tmp;
                    181:
                    182:                        /* Free the segments of each message */
                    183:                        msqptr->msg_cbytes -= msghdr->msg_ts;
1.5       mycroft   184:                        msqptr->msg_qnum--;
1.3       mycroft   185:                        msghdr_tmp = msghdr;
                    186:                        msghdr = msghdr->msg_next;
                    187:                        msg_freehdr(msghdr_tmp);
                    188:                }
1.1       cgd       189:
1.3       mycroft   190:                if (msqptr->msg_cbytes != 0)
                    191:                        panic("msg_cbytes is screwed up");
                    192:                if (msqptr->msg_qnum != 0)
                    193:                        panic("msg_qnum is screwed up");
1.1       cgd       194:
1.3       mycroft   195:                msqptr->msg_qbytes = 0; /* Mark it as free */
1.1       cgd       196:
1.3       mycroft   197:                wakeup((caddr_t)msqptr);
1.1       cgd       198:        }
                    199:
1.3       mycroft   200:                break;
1.1       cgd       201:
1.3       mycroft   202:        case IPC_SET:
1.8       mycroft   203:                if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M)))
1.7       mycroft   204:                        return(eval);
1.3       mycroft   205:                if ((eval = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
                    206:                        return(eval);
                    207:                if (msqbuf.msg_qbytes > msqptr->msg_qbytes && cred->cr_uid != 0)
                    208:                        return(EPERM);
                    209:                if (msqbuf.msg_qbytes > msginfo.msgmnb) {
1.1       cgd       210: #ifdef MSG_DEBUG_OK
1.3       mycroft   211:                        printf("can't increase msg_qbytes beyond %d (truncating)\n",
                    212:                            msginfo.msgmnb);
1.1       cgd       213: #endif
1.3       mycroft   214:                        msqbuf.msg_qbytes = msginfo.msgmnb;     /* silently restrict qbytes to system limit */
                    215:                }
                    216:                if (msqbuf.msg_qbytes == 0) {
1.1       cgd       217: #ifdef MSG_DEBUG_OK
1.3       mycroft   218:                        printf("can't reduce msg_qbytes to 0\n");
1.1       cgd       219: #endif
1.3       mycroft   220:                        return(EINVAL);         /* non-standard errno! */
                    221:                }
                    222:                msqptr->msg_perm.uid = msqbuf.msg_perm.uid;     /* change the owner */
                    223:                msqptr->msg_perm.gid = msqbuf.msg_perm.gid;     /* change the owner */
                    224:                msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) |
                    225:                    (msqbuf.msg_perm.mode & 0777);
                    226:                msqptr->msg_qbytes = msqbuf.msg_qbytes;
                    227:                msqptr->msg_ctime = time.tv_sec;
                    228:                break;
1.1       cgd       229:
1.3       mycroft   230:        case IPC_STAT:
1.6       hpeyerl   231:                if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_R))) {
1.1       cgd       232: #ifdef MSG_DEBUG_OK
1.3       mycroft   233:                        printf("requester doesn't have read access\n");
1.1       cgd       234: #endif
1.3       mycroft   235:                        return(eval);
                    236:                }
                    237:                eval = copyout((caddr_t)msqptr, user_msqptr,
                    238:                    sizeof(struct msqid_ds));
                    239:                break;
1.1       cgd       240:
1.3       mycroft   241:        default:
1.1       cgd       242: #ifdef MSG_DEBUG_OK
1.3       mycroft   243:                printf("invalid command %d\n", cmd);
1.1       cgd       244: #endif
1.3       mycroft   245:                return(EINVAL);
                    246:        }
                    247:
                    248:        if (eval == 0)
                    249:                *retval = rval;
                    250:        return(eval);
1.1       cgd       251: }
                    252:
                    253: int
                    254: msgget(p, uap, retval)
                    255:        struct proc *p;
1.10      cgd       256:        register struct msgget_args /* {
                    257:                syscallarg(key_t) key;
                    258:                syscallarg(int) msgflg;
                    259:        } */ *uap;
                    260:        register_t *retval;
1.1       cgd       261: {
1.3       mycroft   262:        int msqid, eval;
1.10      cgd       263:        int key = SCARG(uap, key);
                    264:        int msgflg = SCARG(uap, msgflg);
1.3       mycroft   265:        struct ucred *cred = p->p_ucred;
                    266:        register struct msqid_ds *msqptr;
1.1       cgd       267:
                    268: #ifdef MSG_DEBUG_OK
1.3       mycroft   269:        printf("msgget(0x%x, 0%o)\n", key, msgflg);
1.1       cgd       270: #endif
                    271:
1.5       mycroft   272:        if (key != IPC_PRIVATE) {
                    273:                for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
1.3       mycroft   274:                        msqptr = &msqids[msqid];
                    275:                        if (msqptr->msg_qbytes != 0 &&
                    276:                            msqptr->msg_perm.key == key)
                    277:                                break;
                    278:                }
                    279:                if (msqid < msginfo.msgmni) {
1.1       cgd       280: #ifdef MSG_DEBUG_OK
1.3       mycroft   281:                        printf("found public key\n");
1.1       cgd       282: #endif
1.3       mycroft   283:                        if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) {
1.1       cgd       284: #ifdef MSG_DEBUG_OK
1.3       mycroft   285:                                printf("not exclusive\n");
1.1       cgd       286: #endif
1.3       mycroft   287:                                return(EEXIST);
                    288:                        }
1.6       hpeyerl   289:                        if ((eval = ipcperm(cred, &msqptr->msg_perm, msgflg & 0700 ))) {
1.1       cgd       290: #ifdef MSG_DEBUG_OK
1.3       mycroft   291:                                printf("requester doesn't have 0%o access\n",
                    292:                                    msgflg & 0700);
1.1       cgd       293: #endif
1.3       mycroft   294:                                return(eval);
                    295:                        }
1.5       mycroft   296:                        goto found;
1.3       mycroft   297:                }
1.1       cgd       298:        }
                    299:
                    300: #ifdef MSG_DEBUG_OK
1.5       mycroft   301:        printf("need to allocate the msqid_ds\n");
1.1       cgd       302: #endif
1.5       mycroft   303:        if (key == IPC_PRIVATE || (msgflg & IPC_CREAT)) {
                    304:                for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
                    305:                        /*
                    306:                         * Look for an unallocated and unlocked msqid_ds.
                    307:                         * msqid_ds's can be locked by msgsnd or msgrcv while
                    308:                         * they are copying the message in/out.  We can't
                    309:                         * re-use the entry until they release it.
                    310:                         */
                    311:                        msqptr = &msqids[msqid];
                    312:                        if (msqptr->msg_qbytes == 0 &&
                    313:                            (msqptr->msg_perm.mode & MSG_LOCKED) == 0)
                    314:                                break;
                    315:                }
                    316:                if (msqid == msginfo.msgmni) {
1.1       cgd       317: #ifdef MSG_DEBUG_OK
1.5       mycroft   318:                        printf("no more msqid_ds's available\n");
1.1       cgd       319: #endif
1.5       mycroft   320:                        return(ENOSPC);
                    321:                }
1.1       cgd       322: #ifdef MSG_DEBUG_OK
1.5       mycroft   323:                printf("msqid %d is available\n", msqid);
1.3       mycroft   324: #endif
1.5       mycroft   325:                msqptr->msg_perm.key = key;
                    326:                msqptr->msg_perm.cuid = cred->cr_uid;
                    327:                msqptr->msg_perm.uid = cred->cr_uid;
                    328:                msqptr->msg_perm.cgid = cred->cr_gid;
                    329:                msqptr->msg_perm.gid = cred->cr_gid;
                    330:                msqptr->msg_perm.mode = (msgflg & 0777);
                    331:                /* Make sure that the returned msqid is unique */
                    332:                msqptr->msg_perm.seq++;
                    333:                msqptr->msg_first = NULL;
                    334:                msqptr->msg_last = NULL;
                    335:                msqptr->msg_cbytes = 0;
                    336:                msqptr->msg_qnum = 0;
                    337:                msqptr->msg_qbytes = msginfo.msgmnb;
                    338:                msqptr->msg_lspid = 0;
                    339:                msqptr->msg_lrpid = 0;
                    340:                msqptr->msg_stime = 0;
                    341:                msqptr->msg_rtime = 0;
                    342:                msqptr->msg_ctime = time.tv_sec;
                    343:        } else {
1.1       cgd       344: #ifdef MSG_DEBUG_OK
1.5       mycroft   345:                printf("didn't find it and wasn't asked to create it\n");
1.1       cgd       346: #endif
1.5       mycroft   347:                return(ENOENT);
1.1       cgd       348:        }
                    349:
1.5       mycroft   350: found:
1.3       mycroft   351:        /* Construct the unique msqid */
                    352:        *retval = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);
                    353:        return(0);
1.1       cgd       354: }
                    355:
                    356: int
                    357: msgsnd(p, uap, retval)
                    358:        struct proc *p;
1.10      cgd       359:        register struct msgsnd_args /* {
                    360:                syscallarg(int) msqid;
                    361:                syscallarg(void *) msgp;
                    362:                syscallarg(size_t) msgsz;
                    363:                syscallarg(int) msgflg;
                    364:        } */ *uap;
                    365:        register_t *retval;
1.1       cgd       366: {
1.10      cgd       367:        int msqid = SCARG(uap, msqid);
                    368:        char *user_msgp = SCARG(uap, msgp);
                    369:        size_t msgsz = SCARG(uap, msgsz);
                    370:        int msgflg = SCARG(uap, msgflg);
1.3       mycroft   371:        int segs_needed, eval;
                    372:        struct ucred *cred = p->p_ucred;
                    373:        register struct msqid_ds *msqptr;
                    374:        register struct msg *msghdr;
                    375:        short next;
1.1       cgd       376:
                    377: #ifdef MSG_DEBUG_OK
1.3       mycroft   378:        printf("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
                    379:            msgflg);
1.1       cgd       380: #endif
                    381:
1.3       mycroft   382:        msqid = IPCID_TO_IX(msqid);
1.1       cgd       383:
1.3       mycroft   384:        if (msqid < 0 || msqid >= msginfo.msgmni) {
1.1       cgd       385: #ifdef MSG_DEBUG_OK
1.3       mycroft   386:                printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
                    387:                    msginfo.msgmni);
1.1       cgd       388: #endif
1.3       mycroft   389:                return(EINVAL);
                    390:        }
1.1       cgd       391:
1.3       mycroft   392:        msqptr = &msqids[msqid];
                    393:        if (msqptr->msg_qbytes == 0) {
1.1       cgd       394: #ifdef MSG_DEBUG_OK
1.3       mycroft   395:                printf("no such message queue id\n");
1.1       cgd       396: #endif
1.3       mycroft   397:                return(EINVAL);
                    398:        }
1.10      cgd       399:        if (msqptr->msg_perm.seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
1.1       cgd       400: #ifdef MSG_DEBUG_OK
1.3       mycroft   401:                printf("wrong sequence number\n");
1.1       cgd       402: #endif
1.3       mycroft   403:                return(EINVAL);
                    404:        }
1.1       cgd       405:
1.6       hpeyerl   406:        if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_W))) {
1.1       cgd       407: #ifdef MSG_DEBUG_OK
1.3       mycroft   408:                printf("requester doesn't have write access\n");
1.1       cgd       409: #endif
1.3       mycroft   410:                return(eval);
                    411:        }
1.1       cgd       412:
1.3       mycroft   413:        segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
1.1       cgd       414: #ifdef MSG_DEBUG_OK
1.3       mycroft   415:        printf("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz,
                    416:            segs_needed);
1.1       cgd       417: #endif
1.3       mycroft   418:        for (;;) {
                    419:                int need_more_resources = 0;
1.1       cgd       420:
1.3       mycroft   421:                /*
                    422:                 * check msgsz
                    423:                 * (inside this loop in case msg_qbytes changes while we sleep)
                    424:                 */
1.1       cgd       425:
1.3       mycroft   426:                if (msgsz < 0 || msgsz > msqptr->msg_qbytes) {
1.1       cgd       427: #ifdef MSG_DEBUG_OK
1.3       mycroft   428:                        printf("msgsz > msqptr->msg_qbytes\n");
1.1       cgd       429: #endif
1.3       mycroft   430:                        return(EINVAL);
                    431:                }
1.1       cgd       432:
1.3       mycroft   433:                if (msqptr->msg_perm.mode & MSG_LOCKED) {
1.1       cgd       434: #ifdef MSG_DEBUG_OK
1.3       mycroft   435:                        printf("msqid is locked\n");
1.1       cgd       436: #endif
1.3       mycroft   437:                        need_more_resources = 1;
                    438:                }
                    439:                if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) {
1.1       cgd       440: #ifdef MSG_DEBUG_OK
1.3       mycroft   441:                        printf("msgsz + msg_cbytes > msg_qbytes\n");
1.1       cgd       442: #endif
1.3       mycroft   443:                        need_more_resources = 1;
                    444:                }
                    445:                if (segs_needed > nfree_msgmaps) {
1.1       cgd       446: #ifdef MSG_DEBUG_OK
1.3       mycroft   447:                        printf("segs_needed > nfree_msgmaps\n");
1.1       cgd       448: #endif
1.3       mycroft   449:                        need_more_resources = 1;
                    450:                }
                    451:                if (free_msghdrs == NULL) {
1.1       cgd       452: #ifdef MSG_DEBUG_OK
1.3       mycroft   453:                        printf("no more msghdrs\n");
1.1       cgd       454: #endif
1.3       mycroft   455:                        need_more_resources = 1;
                    456:                }
1.1       cgd       457:
1.3       mycroft   458:                if (need_more_resources) {
                    459:                        int we_own_it;
1.1       cgd       460:
1.3       mycroft   461:                        if ((msgflg & IPC_NOWAIT) != 0) {
1.1       cgd       462: #ifdef MSG_DEBUG_OK
1.3       mycroft   463:                                printf("need more resources but caller doesn't want to wait\n");
1.1       cgd       464: #endif
1.3       mycroft   465:                                return(EAGAIN);
                    466:                        }
1.1       cgd       467:
1.3       mycroft   468:                        if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) {
1.1       cgd       469: #ifdef MSG_DEBUG_OK
1.3       mycroft   470:                                printf("we don't own the msqid_ds\n");
1.1       cgd       471: #endif
1.3       mycroft   472:                                we_own_it = 0;
                    473:                        } else {
                    474:                                /* Force later arrivals to wait for our
                    475:                                   request */
1.1       cgd       476: #ifdef MSG_DEBUG_OK
1.3       mycroft   477:                                printf("we own the msqid_ds\n");
1.1       cgd       478: #endif
1.3       mycroft   479:                                msqptr->msg_perm.mode |= MSG_LOCKED;
                    480:                                we_own_it = 1;
                    481:                        }
1.1       cgd       482: #ifdef MSG_DEBUG_OK
1.3       mycroft   483:                        printf("goodnight\n");
1.1       cgd       484: #endif
1.3       mycroft   485:                        eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH,
                    486:                            "msgwait", 0);
1.1       cgd       487: #ifdef MSG_DEBUG_OK
1.3       mycroft   488:                        printf("good morning, eval=%d\n", eval);
1.1       cgd       489: #endif
1.3       mycroft   490:                        if (we_own_it)
                    491:                                msqptr->msg_perm.mode &= ~MSG_LOCKED;
                    492:                        if (eval != 0) {
1.1       cgd       493: #ifdef MSG_DEBUG_OK
1.3       mycroft   494:                                printf("msgsnd:  interrupted system call\n");
1.1       cgd       495: #endif
1.3       mycroft   496:                                return(EINTR);
                    497:                        }
1.1       cgd       498:
1.3       mycroft   499:                        /*
                    500:                         * Make sure that the msq queue still exists
                    501:                         */
1.1       cgd       502:
1.3       mycroft   503:                        if (msqptr->msg_qbytes == 0) {
1.1       cgd       504: #ifdef MSG_DEBUG_OK
1.3       mycroft   505:                                printf("msqid deleted\n");
1.1       cgd       506: #endif
1.3       mycroft   507:                                /* The SVID says to return EIDRM. */
1.1       cgd       508: #ifdef EIDRM
1.3       mycroft   509:                                return(EIDRM);
1.1       cgd       510: #else
1.3       mycroft   511:                                /* Unfortunately, BSD doesn't define that code
                    512:                                   yet! */
                    513:                                return(EINVAL);
1.1       cgd       514: #endif
1.3       mycroft   515:                        }
1.1       cgd       516:
1.3       mycroft   517:                } else {
1.1       cgd       518: #ifdef MSG_DEBUG_OK
1.3       mycroft   519:                        printf("got all the resources that we need\n");
1.1       cgd       520: #endif
1.3       mycroft   521:                        break;
                    522:                }
1.1       cgd       523:        }
                    524:
1.3       mycroft   525:        /*
                    526:         * We have the resources that we need.
                    527:         * Make sure!
                    528:         */
1.1       cgd       529:
1.3       mycroft   530:        if (msqptr->msg_perm.mode & MSG_LOCKED)
                    531:                panic("msg_perm.mode & MSG_LOCKED");
                    532:        if (segs_needed > nfree_msgmaps)
                    533:                panic("segs_needed > nfree_msgmaps");
                    534:        if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes)
                    535:                panic("msgsz + msg_cbytes > msg_qbytes");
                    536:        if (free_msghdrs == NULL)
                    537:                panic("no more msghdrs");
1.1       cgd       538:
1.3       mycroft   539:        /*
                    540:         * Re-lock the msqid_ds in case we page-fault when copying in the
                    541:         * message
                    542:         */
1.1       cgd       543:
1.3       mycroft   544:        if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0)
                    545:                panic("msqid_ds is already locked");
                    546:        msqptr->msg_perm.mode |= MSG_LOCKED;
1.1       cgd       547:
1.3       mycroft   548:        /*
                    549:         * Allocate a message header
                    550:         */
1.1       cgd       551:
1.3       mycroft   552:        msghdr = free_msghdrs;
                    553:        free_msghdrs = msghdr->msg_next;
                    554:        msghdr->msg_spot = -1;
                    555:        msghdr->msg_ts = msgsz;
1.1       cgd       556:
1.3       mycroft   557:        /*
                    558:         * Allocate space for the message
                    559:         */
1.1       cgd       560:
1.3       mycroft   561:        while (segs_needed > 0) {
                    562:                if (nfree_msgmaps <= 0)
                    563:                        panic("not enough msgmaps");
                    564:                if (free_msgmaps == -1)
                    565:                        panic("nil free_msgmaps");
                    566:                next = free_msgmaps;
                    567:                if (next <= -1)
                    568:                        panic("next too low #1");
                    569:                if (next >= msginfo.msgseg)
                    570:                        panic("next out of range #1");
                    571: #ifdef MSG_DEBUG_OK
                    572:                printf("allocating segment %d to message\n", next);
                    573: #endif
                    574:                free_msgmaps = msgmaps[next].next;
1.5       mycroft   575:                nfree_msgmaps--;
1.3       mycroft   576:                msgmaps[next].next = msghdr->msg_spot;
                    577:                msghdr->msg_spot = next;
1.5       mycroft   578:                segs_needed--;
1.1       cgd       579:        }
                    580:
1.3       mycroft   581:        /*
                    582:         * Copy in the message type
                    583:         */
1.1       cgd       584:
1.3       mycroft   585:        if ((eval = copyin(user_msgp, &msghdr->msg_type,
                    586:            sizeof(msghdr->msg_type))) != 0) {
1.1       cgd       587: #ifdef MSG_DEBUG_OK
1.3       mycroft   588:                printf("error %d copying the message type\n", eval);
1.1       cgd       589: #endif
1.3       mycroft   590:                msg_freehdr(msghdr);
                    591:                msqptr->msg_perm.mode &= ~MSG_LOCKED;
                    592:                wakeup((caddr_t)msqptr);
                    593:                return(eval);
                    594:        }
                    595:        user_msgp += sizeof(msghdr->msg_type);
1.1       cgd       596:
1.3       mycroft   597:        /*
                    598:         * Validate the message type
                    599:         */
1.1       cgd       600:
1.3       mycroft   601:        if (msghdr->msg_type < 1) {
                    602:                msg_freehdr(msghdr);
                    603:                msqptr->msg_perm.mode &= ~MSG_LOCKED;
                    604:                wakeup((caddr_t)msqptr);
1.1       cgd       605: #ifdef MSG_DEBUG_OK
1.3       mycroft   606:                printf("mtype (%d) < 1\n", msghdr->msg_type);
1.1       cgd       607: #endif
1.3       mycroft   608:                return(EINVAL);
                    609:        }
1.1       cgd       610:
1.3       mycroft   611:        /*
                    612:         * Copy in the message body
                    613:         */
                    614:
                    615:        next = msghdr->msg_spot;
                    616:        while (msgsz > 0) {
                    617:                size_t tlen;
                    618:                if (msgsz > msginfo.msgssz)
                    619:                        tlen = msginfo.msgssz;
                    620:                else
                    621:                        tlen = msgsz;
                    622:                if (next <= -1)
                    623:                        panic("next too low #2");
                    624:                if (next >= msginfo.msgseg)
                    625:                        panic("next out of range #2");
                    626:                if ((eval = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
                    627:                    tlen)) != 0) {
                    628: #ifdef MSG_DEBUG_OK
                    629:                        printf("error %d copying in message segment\n", eval);
                    630: #endif
                    631:                        msg_freehdr(msghdr);
                    632:                        msqptr->msg_perm.mode &= ~MSG_LOCKED;
                    633:                        wakeup((caddr_t)msqptr);
                    634:                        return(eval);
                    635:                }
                    636:                msgsz -= tlen;
                    637:                user_msgp += tlen;
                    638:                next = msgmaps[next].next;
1.1       cgd       639:        }
1.3       mycroft   640:        if (next != -1)
                    641:                panic("didn't use all the msg segments");
1.1       cgd       642:
1.3       mycroft   643:        /*
                    644:         * We've got the message.  Unlock the msqid_ds.
                    645:         */
1.1       cgd       646:
1.3       mycroft   647:        msqptr->msg_perm.mode &= ~MSG_LOCKED;
1.1       cgd       648:
1.3       mycroft   649:        /*
                    650:         * Make sure that the msqid_ds is still allocated.
                    651:         */
1.1       cgd       652:
1.3       mycroft   653:        if (msqptr->msg_qbytes == 0) {
                    654:                msg_freehdr(msghdr);
                    655:                wakeup((caddr_t)msqptr);
                    656:                /* The SVID says to return EIDRM. */
1.1       cgd       657: #ifdef EIDRM
1.3       mycroft   658:                return(EIDRM);
1.1       cgd       659: #else
1.3       mycroft   660:                /* Unfortunately, BSD doesn't define that code yet! */
                    661:                return(EINVAL);
1.1       cgd       662: #endif
1.3       mycroft   663:        }
                    664:
                    665:        /*
                    666:         * Put the message into the queue
                    667:         */
1.1       cgd       668:
1.3       mycroft   669:        if (msqptr->msg_first == NULL) {
                    670:                msqptr->msg_first = msghdr;
                    671:                msqptr->msg_last = msghdr;
                    672:        } else {
                    673:                msqptr->msg_last->msg_next = msghdr;
                    674:                msqptr->msg_last = msghdr;
                    675:        }
                    676:        msqptr->msg_last->msg_next = NULL;
                    677:
                    678:        msqptr->msg_cbytes += msghdr->msg_ts;
1.5       mycroft   679:        msqptr->msg_qnum++;
1.3       mycroft   680:        msqptr->msg_lspid = p->p_pid;
                    681:        msqptr->msg_stime = time.tv_sec;
                    682:
                    683:        wakeup((caddr_t)msqptr);
                    684:        *retval = 0;
                    685:        return(0);
1.1       cgd       686: }
                    687:
                    688: int
                    689: msgrcv(p, uap, retval)
                    690:        struct proc *p;
1.10      cgd       691:        register struct msgrcv_args /* {
                    692:                syscallarg(int) msqid;
                    693:                syscallarg(void *) msgp;
                    694:                syscallarg(size_t) msgsz;
                    695:                syscallarg(long) msgtyp;
                    696:                syscallarg(int) msgflg;
                    697:        } */ *uap;
                    698:        register_t *retval;
1.1       cgd       699: {
1.10      cgd       700:        int msqid = SCARG(uap, msqid);
                    701:        char *user_msgp = SCARG(uap, msgp);
                    702:        size_t msgsz = SCARG(uap, msgsz);
                    703:        long msgtyp = SCARG(uap, msgtyp);
                    704:        int msgflg = SCARG(uap, msgflg);
1.3       mycroft   705:        size_t len;
                    706:        struct ucred *cred = p->p_ucred;
                    707:        register struct msqid_ds *msqptr;
                    708:        register struct msg *msghdr;
                    709:        int eval;
                    710:        short next;
1.1       cgd       711:
                    712: #ifdef MSG_DEBUG_OK
1.3       mycroft   713:        printf("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp,
                    714:            msgsz, msgtyp, msgflg);
1.1       cgd       715: #endif
                    716:
1.3       mycroft   717:        msqid = IPCID_TO_IX(msqid);
1.1       cgd       718:
1.3       mycroft   719:        if (msqid < 0 || msqid >= msginfo.msgmni) {
1.1       cgd       720: #ifdef MSG_DEBUG_OK
1.3       mycroft   721:                printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
                    722:                    msginfo.msgmni);
1.1       cgd       723: #endif
1.3       mycroft   724:                return(EINVAL);
                    725:        }
1.1       cgd       726:
1.3       mycroft   727:        msqptr = &msqids[msqid];
                    728:        if (msqptr->msg_qbytes == 0) {
1.1       cgd       729: #ifdef MSG_DEBUG_OK
1.3       mycroft   730:                printf("no such message queue id\n");
1.1       cgd       731: #endif
1.3       mycroft   732:                return(EINVAL);
                    733:        }
1.10      cgd       734:        if (msqptr->msg_perm.seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
1.1       cgd       735: #ifdef MSG_DEBUG_OK
1.3       mycroft   736:                printf("wrong sequence number\n");
1.1       cgd       737: #endif
1.3       mycroft   738:                return(EINVAL);
                    739:        }
1.1       cgd       740:
1.6       hpeyerl   741:        if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_R))) {
1.1       cgd       742: #ifdef MSG_DEBUG_OK
1.3       mycroft   743:                printf("requester doesn't have read access\n");
1.1       cgd       744: #endif
1.3       mycroft   745:                return(eval);
                    746:        }
1.1       cgd       747:
1.3       mycroft   748:        if (msgsz < 0) {
1.1       cgd       749: #ifdef MSG_DEBUG_OK
1.3       mycroft   750:                printf("msgsz < 0\n");
1.1       cgd       751: #endif
1.3       mycroft   752:                return(EINVAL);
                    753:        }
1.1       cgd       754:
1.3       mycroft   755:        msghdr = NULL;
                    756:        while (msghdr == NULL) {
                    757:                if (msgtyp == 0) {
                    758:                        msghdr = msqptr->msg_first;
                    759:                        if (msghdr != NULL) {
                    760:                                if (msgsz < msghdr->msg_ts &&
                    761:                                    (msgflg & MSG_NOERROR) == 0) {
                    762: #ifdef MSG_DEBUG_OK
                    763:                                        printf("first message on the queue is too big (want %d, got %d)\n",
                    764:                                            msgsz, msghdr->msg_ts);
                    765: #endif
                    766:                                        return(E2BIG);
                    767:                                }
                    768:                                if (msqptr->msg_first == msqptr->msg_last) {
                    769:                                        msqptr->msg_first = NULL;
                    770:                                        msqptr->msg_last = NULL;
                    771:                                } else {
                    772:                                        msqptr->msg_first = msghdr->msg_next;
                    773:                                        if (msqptr->msg_first == NULL)
                    774:                                                panic("msg_first/last screwed up #1");
                    775:                                }
                    776:                        }
                    777:                } else {
                    778:                        struct msg *previous;
                    779:                        struct msg **prev;
1.1       cgd       780:
1.12    ! mycroft   781:                        for (previous = NULL, prev = &msqptr->msg_first;
        !           782:                             (msghdr = *prev) != NULL;
        !           783:                             previous = msghdr, prev = &msghdr->msg_next) {
1.3       mycroft   784:                                /*
                    785:                                 * Is this message's type an exact match or is
                    786:                                 * this message's type less than or equal to
                    787:                                 * the absolute value of a negative msgtyp?
                    788:                                 * Note that the second half of this test can
                    789:                                 * NEVER be true if msgtyp is positive since
                    790:                                 * msg_type is always positive!
                    791:                                 */
                    792:
                    793:                                if (msgtyp == msghdr->msg_type ||
                    794:                                    msghdr->msg_type <= -msgtyp) {
                    795: #ifdef MSG_DEBUG_OK
                    796:                                        printf("found message type %d, requested %d\n",
                    797:                                            msghdr->msg_type, msgtyp);
                    798: #endif
                    799:                                        if (msgsz < msghdr->msg_ts &&
                    800:                                            (msgflg & MSG_NOERROR) == 0) {
                    801: #ifdef MSG_DEBUG_OK
                    802:                                                printf("requested message on the queue is too big (want %d, got %d)\n",
                    803:                                                    msgsz, msghdr->msg_ts);
                    804: #endif
                    805:                                                return(E2BIG);
                    806:                                        }
                    807:                                        *prev = msghdr->msg_next;
                    808:                                        if (msghdr == msqptr->msg_last) {
                    809:                                                if (previous == NULL) {
                    810:                                                        if (prev !=
                    811:                                                            &msqptr->msg_first)
                    812:                                                                panic("msg_first/last screwed up #2");
                    813:                                                        msqptr->msg_first =
                    814:                                                            NULL;
                    815:                                                        msqptr->msg_last =
                    816:                                                            NULL;
                    817:                                                } else {
                    818:                                                        if (prev ==
                    819:                                                            &msqptr->msg_first)
                    820:                                                                panic("msg_first/last screwed up #3");
                    821:                                                        msqptr->msg_last =
                    822:                                                            previous;
                    823:                                                }
                    824:                                        }
                    825:                                        break;
                    826:                                }
                    827:                        }
1.1       cgd       828:                }
                    829:
1.3       mycroft   830:                /*
                    831:                 * We've either extracted the msghdr for the appropriate
                    832:                 * message or there isn't one.
                    833:                 * If there is one then bail out of this loop.
                    834:                 */
1.1       cgd       835:
1.3       mycroft   836:                if (msghdr != NULL)
                    837:                        break;
1.1       cgd       838:
                    839:                /*
1.3       mycroft   840:                 * Hmph!  No message found.  Does the user want to wait?
1.1       cgd       841:                 */
                    842:
1.3       mycroft   843:                if ((msgflg & IPC_NOWAIT) != 0) {
1.1       cgd       844: #ifdef MSG_DEBUG_OK
1.3       mycroft   845:                        printf("no appropriate message found (msgtyp=%d)\n",
                    846:                            msgtyp);
1.1       cgd       847: #endif
1.3       mycroft   848:                        /* The SVID says to return ENOMSG. */
1.1       cgd       849: #ifdef ENOMSG
1.3       mycroft   850:                        return(ENOMSG);
1.1       cgd       851: #else
1.3       mycroft   852:                        /* Unfortunately, BSD doesn't define that code yet! */
                    853:                        return(EAGAIN);
1.1       cgd       854: #endif
1.3       mycroft   855:                }
1.1       cgd       856:
1.3       mycroft   857:                /*
                    858:                 * Wait for something to happen
                    859:                 */
1.1       cgd       860:
                    861: #ifdef MSG_DEBUG_OK
1.3       mycroft   862:                printf("msgrcv:  goodnight\n");
1.1       cgd       863: #endif
1.3       mycroft   864:                eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH, "msgwait",
                    865:                    0);
1.1       cgd       866: #ifdef MSG_DEBUG_OK
1.3       mycroft   867:                printf("msgrcv:  good morning (eval=%d)\n", eval);
1.1       cgd       868: #endif
                    869:
1.3       mycroft   870:                if (eval != 0) {
1.1       cgd       871: #ifdef MSG_DEBUG_OK
1.3       mycroft   872:                        printf("msgsnd:  interrupted system call\n");
1.1       cgd       873: #endif
1.3       mycroft   874:                        return(EINTR);
                    875:                }
1.1       cgd       876:
1.3       mycroft   877:                /*
                    878:                 * Make sure that the msq queue still exists
                    879:                 */
1.1       cgd       880:
1.3       mycroft   881:                if (msqptr->msg_qbytes == 0 ||
1.10      cgd       882:                    msqptr->msg_perm.seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
1.1       cgd       883: #ifdef MSG_DEBUG_OK
1.3       mycroft   884:                        printf("msqid deleted\n");
1.1       cgd       885: #endif
1.3       mycroft   886:                        /* The SVID says to return EIDRM. */
1.1       cgd       887: #ifdef EIDRM
1.3       mycroft   888:                        return(EIDRM);
1.1       cgd       889: #else
1.3       mycroft   890:                        /* Unfortunately, BSD doesn't define that code yet! */
                    891:                        return(EINVAL);
1.1       cgd       892: #endif
1.3       mycroft   893:                }
1.1       cgd       894:        }
                    895:
1.3       mycroft   896:        /*
                    897:         * Return the message to the user.
                    898:         *
                    899:         * First, do the bookkeeping (before we risk being interrupted).
                    900:         */
1.1       cgd       901:
1.3       mycroft   902:        msqptr->msg_cbytes -= msghdr->msg_ts;
1.5       mycroft   903:        msqptr->msg_qnum--;
1.3       mycroft   904:        msqptr->msg_lrpid = p->p_pid;
                    905:        msqptr->msg_rtime = time.tv_sec;
1.1       cgd       906:
1.3       mycroft   907:        /*
                    908:         * Make msgsz the actual amount that we'll be returning.
                    909:         * Note that this effectively truncates the message if it is too long
                    910:         * (since msgsz is never increased).
                    911:         */
1.1       cgd       912:
                    913: #ifdef MSG_DEBUG_OK
1.3       mycroft   914:        printf("found a message, msgsz=%d, msg_ts=%d\n", msgsz,
                    915:            msghdr->msg_ts);
1.1       cgd       916: #endif
1.3       mycroft   917:        if (msgsz > msghdr->msg_ts)
                    918:                msgsz = msghdr->msg_ts;
1.1       cgd       919:
1.3       mycroft   920:        /*
                    921:         * Return the type to the user.
                    922:         */
1.1       cgd       923:
1.12    ! mycroft   924:        eval = copyout((caddr_t)&msghdr->msg_type, user_msgp,
1.3       mycroft   925:            sizeof(msghdr->msg_type));
                    926:        if (eval != 0) {
1.1       cgd       927: #ifdef MSG_DEBUG_OK
1.3       mycroft   928:                printf("error (%d) copying out message type\n", eval);
1.1       cgd       929: #endif
1.3       mycroft   930:                msg_freehdr(msghdr);
                    931:                wakeup((caddr_t)msqptr);
                    932:                return(eval);
                    933:        }
                    934:        user_msgp += sizeof(msghdr->msg_type);
                    935:
                    936:        /*
                    937:         * Return the segments to the user
                    938:         */
1.1       cgd       939:
1.3       mycroft   940:        next = msghdr->msg_spot;
                    941:        for (len = 0; len < msgsz; len += msginfo.msgssz) {
                    942:                size_t tlen;
                    943:
                    944:                if (msgsz > msginfo.msgssz)
                    945:                        tlen = msginfo.msgssz;
                    946:                else
                    947:                        tlen = msgsz;
                    948:                if (next <= -1)
                    949:                        panic("next too low #3");
                    950:                if (next >= msginfo.msgseg)
                    951:                        panic("next out of range #3");
                    952:                eval = copyout((caddr_t)&msgpool[next * msginfo.msgssz],
                    953:                    user_msgp, tlen);
                    954:                if (eval != 0) {
                    955: #ifdef MSG_DEBUG_OK
                    956:                        printf("error (%d) copying out message segment\n",
                    957:                            eval);
                    958: #endif
                    959:                        msg_freehdr(msghdr);
                    960:                        wakeup((caddr_t)msqptr);
                    961:                        return(eval);
                    962:                }
                    963:                user_msgp += tlen;
                    964:                next = msgmaps[next].next;
1.1       cgd       965:        }
                    966:
1.3       mycroft   967:        /*
                    968:         * Done, return the actual number of bytes copied out.
                    969:         */
1.1       cgd       970:
1.3       mycroft   971:        msg_freehdr(msghdr);
                    972:        wakeup((caddr_t)msqptr);
                    973:        *retval = msgsz;
                    974:        return(0);
1.1       cgd       975: }
1.10      cgd       976:
                    977: #if defined(COMPAT_10) && !defined(alpha)
                    978: int
                    979: compat_10_msgsys(p, uap, retval)
                    980:        struct caller *p;
                    981:        struct compat_10_msgsys_args /* {
                    982:                syscallarg(int) which;
                    983:                syscallarg(int) a2;
                    984:                syscallarg(int) a3;
                    985:                syscallarg(int) a4;
                    986:                syscallarg(int) a5;
                    987:                syscallarg(int) a6;
                    988:        } */ *uap;
                    989:        register_t *retval;
                    990: {
1.11      cgd       991:        struct msgctl_args /* {
1.10      cgd       992:                syscallarg(int) msqid;
                    993:                syscallarg(int) cmd;
                    994:                syscallarg(struct msqid_ds *) buf;
1.11      cgd       995:        } */ msgctl_args;
                    996:        struct msgget_args /* {
1.10      cgd       997:                syscallarg(key_t) key;
                    998:                syscallarg(int) msgflg;
1.11      cgd       999:        } */ msgget_args;
                   1000:        struct msgsnd_args /* {
1.10      cgd      1001:                syscallarg(int) msqid;
                   1002:                syscallarg(void *) msgp;
                   1003:                syscallarg(size_t) msgsz;
                   1004:                syscallarg(int) msgflg;
1.11      cgd      1005:        } */ msgsnd_args;
                   1006:        struct msgrcv_args /* {
1.10      cgd      1007:                syscallarg(int) msqid;
                   1008:                syscallarg(void *) msgp;
                   1009:                syscallarg(size_t) msgsz;
                   1010:                syscallarg(long) msgtyp;
                   1011:                syscallarg(int) msgflg;
1.11      cgd      1012:        } */ msgrcv_args;
1.10      cgd      1013:
                   1014:        switch (SCARG(uap, which)) {
                   1015:        case 0:                                 /* msgctl()*/
                   1016:                SCARG(&msgctl_args, msqid) = SCARG(uap, a2);
                   1017:                SCARG(&msgctl_args, cmd) = SCARG(uap, a3);
                   1018:                SCARG(&msgctl_args, buf) =
                   1019:                    (struct msqid_ds *)SCARG(uap, a4);
                   1020:                return (msgctl(p, &msgctl_args, retval));
                   1021:
                   1022:        case 1:                                 /* msgget() */
1.11      cgd      1023:                SCARG(&msgget_args, key) = SCARG(uap, a2);
                   1024:                SCARG(&msgget_args, msgflg) = SCARG(uap, a3);
1.10      cgd      1025:                return (msgget(p, &msgget_args, retval));
                   1026:
                   1027:        case 2:                                 /* msgsnd() */
                   1028:                SCARG(&msgsnd_args, msqid) = SCARG(uap, a2);
                   1029:                SCARG(&msgsnd_args, msgp) = (void *)SCARG(uap, a3);
                   1030:                SCARG(&msgsnd_args, msgsz) = SCARG(uap, a4);
                   1031:                SCARG(&msgsnd_args, msgflg) = SCARG(uap, a5);
1.11      cgd      1032:                return (msgsnd(p, &msgsnd_args, retval));
1.10      cgd      1033:
                   1034:        case 3:                                 /* msgrcv() */
1.11      cgd      1035:                SCARG(&msgrcv_args, msqid) = SCARG(uap, a2);
                   1036:                SCARG(&msgrcv_args, msgp) = (void *)SCARG(uap, a3);
                   1037:                SCARG(&msgrcv_args, msgsz) = SCARG(uap, a4);
                   1038:                SCARG(&msgrcv_args, msgtyp) = SCARG(uap, a5);
                   1039:                SCARG(&msgrcv_args, msgflg) = SCARG(uap, a6);
                   1040:                return (msgrcv(p, &msgrcv_args, retval));
1.10      cgd      1041:
                   1042:        default:
                   1043:                return (EINVAL);
                   1044:        }
                   1045: }
                   1046: #endif /* defined(COMPAT_10) && !defined(alpha) */

CVSweb <webmaster@jp.NetBSD.org>