Deleted Added
full compact
sysv_msg.c (129882) sysv_msg.c (137613)
1/*
2 * Implementation of SVID messages
3 *
4 * Author: Daniel Boulet
5 *
6 * Copyright 1993 Daniel Boulet and RTMX Inc.
7 *
8 * This system call was implemented by Daniel Boulet under contract from RTMX.

--- 4 unchanged lines hidden (view full) ---

13 * Redistribution in binary form may occur without any restrictions.
14 * Obviously, it would be nice if you gave credit where credit is due
15 * but requiring it would be too onerous.
16 *
17 * This software is provided ``AS IS'' without any warranties of any kind.
18 */
19
20#include <sys/cdefs.h>
1/*
2 * Implementation of SVID messages
3 *
4 * Author: Daniel Boulet
5 *
6 * Copyright 1993 Daniel Boulet and RTMX Inc.
7 *
8 * This system call was implemented by Daniel Boulet under contract from RTMX.

--- 4 unchanged lines hidden (view full) ---

13 * Redistribution in binary form may occur without any restrictions.
14 * Obviously, it would be nice if you gave credit where credit is due
15 * but requiring it would be too onerous.
16 *
17 * This software is provided ``AS IS'' without any warranties of any kind.
18 */
19
20#include <sys/cdefs.h>
21__FBSDID("$FreeBSD: head/sys/kern/sysv_msg.c 129882 2004-05-30 20:34:58Z phk $");
21__FBSDID("$FreeBSD: head/sys/kern/sysv_msg.c 137613 2004-11-12 13:23:47Z rwatson $");
22
23#include "opt_sysvipc.h"
24
25#include <sys/param.h>
26#include <sys/systm.h>
27#include <sys/sysproto.h>
28#include <sys/kernel.h>
29#include <sys/proc.h>

--- 22 unchanged lines hidden (view full) ---

52static void msg_freehdr(struct msg *msghdr);
53
54/* XXX casting to (sy_call_t *) is bogus, as usual. */
55static sy_call_t *msgcalls[] = {
56 (sy_call_t *)msgctl, (sy_call_t *)msgget,
57 (sy_call_t *)msgsnd, (sy_call_t *)msgrcv
58};
59
22
23#include "opt_sysvipc.h"
24
25#include <sys/param.h>
26#include <sys/systm.h>
27#include <sys/sysproto.h>
28#include <sys/kernel.h>
29#include <sys/proc.h>

--- 22 unchanged lines hidden (view full) ---

52static void msg_freehdr(struct msg *msghdr);
53
54/* XXX casting to (sy_call_t *) is bogus, as usual. */
55static sy_call_t *msgcalls[] = {
56 (sy_call_t *)msgctl, (sy_call_t *)msgget,
57 (sy_call_t *)msgsnd, (sy_call_t *)msgrcv
58};
59
60struct msg {
61 struct msg *msg_next; /* next msg in the chain */
62 long msg_type; /* type of this message */
63 /* >0 -> type of this message */
64 /* 0 -> free header */
65 u_short msg_ts; /* size of this message */
66 short msg_spot; /* location of start of msg in buffer */
67};
68
69
70#ifndef MSGSSZ
71#define MSGSSZ 8 /* Each segment must be 2^N long */
72#endif
73#ifndef MSGSEG
74#define MSGSEG 2048 /* must be less than 32767 */
75#endif
76#define MSGMAX (MSGSSZ*MSGSEG)
77#ifndef MSGMNB

--- 47 unchanged lines hidden (view full) ---

125#define MSG_LOCKED 01000 /* Is this msqid_ds locked? */
126
127static int nfree_msgmaps; /* # of free map entries */
128static short free_msgmaps; /* head of linked list of free map entries */
129static struct msg *free_msghdrs;/* list of free msg headers */
130static char *msgpool; /* MSGMAX byte long msg buffer pool */
131static struct msgmap *msgmaps; /* MSGSEG msgmap structures */
132static struct msg *msghdrs; /* MSGTQL msg headers */
60#ifndef MSGSSZ
61#define MSGSSZ 8 /* Each segment must be 2^N long */
62#endif
63#ifndef MSGSEG
64#define MSGSEG 2048 /* must be less than 32767 */
65#endif
66#define MSGMAX (MSGSSZ*MSGSEG)
67#ifndef MSGMNB

--- 47 unchanged lines hidden (view full) ---

115#define MSG_LOCKED 01000 /* Is this msqid_ds locked? */
116
117static int nfree_msgmaps; /* # of free map entries */
118static short free_msgmaps; /* head of linked list of free map entries */
119static struct msg *free_msghdrs;/* list of free msg headers */
120static char *msgpool; /* MSGMAX byte long msg buffer pool */
121static struct msgmap *msgmaps; /* MSGSEG msgmap structures */
122static struct msg *msghdrs; /* MSGTQL msg headers */
133static struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */
123static struct msqid_kernel *msqids; /* MSGMNI msqid_kernel struct's */
134static struct mtx msq_mtx; /* global mutex for message queues. */
135
136static void
137msginit()
138{
139 register int i;
140
141 TUNABLE_INT_FETCH("kern.ipc.msgseg", &msginfo.msgseg);

--- 5 unchanged lines hidden (view full) ---

147 if (msgpool == NULL)
148 panic("msgpool is NULL");
149 msgmaps = malloc(sizeof(struct msgmap) * msginfo.msgseg, M_MSG, M_WAITOK);
150 if (msgmaps == NULL)
151 panic("msgmaps is NULL");
152 msghdrs = malloc(sizeof(struct msg) * msginfo.msgtql, M_MSG, M_WAITOK);
153 if (msghdrs == NULL)
154 panic("msghdrs is NULL");
124static struct mtx msq_mtx; /* global mutex for message queues. */
125
126static void
127msginit()
128{
129 register int i;
130
131 TUNABLE_INT_FETCH("kern.ipc.msgseg", &msginfo.msgseg);

--- 5 unchanged lines hidden (view full) ---

137 if (msgpool == NULL)
138 panic("msgpool is NULL");
139 msgmaps = malloc(sizeof(struct msgmap) * msginfo.msgseg, M_MSG, M_WAITOK);
140 if (msgmaps == NULL)
141 panic("msgmaps is NULL");
142 msghdrs = malloc(sizeof(struct msg) * msginfo.msgtql, M_MSG, M_WAITOK);
143 if (msghdrs == NULL)
144 panic("msghdrs is NULL");
155 msqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni, M_MSG, M_WAITOK);
145 msqids = malloc(sizeof(struct msqid_kernel) * msginfo.msgmni, M_MSG,
146 M_WAITOK);
156 if (msqids == NULL)
157 panic("msqids is NULL");
158
159 /*
160 * msginfo.msgssz should be a power of two for efficiency reasons.
161 * It is also pretty silly if msginfo.msgssz is less than 8
162 * or greater than about 256 so ...
163 */

--- 33 unchanged lines hidden (view full) ---

197 msghdrs[i].msg_next = NULL;
198 }
199 free_msghdrs = &msghdrs[0];
200
201 if (msqids == NULL)
202 panic("msqids is NULL");
203
204 for (i = 0; i < msginfo.msgmni; i++) {
147 if (msqids == NULL)
148 panic("msqids is NULL");
149
150 /*
151 * msginfo.msgssz should be a power of two for efficiency reasons.
152 * It is also pretty silly if msginfo.msgssz is less than 8
153 * or greater than about 256 so ...
154 */

--- 33 unchanged lines hidden (view full) ---

188 msghdrs[i].msg_next = NULL;
189 }
190 free_msghdrs = &msghdrs[0];
191
192 if (msqids == NULL)
193 panic("msqids is NULL");
194
195 for (i = 0; i < msginfo.msgmni; i++) {
205 msqids[i].msg_qbytes = 0; /* implies entry is available */
206 msqids[i].msg_perm.seq = 0; /* reset to a known value */
207 msqids[i].msg_perm.mode = 0;
196 msqids[i].u.msg_qbytes = 0; /* implies entry is available */
197 msqids[i].u.msg_perm.seq = 0; /* reset to a known value */
198 msqids[i].u.msg_perm.mode = 0;
208 }
209 mtx_init(&msq_mtx, "msq", NULL, MTX_DEF);
210}
211
212static int
213msgunload()
214{
199 }
200 mtx_init(&msq_mtx, "msq", NULL, MTX_DEF);
201}
202
203static int
204msgunload()
205{
215 struct msqid_ds *msqptr;
206 struct msqid_kernel *msqkptr;
216 int msqid;
217
218 for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
219 /*
220 * Look for an unallocated and unlocked msqid_ds.
221 * msqid_ds's can be locked by msgsnd or msgrcv while
222 * they are copying the message in/out. We can't
223 * re-use the entry until they release it.
224 */
207 int msqid;
208
209 for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
210 /*
211 * Look for an unallocated and unlocked msqid_ds.
212 * msqid_ds's can be locked by msgsnd or msgrcv while
213 * they are copying the message in/out. We can't
214 * re-use the entry until they release it.
215 */
225 msqptr = &msqids[msqid];
226 if (msqptr->msg_qbytes != 0 ||
227 (msqptr->msg_perm.mode & MSG_LOCKED) != 0)
216 msqkptr = &msqids[msqid];
217 if (msqkptr->u.msg_qbytes != 0 ||
218 (msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0)
228 break;
229 }
230 if (msqid != msginfo.msgmni)
231 return (EBUSY);
232
233 free(msgpool, M_MSG);
234 free(msgmaps, M_MSG);
235 free(msghdrs, M_MSG);

--- 109 unchanged lines hidden (view full) ---

345 struct thread *td;
346 register struct msgctl_args *uap;
347{
348 int msqid = uap->msqid;
349 int cmd = uap->cmd;
350 struct msqid_ds *user_msqptr = uap->buf;
351 int rval, error;
352 struct msqid_ds msqbuf;
219 break;
220 }
221 if (msqid != msginfo.msgmni)
222 return (EBUSY);
223
224 free(msgpool, M_MSG);
225 free(msgmaps, M_MSG);
226 free(msghdrs, M_MSG);

--- 109 unchanged lines hidden (view full) ---

336 struct thread *td;
337 register struct msgctl_args *uap;
338{
339 int msqid = uap->msqid;
340 int cmd = uap->cmd;
341 struct msqid_ds *user_msqptr = uap->buf;
342 int rval, error;
343 struct msqid_ds msqbuf;
353 register struct msqid_ds *msqptr;
344 register struct msqid_kernel *msqkptr;
354
355 DPRINTF(("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr));
356 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
357 return (ENOSYS);
358
359 msqid = IPCID_TO_IX(msqid);
360
361 if (msqid < 0 || msqid >= msginfo.msgmni) {
362 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
363 msginfo.msgmni));
364 return (EINVAL);
365 }
366 if (cmd == IPC_SET &&
367 (error = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
368 return (error);
369
345
346 DPRINTF(("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr));
347 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
348 return (ENOSYS);
349
350 msqid = IPCID_TO_IX(msqid);
351
352 if (msqid < 0 || msqid >= msginfo.msgmni) {
353 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
354 msginfo.msgmni));
355 return (EINVAL);
356 }
357 if (cmd == IPC_SET &&
358 (error = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
359 return (error);
360
370 msqptr = &msqids[msqid];
361 msqkptr = &msqids[msqid];
371
372 mtx_lock(&msq_mtx);
362
363 mtx_lock(&msq_mtx);
373 if (msqptr->msg_qbytes == 0) {
364 if (msqkptr->u.msg_qbytes == 0) {
374 DPRINTF(("no such msqid\n"));
375 error = EINVAL;
376 goto done2;
377 }
365 DPRINTF(("no such msqid\n"));
366 error = EINVAL;
367 goto done2;
368 }
378 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
369 if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
379 DPRINTF(("wrong sequence number\n"));
380 error = EINVAL;
381 goto done2;
382 }
383
384 error = 0;
385 rval = 0;
386
387 switch (cmd) {
388
389 case IPC_RMID:
390 {
391 struct msg *msghdr;
370 DPRINTF(("wrong sequence number\n"));
371 error = EINVAL;
372 goto done2;
373 }
374
375 error = 0;
376 rval = 0;
377
378 switch (cmd) {
379
380 case IPC_RMID:
381 {
382 struct msg *msghdr;
392 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_M)))
383 if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_M)))
393 goto done2;
384 goto done2;
385
394 /* Free the message headers */
386 /* Free the message headers */
395 msghdr = msqptr->msg_first;
387 msghdr = msqkptr->u.msg_first;
396 while (msghdr != NULL) {
397 struct msg *msghdr_tmp;
398
399 /* Free the segments of each message */
388 while (msghdr != NULL) {
389 struct msg *msghdr_tmp;
390
391 /* Free the segments of each message */
400 msqptr->msg_cbytes -= msghdr->msg_ts;
401 msqptr->msg_qnum--;
392 msqkptr->u.msg_cbytes -= msghdr->msg_ts;
393 msqkptr->u.msg_qnum--;
402 msghdr_tmp = msghdr;
403 msghdr = msghdr->msg_next;
404 msg_freehdr(msghdr_tmp);
405 }
406
394 msghdr_tmp = msghdr;
395 msghdr = msghdr->msg_next;
396 msg_freehdr(msghdr_tmp);
397 }
398
407 if (msqptr->msg_cbytes != 0)
399 if (msqkptr->u.msg_cbytes != 0)
408 panic("msg_cbytes is screwed up");
400 panic("msg_cbytes is screwed up");
409 if (msqptr->msg_qnum != 0)
401 if (msqkptr->u.msg_qnum != 0)
410 panic("msg_qnum is screwed up");
411
402 panic("msg_qnum is screwed up");
403
412 msqptr->msg_qbytes = 0; /* Mark it as free */
404 msqkptr->u.msg_qbytes = 0; /* Mark it as free */
413
405
414 wakeup(msqptr);
406 wakeup(msqkptr);
415 }
416
417 break;
418
419 case IPC_SET:
407 }
408
409 break;
410
411 case IPC_SET:
420 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_M)))
412 if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_M)))
421 goto done2;
413 goto done2;
422 if (msqbuf.msg_qbytes > msqptr->msg_qbytes) {
414 if (msqbuf.msg_qbytes > msqkptr->u.msg_qbytes) {
423 error = suser(td);
424 if (error)
425 goto done2;
426 }
427 if (msqbuf.msg_qbytes > msginfo.msgmnb) {
428 DPRINTF(("can't increase msg_qbytes beyond %d"
429 "(truncating)\n", msginfo.msgmnb));
430 msqbuf.msg_qbytes = msginfo.msgmnb; /* silently restrict qbytes to system limit */
431 }
432 if (msqbuf.msg_qbytes == 0) {
433 DPRINTF(("can't reduce msg_qbytes to 0\n"));
434 error = EINVAL; /* non-standard errno! */
435 goto done2;
436 }
415 error = suser(td);
416 if (error)
417 goto done2;
418 }
419 if (msqbuf.msg_qbytes > msginfo.msgmnb) {
420 DPRINTF(("can't increase msg_qbytes beyond %d"
421 "(truncating)\n", msginfo.msgmnb));
422 msqbuf.msg_qbytes = msginfo.msgmnb; /* silently restrict qbytes to system limit */
423 }
424 if (msqbuf.msg_qbytes == 0) {
425 DPRINTF(("can't reduce msg_qbytes to 0\n"));
426 error = EINVAL; /* non-standard errno! */
427 goto done2;
428 }
437 msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */
438 msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */
439 msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) |
429 msqkptr->u.msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */
430 msqkptr->u.msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */
431 msqkptr->u.msg_perm.mode = (msqkptr->u.msg_perm.mode & ~0777) |
440 (msqbuf.msg_perm.mode & 0777);
432 (msqbuf.msg_perm.mode & 0777);
441 msqptr->msg_qbytes = msqbuf.msg_qbytes;
442 msqptr->msg_ctime = time_second;
433 msqkptr->u.msg_qbytes = msqbuf.msg_qbytes;
434 msqkptr->u.msg_ctime = time_second;
443 break;
444
445 case IPC_STAT:
435 break;
436
437 case IPC_STAT:
446 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_R))) {
438 if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_R))) {
447 DPRINTF(("requester doesn't have read access\n"));
448 goto done2;
449 }
450 break;
451
452 default:
453 DPRINTF(("invalid command %d\n", cmd));
454 error = EINVAL;
455 goto done2;
456 }
457
458 if (error == 0)
459 td->td_retval[0] = rval;
460done2:
461 mtx_unlock(&msq_mtx);
462 if (cmd == IPC_STAT && error == 0)
439 DPRINTF(("requester doesn't have read access\n"));
440 goto done2;
441 }
442 break;
443
444 default:
445 DPRINTF(("invalid command %d\n", cmd));
446 error = EINVAL;
447 goto done2;
448 }
449
450 if (error == 0)
451 td->td_retval[0] = rval;
452done2:
453 mtx_unlock(&msq_mtx);
454 if (cmd == IPC_STAT && error == 0)
463 error = copyout(msqptr, user_msqptr, sizeof(struct msqid_ds));
455 error = copyout(&(msqkptr->u), user_msqptr, sizeof(struct msqid_ds));
464 return(error);
465}
466
467#ifndef _SYS_SYSPROTO_H_
468struct msgget_args {
469 key_t key;
470 int msgflg;
471};

--- 6 unchanged lines hidden (view full) ---

478msgget(td, uap)
479 struct thread *td;
480 register struct msgget_args *uap;
481{
482 int msqid, error = 0;
483 int key = uap->key;
484 int msgflg = uap->msgflg;
485 struct ucred *cred = td->td_ucred;
456 return(error);
457}
458
459#ifndef _SYS_SYSPROTO_H_
460struct msgget_args {
461 key_t key;
462 int msgflg;
463};

--- 6 unchanged lines hidden (view full) ---

470msgget(td, uap)
471 struct thread *td;
472 register struct msgget_args *uap;
473{
474 int msqid, error = 0;
475 int key = uap->key;
476 int msgflg = uap->msgflg;
477 struct ucred *cred = td->td_ucred;
486 register struct msqid_ds *msqptr = NULL;
478 register struct msqid_kernel *msqkptr = NULL;
487
488 DPRINTF(("msgget(0x%x, 0%o)\n", key, msgflg));
489
490 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
491 return (ENOSYS);
492
493 mtx_lock(&msq_mtx);
494 if (key != IPC_PRIVATE) {
495 for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
479
480 DPRINTF(("msgget(0x%x, 0%o)\n", key, msgflg));
481
482 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
483 return (ENOSYS);
484
485 mtx_lock(&msq_mtx);
486 if (key != IPC_PRIVATE) {
487 for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
496 msqptr = &msqids[msqid];
497 if (msqptr->msg_qbytes != 0 &&
498 msqptr->msg_perm.key == key)
488 msqkptr = &msqids[msqid];
489 if (msqkptr->u.msg_qbytes != 0 &&
490 msqkptr->u.msg_perm.key == key)
499 break;
500 }
501 if (msqid < msginfo.msgmni) {
502 DPRINTF(("found public key\n"));
503 if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) {
504 DPRINTF(("not exclusive\n"));
505 error = EEXIST;
506 goto done2;
507 }
491 break;
492 }
493 if (msqid < msginfo.msgmni) {
494 DPRINTF(("found public key\n"));
495 if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) {
496 DPRINTF(("not exclusive\n"));
497 error = EEXIST;
498 goto done2;
499 }
508 if ((error = ipcperm(td, &msqptr->msg_perm, msgflg & 0700))) {
500 if ((error = ipcperm(td, &msqkptr->u.msg_perm,
501 msgflg & 0700))) {
509 DPRINTF(("requester doesn't have 0%o access\n",
510 msgflg & 0700));
511 goto done2;
512 }
513 goto found;
514 }
515 }
516
517 DPRINTF(("need to allocate the msqid_ds\n"));
518 if (key == IPC_PRIVATE || (msgflg & IPC_CREAT)) {
519 for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
520 /*
521 * Look for an unallocated and unlocked msqid_ds.
522 * msqid_ds's can be locked by msgsnd or msgrcv while
523 * they are copying the message in/out. We can't
524 * re-use the entry until they release it.
525 */
502 DPRINTF(("requester doesn't have 0%o access\n",
503 msgflg & 0700));
504 goto done2;
505 }
506 goto found;
507 }
508 }
509
510 DPRINTF(("need to allocate the msqid_ds\n"));
511 if (key == IPC_PRIVATE || (msgflg & IPC_CREAT)) {
512 for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
513 /*
514 * Look for an unallocated and unlocked msqid_ds.
515 * msqid_ds's can be locked by msgsnd or msgrcv while
516 * they are copying the message in/out. We can't
517 * re-use the entry until they release it.
518 */
526 msqptr = &msqids[msqid];
527 if (msqptr->msg_qbytes == 0 &&
528 (msqptr->msg_perm.mode & MSG_LOCKED) == 0)
519 msqkptr = &msqids[msqid];
520 if (msqkptr->u.msg_qbytes == 0 &&
521 (msqkptr->u.msg_perm.mode & MSG_LOCKED) == 0)
529 break;
530 }
531 if (msqid == msginfo.msgmni) {
532 DPRINTF(("no more msqid_ds's available\n"));
533 error = ENOSPC;
534 goto done2;
535 }
536 DPRINTF(("msqid %d is available\n", msqid));
522 break;
523 }
524 if (msqid == msginfo.msgmni) {
525 DPRINTF(("no more msqid_ds's available\n"));
526 error = ENOSPC;
527 goto done2;
528 }
529 DPRINTF(("msqid %d is available\n", msqid));
537 msqptr->msg_perm.key = key;
538 msqptr->msg_perm.cuid = cred->cr_uid;
539 msqptr->msg_perm.uid = cred->cr_uid;
540 msqptr->msg_perm.cgid = cred->cr_gid;
541 msqptr->msg_perm.gid = cred->cr_gid;
542 msqptr->msg_perm.mode = (msgflg & 0777);
530 msqkptr->u.msg_perm.key = key;
531 msqkptr->u.msg_perm.cuid = cred->cr_uid;
532 msqkptr->u.msg_perm.uid = cred->cr_uid;
533 msqkptr->u.msg_perm.cgid = cred->cr_gid;
534 msqkptr->u.msg_perm.gid = cred->cr_gid;
535 msqkptr->u.msg_perm.mode = (msgflg & 0777);
543 /* Make sure that the returned msqid is unique */
536 /* Make sure that the returned msqid is unique */
544 msqptr->msg_perm.seq = (msqptr->msg_perm.seq + 1) & 0x7fff;
545 msqptr->msg_first = NULL;
546 msqptr->msg_last = NULL;
547 msqptr->msg_cbytes = 0;
548 msqptr->msg_qnum = 0;
549 msqptr->msg_qbytes = msginfo.msgmnb;
550 msqptr->msg_lspid = 0;
551 msqptr->msg_lrpid = 0;
552 msqptr->msg_stime = 0;
553 msqptr->msg_rtime = 0;
554 msqptr->msg_ctime = time_second;
537 msqkptr->u.msg_perm.seq = (msqkptr->u.msg_perm.seq + 1) & 0x7fff;
538 msqkptr->u.msg_first = NULL;
539 msqkptr->u.msg_last = NULL;
540 msqkptr->u.msg_cbytes = 0;
541 msqkptr->u.msg_qnum = 0;
542 msqkptr->u.msg_qbytes = msginfo.msgmnb;
543 msqkptr->u.msg_lspid = 0;
544 msqkptr->u.msg_lrpid = 0;
545 msqkptr->u.msg_stime = 0;
546 msqkptr->u.msg_rtime = 0;
547 msqkptr->u.msg_ctime = time_second;
555 } else {
556 DPRINTF(("didn't find it and wasn't asked to create it\n"));
557 error = ENOENT;
558 goto done2;
559 }
560
561found:
562 /* Construct the unique msqid */
548 } else {
549 DPRINTF(("didn't find it and wasn't asked to create it\n"));
550 error = ENOENT;
551 goto done2;
552 }
553
554found:
555 /* Construct the unique msqid */
563 td->td_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);
556 td->td_retval[0] = IXSEQ_TO_IPCID(msqid, msqkptr->u.msg_perm);
564done2:
565 mtx_unlock(&msq_mtx);
566 return (error);
567}
568
569#ifndef _SYS_SYSPROTO_H_
570struct msgsnd_args {
571 int msqid;

--- 11 unchanged lines hidden (view full) ---

583 struct thread *td;
584 register struct msgsnd_args *uap;
585{
586 int msqid = uap->msqid;
587 const void *user_msgp = uap->msgp;
588 size_t msgsz = uap->msgsz;
589 int msgflg = uap->msgflg;
590 int segs_needed, error = 0;
557done2:
558 mtx_unlock(&msq_mtx);
559 return (error);
560}
561
562#ifndef _SYS_SYSPROTO_H_
563struct msgsnd_args {
564 int msqid;

--- 11 unchanged lines hidden (view full) ---

576 struct thread *td;
577 register struct msgsnd_args *uap;
578{
579 int msqid = uap->msqid;
580 const void *user_msgp = uap->msgp;
581 size_t msgsz = uap->msgsz;
582 int msgflg = uap->msgflg;
583 int segs_needed, error = 0;
591 register struct msqid_ds *msqptr;
584 register struct msqid_kernel *msqkptr;
592 register struct msg *msghdr;
593 short next;
594
595 DPRINTF(("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
596 msgflg));
597 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
598 return (ENOSYS);
599
600 mtx_lock(&msq_mtx);
601 msqid = IPCID_TO_IX(msqid);
602
603 if (msqid < 0 || msqid >= msginfo.msgmni) {
604 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
605 msginfo.msgmni));
606 error = EINVAL;
607 goto done2;
608 }
609
585 register struct msg *msghdr;
586 short next;
587
588 DPRINTF(("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
589 msgflg));
590 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
591 return (ENOSYS);
592
593 mtx_lock(&msq_mtx);
594 msqid = IPCID_TO_IX(msqid);
595
596 if (msqid < 0 || msqid >= msginfo.msgmni) {
597 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
598 msginfo.msgmni));
599 error = EINVAL;
600 goto done2;
601 }
602
610 msqptr = &msqids[msqid];
611 if (msqptr->msg_qbytes == 0) {
603 msqkptr = &msqids[msqid];
604 if (msqkptr->u.msg_qbytes == 0) {
612 DPRINTF(("no such message queue id\n"));
613 error = EINVAL;
614 goto done2;
615 }
605 DPRINTF(("no such message queue id\n"));
606 error = EINVAL;
607 goto done2;
608 }
616 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
609 if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
617 DPRINTF(("wrong sequence number\n"));
618 error = EINVAL;
619 goto done2;
620 }
621
610 DPRINTF(("wrong sequence number\n"));
611 error = EINVAL;
612 goto done2;
613 }
614
622 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_W))) {
615 if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_W))) {
623 DPRINTF(("requester doesn't have write access\n"));
624 goto done2;
625 }
626
627 segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
628 DPRINTF(("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz,
629 segs_needed));
630 for (;;) {
631 int need_more_resources = 0;
632
633 /*
634 * check msgsz
635 * (inside this loop in case msg_qbytes changes while we sleep)
636 */
637
616 DPRINTF(("requester doesn't have write access\n"));
617 goto done2;
618 }
619
620 segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
621 DPRINTF(("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz,
622 segs_needed));
623 for (;;) {
624 int need_more_resources = 0;
625
626 /*
627 * check msgsz
628 * (inside this loop in case msg_qbytes changes while we sleep)
629 */
630
638 if (msgsz > msqptr->msg_qbytes) {
639 DPRINTF(("msgsz > msqptr->msg_qbytes\n"));
631 if (msgsz > msqkptr->u.msg_qbytes) {
632 DPRINTF(("msgsz > msqkptr->u.msg_qbytes\n"));
640 error = EINVAL;
641 goto done2;
642 }
643
633 error = EINVAL;
634 goto done2;
635 }
636
644 if (msqptr->msg_perm.mode & MSG_LOCKED) {
637 if (msqkptr->u.msg_perm.mode & MSG_LOCKED) {
645 DPRINTF(("msqid is locked\n"));
646 need_more_resources = 1;
647 }
638 DPRINTF(("msqid is locked\n"));
639 need_more_resources = 1;
640 }
648 if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) {
641 if (msgsz + msqkptr->u.msg_cbytes > msqkptr->u.msg_qbytes) {
649 DPRINTF(("msgsz + msg_cbytes > msg_qbytes\n"));
650 need_more_resources = 1;
651 }
652 if (segs_needed > nfree_msgmaps) {
653 DPRINTF(("segs_needed > nfree_msgmaps\n"));
654 need_more_resources = 1;
655 }
656 if (free_msghdrs == NULL) {

--- 6 unchanged lines hidden (view full) ---

663
664 if ((msgflg & IPC_NOWAIT) != 0) {
665 DPRINTF(("need more resources but caller "
666 "doesn't want to wait\n"));
667 error = EAGAIN;
668 goto done2;
669 }
670
642 DPRINTF(("msgsz + msg_cbytes > msg_qbytes\n"));
643 need_more_resources = 1;
644 }
645 if (segs_needed > nfree_msgmaps) {
646 DPRINTF(("segs_needed > nfree_msgmaps\n"));
647 need_more_resources = 1;
648 }
649 if (free_msghdrs == NULL) {

--- 6 unchanged lines hidden (view full) ---

656
657 if ((msgflg & IPC_NOWAIT) != 0) {
658 DPRINTF(("need more resources but caller "
659 "doesn't want to wait\n"));
660 error = EAGAIN;
661 goto done2;
662 }
663
671 if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) {
664 if ((msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0) {
672 DPRINTF(("we don't own the msqid_ds\n"));
673 we_own_it = 0;
674 } else {
675 /* Force later arrivals to wait for our
676 request */
677 DPRINTF(("we own the msqid_ds\n"));
665 DPRINTF(("we don't own the msqid_ds\n"));
666 we_own_it = 0;
667 } else {
668 /* Force later arrivals to wait for our
669 request */
670 DPRINTF(("we own the msqid_ds\n"));
678 msqptr->msg_perm.mode |= MSG_LOCKED;
671 msqkptr->u.msg_perm.mode |= MSG_LOCKED;
679 we_own_it = 1;
680 }
681 DPRINTF(("goodnight\n"));
672 we_own_it = 1;
673 }
674 DPRINTF(("goodnight\n"));
682 error = msleep(msqptr, &msq_mtx, (PZERO - 4) | PCATCH,
675 error = msleep(msqkptr, &msq_mtx, (PZERO - 4) | PCATCH,
683 "msgwait", 0);
684 DPRINTF(("good morning, error=%d\n", error));
685 if (we_own_it)
676 "msgwait", 0);
677 DPRINTF(("good morning, error=%d\n", error));
678 if (we_own_it)
686 msqptr->msg_perm.mode &= ~MSG_LOCKED;
679 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
687 if (error != 0) {
688 DPRINTF(("msgsnd: interrupted system call\n"));
689 error = EINTR;
690 goto done2;
691 }
692
693 /*
694 * Make sure that the msq queue still exists
695 */
696
680 if (error != 0) {
681 DPRINTF(("msgsnd: interrupted system call\n"));
682 error = EINTR;
683 goto done2;
684 }
685
686 /*
687 * Make sure that the msq queue still exists
688 */
689
697 if (msqptr->msg_qbytes == 0) {
690 if (msqkptr->u.msg_qbytes == 0) {
698 DPRINTF(("msqid deleted\n"));
699 error = EIDRM;
700 goto done2;
701 }
702
703 } else {
704 DPRINTF(("got all the resources that we need\n"));
705 break;
706 }
707 }
708
709 /*
710 * We have the resources that we need.
711 * Make sure!
712 */
713
691 DPRINTF(("msqid deleted\n"));
692 error = EIDRM;
693 goto done2;
694 }
695
696 } else {
697 DPRINTF(("got all the resources that we need\n"));
698 break;
699 }
700 }
701
702 /*
703 * We have the resources that we need.
704 * Make sure!
705 */
706
714 if (msqptr->msg_perm.mode & MSG_LOCKED)
707 if (msqkptr->u.msg_perm.mode & MSG_LOCKED)
715 panic("msg_perm.mode & MSG_LOCKED");
716 if (segs_needed > nfree_msgmaps)
717 panic("segs_needed > nfree_msgmaps");
708 panic("msg_perm.mode & MSG_LOCKED");
709 if (segs_needed > nfree_msgmaps)
710 panic("segs_needed > nfree_msgmaps");
718 if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes)
711 if (msgsz + msqkptr->u.msg_cbytes > msqkptr->u.msg_qbytes)
719 panic("msgsz + msg_cbytes > msg_qbytes");
720 if (free_msghdrs == NULL)
721 panic("no more msghdrs");
722
723 /*
724 * Re-lock the msqid_ds in case we page-fault when copying in the
725 * message
726 */
727
712 panic("msgsz + msg_cbytes > msg_qbytes");
713 if (free_msghdrs == NULL)
714 panic("no more msghdrs");
715
716 /*
717 * Re-lock the msqid_ds in case we page-fault when copying in the
718 * message
719 */
720
728 if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0)
721 if ((msqkptr->u.msg_perm.mode & MSG_LOCKED) != 0)
729 panic("msqid_ds is already locked");
722 panic("msqid_ds is already locked");
730 msqptr->msg_perm.mode |= MSG_LOCKED;
723 msqkptr->u.msg_perm.mode |= MSG_LOCKED;
731
732 /*
733 * Allocate a message header
734 */
735
736 msghdr = free_msghdrs;
737 free_msghdrs = msghdr->msg_next;
738 msghdr->msg_spot = -1;

--- 26 unchanged lines hidden (view full) ---

765 */
766
767 mtx_unlock(&msq_mtx);
768 if ((error = copyin(user_msgp, &msghdr->msg_type,
769 sizeof(msghdr->msg_type))) != 0) {
770 mtx_lock(&msq_mtx);
771 DPRINTF(("error %d copying the message type\n", error));
772 msg_freehdr(msghdr);
724
725 /*
726 * Allocate a message header
727 */
728
729 msghdr = free_msghdrs;
730 free_msghdrs = msghdr->msg_next;
731 msghdr->msg_spot = -1;

--- 26 unchanged lines hidden (view full) ---

758 */
759
760 mtx_unlock(&msq_mtx);
761 if ((error = copyin(user_msgp, &msghdr->msg_type,
762 sizeof(msghdr->msg_type))) != 0) {
763 mtx_lock(&msq_mtx);
764 DPRINTF(("error %d copying the message type\n", error));
765 msg_freehdr(msghdr);
773 msqptr->msg_perm.mode &= ~MSG_LOCKED;
774 wakeup(msqptr);
766 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
767 wakeup(msqkptr);
775 goto done2;
776 }
777 mtx_lock(&msq_mtx);
778 user_msgp = (const char *)user_msgp + sizeof(msghdr->msg_type);
779
780 /*
781 * Validate the message type
782 */
783
784 if (msghdr->msg_type < 1) {
785 msg_freehdr(msghdr);
768 goto done2;
769 }
770 mtx_lock(&msq_mtx);
771 user_msgp = (const char *)user_msgp + sizeof(msghdr->msg_type);
772
773 /*
774 * Validate the message type
775 */
776
777 if (msghdr->msg_type < 1) {
778 msg_freehdr(msghdr);
786 msqptr->msg_perm.mode &= ~MSG_LOCKED;
787 wakeup(msqptr);
779 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
780 wakeup(msqkptr);
788 DPRINTF(("mtype (%d) < 1\n", msghdr->msg_type));
789 error = EINVAL;
790 goto done2;
791 }
792
793 /*
794 * Copy in the message body
795 */

--- 11 unchanged lines hidden (view full) ---

807 panic("next out of range #2");
808 mtx_unlock(&msq_mtx);
809 if ((error = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
810 tlen)) != 0) {
811 mtx_lock(&msq_mtx);
812 DPRINTF(("error %d copying in message segment\n",
813 error));
814 msg_freehdr(msghdr);
781 DPRINTF(("mtype (%d) < 1\n", msghdr->msg_type));
782 error = EINVAL;
783 goto done2;
784 }
785
786 /*
787 * Copy in the message body
788 */

--- 11 unchanged lines hidden (view full) ---

800 panic("next out of range #2");
801 mtx_unlock(&msq_mtx);
802 if ((error = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
803 tlen)) != 0) {
804 mtx_lock(&msq_mtx);
805 DPRINTF(("error %d copying in message segment\n",
806 error));
807 msg_freehdr(msghdr);
815 msqptr->msg_perm.mode &= ~MSG_LOCKED;
816 wakeup(msqptr);
808 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
809 wakeup(msqkptr);
817 goto done2;
818 }
819 mtx_lock(&msq_mtx);
820 msgsz -= tlen;
821 user_msgp = (const char *)user_msgp + tlen;
822 next = msgmaps[next].next;
823 }
824 if (next != -1)
825 panic("didn't use all the msg segments");
826
827 /*
828 * We've got the message. Unlock the msqid_ds.
829 */
830
810 goto done2;
811 }
812 mtx_lock(&msq_mtx);
813 msgsz -= tlen;
814 user_msgp = (const char *)user_msgp + tlen;
815 next = msgmaps[next].next;
816 }
817 if (next != -1)
818 panic("didn't use all the msg segments");
819
820 /*
821 * We've got the message. Unlock the msqid_ds.
822 */
823
831 msqptr->msg_perm.mode &= ~MSG_LOCKED;
824 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
832
833 /*
834 * Make sure that the msqid_ds is still allocated.
835 */
836
825
826 /*
827 * Make sure that the msqid_ds is still allocated.
828 */
829
837 if (msqptr->msg_qbytes == 0) {
830 if (msqkptr->u.msg_qbytes == 0) {
838 msg_freehdr(msghdr);
831 msg_freehdr(msghdr);
839 wakeup(msqptr);
832 wakeup(msqkptr);
840 error = EIDRM;
841 goto done2;
842 }
843
844 /*
845 * Put the message into the queue
846 */
833 error = EIDRM;
834 goto done2;
835 }
836
837 /*
838 * Put the message into the queue
839 */
847
848 if (msqptr->msg_first == NULL) {
849 msqptr->msg_first = msghdr;
850 msqptr->msg_last = msghdr;
840 if (msqkptr->u.msg_first == NULL) {
841 msqkptr->u.msg_first = msghdr;
842 msqkptr->u.msg_last = msghdr;
851 } else {
843 } else {
852 msqptr->msg_last->msg_next = msghdr;
853 msqptr->msg_last = msghdr;
844 msqkptr->u.msg_last->msg_next = msghdr;
845 msqkptr->u.msg_last = msghdr;
854 }
846 }
855 msqptr->msg_last->msg_next = NULL;
847 msqkptr->u.msg_last->msg_next = NULL;
856
848
857 msqptr->msg_cbytes += msghdr->msg_ts;
858 msqptr->msg_qnum++;
859 msqptr->msg_lspid = td->td_proc->p_pid;
860 msqptr->msg_stime = time_second;
849 msqkptr->u.msg_cbytes += msghdr->msg_ts;
850 msqkptr->u.msg_qnum++;
851 msqkptr->u.msg_lspid = td->td_proc->p_pid;
852 msqkptr->u.msg_stime = time_second;
861
853
862 wakeup(msqptr);
854 wakeup(msqkptr);
863 td->td_retval[0] = 0;
864done2:
865 mtx_unlock(&msq_mtx);
866 return (error);
867}
868
869#ifndef _SYS_SYSPROTO_H_
870struct msgrcv_args {

--- 14 unchanged lines hidden (view full) ---

885 register struct msgrcv_args *uap;
886{
887 int msqid = uap->msqid;
888 void *user_msgp = uap->msgp;
889 size_t msgsz = uap->msgsz;
890 long msgtyp = uap->msgtyp;
891 int msgflg = uap->msgflg;
892 size_t len;
855 td->td_retval[0] = 0;
856done2:
857 mtx_unlock(&msq_mtx);
858 return (error);
859}
860
861#ifndef _SYS_SYSPROTO_H_
862struct msgrcv_args {

--- 14 unchanged lines hidden (view full) ---

877 register struct msgrcv_args *uap;
878{
879 int msqid = uap->msqid;
880 void *user_msgp = uap->msgp;
881 size_t msgsz = uap->msgsz;
882 long msgtyp = uap->msgtyp;
883 int msgflg = uap->msgflg;
884 size_t len;
893 register struct msqid_ds *msqptr;
885 register struct msqid_kernel *msqkptr;
894 register struct msg *msghdr;
895 int error = 0;
896 short next;
897
898 DPRINTF(("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp,
899 msgsz, msgtyp, msgflg));
900
901 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
902 return (ENOSYS);
903
904 msqid = IPCID_TO_IX(msqid);
905
906 if (msqid < 0 || msqid >= msginfo.msgmni) {
907 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
908 msginfo.msgmni));
909 return (EINVAL);
910 }
911
886 register struct msg *msghdr;
887 int error = 0;
888 short next;
889
890 DPRINTF(("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp,
891 msgsz, msgtyp, msgflg));
892
893 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
894 return (ENOSYS);
895
896 msqid = IPCID_TO_IX(msqid);
897
898 if (msqid < 0 || msqid >= msginfo.msgmni) {
899 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
900 msginfo.msgmni));
901 return (EINVAL);
902 }
903
912 msqptr = &msqids[msqid];
904 msqkptr = &msqids[msqid];
913 mtx_lock(&msq_mtx);
905 mtx_lock(&msq_mtx);
914 if (msqptr->msg_qbytes == 0) {
906 if (msqkptr->u.msg_qbytes == 0) {
915 DPRINTF(("no such message queue id\n"));
916 error = EINVAL;
917 goto done2;
918 }
907 DPRINTF(("no such message queue id\n"));
908 error = EINVAL;
909 goto done2;
910 }
919 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
911 if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
920 DPRINTF(("wrong sequence number\n"));
921 error = EINVAL;
922 goto done2;
923 }
924
912 DPRINTF(("wrong sequence number\n"));
913 error = EINVAL;
914 goto done2;
915 }
916
925 if ((error = ipcperm(td, &msqptr->msg_perm, IPC_R))) {
917 if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_R))) {
926 DPRINTF(("requester doesn't have read access\n"));
927 goto done2;
928 }
929
930 msghdr = NULL;
931 while (msghdr == NULL) {
932 if (msgtyp == 0) {
918 DPRINTF(("requester doesn't have read access\n"));
919 goto done2;
920 }
921
922 msghdr = NULL;
923 while (msghdr == NULL) {
924 if (msgtyp == 0) {
933 msghdr = msqptr->msg_first;
925 msghdr = msqkptr->u.msg_first;
934 if (msghdr != NULL) {
935 if (msgsz < msghdr->msg_ts &&
936 (msgflg & MSG_NOERROR) == 0) {
937 DPRINTF(("first message on the queue "
938 "is too big (want %d, got %d)\n",
939 msgsz, msghdr->msg_ts));
940 error = E2BIG;
941 goto done2;
942 }
926 if (msghdr != NULL) {
927 if (msgsz < msghdr->msg_ts &&
928 (msgflg & MSG_NOERROR) == 0) {
929 DPRINTF(("first message on the queue "
930 "is too big (want %d, got %d)\n",
931 msgsz, msghdr->msg_ts));
932 error = E2BIG;
933 goto done2;
934 }
943 if (msqptr->msg_first == msqptr->msg_last) {
944 msqptr->msg_first = NULL;
945 msqptr->msg_last = NULL;
935 if (msqkptr->u.msg_first == msqkptr->u.msg_last) {
936 msqkptr->u.msg_first = NULL;
937 msqkptr->u.msg_last = NULL;
946 } else {
938 } else {
947 msqptr->msg_first = msghdr->msg_next;
948 if (msqptr->msg_first == NULL)
939 msqkptr->u.msg_first = msghdr->msg_next;
940 if (msqkptr->u.msg_first == NULL)
949 panic("msg_first/last screwed up #1");
950 }
951 }
952 } else {
953 struct msg *previous;
954 struct msg **prev;
955
956 previous = NULL;
941 panic("msg_first/last screwed up #1");
942 }
943 }
944 } else {
945 struct msg *previous;
946 struct msg **prev;
947
948 previous = NULL;
957 prev = &(msqptr->msg_first);
949 prev = &(msqkptr->u.msg_first);
958 while ((msghdr = *prev) != NULL) {
959 /*
960 * Is this message's type an exact match or is
961 * this message's type less than or equal to
962 * the absolute value of a negative msgtyp?
963 * Note that the second half of this test can
964 * NEVER be true if msgtyp is positive since
965 * msg_type is always positive!

--- 9 unchanged lines hidden (view full) ---

975 DPRINTF(("requested message "
976 "on the queue is too big "
977 "(want %d, got %d)\n",
978 msgsz, msghdr->msg_ts));
979 error = E2BIG;
980 goto done2;
981 }
982 *prev = msghdr->msg_next;
950 while ((msghdr = *prev) != NULL) {
951 /*
952 * Is this message's type an exact match or is
953 * this message's type less than or equal to
954 * the absolute value of a negative msgtyp?
955 * Note that the second half of this test can
956 * NEVER be true if msgtyp is positive since
957 * msg_type is always positive!

--- 9 unchanged lines hidden (view full) ---

967 DPRINTF(("requested message "
968 "on the queue is too big "
969 "(want %d, got %d)\n",
970 msgsz, msghdr->msg_ts));
971 error = E2BIG;
972 goto done2;
973 }
974 *prev = msghdr->msg_next;
983 if (msghdr == msqptr->msg_last) {
975 if (msghdr == msqkptr->u.msg_last) {
984 if (previous == NULL) {
985 if (prev !=
976 if (previous == NULL) {
977 if (prev !=
986 &msqptr->msg_first)
978 &msqkptr->u.msg_first)
987 panic("msg_first/last screwed up #2");
979 panic("msg_first/last screwed up #2");
988 msqptr->msg_first =
980 msqkptr->u.msg_first =
989 NULL;
981 NULL;
990 msqptr->msg_last =
982 msqkptr->u.msg_last =
991 NULL;
992 } else {
993 if (prev ==
983 NULL;
984 } else {
985 if (prev ==
994 &msqptr->msg_first)
986 &msqkptr->u.msg_first)
995 panic("msg_first/last screwed up #3");
987 panic("msg_first/last screwed up #3");
996 msqptr->msg_last =
988 msqkptr->u.msg_last =
997 previous;
998 }
999 }
1000 break;
1001 }
1002 previous = msghdr;
1003 prev = &(msghdr->msg_next);
1004 }

--- 20 unchanged lines hidden (view full) ---

1025 goto done2;
1026 }
1027
1028 /*
1029 * Wait for something to happen
1030 */
1031
1032 DPRINTF(("msgrcv: goodnight\n"));
989 previous;
990 }
991 }
992 break;
993 }
994 previous = msghdr;
995 prev = &(msghdr->msg_next);
996 }

--- 20 unchanged lines hidden (view full) ---

1017 goto done2;
1018 }
1019
1020 /*
1021 * Wait for something to happen
1022 */
1023
1024 DPRINTF(("msgrcv: goodnight\n"));
1033 error = msleep(msqptr, &msq_mtx, (PZERO - 4) | PCATCH,
1025 error = msleep(msqkptr, &msq_mtx, (PZERO - 4) | PCATCH,
1034 "msgwait", 0);
1035 DPRINTF(("msgrcv: good morning (error=%d)\n", error));
1036
1037 if (error != 0) {
1038 DPRINTF(("msgsnd: interrupted system call\n"));
1039 error = EINTR;
1040 goto done2;
1041 }
1042
1043 /*
1044 * Make sure that the msq queue still exists
1045 */
1046
1026 "msgwait", 0);
1027 DPRINTF(("msgrcv: good morning (error=%d)\n", error));
1028
1029 if (error != 0) {
1030 DPRINTF(("msgsnd: interrupted system call\n"));
1031 error = EINTR;
1032 goto done2;
1033 }
1034
1035 /*
1036 * Make sure that the msq queue still exists
1037 */
1038
1047 if (msqptr->msg_qbytes == 0 ||
1048 msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
1039 if (msqkptr->u.msg_qbytes == 0 ||
1040 msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
1049 DPRINTF(("msqid deleted\n"));
1050 error = EIDRM;
1051 goto done2;
1052 }
1053 }
1054
1055 /*
1056 * Return the message to the user.
1057 *
1058 * First, do the bookkeeping (before we risk being interrupted).
1059 */
1060
1041 DPRINTF(("msqid deleted\n"));
1042 error = EIDRM;
1043 goto done2;
1044 }
1045 }
1046
1047 /*
1048 * Return the message to the user.
1049 *
1050 * First, do the bookkeeping (before we risk being interrupted).
1051 */
1052
1061 msqptr->msg_cbytes -= msghdr->msg_ts;
1062 msqptr->msg_qnum--;
1063 msqptr->msg_lrpid = td->td_proc->p_pid;
1064 msqptr->msg_rtime = time_second;
1053 msqkptr->u.msg_cbytes -= msghdr->msg_ts;
1054 msqkptr->u.msg_qnum--;
1055 msqkptr->u.msg_lrpid = td->td_proc->p_pid;
1056 msqkptr->u.msg_rtime = time_second;
1065
1066 /*
1067 * Make msgsz the actual amount that we'll be returning.
1068 * Note that this effectively truncates the message if it is too long
1069 * (since msgsz is never increased).
1070 */
1071
1072 DPRINTF(("found a message, msgsz=%d, msg_ts=%d\n", msgsz,

--- 7 unchanged lines hidden (view full) ---

1080
1081 mtx_unlock(&msq_mtx);
1082 error = copyout(&(msghdr->msg_type), user_msgp,
1083 sizeof(msghdr->msg_type));
1084 mtx_lock(&msq_mtx);
1085 if (error != 0) {
1086 DPRINTF(("error (%d) copying out message type\n", error));
1087 msg_freehdr(msghdr);
1057
1058 /*
1059 * Make msgsz the actual amount that we'll be returning.
1060 * Note that this effectively truncates the message if it is too long
1061 * (since msgsz is never increased).
1062 */
1063
1064 DPRINTF(("found a message, msgsz=%d, msg_ts=%d\n", msgsz,

--- 7 unchanged lines hidden (view full) ---

1072
1073 mtx_unlock(&msq_mtx);
1074 error = copyout(&(msghdr->msg_type), user_msgp,
1075 sizeof(msghdr->msg_type));
1076 mtx_lock(&msq_mtx);
1077 if (error != 0) {
1078 DPRINTF(("error (%d) copying out message type\n", error));
1079 msg_freehdr(msghdr);
1088 wakeup(msqptr);
1080 wakeup(msqkptr);
1089 goto done2;
1090 }
1091 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
1092
1093 /*
1094 * Return the segments to the user
1095 */
1096

--- 12 unchanged lines hidden (view full) ---

1109 mtx_unlock(&msq_mtx);
1110 error = copyout(&msgpool[next * msginfo.msgssz],
1111 user_msgp, tlen);
1112 mtx_lock(&msq_mtx);
1113 if (error != 0) {
1114 DPRINTF(("error (%d) copying out message segment\n",
1115 error));
1116 msg_freehdr(msghdr);
1081 goto done2;
1082 }
1083 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
1084
1085 /*
1086 * Return the segments to the user
1087 */
1088

--- 12 unchanged lines hidden (view full) ---

1101 mtx_unlock(&msq_mtx);
1102 error = copyout(&msgpool[next * msginfo.msgssz],
1103 user_msgp, tlen);
1104 mtx_lock(&msq_mtx);
1105 if (error != 0) {
1106 DPRINTF(("error (%d) copying out message segment\n",
1107 error));
1108 msg_freehdr(msghdr);
1117 wakeup(msqptr);
1109 wakeup(msqkptr);
1118 goto done2;
1119 }
1120 user_msgp = (char *)user_msgp + tlen;
1121 next = msgmaps[next].next;
1122 }
1123
1124 /*
1125 * Done, return the actual number of bytes copied out.
1126 */
1127
1128 msg_freehdr(msghdr);
1110 goto done2;
1111 }
1112 user_msgp = (char *)user_msgp + tlen;
1113 next = msgmaps[next].next;
1114 }
1115
1116 /*
1117 * Done, return the actual number of bytes copied out.
1118 */
1119
1120 msg_freehdr(msghdr);
1129 wakeup(msqptr);
1121 wakeup(msqkptr);
1130 td->td_retval[0] = msgsz;
1131done2:
1132 mtx_unlock(&msq_mtx);
1133 return (error);
1134}
1135
1136static int
1137sysctl_msqids(SYSCTL_HANDLER_ARGS)
1138{
1139
1140 return (SYSCTL_OUT(req, msqids,
1122 td->td_retval[0] = msgsz;
1123done2:
1124 mtx_unlock(&msq_mtx);
1125 return (error);
1126}
1127
1128static int
1129sysctl_msqids(SYSCTL_HANDLER_ARGS)
1130{
1131
1132 return (SYSCTL_OUT(req, msqids,
1141 sizeof(struct msqid_ds) * msginfo.msgmni));
1133 sizeof(struct msqid_kernel) * msginfo.msgmni));
1142}
1143
1144SYSCTL_DECL(_kern_ipc);
1145SYSCTL_INT(_kern_ipc, OID_AUTO, msgmax, CTLFLAG_RD, &msginfo.msgmax, 0, "");
1146SYSCTL_INT(_kern_ipc, OID_AUTO, msgmni, CTLFLAG_RDTUN, &msginfo.msgmni, 0, "");
1147SYSCTL_INT(_kern_ipc, OID_AUTO, msgmnb, CTLFLAG_RD, &msginfo.msgmnb, 0, "");
1148SYSCTL_INT(_kern_ipc, OID_AUTO, msgtql, CTLFLAG_RD, &msginfo.msgtql, 0, "");
1149SYSCTL_INT(_kern_ipc, OID_AUTO, msgssz, CTLFLAG_RDTUN, &msginfo.msgssz, 0, "");
1150SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RDTUN, &msginfo.msgseg, 0, "");
1151SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
1152 NULL, 0, sysctl_msqids, "", "Message queue IDs");
1134}
1135
1136SYSCTL_DECL(_kern_ipc);
1137SYSCTL_INT(_kern_ipc, OID_AUTO, msgmax, CTLFLAG_RD, &msginfo.msgmax, 0, "");
1138SYSCTL_INT(_kern_ipc, OID_AUTO, msgmni, CTLFLAG_RDTUN, &msginfo.msgmni, 0, "");
1139SYSCTL_INT(_kern_ipc, OID_AUTO, msgmnb, CTLFLAG_RD, &msginfo.msgmnb, 0, "");
1140SYSCTL_INT(_kern_ipc, OID_AUTO, msgtql, CTLFLAG_RD, &msginfo.msgtql, 0, "");
1141SYSCTL_INT(_kern_ipc, OID_AUTO, msgssz, CTLFLAG_RDTUN, &msginfo.msgssz, 0, "");
1142SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RDTUN, &msginfo.msgseg, 0, "");
1143SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
1144 NULL, 0, sysctl_msqids, "", "Message queue IDs");