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"); |