bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 12/17] tests: Add a more serious mach_msg_server() routine


From: Sergey Bugaev
Subject: [PATCH 12/17] tests: Add a more serious mach_msg_server() routine
Date: Wed, 27 Mar 2024 19:18:36 +0300

---
 tests/include/testlib.h |  16 ++++++
 tests/test-syscalls.c   |  40 +------------
 tests/testlib.c         | 123 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+), 37 deletions(-)

diff --git a/tests/include/testlib.h b/tests/include/testlib.h
index cdb2ce13..d2367124 100644
--- a/tests/include/testlib.h
+++ b/tests/include/testlib.h
@@ -70,6 +70,22 @@ thread_t test_thread_start(task_t task, 
void(*routine)(void*), void* arg);
 mach_port_t host_priv(void);
 mach_port_t device_priv(void);
 
+extern void mach_msg_destroy(mach_msg_header_t *msg);
+
+extern mach_msg_return_t mach_msg_server(
+       boolean_t               (*demux) (mach_msg_header_t *request,
+                                         mach_msg_header_t *reply),
+       mach_msg_size_t         max_size,
+       mach_port_t             rcv_name,
+       mach_msg_option_t       options);
+
+extern mach_msg_return_t mach_msg_server_once(
+       boolean_t               (*demux) (mach_msg_header_t *request,
+                                         mach_msg_header_t *reply),
+       mach_msg_size_t         max_size,
+       mach_port_t             rcv_name,
+       mach_msg_option_t       options);
+
 int main(int argc, char *argv[], int envc, char *envp[]);
 
 #endif /* TESTLIB_H */
diff --git a/tests/test-syscalls.c b/tests/test-syscalls.c
index be4df8c3..63c2690a 100644
--- a/tests/test-syscalls.c
+++ b/tests/test-syscalls.c
@@ -49,44 +49,10 @@ kern_return_t catch_exception_raise(mach_port_t 
exception_port,
   last_exc.exception = exception;
   last_exc.code = code;
   last_exc.subcode = subcode;
+  thread_terminate(thread);
   return KERN_SUCCESS;
 }
 
-static char simple_request_data[PAGE_SIZE];
-static char simple_reply_data[PAGE_SIZE];
-int simple_msg_server(boolean_t (*demuxer) (mach_msg_header_t *request,
-                                             mach_msg_header_t *reply),
-                      mach_port_t rcv_port_name,
-                      int num_msgs)
-{
-  int midx = 0, mok = 0;
-  int ret;
-  mig_reply_header_t *request = (mig_reply_header_t*)simple_request_data;
-  mig_reply_header_t *reply = (mig_reply_header_t*)simple_reply_data;
-  while ((midx - num_msgs) < 0)
-    {
-      ret = mach_msg(&request->Head, MACH_RCV_MSG, 0, PAGE_SIZE,
-                     rcv_port_name, 0, MACH_PORT_NULL);
-      switch (ret)
-        {
-        case MACH_MSG_SUCCESS:
-          if ((*demuxer)(&request->Head, &reply->Head))
-            mok++;  // TODO send reply
-          else
-            FAILURE("demuxer didn't handle the message");
-          break;
-        default:
-          ASSERT_RET(ret, "receiving in msg_server");
-          break;
-        }
-      midx++;
-    }
-  if (mok != midx)
-    FAILURE("wrong number of message received");
-  return mok != midx;
-}
-
-
 void test_syscall_bad_arg_on_stack(void *arg)
 {
   /* mach_msg() has 7 arguments, so the last one should be always
@@ -152,13 +118,13 @@ int main(int argc, char *argv[], int envc, char *envp[])
 
   memset(&last_exc, 0, sizeof(last_exc));
   test_thread_start(mach_task_self(), test_bad_syscall_num, NULL);
-  ASSERT_RET(simple_msg_server(exc_server, excp, 1), "error in exc server");
+  ASSERT_RET(mach_msg_server_once(exc_server, 4096, excp, 
MACH_MSG_OPTION_NONE), "error in exc server");
   ASSERT((last_exc.exception == EXC_BAD_INSTRUCTION) && (last_exc.code == 
EXC_I386_INVOP),
          "bad exception for test_bad_syscall_num()");
 
   memset(&last_exc, 0, sizeof(last_exc));
   test_thread_start(mach_task_self(), test_syscall_bad_arg_on_stack, NULL);
-  ASSERT_RET(simple_msg_server(exc_server, excp, 1), "error in exc server");
+  ASSERT_RET(mach_msg_server_once(exc_server, 4096, excp, 
MACH_MSG_OPTION_NONE), "error in exc server");
   ASSERT((last_exc.exception == EXC_BAD_ACCESS) && (last_exc.code == 
KERN_INVALID_ADDRESS),
          "bad exception for test_syscall_bad_arg_on_stack()");
 
diff --git a/tests/testlib.c b/tests/testlib.c
index d2198830..baf1ce5c 100644
--- a/tests/testlib.c
+++ b/tests/testlib.c
@@ -26,6 +26,7 @@
 #include <sys/reboot.h>
 
 #include <mach.user.h>
+#include <mach_port.user.h>
 #include <mach_host.user.h>
 
 
@@ -81,6 +82,128 @@ const char* e2s(int err)
       }
 }
 
+void mach_msg_destroy(mach_msg_header_t *msg)
+{
+       mach_port_t     tmp;
+
+       tmp = mach_reply_port();
+
+       msg->msgh_local_port = msg->msgh_remote_port;
+       msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND,
+                                       MACH_MSGH_BITS_REMOTE(msg->msgh_bits))
+                        | MACH_MSGH_BITS_OTHER(msg->msgh_bits);
+
+       mach_msg(msg, MACH_SEND_MSG, msg->msgh_size, 0, MACH_PORT_NULL,
+                MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+       mach_port_mod_refs(mach_task_self(), tmp, MACH_PORT_RIGHT_RECEIVE, -1);
+}
+
+mach_msg_return_t mach_msg_server(
+       boolean_t               (*demux) (mach_msg_header_t *request,
+                                         mach_msg_header_t *reply),
+       mach_msg_size_t         max_size,
+       mach_port_t             rcv_name,
+       mach_msg_option_t       options)
+{
+       mach_msg_return_t       mr;
+       mig_reply_header_t      *request;
+       mig_reply_header_t      *reply;
+       mig_reply_header_t      *tmp;
+       boolean_t               handled;
+
+       request = __builtin_alloca(max_size);
+       reply = __builtin_alloca(max_size);
+
+GetRequest:
+       mr = mach_msg(&request->Head, MACH_RCV_MSG|options,
+                     0, max_size, rcv_name,
+                     MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+       if (mr)
+               return mr;
+
+Handle:
+       handled = demux(&request->Head, &reply->Head);
+       if (!handled)
+               reply->RetCode = MIG_BAD_ID;
+
+       if (reply->RetCode == MIG_NO_REPLY)
+               goto GetRequest;
+       else if (reply->RetCode != KERN_SUCCESS) {
+               request->Head.msgh_remote_port = MACH_PORT_NULL;
+               mach_msg_destroy(&request->Head);
+       }
+
+       if (!MACH_PORT_VALID(reply->Head.msgh_remote_port)) {
+               mach_msg_destroy(&reply->Head);
+               goto GetRequest;
+       }
+
+       tmp = request;
+       request = reply;
+       reply = tmp;
+
+       mr = mach_msg(&request->Head, MACH_SEND_MSG|MACH_RCV_MSG|options,
+                     request->Head.msgh_size, max_size, rcv_name,
+                     MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+       if (mr == MACH_MSG_SUCCESS)
+               goto Handle;
+       else if (mr == MACH_SEND_INVALID_DEST) {
+               mach_msg_destroy(&request->Head);
+               goto GetRequest;
+       }
+
+       return mr;
+}
+
+mach_msg_return_t mach_msg_server_once(
+       boolean_t               (*demux) (mach_msg_header_t *request,
+                                         mach_msg_header_t *reply),
+       mach_msg_size_t         max_size,
+       mach_port_t             rcv_name,
+       mach_msg_option_t       options)
+{
+       mach_msg_return_t       mr;
+       mig_reply_header_t      *request;
+       mig_reply_header_t      *reply;
+       boolean_t               handled;
+
+       request = __builtin_alloca(max_size);
+       reply = __builtin_alloca(max_size);
+
+       mr = mach_msg(&request->Head, MACH_RCV_MSG|options,
+                     0, max_size, rcv_name,
+                     MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+       if (mr)
+               return mr;
+
+       handled = demux(&request->Head, &reply->Head);
+       if (!handled)
+               reply->RetCode = MIG_BAD_ID;
+
+       if (reply->RetCode == MIG_NO_REPLY)
+               return MACH_MSG_SUCCESS;
+       else if (reply->RetCode != KERN_SUCCESS) {
+               request->Head.msgh_remote_port = MACH_PORT_NULL;
+               mach_msg_destroy(&request->Head);
+       }
+
+       if (!MACH_PORT_VALID(reply->Head.msgh_remote_port)) {
+               mach_msg_destroy(&reply->Head);
+               return MACH_MSG_SUCCESS;
+       }
+
+       mr = mach_msg(&reply->Head, MACH_SEND_MSG|options,
+                     reply->Head.msgh_size, 0, MACH_PORT_NULL,
+                     MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+       if (mr == MACH_SEND_INVALID_DEST)
+               mach_msg_destroy(&reply->Head);
+
+       return mr;
+}
+
 /*
  * Minimal _start() for test modules, we just take the arguments from the
  * kernel, call main() and reboot. As in glibc, we expect the argument pointer
-- 
2.44.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]