(root)/
glibc-2.38/
sysdeps/
mach/
hurd/
mig-reply.c
       1  /* Copyright (C) 1994-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <mach.h>
      19  #include <mach/mig_support.h>
      20  #include <tls.h>
      21  
      22  /* These functions are called by MiG-generated code.  */
      23  
      24  #if !defined (SHARED) || IS_IN (rtld)
      25  mach_port_t __hurd_reply_port0;
      26  #endif
      27  
      28  static mach_port_t
      29  get_reply_port (void)
      30  {
      31  #if !defined (SHARED) || IS_IN (rtld)
      32    if (__LIBC_NO_TLS ())
      33      return __hurd_reply_port0;
      34  #endif
      35    return THREAD_GETMEM (THREAD_SELF, reply_port);
      36  }
      37  
      38  static void
      39  set_reply_port (mach_port_t port)
      40  {
      41  #if !defined (SHARED) || IS_IN (rtld)
      42    if (__LIBC_NO_TLS ())
      43      __hurd_reply_port0 = port;
      44    else
      45  #endif
      46      THREAD_SETMEM (THREAD_SELF, reply_port, port);
      47  }
      48  
      49  /* Called by MiG to get a reply port.  */
      50  mach_port_t
      51  __mig_get_reply_port (void)
      52  {
      53    mach_port_t port = get_reply_port ();
      54    if (__glibc_unlikely (port == MACH_PORT_NULL))
      55      {
      56        port = __mach_reply_port ();
      57        set_reply_port (port);
      58      }
      59    return port;
      60  }
      61  weak_alias (__mig_get_reply_port, mig_get_reply_port)
      62  libc_hidden_def (__mig_get_reply_port)
      63  
      64  /* Called by MiG to deallocate the reply port.  */
      65  void
      66  __mig_dealloc_reply_port (mach_port_t arg)
      67  {
      68    error_t err;
      69    mach_port_t port = get_reply_port ();
      70  
      71    set_reply_port (MACH_PORT_NULL);	/* So the mod_refs RPC won't use it.  */
      72    assert (port == arg);
      73    if (!MACH_PORT_VALID (port))
      74      return;
      75  
      76    err = __mach_port_mod_refs (__mach_task_self (), port,
      77                                MACH_PORT_RIGHT_RECEIVE, -1);
      78    if (err == KERN_INVALID_RIGHT)
      79      /* It could be that during signal handling, the receive right had been
      80         replaced with a dead name.  */
      81      err = __mach_port_mod_refs (__mach_task_self (), port,
      82                                  MACH_PORT_RIGHT_DEAD_NAME, -1);
      83  
      84    assert_perror (err);
      85  }
      86  weak_alias (__mig_dealloc_reply_port, mig_dealloc_reply_port)
      87  libc_hidden_def (__mig_dealloc_reply_port)
      88  
      89  /* Called by mig interfaces when done with a port.  Used to provide the
      90     same interface as needed when a custom allocator is used.  */
      91  void
      92  __mig_put_reply_port(mach_port_t port)
      93  {
      94    /* Do nothing.  */
      95  }
      96  weak_alias (__mig_put_reply_port, mig_put_reply_port)
      97  
      98  /* Called at startup with STACK == NULL.  When per-thread variables are set
      99     up, this is called again with STACK set to the new stack being switched
     100     to, where per-thread variables should be set up.  */
     101  void
     102  __mig_init (void *stack)
     103  {
     104    /* Do nothing.  */
     105  }
     106  weak_alias (__mig_init, mig_init)
     107  libc_hidden_def (__mig_init)