bug-hurd
[Top][All Lists]
Advanced

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

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


From: Samuel Thibault
Subject: Re: [PATCH 12/17] tests: Add a more serious mach_msg_server() routine
Date: Wed, 27 Mar 2024 19:56:57 +0100
User-agent: NeoMutt/20170609 (1.8.3)

Applied, thanks!

Sergey Bugaev, le mer. 27 mars 2024 19:18:36 +0300, a ecrit:
> ---
>  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
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



reply via email to

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