Deleted Added
full compact
sysv_msg.c (164368) sysv_msg.c (165403)
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.

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

43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 */
49
50#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.

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

43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 */
49
50#include <sys/cdefs.h>
51__FBSDID("$FreeBSD: head/sys/kern/sysv_msg.c 164368 2006-11-17 20:43:01Z jkim $");
51__FBSDID("$FreeBSD: head/sys/kern/sysv_msg.c 165403 2006-12-20 19:26:30Z jkim $");
52
53#include "opt_sysvipc.h"
54#include "opt_mac.h"
55
56#include <sys/param.h>
57#include <sys/systm.h>
58#include <sys/sysproto.h>
59#include <sys/kernel.h>

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

391 struct thread *td;
392 register struct msgctl_args *uap;
393{
394 int msqid = uap->msqid;
395 int cmd = uap->cmd;
396 struct msqid_ds msqbuf;
397 int error;
398
52
53#include "opt_sysvipc.h"
54#include "opt_mac.h"
55
56#include <sys/param.h>
57#include <sys/systm.h>
58#include <sys/sysproto.h>
59#include <sys/kernel.h>

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

391 struct thread *td;
392 register struct msgctl_args *uap;
393{
394 int msqid = uap->msqid;
395 int cmd = uap->cmd;
396 struct msqid_ds msqbuf;
397 int error;
398
399 DPRINTF(("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, uap->buf));
399 DPRINTF(("call to msgctl(%d, %d, %p)\n", msqid, cmd, uap->buf));
400 if (cmd == IPC_SET &&
401 (error = copyin(uap->buf, &msqbuf, sizeof(msqbuf))) != 0)
402 return (error);
403 error = kern_msgctl(td, msqid, cmd, &msqbuf);
404 if (cmd == IPC_STAT && error == 0)
405 error = copyout(&msqbuf, uap->buf, sizeof(struct msqid_ds));
406 return (error);
407}

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

666struct msgsnd_args {
667 int msqid;
668 const void *msgp;
669 size_t msgsz;
670 int msgflg;
671};
672#endif
673
400 if (cmd == IPC_SET &&
401 (error = copyin(uap->buf, &msqbuf, sizeof(msqbuf))) != 0)
402 return (error);
403 error = kern_msgctl(td, msqid, cmd, &msqbuf);
404 if (cmd == IPC_STAT && error == 0)
405 error = copyout(&msqbuf, uap->buf, sizeof(struct msqid_ds));
406 return (error);
407}

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

666struct msgsnd_args {
667 int msqid;
668 const void *msgp;
669 size_t msgsz;
670 int msgflg;
671};
672#endif
673
674/*
675 * MPSAFE
676 */
677int
674int
678msgsnd(td, uap)
675kern_msgsnd(td, msqid, msgp, msgsz, msgflg, mtype)
679 struct thread *td;
676 struct thread *td;
680 register struct msgsnd_args *uap;
677 int msqid;
678 const void *msgp; /* XXX msgp is actually mtext. */
679 size_t msgsz;
680 int msgflg;
681 long mtype;
681{
682{
682 int msqid = uap->msqid;
683 const void *user_msgp = uap->msgp;
684 size_t msgsz = uap->msgsz;
685 int msgflg = uap->msgflg;
686 int segs_needed, error = 0;
683 int msqix, segs_needed, error = 0;
687 register struct msqid_kernel *msqkptr;
688 register struct msg *msghdr;
689 short next;
690
684 register struct msqid_kernel *msqkptr;
685 register struct msg *msghdr;
686 short next;
687
691 DPRINTF(("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
692 msgflg));
693 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
694 return (ENOSYS);
695
696 mtx_lock(&msq_mtx);
688 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
689 return (ENOSYS);
690
691 mtx_lock(&msq_mtx);
697 msqid = IPCID_TO_IX(msqid);
692 msqix = IPCID_TO_IX(msqid);
698
693
699 if (msqid < 0 || msqid >= msginfo.msgmni) {
700 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
694 if (msqix < 0 || msqix >= msginfo.msgmni) {
695 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqix,
701 msginfo.msgmni));
702 error = EINVAL;
703 goto done2;
704 }
705
696 msginfo.msgmni));
697 error = EINVAL;
698 goto done2;
699 }
700
706 msqkptr = &msqids[msqid];
701 msqkptr = &msqids[msqix];
707 if (msqkptr->u.msg_qbytes == 0) {
708 DPRINTF(("no such message queue id\n"));
709 error = EINVAL;
710 goto done2;
711 }
702 if (msqkptr->u.msg_qbytes == 0) {
703 DPRINTF(("no such message queue id\n"));
704 error = EINVAL;
705 goto done2;
706 }
712 if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
707 if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(msqid)) {
713 DPRINTF(("wrong sequence number\n"));
714 error = EINVAL;
715 goto done2;
716 }
717
718 if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_W))) {
719 DPRINTF(("requester doesn't have write access\n"));
720 goto done2;
721 }
722
723#ifdef MAC
724 error = mac_check_sysv_msqsnd(td->td_ucred, msqkptr);
725 if (error != 0)
726 goto done2;
727#endif
728
729 segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
708 DPRINTF(("wrong sequence number\n"));
709 error = EINVAL;
710 goto done2;
711 }
712
713 if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_W))) {
714 DPRINTF(("requester doesn't have write access\n"));
715 goto done2;
716 }
717
718#ifdef MAC
719 error = mac_check_sysv_msqsnd(td->td_ucred, msqkptr);
720 if (error != 0)
721 goto done2;
722#endif
723
724 segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
730 DPRINTF(("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz,
731 segs_needed));
725 DPRINTF(("msgsz=%zu, msgssz=%d, segs_needed=%d\n", msgsz,
726 msginfo.msgssz, segs_needed));
732 for (;;) {
733 int need_more_resources = 0;
734
735 /*
736 * check msgsz
737 * (inside this loop in case msg_qbytes changes while we sleep)
738 */
739

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

838 /*
839 * Allocate a message header
840 */
841
842 msghdr = free_msghdrs;
843 free_msghdrs = msghdr->msg_next;
844 msghdr->msg_spot = -1;
845 msghdr->msg_ts = msgsz;
727 for (;;) {
728 int need_more_resources = 0;
729
730 /*
731 * check msgsz
732 * (inside this loop in case msg_qbytes changes while we sleep)
733 */
734

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

833 /*
834 * Allocate a message header
835 */
836
837 msghdr = free_msghdrs;
838 free_msghdrs = msghdr->msg_next;
839 msghdr->msg_spot = -1;
840 msghdr->msg_ts = msgsz;
841 msghdr->msg_type = mtype;
846#ifdef MAC
847 /*
848 * XXXMAC: Should the mac_check_sysv_msgmsq check follow here
849 * immediately? Or, should it be checked just before the msg is
850 * enqueued in the msgq (as it is done now)?
851 */
852 mac_create_sysv_msgmsg(td->td_ucred, msqkptr, msghdr);
853#endif

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

870 free_msgmaps = msgmaps[next].next;
871 nfree_msgmaps--;
872 msgmaps[next].next = msghdr->msg_spot;
873 msghdr->msg_spot = next;
874 segs_needed--;
875 }
876
877 /*
842#ifdef MAC
843 /*
844 * XXXMAC: Should the mac_check_sysv_msgmsq check follow here
845 * immediately? Or, should it be checked just before the msg is
846 * enqueued in the msgq (as it is done now)?
847 */
848 mac_create_sysv_msgmsg(td->td_ucred, msqkptr, msghdr);
849#endif

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

866 free_msgmaps = msgmaps[next].next;
867 nfree_msgmaps--;
868 msgmaps[next].next = msghdr->msg_spot;
869 msghdr->msg_spot = next;
870 segs_needed--;
871 }
872
873 /*
878 * Copy in the message type
879 */
880
881 mtx_unlock(&msq_mtx);
882 if ((error = copyin(user_msgp, &msghdr->msg_type,
883 sizeof(msghdr->msg_type))) != 0) {
884 mtx_lock(&msq_mtx);
885 DPRINTF(("error %d copying the message type\n", error));
886 msg_freehdr(msghdr);
887 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
888 wakeup(msqkptr);
889 goto done2;
890 }
891 mtx_lock(&msq_mtx);
892 user_msgp = (const char *)user_msgp + sizeof(msghdr->msg_type);
893
894 /*
895 * Validate the message type
896 */
897
898 if (msghdr->msg_type < 1) {
899 msg_freehdr(msghdr);
900 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
901 wakeup(msqkptr);
874 * Validate the message type
875 */
876
877 if (msghdr->msg_type < 1) {
878 msg_freehdr(msghdr);
879 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
880 wakeup(msqkptr);
902 DPRINTF(("mtype (%d) < 1\n", msghdr->msg_type));
881 DPRINTF(("mtype (%ld) < 1\n", msghdr->msg_type));
903 error = EINVAL;
904 goto done2;
905 }
906
907 /*
908 * Copy in the message body
909 */
910

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

915 tlen = msginfo.msgssz;
916 else
917 tlen = msgsz;
918 if (next <= -1)
919 panic("next too low #2");
920 if (next >= msginfo.msgseg)
921 panic("next out of range #2");
922 mtx_unlock(&msq_mtx);
882 error = EINVAL;
883 goto done2;
884 }
885
886 /*
887 * Copy in the message body
888 */
889

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

894 tlen = msginfo.msgssz;
895 else
896 tlen = msgsz;
897 if (next <= -1)
898 panic("next too low #2");
899 if (next >= msginfo.msgseg)
900 panic("next out of range #2");
901 mtx_unlock(&msq_mtx);
923 if ((error = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
902 if ((error = copyin(msgp, &msgpool[next * msginfo.msgssz],
924 tlen)) != 0) {
925 mtx_lock(&msq_mtx);
926 DPRINTF(("error %d copying in message segment\n",
927 error));
928 msg_freehdr(msghdr);
929 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
930 wakeup(msqkptr);
931 goto done2;
932 }
933 mtx_lock(&msq_mtx);
934 msgsz -= tlen;
903 tlen)) != 0) {
904 mtx_lock(&msq_mtx);
905 DPRINTF(("error %d copying in message segment\n",
906 error));
907 msg_freehdr(msghdr);
908 msqkptr->u.msg_perm.mode &= ~MSG_LOCKED;
909 wakeup(msqkptr);
910 goto done2;
911 }
912 mtx_lock(&msq_mtx);
913 msgsz -= tlen;
935 user_msgp = (const char *)user_msgp + tlen;
914 msgp = (const char *)msgp + tlen;
936 next = msgmaps[next].next;
937 }
938 if (next != -1)
939 panic("didn't use all the msg segments");
940
941 /*
942 * We've got the message. Unlock the msqid_ds.
943 */

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

994
995 wakeup(msqkptr);
996 td->td_retval[0] = 0;
997done2:
998 mtx_unlock(&msq_mtx);
999 return (error);
1000}
1001
915 next = msgmaps[next].next;
916 }
917 if (next != -1)
918 panic("didn't use all the msg segments");
919
920 /*
921 * We've got the message. Unlock the msqid_ds.
922 */

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

973
974 wakeup(msqkptr);
975 td->td_retval[0] = 0;
976done2:
977 mtx_unlock(&msq_mtx);
978 return (error);
979}
980
981/*
982 * MPSAFE
983 */
984int
985msgsnd(td, uap)
986 struct thread *td;
987 register struct msgsnd_args *uap;
988{
989 int error;
990 long mtype;
991
992 DPRINTF(("call to msgsnd(%d, %p, %zu, %d)\n", uap->msqid, uap->msgp,
993 uap->msgsz, uap->msgflg));
994
995 if ((error = copyin(uap->msgp, &mtype, sizeof(mtype))) != 0) {
996 DPRINTF(("error %d copying the message type\n", error));
997 return (error);
998 }
999 return (kern_msgsnd(td, uap->msqid,
1000 (const char *)uap->msgp + sizeof(mtype),
1001 uap->msgsz, uap->msgflg, mtype));
1002}
1003
1002#ifndef _SYS_SYSPROTO_H_
1003struct msgrcv_args {
1004 int msqid;
1005 void *msgp;
1006 size_t msgsz;
1007 long msgtyp;
1008 int msgflg;
1009};
1010#endif
1011
1004#ifndef _SYS_SYSPROTO_H_
1005struct msgrcv_args {
1006 int msqid;
1007 void *msgp;
1008 size_t msgsz;
1009 long msgtyp;
1010 int msgflg;
1011};
1012#endif
1013
1012/*
1013 * MPSAFE
1014 */
1015int
1014int
1016msgrcv(td, uap)
1015kern_msgrcv(td, msqid, msgp, msgsz, msgtyp, msgflg, mtype)
1017 struct thread *td;
1016 struct thread *td;
1018 register struct msgrcv_args *uap;
1017 int msqid;
1018 void *msgp; /* XXX msgp is actually mtext. */
1019 size_t msgsz;
1020 long msgtyp;
1021 int msgflg;
1022 long *mtype;
1019{
1023{
1020 int msqid = uap->msqid;
1021 void *user_msgp = uap->msgp;
1022 size_t msgsz = uap->msgsz;
1023 long msgtyp = uap->msgtyp;
1024 int msgflg = uap->msgflg;
1025 size_t len;
1026 register struct msqid_kernel *msqkptr;
1027 register struct msg *msghdr;
1024 size_t len;
1025 register struct msqid_kernel *msqkptr;
1026 register struct msg *msghdr;
1028 int error = 0;
1027 int msqix, error = 0;
1029 short next;
1030
1028 short next;
1029
1031 DPRINTF(("call to msgrcv(%d, 0x%x, %d, %ld, %d)\n", msqid, user_msgp,
1032 msgsz, msgtyp, msgflg));
1033
1034 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
1035 return (ENOSYS);
1036
1030 if (!jail_sysvipc_allowed && jailed(td->td_ucred))
1031 return (ENOSYS);
1032
1037 msqid = IPCID_TO_IX(msqid);
1033 msqix = IPCID_TO_IX(msqid);
1038
1034
1039 if (msqid < 0 || msqid >= msginfo.msgmni) {
1040 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
1035 if (msqix < 0 || msqix >= msginfo.msgmni) {
1036 DPRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqix,
1041 msginfo.msgmni));
1042 return (EINVAL);
1043 }
1044
1037 msginfo.msgmni));
1038 return (EINVAL);
1039 }
1040
1045 msqkptr = &msqids[msqid];
1041 msqkptr = &msqids[msqix];
1046 mtx_lock(&msq_mtx);
1047 if (msqkptr->u.msg_qbytes == 0) {
1048 DPRINTF(("no such message queue id\n"));
1049 error = EINVAL;
1050 goto done2;
1051 }
1042 mtx_lock(&msq_mtx);
1043 if (msqkptr->u.msg_qbytes == 0) {
1044 DPRINTF(("no such message queue id\n"));
1045 error = EINVAL;
1046 goto done2;
1047 }
1052 if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
1048 if (msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(msqid)) {
1053 DPRINTF(("wrong sequence number\n"));
1054 error = EINVAL;
1055 goto done2;
1056 }
1057
1058 if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_R))) {
1059 DPRINTF(("requester doesn't have read access\n"));
1060 goto done2;

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

1069 msghdr = NULL;
1070 while (msghdr == NULL) {
1071 if (msgtyp == 0) {
1072 msghdr = msqkptr->u.msg_first;
1073 if (msghdr != NULL) {
1074 if (msgsz < msghdr->msg_ts &&
1075 (msgflg & MSG_NOERROR) == 0) {
1076 DPRINTF(("first message on the queue "
1049 DPRINTF(("wrong sequence number\n"));
1050 error = EINVAL;
1051 goto done2;
1052 }
1053
1054 if ((error = ipcperm(td, &msqkptr->u.msg_perm, IPC_R))) {
1055 DPRINTF(("requester doesn't have read access\n"));
1056 goto done2;

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

1065 msghdr = NULL;
1066 while (msghdr == NULL) {
1067 if (msgtyp == 0) {
1068 msghdr = msqkptr->u.msg_first;
1069 if (msghdr != NULL) {
1070 if (msgsz < msghdr->msg_ts &&
1071 (msgflg & MSG_NOERROR) == 0) {
1072 DPRINTF(("first message on the queue "
1077 "is too big (want %d, got %d)\n",
1073 "is too big (want %zu, got %d)\n",
1078 msgsz, msghdr->msg_ts));
1079 error = E2BIG;
1080 goto done2;
1081 }
1082#ifdef MAC
1083 error = mac_check_sysv_msgrcv(td->td_ucred,
1084 msghdr);
1085 if (error != 0)

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

1107 * the absolute value of a negative msgtyp?
1108 * Note that the second half of this test can
1109 * NEVER be true if msgtyp is positive since
1110 * msg_type is always positive!
1111 */
1112
1113 if (msgtyp == msghdr->msg_type ||
1114 msghdr->msg_type <= -msgtyp) {
1074 msgsz, msghdr->msg_ts));
1075 error = E2BIG;
1076 goto done2;
1077 }
1078#ifdef MAC
1079 error = mac_check_sysv_msgrcv(td->td_ucred,
1080 msghdr);
1081 if (error != 0)

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

1103 * the absolute value of a negative msgtyp?
1104 * Note that the second half of this test can
1105 * NEVER be true if msgtyp is positive since
1106 * msg_type is always positive!
1107 */
1108
1109 if (msgtyp == msghdr->msg_type ||
1110 msghdr->msg_type <= -msgtyp) {
1115 DPRINTF(("found message type %d, "
1116 "requested %d\n",
1111 DPRINTF(("found message type %ld, "
1112 "requested %ld\n",
1117 msghdr->msg_type, msgtyp));
1118 if (msgsz < msghdr->msg_ts &&
1119 (msgflg & MSG_NOERROR) == 0) {
1120 DPRINTF(("requested message "
1121 "on the queue is too big "
1113 msghdr->msg_type, msgtyp));
1114 if (msgsz < msghdr->msg_ts &&
1115 (msgflg & MSG_NOERROR) == 0) {
1116 DPRINTF(("requested message "
1117 "on the queue is too big "
1122 "(want %d, got %d)\n",
1118 "(want %zu, got %hu)\n",
1123 msgsz, msghdr->msg_ts));
1124 error = E2BIG;
1125 goto done2;
1126 }
1127#ifdef MAC
1128 error = mac_check_sysv_msgrcv(
1129 td->td_ucred, msghdr);
1130 if (error != 0)

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

1164 if (msghdr != NULL)
1165 break;
1166
1167 /*
1168 * Hmph! No message found. Does the user want to wait?
1169 */
1170
1171 if ((msgflg & IPC_NOWAIT) != 0) {
1119 msgsz, msghdr->msg_ts));
1120 error = E2BIG;
1121 goto done2;
1122 }
1123#ifdef MAC
1124 error = mac_check_sysv_msgrcv(
1125 td->td_ucred, msghdr);
1126 if (error != 0)

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

1160 if (msghdr != NULL)
1161 break;
1162
1163 /*
1164 * Hmph! No message found. Does the user want to wait?
1165 */
1166
1167 if ((msgflg & IPC_NOWAIT) != 0) {
1172 DPRINTF(("no appropriate message found (msgtyp=%d)\n",
1168 DPRINTF(("no appropriate message found (msgtyp=%ld)\n",
1173 msgtyp));
1174 /* The SVID says to return ENOMSG. */
1175 error = ENOMSG;
1176 goto done2;
1177 }
1178
1179 /*
1180 * Wait for something to happen

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

1191 goto done2;
1192 }
1193
1194 /*
1195 * Make sure that the msq queue still exists
1196 */
1197
1198 if (msqkptr->u.msg_qbytes == 0 ||
1169 msgtyp));
1170 /* The SVID says to return ENOMSG. */
1171 error = ENOMSG;
1172 goto done2;
1173 }
1174
1175 /*
1176 * Wait for something to happen

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

1187 goto done2;
1188 }
1189
1190 /*
1191 * Make sure that the msq queue still exists
1192 */
1193
1194 if (msqkptr->u.msg_qbytes == 0 ||
1199 msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
1195 msqkptr->u.msg_perm.seq != IPCID_TO_SEQ(msqid)) {
1200 DPRINTF(("msqid deleted\n"));
1201 error = EIDRM;
1202 goto done2;
1203 }
1204 }
1205
1206 /*
1207 * Return the message to the user.

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

1215 msqkptr->u.msg_rtime = time_second;
1216
1217 /*
1218 * Make msgsz the actual amount that we'll be returning.
1219 * Note that this effectively truncates the message if it is too long
1220 * (since msgsz is never increased).
1221 */
1222
1196 DPRINTF(("msqid deleted\n"));
1197 error = EIDRM;
1198 goto done2;
1199 }
1200 }
1201
1202 /*
1203 * Return the message to the user.

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

1211 msqkptr->u.msg_rtime = time_second;
1212
1213 /*
1214 * Make msgsz the actual amount that we'll be returning.
1215 * Note that this effectively truncates the message if it is too long
1216 * (since msgsz is never increased).
1217 */
1218
1223 DPRINTF(("found a message, msgsz=%d, msg_ts=%d\n", msgsz,
1219 DPRINTF(("found a message, msgsz=%zu, msg_ts=%hu\n", msgsz,
1224 msghdr->msg_ts));
1225 if (msgsz > msghdr->msg_ts)
1226 msgsz = msghdr->msg_ts;
1220 msghdr->msg_ts));
1221 if (msgsz > msghdr->msg_ts)
1222 msgsz = msghdr->msg_ts;
1223 *mtype = msghdr->msg_type;
1227
1228 /*
1224
1225 /*
1229 * Return the type to the user.
1230 */
1231
1232 mtx_unlock(&msq_mtx);
1233 error = copyout(&(msghdr->msg_type), user_msgp,
1234 sizeof(msghdr->msg_type));
1235 mtx_lock(&msq_mtx);
1236 if (error != 0) {
1237 DPRINTF(("error (%d) copying out message type\n", error));
1238 msg_freehdr(msghdr);
1239 wakeup(msqkptr);
1240 goto done2;
1241 }
1242 user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
1243
1244 /*
1245 * Return the segments to the user
1246 */
1247
1248 next = msghdr->msg_spot;
1249 for (len = 0; len < msgsz; len += msginfo.msgssz) {
1250 size_t tlen;
1251
1252 if (msgsz - len > msginfo.msgssz)
1253 tlen = msginfo.msgssz;
1254 else
1255 tlen = msgsz - len;
1256 if (next <= -1)
1257 panic("next too low #3");
1258 if (next >= msginfo.msgseg)
1259 panic("next out of range #3");
1260 mtx_unlock(&msq_mtx);
1226 * Return the segments to the user
1227 */
1228
1229 next = msghdr->msg_spot;
1230 for (len = 0; len < msgsz; len += msginfo.msgssz) {
1231 size_t tlen;
1232
1233 if (msgsz - len > msginfo.msgssz)
1234 tlen = msginfo.msgssz;
1235 else
1236 tlen = msgsz - len;
1237 if (next <= -1)
1238 panic("next too low #3");
1239 if (next >= msginfo.msgseg)
1240 panic("next out of range #3");
1241 mtx_unlock(&msq_mtx);
1261 error = copyout(&msgpool[next * msginfo.msgssz],
1262 user_msgp, tlen);
1242 error = copyout(&msgpool[next * msginfo.msgssz], msgp, tlen);
1263 mtx_lock(&msq_mtx);
1264 if (error != 0) {
1265 DPRINTF(("error (%d) copying out message segment\n",
1266 error));
1267 msg_freehdr(msghdr);
1268 wakeup(msqkptr);
1269 goto done2;
1270 }
1243 mtx_lock(&msq_mtx);
1244 if (error != 0) {
1245 DPRINTF(("error (%d) copying out message segment\n",
1246 error));
1247 msg_freehdr(msghdr);
1248 wakeup(msqkptr);
1249 goto done2;
1250 }
1271 user_msgp = (char *)user_msgp + tlen;
1251 msgp = (char *)msgp + tlen;
1272 next = msgmaps[next].next;
1273 }
1274
1275 /*
1276 * Done, return the actual number of bytes copied out.
1277 */
1278
1279 msg_freehdr(msghdr);
1280 wakeup(msqkptr);
1281 td->td_retval[0] = msgsz;
1282done2:
1283 mtx_unlock(&msq_mtx);
1284 return (error);
1285}
1286
1252 next = msgmaps[next].next;
1253 }
1254
1255 /*
1256 * Done, return the actual number of bytes copied out.
1257 */
1258
1259 msg_freehdr(msghdr);
1260 wakeup(msqkptr);
1261 td->td_retval[0] = msgsz;
1262done2:
1263 mtx_unlock(&msq_mtx);
1264 return (error);
1265}
1266
1267/*
1268 * MPSAFE
1269 */
1270int
1271msgrcv(td, uap)
1272 struct thread *td;
1273 register struct msgrcv_args *uap;
1274{
1275 int error;
1276 long mtype;
1277
1278 DPRINTF(("call to msgrcv(%d, %p, %zu, %ld, %d)\n", uap->msqid,
1279 uap->msgp, uap->msgsz, uap->msgtyp, uap->msgflg));
1280
1281 if ((error = kern_msgrcv(td, uap->msqid,
1282 (char *)uap->msgp + sizeof(mtype), uap->msgsz,
1283 uap->msgtyp, uap->msgflg, &mtype)) != 0)
1284 return (error);
1285 if ((error = copyout(&mtype, uap->msgp, sizeof(mtype))) != 0)
1286 DPRINTF(("error %d copying the message type\n", error));
1287 return (error);
1288}
1289
1287static int
1288sysctl_msqids(SYSCTL_HANDLER_ARGS)
1289{
1290
1291 return (SYSCTL_OUT(req, msqids,
1292 sizeof(struct msqid_kernel) * msginfo.msgmni));
1293}
1294

--- 14 unchanged lines hidden ---
1290static int
1291sysctl_msqids(SYSCTL_HANDLER_ARGS)
1292{
1293
1294 return (SYSCTL_OUT(req, msqids,
1295 sizeof(struct msqid_kernel) * msginfo.msgmni));
1296}
1297

--- 14 unchanged lines hidden ---