Deleted Added
full compact
sysv_msg.c (80670) sysv_msg.c (82607)
1/* $FreeBSD: head/sys/kern/sysv_msg.c 80670 2001-07-30 19:28:02Z asmodai $ */
1/* $FreeBSD: head/sys/kern/sysv_msg.c 82607 2001-08-31 00:02:18Z dillon $ */
2
3/*
4 * Implementation of SVID messages
5 *
6 * Author: Daniel Boulet
7 *
8 * Copyright 1993 Daniel Boulet and RTMX Inc.
9 *

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

21
22#include "opt_sysvipc.h"
23
24#include <sys/param.h>
25#include <sys/systm.h>
26#include <sys/sysproto.h>
27#include <sys/kernel.h>
28#include <sys/proc.h>
2
3/*
4 * Implementation of SVID messages
5 *
6 * Author: Daniel Boulet
7 *
8 * Copyright 1993 Daniel Boulet and RTMX Inc.
9 *

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

21
22#include "opt_sysvipc.h"
23
24#include <sys/param.h>
25#include <sys/systm.h>
26#include <sys/sysproto.h>
27#include <sys/kernel.h>
28#include <sys/proc.h>
29#include <sys/lock.h>
30#include <sys/mutex.h>
29#include <sys/msg.h>
30#include <sys/syscall.h>
31#include <sys/sysent.h>
32#include <sys/sysctl.h>
33#include <sys/malloc.h>
34#include <sys/jail.h>
35
36static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");

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

258SYSCALL_MODULE_HELPER(msgrcv, 5);
259
260DECLARE_MODULE(sysvmsg, sysvmsg_mod,
261 SI_SUB_SYSV_MSG, SI_ORDER_FIRST);
262MODULE_VERSION(sysvmsg, 1);
263
264/*
265 * Entry point for all MSG calls
31#include <sys/msg.h>
32#include <sys/syscall.h>
33#include <sys/sysent.h>
34#include <sys/sysctl.h>
35#include <sys/malloc.h>
36#include <sys/jail.h>
37
38static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");

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

260SYSCALL_MODULE_HELPER(msgrcv, 5);
261
262DECLARE_MODULE(sysvmsg, sysvmsg_mod,
263 SI_SUB_SYSV_MSG, SI_ORDER_FIRST);
264MODULE_VERSION(sysvmsg, 1);
265
266/*
267 * Entry point for all MSG calls
268 *
269 * MPSAFE
266 */
267int
268msgsys(p, uap)
269 struct proc *p;
270 /* XXX actually varargs. */
271 struct msgsys_args /* {
272 u_int which;
273 int a2;
274 int a3;
275 int a4;
276 int a5;
277 int a6;
278 } */ *uap;
279{
270 */
271int
272msgsys(p, uap)
273 struct proc *p;
274 /* XXX actually varargs. */
275 struct msgsys_args /* {
276 u_int which;
277 int a2;
278 int a3;
279 int a4;
280 int a5;
281 int a6;
282 } */ *uap;
283{
284 int error;
280
285
281 if (!jail_sysvipc_allowed && jailed(p->p_ucred))
282 return (ENOSYS);
286 mtx_lock(&Giant);
283
287
284 if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0]))
285 return (EINVAL);
286 return ((*msgcalls[uap->which])(p, &uap->a2));
288 if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
289 error = ENOSYS;
290 goto done2;
291 }
292 if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0])) {
293 error = EINVAL;
294 goto done2;
295 }
296 error = (*msgcalls[uap->which])(p, &uap->a2);
297done2:
298 mtx_unlock(&Giant);
299 return (error);
287}
288
289static void
290msg_freehdr(msghdr)
291 struct msg *msghdr;
292{
293 while (msghdr->msg_ts > 0) {
294 short next;

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

313#ifndef _SYS_SYSPROTO_H_
314struct msgctl_args {
315 int msqid;
316 int cmd;
317 struct msqid_ds *buf;
318};
319#endif
320
300}
301
302static void
303msg_freehdr(msghdr)
304 struct msg *msghdr;
305{
306 while (msghdr->msg_ts > 0) {
307 short next;

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

326#ifndef _SYS_SYSPROTO_H_
327struct msgctl_args {
328 int msqid;
329 int cmd;
330 struct msqid_ds *buf;
331};
332#endif
333
334/*
335 * MPSAFE
336 */
321int
322msgctl(p, uap)
323 struct proc *p;
324 register struct msgctl_args *uap;
325{
326 int msqid = uap->msqid;
327 int cmd = uap->cmd;
328 struct msqid_ds *user_msqptr = uap->buf;
337int
338msgctl(p, uap)
339 struct proc *p;
340 register struct msgctl_args *uap;
341{
342 int msqid = uap->msqid;
343 int cmd = uap->cmd;
344 struct msqid_ds *user_msqptr = uap->buf;
329 int rval, eval;
345 int rval, error;
330 struct msqid_ds msqbuf;
331 register struct msqid_ds *msqptr;
332
333#ifdef MSG_DEBUG_OK
334 printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr);
335#endif
346 struct msqid_ds msqbuf;
347 register struct msqid_ds *msqptr;
348
349#ifdef MSG_DEBUG_OK
350 printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr);
351#endif
352 mtx_lock(&Giant);
336
353
337 if (!jail_sysvipc_allowed && jailed(p->p_ucred))
338 return (ENOSYS);
354 if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
355 error = ENOSYS;
356 goto done2;
357 }
339
340 msqid = IPCID_TO_IX(msqid);
341
342 if (msqid < 0 || msqid >= msginfo.msgmni) {
343#ifdef MSG_DEBUG_OK
344 printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
345 msginfo.msgmni);
346#endif
358
359 msqid = IPCID_TO_IX(msqid);
360
361 if (msqid < 0 || msqid >= msginfo.msgmni) {
362#ifdef MSG_DEBUG_OK
363 printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
364 msginfo.msgmni);
365#endif
347 return(EINVAL);
366 error = EINVAL;
367 goto done2;
348 }
349
350 msqptr = &msqids[msqid];
351
352 if (msqptr->msg_qbytes == 0) {
353#ifdef MSG_DEBUG_OK
354 printf("no such msqid\n");
355#endif
368 }
369
370 msqptr = &msqids[msqid];
371
372 if (msqptr->msg_qbytes == 0) {
373#ifdef MSG_DEBUG_OK
374 printf("no such msqid\n");
375#endif
356 return(EINVAL);
376 error = EINVAL;
377 goto done2;
357 }
358 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
359#ifdef MSG_DEBUG_OK
360 printf("wrong sequence number\n");
361#endif
378 }
379 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
380#ifdef MSG_DEBUG_OK
381 printf("wrong sequence number\n");
382#endif
362 return(EINVAL);
383 error = EINVAL;
384 goto done2;
363 }
364
385 }
386
365 eval = 0;
387 error = 0;
366 rval = 0;
367
368 switch (cmd) {
369
370 case IPC_RMID:
371 {
372 struct msg *msghdr;
388 rval = 0;
389
390 switch (cmd) {
391
392 case IPC_RMID:
393 {
394 struct msg *msghdr;
373 if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M)))
374 return(eval);
395 if ((error = ipcperm(p, &msqptr->msg_perm, IPC_M)))
396 goto done2;
375 /* Free the message headers */
376 msghdr = msqptr->msg_first;
377 while (msghdr != NULL) {
378 struct msg *msghdr_tmp;
379
380 /* Free the segments of each message */
381 msqptr->msg_cbytes -= msghdr->msg_ts;
382 msqptr->msg_qnum--;

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

393 msqptr->msg_qbytes = 0; /* Mark it as free */
394
395 wakeup((caddr_t)msqptr);
396 }
397
398 break;
399
400 case IPC_SET:
397 /* Free the message headers */
398 msghdr = msqptr->msg_first;
399 while (msghdr != NULL) {
400 struct msg *msghdr_tmp;
401
402 /* Free the segments of each message */
403 msqptr->msg_cbytes -= msghdr->msg_ts;
404 msqptr->msg_qnum--;

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

415 msqptr->msg_qbytes = 0; /* Mark it as free */
416
417 wakeup((caddr_t)msqptr);
418 }
419
420 break;
421
422 case IPC_SET:
401 if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M)))
402 return(eval);
403 if ((eval = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
404 return(eval);
423 if ((error = ipcperm(p, &msqptr->msg_perm, IPC_M)))
424 goto done2;
425 if ((error = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
426 goto done2;
405 if (msqbuf.msg_qbytes > msqptr->msg_qbytes) {
427 if (msqbuf.msg_qbytes > msqptr->msg_qbytes) {
406 eval = suser(p);
407 if (eval)
408 return(eval);
428 error = suser(p);
429 if (error)
430 goto done2;
409 }
410 if (msqbuf.msg_qbytes > msginfo.msgmnb) {
411#ifdef MSG_DEBUG_OK
412 printf("can't increase msg_qbytes beyond %d (truncating)\n",
413 msginfo.msgmnb);
414#endif
415 msqbuf.msg_qbytes = msginfo.msgmnb; /* silently restrict qbytes to system limit */
416 }
417 if (msqbuf.msg_qbytes == 0) {
418#ifdef MSG_DEBUG_OK
419 printf("can't reduce msg_qbytes to 0\n");
420#endif
431 }
432 if (msqbuf.msg_qbytes > msginfo.msgmnb) {
433#ifdef MSG_DEBUG_OK
434 printf("can't increase msg_qbytes beyond %d (truncating)\n",
435 msginfo.msgmnb);
436#endif
437 msqbuf.msg_qbytes = msginfo.msgmnb; /* silently restrict qbytes to system limit */
438 }
439 if (msqbuf.msg_qbytes == 0) {
440#ifdef MSG_DEBUG_OK
441 printf("can't reduce msg_qbytes to 0\n");
442#endif
421 return(EINVAL); /* non-standard errno! */
443 error = EINVAL; /* non-standard errno! */
444 goto done2;
422 }
423 msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */
424 msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */
425 msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) |
426 (msqbuf.msg_perm.mode & 0777);
427 msqptr->msg_qbytes = msqbuf.msg_qbytes;
428 msqptr->msg_ctime = time_second;
429 break;
430
431 case IPC_STAT:
445 }
446 msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */
447 msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */
448 msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) |
449 (msqbuf.msg_perm.mode & 0777);
450 msqptr->msg_qbytes = msqbuf.msg_qbytes;
451 msqptr->msg_ctime = time_second;
452 break;
453
454 case IPC_STAT:
432 if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
455 if ((error = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
433#ifdef MSG_DEBUG_OK
434 printf("requester doesn't have read access\n");
435#endif
456#ifdef MSG_DEBUG_OK
457 printf("requester doesn't have read access\n");
458#endif
436 return(eval);
459 goto done2;
437 }
460 }
438 eval = copyout((caddr_t)msqptr, user_msqptr,
461 error = copyout((caddr_t)msqptr, user_msqptr,
439 sizeof(struct msqid_ds));
440 break;
441
442 default:
443#ifdef MSG_DEBUG_OK
444 printf("invalid command %d\n", cmd);
445#endif
462 sizeof(struct msqid_ds));
463 break;
464
465 default:
466#ifdef MSG_DEBUG_OK
467 printf("invalid command %d\n", cmd);
468#endif
446 return(EINVAL);
469 error = EINVAL;
470 goto done2;
447 }
448
471 }
472
449 if (eval == 0)
473 if (error == 0)
450 p->p_retval[0] = rval;
474 p->p_retval[0] = rval;
451 return(eval);
475done2:
476 mtx_unlock(&Giant);
477 return(error);
452}
453
454#ifndef _SYS_SYSPROTO_H_
455struct msgget_args {
456 key_t key;
457 int msgflg;
458};
459#endif
460
478}
479
480#ifndef _SYS_SYSPROTO_H_
481struct msgget_args {
482 key_t key;
483 int msgflg;
484};
485#endif
486
487/*
488 * MPSAFE
489 */
461int
462msgget(p, uap)
463 struct proc *p;
464 register struct msgget_args *uap;
465{
490int
491msgget(p, uap)
492 struct proc *p;
493 register struct msgget_args *uap;
494{
466 int msqid, eval;
495 int msqid, error = 0;
467 int key = uap->key;
468 int msgflg = uap->msgflg;
469 struct ucred *cred = p->p_ucred;
470 register struct msqid_ds *msqptr = NULL;
471
472#ifdef MSG_DEBUG_OK
473 printf("msgget(0x%x, 0%o)\n", key, msgflg);
474#endif
475
496 int key = uap->key;
497 int msgflg = uap->msgflg;
498 struct ucred *cred = p->p_ucred;
499 register struct msqid_ds *msqptr = NULL;
500
501#ifdef MSG_DEBUG_OK
502 printf("msgget(0x%x, 0%o)\n", key, msgflg);
503#endif
504
476 if (!jail_sysvipc_allowed && jailed(p->p_ucred))
477 return (ENOSYS);
505 mtx_lock(&Giant);
478
506
507 if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
508 error = ENOSYS;
509 goto done2;
510 }
511
479 if (key != IPC_PRIVATE) {
480 for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
481 msqptr = &msqids[msqid];
482 if (msqptr->msg_qbytes != 0 &&
483 msqptr->msg_perm.key == key)
484 break;
485 }
486 if (msqid < msginfo.msgmni) {
487#ifdef MSG_DEBUG_OK
488 printf("found public key\n");
489#endif
490 if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) {
491#ifdef MSG_DEBUG_OK
492 printf("not exclusive\n");
493#endif
512 if (key != IPC_PRIVATE) {
513 for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
514 msqptr = &msqids[msqid];
515 if (msqptr->msg_qbytes != 0 &&
516 msqptr->msg_perm.key == key)
517 break;
518 }
519 if (msqid < msginfo.msgmni) {
520#ifdef MSG_DEBUG_OK
521 printf("found public key\n");
522#endif
523 if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) {
524#ifdef MSG_DEBUG_OK
525 printf("not exclusive\n");
526#endif
494 return(EEXIST);
527 error = EEXIST;
528 goto done2;
495 }
529 }
496 if ((eval = ipcperm(p, &msqptr->msg_perm, msgflg & 0700 ))) {
530 if ((error = ipcperm(p, &msqptr->msg_perm, msgflg & 0700 ))) {
497#ifdef MSG_DEBUG_OK
498 printf("requester doesn't have 0%o access\n",
499 msgflg & 0700);
500#endif
531#ifdef MSG_DEBUG_OK
532 printf("requester doesn't have 0%o access\n",
533 msgflg & 0700);
534#endif
501 return(eval);
535 goto done2;
502 }
503 goto found;
504 }
505 }
506
507#ifdef MSG_DEBUG_OK
508 printf("need to allocate the msqid_ds\n");
509#endif

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

519 if (msqptr->msg_qbytes == 0 &&
520 (msqptr->msg_perm.mode & MSG_LOCKED) == 0)
521 break;
522 }
523 if (msqid == msginfo.msgmni) {
524#ifdef MSG_DEBUG_OK
525 printf("no more msqid_ds's available\n");
526#endif
536 }
537 goto found;
538 }
539 }
540
541#ifdef MSG_DEBUG_OK
542 printf("need to allocate the msqid_ds\n");
543#endif

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

553 if (msqptr->msg_qbytes == 0 &&
554 (msqptr->msg_perm.mode & MSG_LOCKED) == 0)
555 break;
556 }
557 if (msqid == msginfo.msgmni) {
558#ifdef MSG_DEBUG_OK
559 printf("no more msqid_ds's available\n");
560#endif
527 return(ENOSPC);
561 error = ENOSPC;
562 goto done2;
528 }
529#ifdef MSG_DEBUG_OK
530 printf("msqid %d is available\n", msqid);
531#endif
532 msqptr->msg_perm.key = key;
533 msqptr->msg_perm.cuid = cred->cr_uid;
534 msqptr->msg_perm.uid = cred->cr_uid;
535 msqptr->msg_perm.cgid = cred->cr_gid;

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

546 msqptr->msg_lrpid = 0;
547 msqptr->msg_stime = 0;
548 msqptr->msg_rtime = 0;
549 msqptr->msg_ctime = time_second;
550 } else {
551#ifdef MSG_DEBUG_OK
552 printf("didn't find it and wasn't asked to create it\n");
553#endif
563 }
564#ifdef MSG_DEBUG_OK
565 printf("msqid %d is available\n", msqid);
566#endif
567 msqptr->msg_perm.key = key;
568 msqptr->msg_perm.cuid = cred->cr_uid;
569 msqptr->msg_perm.uid = cred->cr_uid;
570 msqptr->msg_perm.cgid = cred->cr_gid;

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

581 msqptr->msg_lrpid = 0;
582 msqptr->msg_stime = 0;
583 msqptr->msg_rtime = 0;
584 msqptr->msg_ctime = time_second;
585 } else {
586#ifdef MSG_DEBUG_OK
587 printf("didn't find it and wasn't asked to create it\n");
588#endif
554 return(ENOENT);
589 error = ENOENT;
590 goto done2;
555 }
556
557found:
558 /* Construct the unique msqid */
559 p->p_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);
591 }
592
593found:
594 /* Construct the unique msqid */
595 p->p_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);
560 return(0);
596done2:
597 mtx_unlock(&Giant);
598 return (error);
561}
562
563#ifndef _SYS_SYSPROTO_H_
564struct msgsnd_args {
565 int msqid;
566 void *msgp;
567 size_t msgsz;
568 int msgflg;
569};
570#endif
571
599}
600
601#ifndef _SYS_SYSPROTO_H_
602struct msgsnd_args {
603 int msqid;
604 void *msgp;
605 size_t msgsz;
606 int msgflg;
607};
608#endif
609
610/*
611 * MPSAFE
612 */
572int
573msgsnd(p, uap)
574 struct proc *p;
575 register struct msgsnd_args *uap;
576{
577 int msqid = uap->msqid;
578 void *user_msgp = uap->msgp;
579 size_t msgsz = uap->msgsz;
580 int msgflg = uap->msgflg;
613int
614msgsnd(p, uap)
615 struct proc *p;
616 register struct msgsnd_args *uap;
617{
618 int msqid = uap->msqid;
619 void *user_msgp = uap->msgp;
620 size_t msgsz = uap->msgsz;
621 int msgflg = uap->msgflg;
581 int segs_needed, eval;
622 int segs_needed, error = 0;
582 register struct msqid_ds *msqptr;
583 register struct msg *msghdr;
584 short next;
585
586#ifdef MSG_DEBUG_OK
587 printf("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
588 msgflg);
589#endif
623 register struct msqid_ds *msqptr;
624 register struct msg *msghdr;
625 short next;
626
627#ifdef MSG_DEBUG_OK
628 printf("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
629 msgflg);
630#endif
631 mtx_lock(&Giant);
590
632
591 if (!jail_sysvipc_allowed && jailed(p->p_ucred))
592 return (ENOSYS);
633 if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
634 error = ENOSYS;
635 goto done2;
636 }
593
594 msqid = IPCID_TO_IX(msqid);
595
596 if (msqid < 0 || msqid >= msginfo.msgmni) {
597#ifdef MSG_DEBUG_OK
598 printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
599 msginfo.msgmni);
600#endif
637
638 msqid = IPCID_TO_IX(msqid);
639
640 if (msqid < 0 || msqid >= msginfo.msgmni) {
641#ifdef MSG_DEBUG_OK
642 printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
643 msginfo.msgmni);
644#endif
601 return(EINVAL);
645 error = EINVAL;
646 goto done2;
602 }
603
604 msqptr = &msqids[msqid];
605 if (msqptr->msg_qbytes == 0) {
606#ifdef MSG_DEBUG_OK
607 printf("no such message queue id\n");
608#endif
647 }
648
649 msqptr = &msqids[msqid];
650 if (msqptr->msg_qbytes == 0) {
651#ifdef MSG_DEBUG_OK
652 printf("no such message queue id\n");
653#endif
609 return(EINVAL);
654 error = EINVAL;
655 goto done2;
610 }
611 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
612#ifdef MSG_DEBUG_OK
613 printf("wrong sequence number\n");
614#endif
656 }
657 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
658#ifdef MSG_DEBUG_OK
659 printf("wrong sequence number\n");
660#endif
615 return(EINVAL);
661 error = EINVAL;
662 goto done2;
616 }
617
663 }
664
618 if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_W))) {
665 if ((error = ipcperm(p, &msqptr->msg_perm, IPC_W))) {
619#ifdef MSG_DEBUG_OK
620 printf("requester doesn't have write access\n");
621#endif
666#ifdef MSG_DEBUG_OK
667 printf("requester doesn't have write access\n");
668#endif
622 return(eval);
669 goto done2;
623 }
624
625 segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
626#ifdef MSG_DEBUG_OK
627 printf("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz,
628 segs_needed);
629#endif
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
638 if (msgsz > msqptr->msg_qbytes) {
639#ifdef MSG_DEBUG_OK
640 printf("msgsz > msqptr->msg_qbytes\n");
641#endif
670 }
671
672 segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
673#ifdef MSG_DEBUG_OK
674 printf("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz,
675 segs_needed);
676#endif
677 for (;;) {
678 int need_more_resources = 0;
679
680 /*
681 * check msgsz
682 * (inside this loop in case msg_qbytes changes while we sleep)
683 */
684
685 if (msgsz > msqptr->msg_qbytes) {
686#ifdef MSG_DEBUG_OK
687 printf("msgsz > msqptr->msg_qbytes\n");
688#endif
642 return(EINVAL);
689 error = EINVAL;
690 goto done2;
643 }
644
645 if (msqptr->msg_perm.mode & MSG_LOCKED) {
646#ifdef MSG_DEBUG_OK
647 printf("msqid is locked\n");
648#endif
649 need_more_resources = 1;
650 }

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

669
670 if (need_more_resources) {
671 int we_own_it;
672
673 if ((msgflg & IPC_NOWAIT) != 0) {
674#ifdef MSG_DEBUG_OK
675 printf("need more resources but caller doesn't want to wait\n");
676#endif
691 }
692
693 if (msqptr->msg_perm.mode & MSG_LOCKED) {
694#ifdef MSG_DEBUG_OK
695 printf("msqid is locked\n");
696#endif
697 need_more_resources = 1;
698 }

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

717
718 if (need_more_resources) {
719 int we_own_it;
720
721 if ((msgflg & IPC_NOWAIT) != 0) {
722#ifdef MSG_DEBUG_OK
723 printf("need more resources but caller doesn't want to wait\n");
724#endif
677 return(EAGAIN);
725 error = EAGAIN;
726 goto done2;
678 }
679
680 if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) {
681#ifdef MSG_DEBUG_OK
682 printf("we don't own the msqid_ds\n");
683#endif
684 we_own_it = 0;
685 } else {
686 /* Force later arrivals to wait for our
687 request */
688#ifdef MSG_DEBUG_OK
689 printf("we own the msqid_ds\n");
690#endif
691 msqptr->msg_perm.mode |= MSG_LOCKED;
692 we_own_it = 1;
693 }
694#ifdef MSG_DEBUG_OK
695 printf("goodnight\n");
696#endif
727 }
728
729 if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) {
730#ifdef MSG_DEBUG_OK
731 printf("we don't own the msqid_ds\n");
732#endif
733 we_own_it = 0;
734 } else {
735 /* Force later arrivals to wait for our
736 request */
737#ifdef MSG_DEBUG_OK
738 printf("we own the msqid_ds\n");
739#endif
740 msqptr->msg_perm.mode |= MSG_LOCKED;
741 we_own_it = 1;
742 }
743#ifdef MSG_DEBUG_OK
744 printf("goodnight\n");
745#endif
697 eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH,
746 error = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH,
698 "msgwait", 0);
699#ifdef MSG_DEBUG_OK
747 "msgwait", 0);
748#ifdef MSG_DEBUG_OK
700 printf("good morning, eval=%d\n", eval);
749 printf("good morning, error=%d\n", error);
701#endif
702 if (we_own_it)
703 msqptr->msg_perm.mode &= ~MSG_LOCKED;
750#endif
751 if (we_own_it)
752 msqptr->msg_perm.mode &= ~MSG_LOCKED;
704 if (eval != 0) {
753 if (error != 0) {
705#ifdef MSG_DEBUG_OK
706 printf("msgsnd: interrupted system call\n");
707#endif
754#ifdef MSG_DEBUG_OK
755 printf("msgsnd: interrupted system call\n");
756#endif
708 return(EINTR);
757 error = EINTR;
758 goto done2;
709 }
710
711 /*
712 * Make sure that the msq queue still exists
713 */
714
715 if (msqptr->msg_qbytes == 0) {
716#ifdef MSG_DEBUG_OK
717 printf("msqid deleted\n");
718#endif
759 }
760
761 /*
762 * Make sure that the msq queue still exists
763 */
764
765 if (msqptr->msg_qbytes == 0) {
766#ifdef MSG_DEBUG_OK
767 printf("msqid deleted\n");
768#endif
719 return(EIDRM);
769 error = EIDRM;
770 goto done2;
720 }
721
722 } else {
723#ifdef MSG_DEBUG_OK
724 printf("got all the resources that we need\n");
725#endif
726 break;
727 }

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

782 msghdr->msg_spot = next;
783 segs_needed--;
784 }
785
786 /*
787 * Copy in the message type
788 */
789
771 }
772
773 } else {
774#ifdef MSG_DEBUG_OK
775 printf("got all the resources that we need\n");
776#endif
777 break;
778 }

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

833 msghdr->msg_spot = next;
834 segs_needed--;
835 }
836
837 /*
838 * Copy in the message type
839 */
840
790 if ((eval = copyin(user_msgp, &msghdr->msg_type,
841 if ((error = copyin(user_msgp, &msghdr->msg_type,
791 sizeof(msghdr->msg_type))) != 0) {
792#ifdef MSG_DEBUG_OK
842 sizeof(msghdr->msg_type))) != 0) {
843#ifdef MSG_DEBUG_OK
793 printf("error %d copying the message type\n", eval);
844 printf("error %d copying the message type\n", error);
794#endif
795 msg_freehdr(msghdr);
796 msqptr->msg_perm.mode &= ~MSG_LOCKED;
797 wakeup((caddr_t)msqptr);
845#endif
846 msg_freehdr(msghdr);
847 msqptr->msg_perm.mode &= ~MSG_LOCKED;
848 wakeup((caddr_t)msqptr);
798 return(eval);
849 goto done2;
799 }
800 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
801
802 /*
803 * Validate the message type
804 */
805
806 if (msghdr->msg_type < 1) {
807 msg_freehdr(msghdr);
808 msqptr->msg_perm.mode &= ~MSG_LOCKED;
809 wakeup((caddr_t)msqptr);
810#ifdef MSG_DEBUG_OK
811 printf("mtype (%d) < 1\n", msghdr->msg_type);
812#endif
850 }
851 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
852
853 /*
854 * Validate the message type
855 */
856
857 if (msghdr->msg_type < 1) {
858 msg_freehdr(msghdr);
859 msqptr->msg_perm.mode &= ~MSG_LOCKED;
860 wakeup((caddr_t)msqptr);
861#ifdef MSG_DEBUG_OK
862 printf("mtype (%d) < 1\n", msghdr->msg_type);
863#endif
813 return(EINVAL);
864 error = EINVAL;
865 goto done2;
814 }
815
816 /*
817 * Copy in the message body
818 */
819
820 next = msghdr->msg_spot;
821 while (msgsz > 0) {
822 size_t tlen;
823 if (msgsz > msginfo.msgssz)
824 tlen = msginfo.msgssz;
825 else
826 tlen = msgsz;
827 if (next <= -1)
828 panic("next too low #2");
829 if (next >= msginfo.msgseg)
830 panic("next out of range #2");
866 }
867
868 /*
869 * Copy in the message body
870 */
871
872 next = msghdr->msg_spot;
873 while (msgsz > 0) {
874 size_t tlen;
875 if (msgsz > msginfo.msgssz)
876 tlen = msginfo.msgssz;
877 else
878 tlen = msgsz;
879 if (next <= -1)
880 panic("next too low #2");
881 if (next >= msginfo.msgseg)
882 panic("next out of range #2");
831 if ((eval = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
883 if ((error = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
832 tlen)) != 0) {
833#ifdef MSG_DEBUG_OK
884 tlen)) != 0) {
885#ifdef MSG_DEBUG_OK
834 printf("error %d copying in message segment\n", eval);
886 printf("error %d copying in message segment\n", error);
835#endif
836 msg_freehdr(msghdr);
837 msqptr->msg_perm.mode &= ~MSG_LOCKED;
838 wakeup((caddr_t)msqptr);
887#endif
888 msg_freehdr(msghdr);
889 msqptr->msg_perm.mode &= ~MSG_LOCKED;
890 wakeup((caddr_t)msqptr);
839 return(eval);
891 goto done2;
840 }
841 msgsz -= tlen;
842 user_msgp = (char *)user_msgp + tlen;
843 next = msgmaps[next].next;
844 }
845 if (next != -1)
846 panic("didn't use all the msg segments");
847

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

853
854 /*
855 * Make sure that the msqid_ds is still allocated.
856 */
857
858 if (msqptr->msg_qbytes == 0) {
859 msg_freehdr(msghdr);
860 wakeup((caddr_t)msqptr);
892 }
893 msgsz -= tlen;
894 user_msgp = (char *)user_msgp + tlen;
895 next = msgmaps[next].next;
896 }
897 if (next != -1)
898 panic("didn't use all the msg segments");
899

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

905
906 /*
907 * Make sure that the msqid_ds is still allocated.
908 */
909
910 if (msqptr->msg_qbytes == 0) {
911 msg_freehdr(msghdr);
912 wakeup((caddr_t)msqptr);
861 return(EIDRM);
913 error = EIDRM;
914 goto done2;
862 }
863
864 /*
865 * Put the message into the queue
866 */
867
868 if (msqptr->msg_first == NULL) {
869 msqptr->msg_first = msghdr;

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

876
877 msqptr->msg_cbytes += msghdr->msg_ts;
878 msqptr->msg_qnum++;
879 msqptr->msg_lspid = p->p_pid;
880 msqptr->msg_stime = time_second;
881
882 wakeup((caddr_t)msqptr);
883 p->p_retval[0] = 0;
915 }
916
917 /*
918 * Put the message into the queue
919 */
920
921 if (msqptr->msg_first == NULL) {
922 msqptr->msg_first = msghdr;

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

929
930 msqptr->msg_cbytes += msghdr->msg_ts;
931 msqptr->msg_qnum++;
932 msqptr->msg_lspid = p->p_pid;
933 msqptr->msg_stime = time_second;
934
935 wakeup((caddr_t)msqptr);
936 p->p_retval[0] = 0;
884 return(0);
937done2:
938 mtx_unlock(&Giant);
939 return (error);
885}
886
887#ifndef _SYS_SYSPROTO_H_
888struct msgrcv_args {
889 int msqid;
890 void *msgp;
891 size_t msgsz;
892 long msgtyp;
893 int msgflg;
894};
895#endif
896
940}
941
942#ifndef _SYS_SYSPROTO_H_
943struct msgrcv_args {
944 int msqid;
945 void *msgp;
946 size_t msgsz;
947 long msgtyp;
948 int msgflg;
949};
950#endif
951
952/*
953 * MPSAFE
954 */
897int
898msgrcv(p, uap)
899 struct proc *p;
900 register struct msgrcv_args *uap;
901{
902 int msqid = uap->msqid;
903 void *user_msgp = uap->msgp;
904 size_t msgsz = uap->msgsz;
905 long msgtyp = uap->msgtyp;
906 int msgflg = uap->msgflg;
907 size_t len;
908 register struct msqid_ds *msqptr;
909 register struct msg *msghdr;
955int
956msgrcv(p, uap)
957 struct proc *p;
958 register struct msgrcv_args *uap;
959{
960 int msqid = uap->msqid;
961 void *user_msgp = uap->msgp;
962 size_t msgsz = uap->msgsz;
963 long msgtyp = uap->msgtyp;
964 int msgflg = uap->msgflg;
965 size_t len;
966 register struct msqid_ds *msqptr;
967 register struct msg *msghdr;
910 int eval;
968 int error = 0;
911 short next;
912
913#ifdef MSG_DEBUG_OK
914 printf("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp,
915 msgsz, msgtyp, msgflg);
916#endif
917
969 short next;
970
971#ifdef MSG_DEBUG_OK
972 printf("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp,
973 msgsz, msgtyp, msgflg);
974#endif
975
918 if (!jail_sysvipc_allowed && jailed(p->p_ucred))
919 return (ENOSYS);
976 mtx_lock(&Giant);
920
977
978 if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
979 error = ENOSYS;
980 goto done2;
981 }
982
921 msqid = IPCID_TO_IX(msqid);
922
923 if (msqid < 0 || msqid >= msginfo.msgmni) {
924#ifdef MSG_DEBUG_OK
925 printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
926 msginfo.msgmni);
927#endif
983 msqid = IPCID_TO_IX(msqid);
984
985 if (msqid < 0 || msqid >= msginfo.msgmni) {
986#ifdef MSG_DEBUG_OK
987 printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
988 msginfo.msgmni);
989#endif
928 return(EINVAL);
990 error = EINVAL;
991 goto done2;
929 }
930
931 msqptr = &msqids[msqid];
932 if (msqptr->msg_qbytes == 0) {
933#ifdef MSG_DEBUG_OK
934 printf("no such message queue id\n");
935#endif
992 }
993
994 msqptr = &msqids[msqid];
995 if (msqptr->msg_qbytes == 0) {
996#ifdef MSG_DEBUG_OK
997 printf("no such message queue id\n");
998#endif
936 return(EINVAL);
999 error = EINVAL;
1000 goto done2;
937 }
938 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
939#ifdef MSG_DEBUG_OK
940 printf("wrong sequence number\n");
941#endif
1001 }
1002 if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
1003#ifdef MSG_DEBUG_OK
1004 printf("wrong sequence number\n");
1005#endif
942 return(EINVAL);
1006 error = EINVAL;
1007 goto done2;
943 }
944
1008 }
1009
945 if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
1010 if ((error = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
946#ifdef MSG_DEBUG_OK
947 printf("requester doesn't have read access\n");
948#endif
1011#ifdef MSG_DEBUG_OK
1012 printf("requester doesn't have read access\n");
1013#endif
949 return(eval);
1014 goto done2;
950 }
951
952 msghdr = NULL;
953 while (msghdr == NULL) {
954 if (msgtyp == 0) {
955 msghdr = msqptr->msg_first;
956 if (msghdr != NULL) {
957 if (msgsz < msghdr->msg_ts &&
958 (msgflg & MSG_NOERROR) == 0) {
959#ifdef MSG_DEBUG_OK
960 printf("first message on the queue is too big (want %d, got %d)\n",
961 msgsz, msghdr->msg_ts);
962#endif
1015 }
1016
1017 msghdr = NULL;
1018 while (msghdr == NULL) {
1019 if (msgtyp == 0) {
1020 msghdr = msqptr->msg_first;
1021 if (msghdr != NULL) {
1022 if (msgsz < msghdr->msg_ts &&
1023 (msgflg & MSG_NOERROR) == 0) {
1024#ifdef MSG_DEBUG_OK
1025 printf("first message on the queue is too big (want %d, got %d)\n",
1026 msgsz, msghdr->msg_ts);
1027#endif
963 return(E2BIG);
1028 error = E2BIG;
1029 goto done2;
964 }
965 if (msqptr->msg_first == msqptr->msg_last) {
966 msqptr->msg_first = NULL;
967 msqptr->msg_last = NULL;
968 } else {
969 msqptr->msg_first = msghdr->msg_next;
970 if (msqptr->msg_first == NULL)
971 panic("msg_first/last screwed up #1");

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

994 msghdr->msg_type, msgtyp);
995#endif
996 if (msgsz < msghdr->msg_ts &&
997 (msgflg & MSG_NOERROR) == 0) {
998#ifdef MSG_DEBUG_OK
999 printf("requested message on the queue is too big (want %d, got %d)\n",
1000 msgsz, msghdr->msg_ts);
1001#endif
1030 }
1031 if (msqptr->msg_first == msqptr->msg_last) {
1032 msqptr->msg_first = NULL;
1033 msqptr->msg_last = NULL;
1034 } else {
1035 msqptr->msg_first = msghdr->msg_next;
1036 if (msqptr->msg_first == NULL)
1037 panic("msg_first/last screwed up #1");

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

1060 msghdr->msg_type, msgtyp);
1061#endif
1062 if (msgsz < msghdr->msg_ts &&
1063 (msgflg & MSG_NOERROR) == 0) {
1064#ifdef MSG_DEBUG_OK
1065 printf("requested message on the queue is too big (want %d, got %d)\n",
1066 msgsz, msghdr->msg_ts);
1067#endif
1002 return(E2BIG);
1068 error = E2BIG;
1069 goto done2;
1003 }
1004 *prev = msghdr->msg_next;
1005 if (msghdr == msqptr->msg_last) {
1006 if (previous == NULL) {
1007 if (prev !=
1008 &msqptr->msg_first)
1009 panic("msg_first/last screwed up #2");
1010 msqptr->msg_first =

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

1040 */
1041
1042 if ((msgflg & IPC_NOWAIT) != 0) {
1043#ifdef MSG_DEBUG_OK
1044 printf("no appropriate message found (msgtyp=%d)\n",
1045 msgtyp);
1046#endif
1047 /* The SVID says to return ENOMSG. */
1070 }
1071 *prev = msghdr->msg_next;
1072 if (msghdr == msqptr->msg_last) {
1073 if (previous == NULL) {
1074 if (prev !=
1075 &msqptr->msg_first)
1076 panic("msg_first/last screwed up #2");
1077 msqptr->msg_first =

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

1107 */
1108
1109 if ((msgflg & IPC_NOWAIT) != 0) {
1110#ifdef MSG_DEBUG_OK
1111 printf("no appropriate message found (msgtyp=%d)\n",
1112 msgtyp);
1113#endif
1114 /* The SVID says to return ENOMSG. */
1048 return(ENOMSG);
1115 error = ENOMSG;
1116 goto done2;
1049 }
1050
1051 /*
1052 * Wait for something to happen
1053 */
1054
1055#ifdef MSG_DEBUG_OK
1056 printf("msgrcv: goodnight\n");
1057#endif
1117 }
1118
1119 /*
1120 * Wait for something to happen
1121 */
1122
1123#ifdef MSG_DEBUG_OK
1124 printf("msgrcv: goodnight\n");
1125#endif
1058 eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH, "msgwait",
1126 error = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH, "msgwait",
1059 0);
1060#ifdef MSG_DEBUG_OK
1127 0);
1128#ifdef MSG_DEBUG_OK
1061 printf("msgrcv: good morning (eval=%d)\n", eval);
1129 printf("msgrcv: good morning (error=%d)\n", error);
1062#endif
1063
1130#endif
1131
1064 if (eval != 0) {
1132 if (error != 0) {
1065#ifdef MSG_DEBUG_OK
1066 printf("msgsnd: interrupted system call\n");
1067#endif
1133#ifdef MSG_DEBUG_OK
1134 printf("msgsnd: interrupted system call\n");
1135#endif
1068 return(EINTR);
1136 error = EINTR;
1137 goto done2;
1069 }
1070
1071 /*
1072 * Make sure that the msq queue still exists
1073 */
1074
1075 if (msqptr->msg_qbytes == 0 ||
1076 msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
1077#ifdef MSG_DEBUG_OK
1078 printf("msqid deleted\n");
1079#endif
1138 }
1139
1140 /*
1141 * Make sure that the msq queue still exists
1142 */
1143
1144 if (msqptr->msg_qbytes == 0 ||
1145 msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
1146#ifdef MSG_DEBUG_OK
1147 printf("msqid deleted\n");
1148#endif
1080 return(EIDRM);
1149 error = EIDRM;
1150 goto done2;
1081 }
1082 }
1083
1084 /*
1085 * Return the message to the user.
1086 *
1087 * First, do the bookkeeping (before we risk being interrupted).
1088 */

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

1104#endif
1105 if (msgsz > msghdr->msg_ts)
1106 msgsz = msghdr->msg_ts;
1107
1108 /*
1109 * Return the type to the user.
1110 */
1111
1151 }
1152 }
1153
1154 /*
1155 * Return the message to the user.
1156 *
1157 * First, do the bookkeeping (before we risk being interrupted).
1158 */

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

1174#endif
1175 if (msgsz > msghdr->msg_ts)
1176 msgsz = msghdr->msg_ts;
1177
1178 /*
1179 * Return the type to the user.
1180 */
1181
1112 eval = copyout((caddr_t)&(msghdr->msg_type), user_msgp,
1182 error = copyout((caddr_t)&(msghdr->msg_type), user_msgp,
1113 sizeof(msghdr->msg_type));
1183 sizeof(msghdr->msg_type));
1114 if (eval != 0) {
1184 if (error != 0) {
1115#ifdef MSG_DEBUG_OK
1185#ifdef MSG_DEBUG_OK
1116 printf("error (%d) copying out message type\n", eval);
1186 printf("error (%d) copying out message type\n", error);
1117#endif
1118 msg_freehdr(msghdr);
1119 wakeup((caddr_t)msqptr);
1187#endif
1188 msg_freehdr(msghdr);
1189 wakeup((caddr_t)msqptr);
1120 return(eval);
1190 goto done2;
1121 }
1122 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
1123
1124 /*
1125 * Return the segments to the user
1126 */
1127
1128 next = msghdr->msg_spot;
1129 for (len = 0; len < msgsz; len += msginfo.msgssz) {
1130 size_t tlen;
1131
1132 if (msgsz - len > msginfo.msgssz)
1133 tlen = msginfo.msgssz;
1134 else
1135 tlen = msgsz - len;
1136 if (next <= -1)
1137 panic("next too low #3");
1138 if (next >= msginfo.msgseg)
1139 panic("next out of range #3");
1191 }
1192 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
1193
1194 /*
1195 * Return the segments to the user
1196 */
1197
1198 next = msghdr->msg_spot;
1199 for (len = 0; len < msgsz; len += msginfo.msgssz) {
1200 size_t tlen;
1201
1202 if (msgsz - len > msginfo.msgssz)
1203 tlen = msginfo.msgssz;
1204 else
1205 tlen = msgsz - len;
1206 if (next <= -1)
1207 panic("next too low #3");
1208 if (next >= msginfo.msgseg)
1209 panic("next out of range #3");
1140 eval = copyout((caddr_t)&msgpool[next * msginfo.msgssz],
1210 error = copyout((caddr_t)&msgpool[next * msginfo.msgssz],
1141 user_msgp, tlen);
1211 user_msgp, tlen);
1142 if (eval != 0) {
1212 if (error != 0) {
1143#ifdef MSG_DEBUG_OK
1144 printf("error (%d) copying out message segment\n",
1213#ifdef MSG_DEBUG_OK
1214 printf("error (%d) copying out message segment\n",
1145 eval);
1215 error);
1146#endif
1147 msg_freehdr(msghdr);
1148 wakeup((caddr_t)msqptr);
1216#endif
1217 msg_freehdr(msghdr);
1218 wakeup((caddr_t)msqptr);
1149 return(eval);
1219 goto done2;
1150 }
1151 user_msgp = (char *)user_msgp + tlen;
1152 next = msgmaps[next].next;
1153 }
1154
1155 /*
1156 * Done, return the actual number of bytes copied out.
1157 */
1158
1159 msg_freehdr(msghdr);
1160 wakeup((caddr_t)msqptr);
1161 p->p_retval[0] = msgsz;
1220 }
1221 user_msgp = (char *)user_msgp + tlen;
1222 next = msgmaps[next].next;
1223 }
1224
1225 /*
1226 * Done, return the actual number of bytes copied out.
1227 */
1228
1229 msg_freehdr(msghdr);
1230 wakeup((caddr_t)msqptr);
1231 p->p_retval[0] = msgsz;
1162 return(0);
1232done2:
1233 mtx_unlock(&Giant);
1234 return (error);
1163}
1164
1165static int
1166sysctl_msqids(SYSCTL_HANDLER_ARGS)
1167{
1168
1169 return (SYSCTL_OUT(req, msqids,
1170 sizeof(struct msqid_ds) * msginfo.msgmni));
1171}
1172
1173SYSCTL_DECL(_kern_ipc);
1174SYSCTL_INT(_kern_ipc, OID_AUTO, msgmax, CTLFLAG_RD, &msginfo.msgmax, 0, "");
1175SYSCTL_INT(_kern_ipc, OID_AUTO, msgmni, CTLFLAG_RD, &msginfo.msgmni, 0, "");
1176SYSCTL_INT(_kern_ipc, OID_AUTO, msgmnb, CTLFLAG_RD, &msginfo.msgmnb, 0, "");
1177SYSCTL_INT(_kern_ipc, OID_AUTO, msgtql, CTLFLAG_RD, &msginfo.msgtql, 0, "");
1178SYSCTL_INT(_kern_ipc, OID_AUTO, msgssz, CTLFLAG_RD, &msginfo.msgssz, 0, "");
1179SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RD, &msginfo.msgseg, 0, "")
1180SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
1181 NULL, 0, sysctl_msqids, "", "Message queue IDs");
1235}
1236
1237static int
1238sysctl_msqids(SYSCTL_HANDLER_ARGS)
1239{
1240
1241 return (SYSCTL_OUT(req, msqids,
1242 sizeof(struct msqid_ds) * msginfo.msgmni));
1243}
1244
1245SYSCTL_DECL(_kern_ipc);
1246SYSCTL_INT(_kern_ipc, OID_AUTO, msgmax, CTLFLAG_RD, &msginfo.msgmax, 0, "");
1247SYSCTL_INT(_kern_ipc, OID_AUTO, msgmni, CTLFLAG_RD, &msginfo.msgmni, 0, "");
1248SYSCTL_INT(_kern_ipc, OID_AUTO, msgmnb, CTLFLAG_RD, &msginfo.msgmnb, 0, "");
1249SYSCTL_INT(_kern_ipc, OID_AUTO, msgtql, CTLFLAG_RD, &msginfo.msgtql, 0, "");
1250SYSCTL_INT(_kern_ipc, OID_AUTO, msgssz, CTLFLAG_RD, &msginfo.msgssz, 0, "");
1251SYSCTL_INT(_kern_ipc, OID_AUTO, msgseg, CTLFLAG_RD, &msginfo.msgseg, 0, "")
1252SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
1253 NULL, 0, sysctl_msqids, "", "Message queue IDs");