]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add support for the POSIX message queue system calls.
authorTom Hughes <tom@compton.nu>
Sat, 14 Aug 2004 18:52:27 +0000 (18:52 +0000)
committerTom Hughes <tom@compton.nu>
Sat, 14 Aug 2004 18:52:27 +0000 (18:52 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2585

configure.in
coregrind/vg_syscalls.c
include/vg_kerneliface.h
none/tests/Makefile.am
none/tests/mq.c [new file with mode: 0644]
none/tests/mq.stderr.exp [new file with mode: 0644]
none/tests/mq.vgtest [new file with mode: 0644]

index b77a869c66d9e60850147474c0cb66b9848425ee..6d65c2ecdd86f27795527f00e7629f263304e152 100644 (file)
@@ -331,7 +331,7 @@ AC_SUBST(PREFERRED_STACK_BOUNDARY)
 
 # Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h sys/statfs.h sys/time.h sys/endian.h endian.h termios.h unistd.h utime.h linux/fb.h linux/mii.h])
+AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h sys/statfs.h sys/time.h sys/endian.h endian.h termios.h unistd.h utime.h linux/fb.h linux/mii.h mqueue.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_TYPE_UID_T
index 687c10b8f4c7a1afea6939fe4f5395f4629af59a..15246e3b746ffcecafbcd48638ad3994874f9bea 100644 (file)
@@ -5548,6 +5548,118 @@ POST(io_cancel)
    VG_TRACK( post_mem_write, arg3, sizeof(vki_io_event) );
 }
 
+PRE(mq_open)
+{
+   /* mqd_t mq_open(const char *name, int oflag, ...); */
+   MAYBE_PRINTF("mq_open( %p(%s), %d )\n", arg1,arg1,arg2);
+   SYSCALL_TRACK( pre_mem_read_asciiz, tid, "mq_open(name)", arg1 );
+   if ((arg2 & VKI_O_CREAT) != 0 && arg4 != 0) {
+      const struct vki_mq_attr *attr = (struct vki_mq_attr *)arg4;
+      SYSCALL_TRACK( pre_mem_read, tid, "mq_open(attr->mq_maxmsg)",
+                     (Addr)&attr->mq_maxmsg, sizeof(attr->mq_maxmsg) );
+      SYSCALL_TRACK( pre_mem_read, tid, "mq_open(attr->mq_msgsize)",
+                     (Addr)&attr->mq_msgsize, sizeof(attr->mq_msgsize) );
+   }
+}
+
+POST(mq_open)
+{
+   if (!fd_allowed(res, "mq_open", tid, True)) {
+      VG_(close)(res);
+      res = -VKI_EMFILE;
+   } else {
+      if (VG_(clo_track_fds))
+         record_fd_open(tid, res, VG_(arena_strdup)(VG_AR_CORE, (Char*)arg1));
+   }
+   MAYBE_PRINTF("%d\n",res);
+}
+
+PRE(mq_unlink)
+{
+   /* int mq_unlink(const char *name) */
+   MAYBE_PRINTF("mq_unlink ( %p \"%s\" )\n",arg1, arg1);
+   SYSCALL_TRACK( pre_mem_read_asciiz, tid, "mq_unlink(name)", arg1 );
+}
+
+PRE(mq_timedsend)
+{
+   /* int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
+                       unsigned msg_prio, const struct timespec *abs_timeout); */
+   MAYBE_PRINTF("mq_timedsend ( %d, %p, %d, %d, %p )\n",
+                arg1,arg2,arg3,arg4,arg5);
+   if (!fd_allowed(arg1, "mq_timedsend", tid, False)) {
+      res = -VKI_EBADF;
+   } else {
+      SYSCALL_TRACK( pre_mem_read, tid, "mq_timedsend(msg_ptr)", arg2, arg3 );
+      if (arg5 != 0)
+         SYSCALL_TRACK( pre_mem_read, tid, "mq_timedsend(abs_timeout)", arg5,
+                        sizeof(struct timespec) );
+   }
+}
+
+PRE(mq_timedreceive)
+{
+   /* ssize_t mq_timedreceive(mqd_t mqdes, char *restrict msg_ptr,
+                              size_t msg_len, unsigned *restrict msg_prio,
+                              const struct timespec *restrict abs_timeout); */
+   MAYBE_PRINTF("mq_timedreceive( %d, %p, %d, %p, %p )\n",
+                arg1,arg2,arg3,arg4,arg5);
+   if (!fd_allowed(arg1, "mq_timedreceive", tid, False)) {
+      res = -VKI_EBADF;
+   } else {
+      SYSCALL_TRACK( pre_mem_write, tid, "mq_timedreceive(msg_ptr)", arg2, arg3 );
+      if (arg4 != 0)
+         SYSCALL_TRACK( pre_mem_write, tid, "mq_timedreceive(msg_prio)",
+                        arg4, sizeof(unsigned int) );
+      if (arg5 != 0)
+         SYSCALL_TRACK( pre_mem_read, tid, "mq_timedreceive(abs_timeout)",
+                        arg5, sizeof(struct timespec) );
+   }
+}
+
+POST(mq_timedreceive)
+{
+   VG_TRACK( post_mem_write, arg2, arg3 );
+   if (arg4 != 0)
+      VG_TRACK( post_mem_write, arg4, sizeof(unsigned int) );
+}
+
+PRE(mq_notify)
+{
+   /* int mq_notify(mqd_t mqdes, const struct sigevent *notification); */
+   MAYBE_PRINTF("mq_notify( %d, %p )\n", arg1,arg2 );
+   if (!fd_allowed(arg1, "mq_notify", tid, False))
+      res = -VKI_EBADF;
+   else if (arg2 != 0)
+      SYSCALL_TRACK( pre_mem_read, tid, "mq_notify", arg2,
+                     sizeof(struct sigevent) );
+}
+
+PRE(mq_getsetattr)
+{
+   /* int mq_getsetattr(mqd_t mqdes, const struct mq_attr *restrict mqstat,
+                        struct mq_attr *restrict omqstat); */
+   MAYBE_PRINTF("mq_getsetattr( %d, %p, %p )\n", arg1,arg2,arg3 );
+   if (!fd_allowed(arg1, "mq_getsetattr", tid, False)) {
+      res = -VKI_EBADF;
+   } else {
+      if (arg2 != 0) {
+         const struct vki_mq_attr *attr = (struct vki_mq_attr *)arg2;
+         SYSCALL_TRACK( pre_mem_read, tid, "mq_getsetattr(mqstat->mq_flags)",
+                        (Addr)&attr->mq_flags, sizeof(attr->mq_flags) );
+      }
+      if (arg3 != 0)
+         SYSCALL_TRACK( pre_mem_write, tid, "mq_getsetattr(omqstat)", arg3,
+                        sizeof(struct vki_mq_attr) );
+   }   
+}
+
+POST(mq_getsetattr)
+{
+   if (arg3 != 0)
+      VG_TRACK( post_mem_write, arg3, sizeof(struct vki_mq_attr) );
+}
+
 #undef SYSNO
 #undef res
 #undef arg1
@@ -5822,6 +5934,13 @@ static const struct sys_info sys_info[] = {
    SYSB_(io_submit,             0),
    SYSBA(io_cancel,             0),
 
+   SYSBA(mq_open,               0),
+   SYSB_(mq_unlink,             0),
+   SYSB_(mq_timedsend,          MayBlock),
+   SYSBA(mq_timedreceive,       MayBlock),
+   SYSB_(mq_notify,             0),
+   SYSBA(mq_getsetattr,         0),
+
 #if !SIGNAL_SIMULATION
    SYSBA(sigaltstack,          0),
    SYSBA(rt_sigaction,         0),
index c4b02202ee875528c31833734deb4b392de33c67..6038623294d7decd69e5b3bc6aa0187c52f81d9e 100644 (file)
@@ -953,6 +953,17 @@ enum {
     VKI_IOCB_CMD_NOOP = 6,
 };
 
+/*
+ * linux/mqueue.h
+ */
+
+struct vki_mq_attr {
+       long    mq_flags;       /* message queue flags                  */
+       long    mq_maxmsg;      /* maximum number of messages           */
+       long    mq_msgsize;     /* maximum message size                 */
+       long    mq_curmsgs;     /* number of messages currently queued  */
+       long    __reserved[4];  /* ignored for input, zeroed for output */
+};
 
 #endif /*  __VG_KERNELIFACE_H */
 
index 6dc2564e742c0c0e296101463ed2591e00fc12af..6ddfca3c88273e0cd2d246092747fab6a6e93e25 100644 (file)
@@ -41,6 +41,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        $(addsuffix .vgtest,$(INSN_TESTS)) \
        int.stderr.exp int.stdout.exp int.vgtest \
        map_unmap.stderr.exp map_unmap.stdout.exp map_unmap.vgtest \
+       mq.stderr.exp mq.vgtest \
        mremap.stderr.exp mremap.stdout.exp mremap.vgtest \
        munmap_exe.stderr.exp munmap_exe.vgtest \
        pth_blockedsig.stderr.exp \
@@ -71,7 +72,7 @@ check_PROGRAMS = \
        args badseg bitfield1 bt_everything bt_literal closeall coolo_strlen \
        cpuid dastest discard exec-sigmask execve fcntl_setown floored fork \
        fpu_lazy_eflags fucomip $(INSN_TESTS) \
-       int munmap_exe map_unmap mremap rcl_assert rcrl readline1 \
+       int munmap_exe map_unmap mq mremap rcl_assert rcrl readline1 \
        resolv rlimit_nofile seg_override sem semlimit sha1_test \
        shortpush shorts smc1 susphello pth_blockedsig pushpopseg \
        syscall-restart1 syscall-restart2 system \
@@ -115,6 +116,8 @@ insn_sse2_SOURCES   = insn_sse2.def
 insn_sse2_LDADD                = -lm
 int_SOURCES            = int.c
 map_unmap_SOURCES      = map_unmap.c
+mq_SOURCES             = mq.c
+mq_LDADD               = -lrt
 mremap_SOURCES         = mremap.c
 munmap_exe_SOURCES     = munmap_exe.c
 pushpopseg_SOURCES     = pushpopseg.c
diff --git a/none/tests/mq.c b/none/tests/mq.c
new file mode 100644 (file)
index 0000000..2e7cf20
--- /dev/null
@@ -0,0 +1,115 @@
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_MQUEUE_H
+
+#include <mqueue.h>
+
+#define MSGMAX 10
+#define MSGSIZEMAX 1024
+
+int main(int argc, char **argv)
+{
+  struct mq_attr mqa;
+  mqd_t mqdw;
+  mqd_t mqdr;
+  char buffer[MSGSIZEMAX];
+  unsigned int priority;
+  int len;
+
+  mqa.mq_maxmsg = MSGMAX;
+  mqa.mq_msgsize = MSGSIZEMAX;
+  
+  if ((mqdw = mq_open("/valgrind-mqueue", O_CREAT|O_EXCL|O_WRONLY, 0600, &mqa)) < 0)
+    {
+      perror("mq_open");
+      exit(1);
+    }
+
+  if ((mqdr = mq_open("/valgrind-mqueue", O_RDONLY)) < 0)
+    {
+      perror("mq_open");
+      mq_unlink("/valgrind-mqueue");
+      mq_close(mqdw);
+      exit(1);
+    }
+  
+  if (mq_unlink("/valgrind-mqueue") < 0)
+    {
+      perror("mq_unlink");
+      mq_close(mqdw);
+      mq_close(mqdr);
+      exit(1);
+    }
+
+  if (mq_send(mqdw, "PING", 4, 0) < 0)
+    {
+      perror("mq_send");
+      mq_close(mqdr);
+      mq_close(mqdw);
+      exit(1);
+    }
+
+  if ((len = mq_receive(mqdr, buffer, sizeof(buffer), &priority)) < 0)
+    {
+      perror("mq_receive");
+      mq_close(mqdr);
+      mq_close(mqdw);
+      exit(1);
+    }
+
+  if (len != 4 || memcmp(buffer, "PING", 4) != 0)
+    {
+      fprintf(stderr, "Message corrupt!");
+    }
+
+  if (mq_notify(mqdr, NULL) < 0)
+    {
+      perror("mq_notify");
+      mq_close(mqdr);
+      mq_close(mqdw);
+      exit(1);
+    }
+
+  if (mq_getattr(mqdr, &mqa) < 0)
+    {
+      perror("mq_getattr");
+      mq_close(mqdr);
+      mq_close(mqdw);
+      exit(1);
+    }
+
+  if (mq_setattr(mqdw, &mqa, &mqa) < 0)
+    {
+      perror("mq_getattr");
+      mq_close(mqdr);
+      mq_close(mqdw);
+      exit(1);
+    }
+
+  if (mq_close(mqdr) < 0)
+    {
+      perror("mq_close");
+      mq_close(mqdw);
+      exit(1);
+    }
+  
+  if (mq_close(mqdw) < 0)
+    {
+      perror("mq_close");
+      exit(1);
+    }
+
+  exit(0);
+}
+
+#else
+
+int main(int argc, char **argv)
+{
+  exit(0);
+}
+
+#endif
diff --git a/none/tests/mq.stderr.exp b/none/tests/mq.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/mq.vgtest b/none/tests/mq.vgtest
new file mode 100644 (file)
index 0000000..8a5fe3f
--- /dev/null
@@ -0,0 +1 @@
+prog: mq