mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-11-03 20:53:13 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			226 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			226 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
 | 
						||
   This file is part of the GNU C Library.
 | 
						||
 | 
						||
   The GNU C Library is free software; you can redistribute it and/or
 | 
						||
   modify it under the terms of the GNU Lesser General Public
 | 
						||
   License as published by the Free Software Foundation; either
 | 
						||
   version 2.1 of the License, or (at your option) any later version.
 | 
						||
 | 
						||
   The GNU C Library is distributed in the hope that it will be useful,
 | 
						||
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						||
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						||
   Lesser General Public License for more details.
 | 
						||
 | 
						||
   You should have received a copy of the GNU Lesser General Public
 | 
						||
   License along with the GNU C Library; if not, see
 | 
						||
   <http://www.gnu.org/licenses/>.  */
 | 
						||
 | 
						||
#include <sys/stat.h>
 | 
						||
#include <stdlib.h>
 | 
						||
#include <stdio.h>
 | 
						||
#include <unistd.h>
 | 
						||
#include <hurd.h>
 | 
						||
#include <hurd/port.h>
 | 
						||
#include "set-hooks.h"
 | 
						||
#include "hurdmalloc.h"		/* XXX */
 | 
						||
 | 
						||
 | 
						||
int _hurd_exec_flags;
 | 
						||
struct hurd_port *_hurd_ports;
 | 
						||
unsigned int _hurd_nports;
 | 
						||
mode_t _hurd_umask;
 | 
						||
sigset_t _hurdsig_traced;
 | 
						||
 | 
						||
char **__libc_argv;
 | 
						||
int __libc_argc;
 | 
						||
 | 
						||
 | 
						||
error_t
 | 
						||
_hurd_ports_use (int which, error_t (*operate) (mach_port_t))
 | 
						||
{
 | 
						||
  if (__glibc_unlikely (_hurd_ports == NULL))
 | 
						||
    /* This means that _hurd_init has not been called yet, which is
 | 
						||
       normally only the case in the bootstrap filesystem, and there
 | 
						||
       only in the early phases of booting.  */
 | 
						||
    return EGRATUITOUS;
 | 
						||
 | 
						||
  return HURD_PORT_USE (&_hurd_ports[which], (*operate) (port));
 | 
						||
}
 | 
						||
 | 
						||
DEFINE_HOOK (_hurd_subinit, (void));
 | 
						||
 | 
						||
__typeof (_hurd_proc_init) _hurd_new_proc_init;	/* below */
 | 
						||
 | 
						||
/* Initialize the library data structures from the
 | 
						||
   ints and ports passed to us by the exec server.
 | 
						||
 | 
						||
   PORTARRAY and INTARRAY are vm_deallocate'd.  */
 | 
						||
 | 
						||
void
 | 
						||
_hurd_init (int flags, char **argv,
 | 
						||
	    mach_port_t *portarray, size_t portarraysize,
 | 
						||
	    int *intarray, size_t intarraysize)
 | 
						||
{
 | 
						||
  size_t i;
 | 
						||
 | 
						||
  _hurd_exec_flags = flags;
 | 
						||
 | 
						||
  _hurd_ports = malloc (portarraysize * sizeof (*_hurd_ports));
 | 
						||
  if (_hurd_ports == NULL)
 | 
						||
    __libc_fatal ("Can't allocate _hurd_ports\n");
 | 
						||
  _hurd_nports = portarraysize;
 | 
						||
 | 
						||
  /* See what ports we were passed.  */
 | 
						||
  for (i = 0; i < portarraysize; ++i)
 | 
						||
    _hurd_port_init (&_hurd_ports[i], portarray[i]);
 | 
						||
 | 
						||
  /* When the user asks for the bootstrap port,
 | 
						||
     he will get the one the exec server passed us.  */
 | 
						||
  __task_set_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT,
 | 
						||
			   portarray[INIT_PORT_BOOTSTRAP]);
 | 
						||
 | 
						||
  if (intarraysize > INIT_UMASK)
 | 
						||
    _hurd_umask = intarray[INIT_UMASK] & 0777;
 | 
						||
  else
 | 
						||
    _hurd_umask = CMASK;
 | 
						||
 | 
						||
  if (intarraysize > INIT_TRACEMASK)
 | 
						||
    _hurdsig_traced = intarray[INIT_TRACEMASK];
 | 
						||
 | 
						||
  /* Tell the proc server we exist, if it does.  */
 | 
						||
  if (portarray[INIT_PORT_PROC] != MACH_PORT_NULL)
 | 
						||
    _hurd_new_proc_init (argv, intarray, intarraysize);
 | 
						||
 | 
						||
  /* All done with init ints and ports.  */
 | 
						||
  __vm_deallocate (__mach_task_self (),
 | 
						||
		   (vm_address_t) intarray,
 | 
						||
		   intarraysize * sizeof (int));
 | 
						||
  __vm_deallocate (__mach_task_self (),
 | 
						||
		   (vm_address_t) portarray,
 | 
						||
		   portarraysize * sizeof (mach_port_t));
 | 
						||
 | 
						||
  if (flags & EXEC_SECURE)
 | 
						||
    /* XXX if secure exec, elide environment variables
 | 
						||
       which the library uses and could be security holes.
 | 
						||
       CORESERVER, COREFILE
 | 
						||
       */ ;
 | 
						||
 | 
						||
  /* Call other things which want to do some initialization.  These are not
 | 
						||
     on the __libc_subinit hook because things there like to be able to
 | 
						||
     assume the availability of the POSIX.1 services we provide.  */
 | 
						||
  RUN_HOOK (_hurd_subinit, ());
 | 
						||
}
 | 
						||
 | 
						||
#include <hurd/signal.h>
 | 
						||
 | 
						||
/* The user can do "int _hide_arguments = 1;" to make
 | 
						||
   sure the arguments are never visible with `ps'.  */
 | 
						||
int _hide_arguments, _hide_environment;
 | 
						||
 | 
						||
/* Hook for things which should be initialized as soon as the proc
 | 
						||
   server is available.  */
 | 
						||
DEFINE_HOOK (_hurd_proc_subinit, (void));
 | 
						||
 | 
						||
/* Do startup handshaking with the proc server just installed in _hurd_ports.
 | 
						||
   Call _hurdsig_init to set up signal processing.  */
 | 
						||
 | 
						||
void
 | 
						||
_hurd_new_proc_init (char **argv,
 | 
						||
		     const int *intarray, size_t intarraysize)
 | 
						||
{
 | 
						||
  mach_port_t oldmsg;
 | 
						||
  struct hurd_userlink ulink;
 | 
						||
  process_t procserver;
 | 
						||
 | 
						||
  /* Initialize the signal code; Mach exceptions will become signals.  */
 | 
						||
  _hurdsig_init (intarray, intarraysize);
 | 
						||
 | 
						||
  /* The signal thread is now prepared to receive messages.
 | 
						||
     It is safe to give the port to the proc server.  */
 | 
						||
 | 
						||
  procserver = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink);
 | 
						||
 | 
						||
  /* Give the proc server our message port.  */
 | 
						||
  __proc_setmsgport (procserver, _hurd_msgport, &oldmsg);
 | 
						||
  if (oldmsg != MACH_PORT_NULL)
 | 
						||
    /* Deallocate the old msg port we replaced.  */
 | 
						||
    __mach_port_deallocate (__mach_task_self (), oldmsg);
 | 
						||
 | 
						||
  /* Tell the proc server where our args and environment are.  */
 | 
						||
  __proc_set_arg_locations (procserver,
 | 
						||
			    _hide_arguments ? 0 : (vm_address_t) argv,
 | 
						||
			    _hide_environment ? 0 : (vm_address_t) __environ);
 | 
						||
 | 
						||
  _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, procserver);
 | 
						||
 | 
						||
  /* Initialize proc server-assisted fault recovery for the signal thread.  */
 | 
						||
  _hurdsig_fault_init ();
 | 
						||
 | 
						||
  /* Call other things which want to do some initialization.  These are not
 | 
						||
     on the _hurd_subinit hook because things there assume that things done
 | 
						||
     here, like _hurd_pid, are already initialized.  */
 | 
						||
  RUN_HOOK (_hurd_proc_subinit, ());
 | 
						||
 | 
						||
  /* XXX This code should probably be removed entirely at some point.  This
 | 
						||
     conditional should make it reasonably usable with old gdb's for a
 | 
						||
     while.  Eventually it probably makes most sense for the exec server to
 | 
						||
     mask out EXEC_SIGTRAP so the debugged program is closer to not being
 | 
						||
     able to tell it's being debugged.  */
 | 
						||
  if (!__sigisemptyset (&_hurdsig_traced)
 | 
						||
#ifdef EXEC_SIGTRAP
 | 
						||
      && !(_hurd_exec_flags & EXEC_SIGTRAP)
 | 
						||
#endif
 | 
						||
      )
 | 
						||
    /* This process is "traced", meaning it should stop on signals or exec.
 | 
						||
       We are all set up now to handle signals.  Stop ourselves, to inform
 | 
						||
       our parent (presumably a debugger) that the exec has completed.  */
 | 
						||
    __msg_sig_post (_hurd_msgport, SIGTRAP, 0, __mach_task_self ());
 | 
						||
}
 | 
						||
 | 
						||
#include <shlib-compat.h>
 | 
						||
versioned_symbol (libc, _hurd_new_proc_init, _hurd_proc_init, GLIBC_2_1);
 | 
						||
 | 
						||
/* Called when we get a message telling us to change our proc server port.  */
 | 
						||
 | 
						||
error_t
 | 
						||
_hurd_setproc (process_t procserver)
 | 
						||
{
 | 
						||
  error_t err;
 | 
						||
  mach_port_t oldmsg;
 | 
						||
 | 
						||
  /* Give the proc server our message port.  */
 | 
						||
  if (err = __proc_setmsgport (procserver, _hurd_msgport, &oldmsg))
 | 
						||
    return err;
 | 
						||
  if (oldmsg != MACH_PORT_NULL)
 | 
						||
    /* Deallocate the old msg port we replaced.  */
 | 
						||
    __mach_port_deallocate (__mach_task_self (), oldmsg);
 | 
						||
 | 
						||
  /* Tell the proc server where our args and environment are.  */
 | 
						||
  if (err = __proc_set_arg_locations (procserver,
 | 
						||
				      _hide_arguments ? 0 :
 | 
						||
				      (vm_address_t) __libc_argv,
 | 
						||
				      _hide_environment ? 0 :
 | 
						||
				      (vm_address_t) __environ))
 | 
						||
    return err;
 | 
						||
 | 
						||
  /* Those calls worked, so the port looks good.  */
 | 
						||
  _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], procserver);
 | 
						||
 | 
						||
  {
 | 
						||
    pid_t oldpgrp = _hurd_pgrp;
 | 
						||
 | 
						||
    /* Call these functions again so they can fetch the
 | 
						||
       new information from the new proc server.  */
 | 
						||
    RUN_HOOK (_hurd_proc_subinit, ());
 | 
						||
 | 
						||
    if (_hurd_pgrp != oldpgrp)
 | 
						||
      {
 | 
						||
	/* Run things that want notification of a pgrp change.  */
 | 
						||
	DECLARE_HOOK (_hurd_pgrp_changed_hook, (pid_t));
 | 
						||
	RUN_HOOK (_hurd_pgrp_changed_hook, (_hurd_pgrp));
 | 
						||
      }
 | 
						||
  }
 | 
						||
 | 
						||
  return 0;
 | 
						||
}
 |