Blame hurd/hurdinit.c

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