aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/msg.c
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2013-01-04 18:34:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-01-04 19:11:45 -0500
commitf9dd87f4738c7555aca2cdf8cb2b2326cafb0cad (patch)
tree4fb581910eaee4309ae6befeef8c4f921b274c5d /ipc/msg.c
parent03f595668017f1a1fb971c02fc37140bc6e7bb1c (diff)
ipc: message queue receive cleanup
Move all message related manipulation into one function msg_fill(). Actually, two functions because of the compat one. [akpm@linux-foundation.org: checkpatch fixes] Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Cc: Serge Hallyn <serge.hallyn@canonical.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Pavel Emelyanov <xemul@parallels.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/msg.c')
-rw-r--r--ipc/msg.c44
1 files changed, 23 insertions, 21 deletions
diff --git a/ipc/msg.c b/ipc/msg.c
index 2f272fa76595..cefc24f46e3e 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -755,15 +755,30 @@ static inline int convert_mode(long *msgtyp, int msgflg)
755 return SEARCH_EQUAL; 755 return SEARCH_EQUAL;
756} 756}
757 757
758long do_msgrcv(int msqid, long *pmtype, void __user *mtext, 758static long do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
759 size_t msgsz, long msgtyp, int msgflg) 759{
760 struct msgbuf __user *msgp = dest;
761 size_t msgsz;
762
763 if (put_user(msg->m_type, &msgp->mtype))
764 return -EFAULT;
765
766 msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
767 if (store_msg(msgp->mtext, msg, msgsz))
768 return -EFAULT;
769 return msgsz;
770}
771
772long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
773 int msgflg,
774 long (*msg_handler)(void __user *, struct msg_msg *, size_t))
760{ 775{
761 struct msg_queue *msq; 776 struct msg_queue *msq;
762 struct msg_msg *msg; 777 struct msg_msg *msg;
763 int mode; 778 int mode;
764 struct ipc_namespace *ns; 779 struct ipc_namespace *ns;
765 780
766 if (msqid < 0 || (long) msgsz < 0) 781 if (msqid < 0 || (long) bufsz < 0)
767 return -EINVAL; 782 return -EINVAL;
768 mode = convert_mode(&msgtyp, msgflg); 783 mode = convert_mode(&msgtyp, msgflg);
769 ns = current->nsproxy->ipc_ns; 784 ns = current->nsproxy->ipc_ns;
@@ -804,7 +819,7 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
804 * Found a suitable message. 819 * Found a suitable message.
805 * Unlink it from the queue. 820 * Unlink it from the queue.
806 */ 821 */
807 if ((msgsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) { 822 if ((bufsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) {
808 msg = ERR_PTR(-E2BIG); 823 msg = ERR_PTR(-E2BIG);
809 goto out_unlock; 824 goto out_unlock;
810 } 825 }
@@ -831,7 +846,7 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
831 if (msgflg & MSG_NOERROR) 846 if (msgflg & MSG_NOERROR)
832 msr_d.r_maxsize = INT_MAX; 847 msr_d.r_maxsize = INT_MAX;
833 else 848 else
834 msr_d.r_maxsize = msgsz; 849 msr_d.r_maxsize = bufsz;
835 msr_d.r_msg = ERR_PTR(-EAGAIN); 850 msr_d.r_msg = ERR_PTR(-EAGAIN);
836 current->state = TASK_INTERRUPTIBLE; 851 current->state = TASK_INTERRUPTIBLE;
837 msg_unlock(msq); 852 msg_unlock(msq);
@@ -894,29 +909,16 @@ out_unlock:
894 if (IS_ERR(msg)) 909 if (IS_ERR(msg))
895 return PTR_ERR(msg); 910 return PTR_ERR(msg);
896 911
897 msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz; 912 bufsz = msg_handler(buf, msg, bufsz);
898 *pmtype = msg->m_type;
899 if (store_msg(mtext, msg, msgsz))
900 msgsz = -EFAULT;
901
902 free_msg(msg); 913 free_msg(msg);
903 914
904 return msgsz; 915 return bufsz;
905} 916}
906 917
907SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, 918SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
908 long, msgtyp, int, msgflg) 919 long, msgtyp, int, msgflg)
909{ 920{
910 long err, mtype; 921 return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill);
911
912 err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg);
913 if (err < 0)
914 goto out;
915
916 if (put_user(mtype, &msgp->mtype))
917 err = -EFAULT;
918out:
919 return err;
920} 922}
921 923
922#ifdef CONFIG_PROC_FS 924#ifdef CONFIG_PROC_FS