Blame hurd/hurdinit.c

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