[PATCH] ipc/msg: add msgsnd_timed and msgrcv_timed syscall for system V message queue
Eric Gao
eric.tech at foxmail.com
Sat Feb 27 01:52:02 EST 2021
sometimes, we need the msgsnd or msgrcv syscall can return after a limited
time, so that the business thread do not be blocked here all the time. In
this case, I add the msgsnd_timed and msgrcv_timed syscall that with time
parameter, which has a unit of ms.
Signed-off-by: Eric Gao <eric.tech at foxmail.com>
---
arch/alpha/kernel/syscalls/syscall.tbl | 2 +
arch/arm/tools/syscall.tbl | 2 +
arch/arm64/include/asm/unistd.h | 2 +-
arch/arm64/include/asm/unistd32.h | 4 ++
arch/ia64/kernel/syscalls/syscall.tbl | 2 +
arch/m68k/kernel/syscalls/syscall.tbl | 2 +
arch/microblaze/kernel/syscalls/syscall.tbl | 2 +
arch/mips/kernel/syscalls/syscall_n32.tbl | 2 +
arch/mips/kernel/syscalls/syscall_n64.tbl | 2 +
arch/mips/kernel/syscalls/syscall_o32.tbl | 2 +
arch/parisc/kernel/syscalls/syscall.tbl | 2 +
arch/powerpc/kernel/syscalls/syscall.tbl | 2 +
arch/s390/kernel/syscalls/syscall.tbl | 2 +
arch/sh/kernel/syscalls/syscall.tbl | 2 +
arch/sparc/kernel/syscalls/syscall.tbl | 2 +
arch/x86/entry/syscalls/syscall_32.tbl | 2 +
arch/x86/entry/syscalls/syscall_64.tbl | 2 +
arch/xtensa/kernel/syscalls/syscall.tbl | 2 +
include/linux/compat.h | 4 ++
include/linux/syscalls.h | 4 ++
include/uapi/asm-generic/unistd.h | 6 +-
ipc/msg.c | 87 ++++++++++++++++++++++++++---
kernel/sys_ni.c | 4 ++
23 files changed, 133 insertions(+), 10 deletions(-)
diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl
index 02f0244..eed8cc6 100644
--- a/arch/alpha/kernel/syscalls/syscall.tbl
+++ b/arch/alpha/kernel/syscalls/syscall.tbl
@@ -482,3 +482,5 @@
550 common process_madvise sys_process_madvise
551 common epoll_pwait2 sys_epoll_pwait2
552 common mount_setattr sys_mount_setattr
+553 common msgrcv_timed sys_msgrcv_timed
+554 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/arm/tools/syscall.tbl b/arch/arm/tools/syscall.tbl
index dcc1191..c16baa6 100644
--- a/arch/arm/tools/syscall.tbl
+++ b/arch/arm/tools/syscall.tbl
@@ -456,3 +456,5 @@
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 949788f..64ebdc1e 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -38,7 +38,7 @@
#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5)
#define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800)
-#define __NR_compat_syscalls 443
+#define __NR_compat_syscalls 445
#endif
#define __ARCH_WANT_SYS_CLONE
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 3d874f6..705676a 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -893,6 +893,10 @@ __SYSCALL(__NR_process_madvise, sys_process_madvise)
__SYSCALL(__NR_epoll_pwait2, compat_sys_epoll_pwait2)
#define __NR_mount_setattr 442
__SYSCALL(__NR_mount_setattr, sys_mount_setattr)
+#define __NR_msgrcv_timed 443
+__SYSCALL(__NR_msgrcv_timed, sys_msgrcv_timed)
+#define __NR_msgsnd_timed 444
+__SYSCALL(__NR_msgsnd_timed, sys_msgsnd_timed)
/*
* Please add new compat syscalls above this comment and update
diff --git a/arch/ia64/kernel/syscalls/syscall.tbl b/arch/ia64/kernel/syscalls/syscall.tbl
index d892311..ad57e6d 100644
--- a/arch/ia64/kernel/syscalls/syscall.tbl
+++ b/arch/ia64/kernel/syscalls/syscall.tbl
@@ -363,3 +363,5 @@
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl
index 72bde67..1d33825 100644
--- a/arch/m68k/kernel/syscalls/syscall.tbl
+++ b/arch/m68k/kernel/syscalls/syscall.tbl
@@ -442,3 +442,5 @@
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/microblaze/kernel/syscalls/syscall.tbl b/arch/microblaze/kernel/syscalls/syscall.tbl
index d603a5e..38d7f7a 100644
--- a/arch/microblaze/kernel/syscalls/syscall.tbl
+++ b/arch/microblaze/kernel/syscalls/syscall.tbl
@@ -448,3 +448,5 @@
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl
index 8fd8c17..42b7db5 100644
--- a/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -381,3 +381,5 @@
440 n32 process_madvise sys_process_madvise
441 n32 epoll_pwait2 compat_sys_epoll_pwait2
442 n32 mount_setattr sys_mount_setattr
+443 n32 msgrcv_timed sys_msgrcv_timed
+444 n32 msgsnd_timed sys_msgsnd_timed
diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl
index 169f214..060208b 100644
--- a/arch/mips/kernel/syscalls/syscall_n64.tbl
+++ b/arch/mips/kernel/syscalls/syscall_n64.tbl
@@ -357,3 +357,5 @@
440 n64 process_madvise sys_process_madvise
441 n64 epoll_pwait2 sys_epoll_pwait2
442 n64 mount_setattr sys_mount_setattr
+443 n64 msgrcv_timed sys_msgrcv_timed
+444 n64 msgsnd_timed sys_msgsnd_timed
diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl
index 090d29c..0f1f6ee 100644
--- a/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ b/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -430,3 +430,5 @@
440 o32 process_madvise sys_process_madvise
441 o32 epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 o32 mount_setattr sys_mount_setattr
+443 o32 msgrcv_timed sys_msgrcv_timed
+444 o32 msgsnd_timed sys_msgsnd_timed
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index 271a925..fef5544 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -440,3 +440,5 @@
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed compat_sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed compat_sys_msgsnd_timed
diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl
index 0b2480c..115217c 100644
--- a/arch/powerpc/kernel/syscalls/syscall.tbl
+++ b/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -522,3 +522,5 @@
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed compat_sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed compat_sys_msgsnd_timed
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl
index 3abef21..863b992 100644
--- a/arch/s390/kernel/syscalls/syscall.tbl
+++ b/arch/s390/kernel/syscalls/syscall.tbl
@@ -445,3 +445,5 @@
440 common process_madvise sys_process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed compat_sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed compat_sys_msgsnd_timed
diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl
index d08eeba..24245c0 100644
--- a/arch/sh/kernel/syscalls/syscall.tbl
+++ b/arch/sh/kernel/syscalls/syscall.tbl
@@ -445,3 +445,5 @@
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed
diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl
index 84403a9..d35e062 100644
--- a/arch/sparc/kernel/syscalls/syscall.tbl
+++ b/arch/sparc/kernel/syscalls/syscall.tbl
@@ -488,3 +488,5 @@
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed compat_sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed compat_sys_msgsnd_timed
diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index a1c9f496f..6adc251 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -447,3 +447,5 @@
440 i386 process_madvise sys_process_madvise
441 i386 epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 i386 mount_setattr sys_mount_setattr
+443 i386 msgrcv_timed sys_msgrcv_timed compat_sys_msgrcv_timed
+444 i386 msgsnd_timed sys_msgsnd_timed compat_sys_msgsnd_timed
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 7bf01cb..44e4c63 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -364,6 +364,8 @@
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed
#
# Due to a historical design error, certain syscalls are numbered differently
diff --git a/arch/xtensa/kernel/syscalls/syscall.tbl b/arch/xtensa/kernel/syscalls/syscall.tbl
index 365a9b8..12bdd62 100644
--- a/arch/xtensa/kernel/syscalls/syscall.tbl
+++ b/arch/xtensa/kernel/syscalls/syscall.tbl
@@ -413,3 +413,5 @@
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
+443 common msgrcv_timed sys_msgrcv_timed
+444 common msgsnd_timed sys_msgsnd_timed
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 6e65be7..e2fd2ac 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -743,6 +743,10 @@ asmlinkage long compat_sys_msgrcv(int msqid, compat_uptr_t msgp,
compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg);
asmlinkage long compat_sys_msgsnd(int msqid, compat_uptr_t msgp,
compat_ssize_t msgsz, int msgflg);
+asmlinkage long compat_sys_msgrcv_timed(int msqid, compat_uptr_t msgp,
+ compat_ssize_t msgsz, compat_long_t msgtyp, int msgflg, compat_long_t timeoutms);
+asmlinkage long compat_sys_msgsnd_timed(int msqid, compat_uptr_t msgp,
+ compat_ssize_t msgsz, int msgflg, compat_long_t timeoutms);
/* ipc/sem.c */
asmlinkage long compat_sys_semctl(int semid, int semnum, int cmd, int arg);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 2839dc9..369cc19 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -808,6 +808,10 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp,
size_t msgsz, long msgtyp, int msgflg);
asmlinkage long sys_msgsnd(int msqid, struct msgbuf __user *msgp,
size_t msgsz, int msgflg);
+asmlinkage long sys_msgrcv_timed(int msqid, struct msgbuf __user *msgp,
+ size_t msgsz, long msgtyp, int msgflg, long timeoutms);
+asmlinkage long sys_msgsnd_timed(int msqid, struct msgbuf __user *msgp,
+ size_t msgsz, int msgflg, long timeoutms);
/* ipc/sem.c */
asmlinkage long sys_semget(key_t key, int nsems, int semflg);
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index ce58cff..ef3cfad 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -561,6 +561,10 @@ __SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl)
__SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv)
#define __NR_msgsnd 189
__SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
+#define __NR_msgrcv_timed 443
+__SC_COMP(__NR_msgrcv_timed, sys_msgrcv_timed, compat_sys_msgrcv_timed)
+#define __NR_msgsnd_timed 444
+__SC_COMP(__NR_msgsnd_timed, sys_msgsnd_timed, compat_sys_msgsnd_timed)
/* ipc/sem.c */
#define __NR_semget 190
@@ -865,7 +869,7 @@ __SC_COMP(__NR_epoll_pwait2, sys_epoll_pwait2, compat_sys_epoll_pwait2)
__SYSCALL(__NR_mount_setattr, sys_mount_setattr)
#undef __NR_syscalls
-#define __NR_syscalls 443
+#define __NR_syscalls 445
/*
* 32 bit systems traditionally used different
diff --git a/ipc/msg.c b/ipc/msg.c
index acd1bc7..88167c0 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -838,13 +838,14 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg,
}
static long do_msgsnd(int msqid, long mtype, void __user *mtext,
- size_t msgsz, int msgflg)
+ size_t msgsz, int msgflg, long timeoutms)
{
struct msg_queue *msq;
struct msg_msg *msg;
int err;
struct ipc_namespace *ns;
DEFINE_WAKE_Q(wake_q);
+ bool timeoutflag = false;
ns = current->nsproxy->ipc_ns;
@@ -905,7 +906,15 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext,
ipc_unlock_object(&msq->q_perm);
rcu_read_unlock();
- schedule();
+
+ /* sometimes, we need msgsnd syscall return after a given time */
+ if (timeoutms <= 0) {
+ schedule();
+ } else {
+ timeoutms = schedule_timeout(timeoutms);
+ if (timeoutms == 0)
+ timeoutflag = true;
+ }
rcu_read_lock();
ipc_lock_object(&msq->q_perm);
@@ -918,6 +927,11 @@ static long do_msgsnd(int msqid, long mtype, void __user *mtext,
}
ss_del(&s);
+ if (true == timeoutflag) {
+ err = -ETIME;
+ goto out_unlock0;
+ }
+
if (signal_pending(current)) {
err = -ERESTARTNOHAND;
goto out_unlock0;
@@ -957,7 +971,7 @@ long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz,
if (get_user(mtype, &msgp->mtype))
return -EFAULT;
- return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
+ return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg, 0);
}
SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
@@ -966,6 +980,18 @@ SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
return ksys_msgsnd(msqid, msgp, msgsz, msgflg);
}
+SYSCALL_DEFINE5(msgsnd_timed, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
+ int, msgflg, long, timeoutms)
+{
+ long mtype;
+
+ timeoutms = (timeoutms + 9) / 10;
+
+ if (get_user(mtype, &msgp->mtype))
+ return -EFAULT;
+ return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg, timeoutms);
+}
+
#ifdef CONFIG_COMPAT
struct compat_msgbuf {
@@ -981,7 +1007,7 @@ long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp,
if (get_user(mtype, &up->mtype))
return -EFAULT;
- return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg);
+ return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg, 0);
}
COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
@@ -989,6 +1015,20 @@ COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
{
return compat_ksys_msgsnd(msqid, msgp, msgsz, msgflg);
}
+
+COMPAT_SYSCALL_DEFINE5(msgsnd_timed, int, msqid, compat_uptr_t, msgp,
+ compat_ssize_t, msgsz, int, msgflg, compat_long_t, timeoutms)
+{
+ struct compat_msgbuf __user *up = compat_ptr(msgp);
+ compat_long_t mtype;
+
+ timeoutms = (timeoutms + 9) / 10;
+
+ if (get_user(mtype, &up->mtype))
+ return -EFAULT;
+
+ return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg, (long)timeoutms);
+}
#endif
static inline int convert_mode(long *msgtyp, int msgflg)
@@ -1088,13 +1128,14 @@ static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode)
}
static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg,
- long (*msg_handler)(void __user *, struct msg_msg *, size_t))
+ long (*msg_handler)(void __user *, struct msg_msg *, size_t), long timeoutms)
{
int mode;
struct msg_queue *msq;
struct ipc_namespace *ns;
struct msg_msg *msg, *copy = NULL;
DEFINE_WAKE_Q(wake_q);
+ bool timeoutflag = false;
ns = current->nsproxy->ipc_ns;
@@ -1187,7 +1228,15 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in
ipc_unlock_object(&msq->q_perm);
rcu_read_unlock();
- schedule();
+
+ /* sometimes, we need msgrcv syscall return after a given time */
+ if (timeoutms <= 0) {
+ schedule();
+ } else {
+ timeoutms = schedule_timeout(timeoutms);
+ if (timeoutms == 0)
+ timeoutflag = true;
+ }
/*
* Lockless receive, part 1:
@@ -1229,6 +1278,12 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in
goto out_unlock0;
list_del(&msr_d.r_list);
+
+ if (true == timeoutflag) {
+ msg = ERR_PTR(-ETIME);
+ goto out_unlock0;
+ }
+
if (signal_pending(current)) {
msg = ERR_PTR(-ERESTARTNOHAND);
goto out_unlock0;
@@ -1256,7 +1311,7 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in
long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
long msgtyp, int msgflg)
{
- return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill);
+ return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill, 0);
}
SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
@@ -1265,6 +1320,13 @@ SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
return ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
}
+SYSCALL_DEFINE6(msgrcv_timed, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
+ long, msgtyp, int, msgflg, long, timeoutms)
+{
+ timeoutms = (timeoutms + 9) / 10;
+ return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill, timeoutms);
+}
+
#ifdef CONFIG_COMPAT
static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
{
@@ -1284,7 +1346,7 @@ long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz,
compat_long_t msgtyp, int msgflg)
{
return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
- msgflg, compat_do_msg_fill);
+ msgflg, compat_do_msg_fill, 0);
}
COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
@@ -1293,6 +1355,15 @@ COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
{
return compat_ksys_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg);
}
+
+COMPAT_SYSCALL_DEFINE6(msgrcv_timed, int, msqid, compat_uptr_t, msgp,
+ compat_ssize_t, msgsz, compat_long_t, msgtyp,
+ int, msgflg, compat_long_t, timeoutms)
+{
+ timeoutms = (timeoutms + 9) / 10;
+ return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
+ msgflg, compat_do_msg_fill, (long)timeoutms);
+}
#endif
void msg_init_ns(struct ipc_namespace *ns)
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 19aa8068..783a1de 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -212,6 +212,10 @@ COND_SYSCALL(msgrcv);
COND_SYSCALL_COMPAT(msgrcv);
COND_SYSCALL(msgsnd);
COND_SYSCALL_COMPAT(msgsnd);
+COND_SYSCALL(msgrcv_timed);
+COND_SYSCALL_COMPAT(msgrcv_timed);
+COND_SYSCALL(msgsnd_timed);
+COND_SYSCALL_COMPAT(msgsnd_timed);
/* ipc/sem.c */
COND_SYSCALL(semget);
--
2.7.4
More information about the linux-arm-kernel
mailing list