Back to index

glibc  2.9
Defines | Functions | Variables
hurd.h File Reference
#include <features.h>
#include <mach.h>
#include <mach/mig_errors.h>
#include <hurd/hurd_types.h>
#include <hurd/auth.h>
#include <hurd/process.h>
#include <hurd/fs.h>
#include <hurd/io.h>
#include <hurd/port.h>
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>

Go to the source code of this file.

Defines

#define _HURD_H_EXTERN_INLINE   __extern_inline
#define __USEPORT(which, expr)   HURD_PORT_USE (&_hurd_ports[INIT_PORT_##which], (expr))
#define __need_FILE

Functions

_HURD_H_EXTERN_INLINE int __hurd_fail (error_t err)
error_t _hurd_ports_use (int which, error_t(*operate)(mach_port_t))
int _hurd_set_brk (vm_address_t newbrk)
error_t _hurd_ports_get (unsigned int which, mach_port_t *result)
error_t _hurd_ports_set (unsigned int which, mach_port_t newport)
process_t getproc (void)
file_t getcwdir (void)
file_t getcrdir (void)
auth_t getauth (void)
mach_port_t getcttyid (void)
int setproc (process_t)
int setcwdir (file_t)
int setcrdir (file_t)
int setcttyid (mach_port_t)
int __setauth (auth_t)
int setauth (auth_t)
int _hurd_change_directory_port_from_name (struct hurd_port *portcell, const char *name)
int _hurd_change_directory_port_from_fd (struct hurd_port *portcell, int fd)
int geteuids (int __n, uid_t *__uidset)
int seteuids (int __n, const uid_t *__uidset)
file_t __file_name_split (const char *file, char **name)
file_t file_name_split (const char *file, char **name)
file_t __directory_name_split (const char *file, char **name)
file_t directory_name_split (const char *file, char **name)
file_t __file_name_lookup (const char *file, int flags, mode_t mode)
file_t file_name_lookup (const char *file, int flags, mode_t mode)
file_t __file_name_lookup_under (file_t startdir, const char *file, int flags, mode_t mode)
file_t file_name_lookup_under (file_t startdir, const char *file, int flags, mode_t mode)
file_t file_name_path_lookup (const char *file_name, const char *path, int flags, mode_t mode, char **prefixed_name)
int openport (io_t port, int flags)
FILEfopenport (io_t port, const char *mode)
FILE__fopenport (io_t port, const char *mode)
error_t _hurd_exec (task_t task, file_t file, char *const argv[], char *const envp[])
void _hurd_exit (int status) __attribute__((noreturn))
void _hurd_init (int flags, char **argv, mach_port_t *portarray, size_t portarraysize, int *intarray, size_t intarraysize)
void _hurd_proc_init (char **argv, const int *intarray, size_t intarraysize)
socket_t _hurd_socket_server (int domain, int dead)
error_t _hurd_sig_post (pid_t pid, int sig, mach_port_t refport)
error_t hurd_sig_post (pid_t pid, int sig, mach_port_t refport)
kern_return_t __get_privileged_ports (mach_port_t *host_priv_ptr, device_t *device_master_ptr)
kern_return_t get_privileged_ports (mach_port_t *host_priv_ptr, device_t *device_master_ptr)
pid_t __task2pid (task_t task)
pid_t task2pid (task_t task)
task_t __pid2task (pid_t pid)
task_t pid2task (pid_t pid)
thread_t hurd_thread_self (void)
error_t hurd_thread_cancel (thread_t thread)
int hurd_check_cancel (void)
io_t __getdport (int fd)
io_t getdport (int fd)
int vpprintf (io_t port, const char *format, va_list arg)

Variables

int _hurd_exec_flags
struct hurd_port_hurd_ports
unsigned int _hurd_nports
mode_t _hurd_umask
sigset_t _hurdsig_traced
vm_address_t _hurd_stack_base
vm_size_t _hurd_stack_size
mach_port_t * _hurd_init_dtable
mach_msg_type_number_t _hurd_init_dtablesize
pid_t _hurd_pid
pid_t _hurd_ppid
pid_t _hurd_pgrp
int _hurd_orphaned
unsigned int _hurd_pids_changed_stamp
vm_address_t _hurd_brk
vm_address_t _hurd_data_end
mach_port_t _hurd_host_priv
mach_port_t _hurd_device_master

Define Documentation

#define __need_FILE

Definition at line 146 of file hurd.h.

#define __USEPORT (   which,
  expr 
)    HURD_PORT_USE (&_hurd_ports[INIT_PORT_##which], (expr))

Definition at line 92 of file hurd.h.

Definition at line 48 of file hurd.h.


Function Documentation

file_t __directory_name_split ( const char *  file,
char **  name 
)

Here is the caller graph for this function:

file_t __file_name_lookup ( const char *  file,
int  flags,
mode_t  mode 
)

Here is the caller graph for this function:

file_t __file_name_lookup_under ( file_t  startdir,
const char *  file,
int  flags,
mode_t  mode 
)

Here is the caller graph for this function:

file_t __file_name_split ( const char *  file,
char **  name 
)

Here is the caller graph for this function:

FILE* __fopenport ( io_t  port,
const char *  mode 
)
kern_return_t __get_privileged_ports ( mach_port_t *  host_priv_ptr,
device_t *  device_master_ptr 
)

Definition at line 28 of file privports.c.

{
  if ((host_priv_ptr && _hurd_host_priv == MACH_PORT_NULL)
      || (device_master_ptr && _hurd_device_master == MACH_PORT_NULL))
    {
      error_t err;

      if (_hurd_ports)
       /* We have gotten some initial ports, so perhaps
          we have a proc server to talk to.  */
       err = __USEPORT (PROC, __proc_getprivports (port,
                                              &_hurd_host_priv,
                                              &_hurd_device_master));
      else
       return MACH_SEND_INVALID_DEST;

      if (err)
       return err;
    }

  if (host_priv_ptr)
    {
      error_t err = _hurd_host_priv == MACH_PORT_NULL ? 0
       : __mach_port_mod_refs (mach_task_self (),
                            _hurd_host_priv, MACH_PORT_RIGHT_SEND, +1);
      if (err)
       return err;
      *host_priv_ptr = _hurd_host_priv;
    }

  if (device_master_ptr)
    {
      error_t err = _hurd_device_master == MACH_PORT_NULL ? 0
       : __mach_port_mod_refs (mach_task_self (),
                            _hurd_device_master, MACH_PORT_RIGHT_SEND, +1);
      if (err)
       return err;
      *device_master_ptr = _hurd_device_master;
    }

  return KERN_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

io_t __getdport ( int  fd)

Here is the caller graph for this function:

Definition at line 52 of file hurd.h.

{
  switch (err)
    {
    case EMACH_SEND_INVALID_DEST:
    case EMIG_SERVER_DIED:
      /* The server has disappeared!  */
      err = EIEIO;
      break;

    case KERN_NO_SPACE:
      err = ENOMEM;
      break;

    case KERN_INVALID_ARGUMENT:
      err = EINVAL;
      break;

    case 0:
      return 0;

    default:
      break;
    }

  errno = err;
  return -1;
}

Here is the call graph for this function:

task_t __pid2task ( pid_t  pid)

Here is the caller graph for this function:

int __setauth ( auth_t  )

Here is the caller graph for this function:

pid_t __task2pid ( task_t  task)
int _hurd_change_directory_port_from_fd ( struct hurd_port portcell,
int  fd 
)

Definition at line 28 of file hurdfchdir.c.

{
  int ret;
  struct hurd_fd *d = _hurd_fd_get (fd);

  if (!d)
    return __hurd_fail (EBADF);

  HURD_CRITICAL_BEGIN;

  ret = HURD_PORT_USE (&d->port,
                     ({
                      int ret;
                      /* We look up "." to force ENOTDIR if it's not a
                         directory and EACCES if we don't have search
                         permission.  */
                      file_t dir = __file_name_lookup_under (port, ".",
                                                        O_NOTRANS, 0);
                      if (dir == MACH_PORT_NULL)
                        ret = -1;
                      else
                        {
                          _hurd_port_set (portcell, dir);
                          ret = 0;
                        }
                      ret;
                     }));

  HURD_CRITICAL_END;

  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _hurd_change_directory_port_from_name ( struct hurd_port portcell,
const char *  name 
)

Definition at line 29 of file hurdchdir.c.

{
  size_t len;
  const char *lookup;
  file_t dir;

  /* Append trailing "/." to directory name to force ENOTDIR if it's not a
     directory and EACCES if we don't have search permission.  */
  len = strlen (name);
  if (len >= 2 && name[len - 2] == '/' && name[len - 1] == '.')
    lookup = name;
  else
    {
      char *n = alloca (len + 3);
      memcpy (n, name, len);
      n[len] = '/';
      n[len + 1] = '.';
      n[len + 2] = '\0';
      lookup = n;
    }

  dir = __file_name_lookup (lookup, 0, 0);
  if (dir == MACH_PORT_NULL)
    return -1;

  _hurd_port_set (portcell, dir);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

error_t _hurd_exec ( task_t  task,
file_t  file,
char *const  argv[],
char *const  envp[] 
)

Definition at line 37 of file hurdexec.c.

{
  error_t err;
  char *args, *env;
  size_t argslen, envlen;
  int ints[INIT_INT_MAX];
  mach_port_t ports[_hurd_nports];
  struct hurd_userlink ulink_ports[_hurd_nports];
  inline void free_port (unsigned int i)
    {
      _hurd_port_free (&_hurd_ports[i], &ulink_ports[i], ports[i]);
    }
  file_t *dtable;
  unsigned int dtablesize, i;
  struct hurd_port **dtable_cells;
  struct hurd_userlink *ulink_dtable;
  struct hurd_sigstate *ss;
  mach_port_t *please_dealloc, *pdp;
  int reauth = 0;

  /* XXX needs to be hurdmalloc XXX */
  if (argv == NULL)
    args = NULL, argslen = 0;
  else if (err = __argz_create (argv, &args, &argslen))
    return err;
  if (envp == NULL)
    env = NULL, envlen = 0;
  else if (err = __argz_create (envp, &env, &envlen))
    goto outargs;

  /* Load up the ports to give to the new program.  */
  for (i = 0; i < _hurd_nports; ++i)
    if (i == INIT_PORT_PROC && task != __mach_task_self ())
      {
       /* This is another task, so we need to ask the proc server
          for the right proc server port for it.  */
       if (err = __USEPORT (PROC, __proc_task2proc (port, task, &ports[i])))
         {
           while (--i > 0)
             free_port (i);
           goto outenv;
         }
      }
    else
      ports[i] = _hurd_port_get (&_hurd_ports[i], &ulink_ports[i]);


  /* Load up the ints to give the new program.  */
  for (i = 0; i < INIT_INT_MAX; ++i)
    switch (i)
      {
      case INIT_UMASK:
       ints[i] = _hurd_umask;
       break;

      case INIT_SIGMASK:
      case INIT_SIGIGN:
      case INIT_SIGPENDING:
       /* We will set these all below.  */
       break;

      case INIT_TRACEMASK:
       ints[i] = _hurdsig_traced;
       break;

      default:
       ints[i] = 0;
      }

  ss = _hurd_self_sigstate ();

  assert (! __spin_lock_locked (&ss->critical_section_lock));
  __spin_lock (&ss->critical_section_lock);

  __spin_lock (&ss->lock);
  ints[INIT_SIGMASK] = ss->blocked;
  ints[INIT_SIGPENDING] = ss->pending;
  ints[INIT_SIGIGN] = 0;
  for (i = 1; i < NSIG; ++i)
    if (ss->actions[i].sa_handler == SIG_IGN)
      ints[INIT_SIGIGN] |= __sigmask (i);

  /* We hold the sigstate lock until the exec has failed so that no signal
     can arrive between when we pack the blocked and ignored signals, and
     when the exec actually happens.  A signal handler could change what
     signals are blocked and ignored.  Either the change will be reflected
     in the exec, or the signal will never be delivered.  Setting the
     critical section flag avoids anything we call trying to acquire the
     sigstate lock.  */

  __spin_unlock (&ss->lock);

  /* Pack up the descriptor table to give the new program.  */
  __mutex_lock (&_hurd_dtable_lock);

  dtablesize = _hurd_dtable ? _hurd_dtablesize : _hurd_init_dtablesize;

  if (task == __mach_task_self ())
    /* Request the exec server to deallocate some ports from us if the exec
       succeeds.  The init ports and descriptor ports will arrive in the
       new program's exec_startup message.  If we failed to deallocate
       them, the new program would have duplicate user references for them.
       But we cannot deallocate them ourselves, because we must still have
       them after a failed exec call.  */
    please_dealloc = __alloca ((_hurd_nports + 3 + (3 * dtablesize))
                            * sizeof (mach_port_t));
  else
    please_dealloc = NULL;
  pdp = please_dealloc;

  if (_hurd_dtable != NULL)
    {
      dtable = __alloca (dtablesize * sizeof (dtable[0]));
      ulink_dtable = __alloca (dtablesize * sizeof (ulink_dtable[0]));
      dtable_cells = __alloca (dtablesize * sizeof (dtable_cells[0]));
      for (i = 0; i < dtablesize; ++i)
       {
         struct hurd_fd *const d = _hurd_dtable[i];
         if (d == NULL)
           {
             dtable[i] = MACH_PORT_NULL;
             continue;
           }
         __spin_lock (&d->port.lock);
         if (d->flags & FD_CLOEXEC)
           {
             /* This descriptor is marked to be closed on exec.
               So don't pass it to the new program.  */
             dtable[i] = MACH_PORT_NULL;
             if (pdp && d->port.port != MACH_PORT_NULL)
              {
                /* We still need to deallocate the ports.  */
                *pdp++ = d->port.port;
                if (d->ctty.port != MACH_PORT_NULL)
                  *pdp++ = d->ctty.port;
              }
             __spin_unlock (&d->port.lock);
           }
         else
           {
             if (pdp && d->ctty.port != MACH_PORT_NULL)
              /* All the elements of DTABLE are added to PLEASE_DEALLOC
                 below, so we needn't add the port itself.
                 But we must deallocate the ctty port as well as
                 the normal port that got installed in DTABLE[I].  */
              *pdp++ = d->ctty.port;
             dtable[i] = _hurd_port_locked_get (&d->port, &ulink_dtable[i]);
             dtable_cells[i] = &d->port;
           }
       }
    }
  else
    {
      dtable = _hurd_init_dtable;
      ulink_dtable = NULL;
      dtable_cells = NULL;
    }

  /* Prune trailing null ports from the descriptor table.  */
  while (dtablesize > 0 && dtable[dtablesize - 1] == MACH_PORT_NULL)
    --dtablesize;

  /* See if we need to diddle the auth port of the new program.
     The purpose of this is to get the effect setting the saved-set UID and
     GID to the respective effective IDs after the exec, as POSIX.1 requires.
     Note that we don't reauthenticate with the proc server; that would be a
     no-op since it only keeps track of the effective UIDs, and if it did
     keep track of the available IDs we would have the problem that we'd be
     changing the IDs before the exec and have to change them back after a
     failure.  Arguably we could skip all the reauthentications because the
     available IDs have no bearing on any filesystem.  But the conservative
     approach is to reauthenticate all the io ports so that no state anywhere
     reflects that our whole ID set differs from what we've set it to.  */
  __mutex_lock (&_hurd_id.lock);
  err = _hurd_check_ids ();
  if (err == 0 && ((_hurd_id.aux.nuids >= 2 && _hurd_id.gen.nuids >= 1
                  && _hurd_id.aux.uids[1] != _hurd_id.gen.uids[0])
                 || (_hurd_id.aux.ngids >= 2 && _hurd_id.gen.ngids >= 1
                     && _hurd_id.aux.gids[1] != _hurd_id.gen.gids[0])))
    {
      /* We have euid != svuid or egid != svgid.  POSIX.1 says that exec
        sets svuid = euid and svgid = egid.  So we must get a new auth
        port and reauthenticate everything with it.  We'll pass the new
        ports in file_exec instead of our own ports.  */

      auth_t newauth;

      _hurd_id.aux.uids[1] = _hurd_id.gen.uids[0];
      _hurd_id.aux.gids[1] = _hurd_id.gen.gids[0];
      _hurd_id.valid = 0;
      if (_hurd_id.rid_auth != MACH_PORT_NULL)
       {
         __mach_port_deallocate (__mach_task_self (), _hurd_id.rid_auth);
         _hurd_id.rid_auth = MACH_PORT_NULL;
       }

      err = __auth_makeauth (ports[INIT_PORT_AUTH],
                          NULL, MACH_MSG_TYPE_COPY_SEND, 0,
                          _hurd_id.gen.uids, _hurd_id.gen.nuids,
                          _hurd_id.aux.uids, _hurd_id.aux.nuids,
                          _hurd_id.gen.gids, _hurd_id.gen.ngids,
                          _hurd_id.aux.gids, _hurd_id.aux.ngids,
                          &newauth);
      if (err == 0)
       {
         /* Now we have to reauthenticate the ports with this new ID.
          */

         inline error_t reauth_io (io_t port, io_t *newport)
           {
             mach_port_t ref = __mach_reply_port ();
             *newport = MACH_PORT_NULL;
             error_t err = __io_reauthenticate (port,
                                           ref, MACH_MSG_TYPE_MAKE_SEND);
             if (!err)
              err = __auth_user_authenticate (newauth,
                                          ref, MACH_MSG_TYPE_MAKE_SEND,
                                          newport);
             __mach_port_destroy (__mach_task_self (), ref);
             return err;
           }
         inline void reauth_port (unsigned int idx)
           {
             io_t newport;
             err = reauth_io (ports[idx], &newport) ?: err;
             if (pdp)
              *pdp++ = ports[idx]; /* XXX presumed still in _hurd_ports */
             free_port (idx);
             ports[idx] = newport;
           }

         if (pdp)
           *pdp++ = ports[INIT_PORT_AUTH];
         free_port (INIT_PORT_AUTH);
         ports[INIT_PORT_AUTH] = newauth;

         reauth_port (INIT_PORT_CRDIR);
         reauth_port (INIT_PORT_CWDIR);

         if (!err)
           {
             /* Now we'll reauthenticate each file descriptor.  */
             if (ulink_dtable == NULL)
              {
                assert (dtable == _hurd_init_dtable);
                dtable = __alloca (dtablesize * sizeof (dtable[0]));
                for (i = 0; i < dtablesize; ++i)
                  if (_hurd_init_dtable[i] != MACH_PORT_NULL)
                    {
                     if (pdp)
                       *pdp++ = _hurd_init_dtable[i];
                     err = reauth_io (_hurd_init_dtable[i], &dtable[i]);
                     if (err)
                       {
                         while (++i < dtablesize)
                           dtable[i] = MACH_PORT_NULL;
                         break;
                       }
                    }
                  else
                    dtable[i] = MACH_PORT_NULL;
              }
             else
              {
                if (pdp)
                  {
                    /* Ask to deallocate all the old fd ports,
                      since we will have new ones in DTABLE.  */
                    memcpy (pdp, dtable, dtablesize * sizeof pdp[0]);
                    pdp += dtablesize;
                  }
                for (i = 0; i < dtablesize; ++i)
                  if (dtable[i] != MACH_PORT_NULL)
                    {
                     io_t newport;
                     err = reauth_io (dtable[i], &newport);
                     _hurd_port_free (dtable_cells[i], &ulink_dtable[i],
                                    dtable[i]);
                     dtable[i] = newport;
                     if (err)
                       {
                         while (++i < dtablesize)
                           _hurd_port_free (dtable_cells[i],
                                          &ulink_dtable[i], dtable[i]);
                         break;
                       }
                    }
                ulink_dtable = NULL;
                dtable_cells = NULL;
              }
           }
       }

      reauth = 1;
    }
  __mutex_unlock (&_hurd_id.lock);

  /* The information is all set up now.  Try to exec the file.  */
  if (!err)
    {
      int flags;

      if (pdp)
       {
         /* Request the exec server to deallocate some ports from us if
            the exec succeeds.  The init ports and descriptor ports will
            arrive in the new program's exec_startup message.  If we
            failed to deallocate them, the new program would have
            duplicate user references for them.  But we cannot deallocate
            them ourselves, because we must still have them after a failed
            exec call.  */

         for (i = 0; i < _hurd_nports; ++i)
           *pdp++ = ports[i];
         for (i = 0; i < dtablesize; ++i)
           *pdp++ = dtable[i];
       }

      flags = 0;
#ifdef EXEC_SIGTRAP
      /* PTRACE_TRACEME sets all bits in _hurdsig_traced, which is
        propagated through exec by INIT_TRACEMASK, so this checks if
        PTRACE_TRACEME has been called in this process in any of its
        current or prior lives.  */
      if (__sigismember (&_hurdsig_traced, SIGKILL))
       flags |= EXEC_SIGTRAP;
#endif
      err = __file_exec (file, task, flags,
                      args, argslen, env, envlen,
                      dtable, MACH_MSG_TYPE_COPY_SEND, dtablesize,
                      ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
                      ints, INIT_INT_MAX,
                      please_dealloc, pdp - please_dealloc,
                      &_hurd_msgport, task == __mach_task_self () ? 1 : 0);
    }

  /* Release references to the standard ports.  */
  for (i = 0; i < _hurd_nports; ++i)
    if ((i == INIT_PORT_PROC && task != __mach_task_self ())
       || (reauth && (i == INIT_PORT_AUTH
                     || i == INIT_PORT_CRDIR || i == INIT_PORT_CWDIR)))
      __mach_port_deallocate (__mach_task_self (), ports[i]);
    else
      free_port (i);

  /* Release references to the file descriptor ports.  */
  if (ulink_dtable != NULL)
    {
      for (i = 0; i < dtablesize; ++i)
       if (dtable[i] != MACH_PORT_NULL)
         _hurd_port_free (dtable_cells[i], &ulink_dtable[i], dtable[i]);
    }
  else if (dtable && dtable != _hurd_init_dtable)
    for (i = 0; i < dtablesize; ++i)
      __mach_port_deallocate (__mach_task_self (), dtable[i]);

  /* Release lock on the file descriptor table. */
  __mutex_unlock (&_hurd_dtable_lock);

  /* Safe to let signals happen now.  */
  _hurd_critical_section_unlock (ss);

 outargs:
  free (args);
 outenv:
  free (env);
  return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _hurd_exit ( int  status)

Definition at line 26 of file _exit.c.

{
  /* Give the proc server our exit status.  */
  __USEPORT (PROC, __proc_mark_exit (port, status, 0));

  /* Commit suicide.  */
  __task_terminate (__mach_task_self ());

  /* Perhaps the cached mach_task_self was bogus.  */
  __task_terminate ((__mach_task_self) ());

  /* This sucker really doesn't want to die.  */
  while (1)
    {
#ifdef LOSE
      LOSE;
#else
      volatile const int zero = 0, one = 1;
      volatile int lossage = one / zero;
#endif
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _hurd_init ( int  flags,
char **  argv,
mach_port_t *  portarray,
size_t  portarraysize,
int intarray,
size_t  intarraysize 
)

Here is the caller graph for this function:

error_t _hurd_ports_get ( unsigned int  which,
mach_port_t *  result 
)

Definition at line 35 of file ports-get.c.

{
  if (which >= _hurd_nports)
    return EINVAL;
  if (which >= INIT_PORT_MAX || _hurd_ports_getters[which] == NULL)
    return HURD_PORT_USE (&_hurd_ports[which],
                       (*result = port) == MACH_PORT_NULL ? 0 
                       : __mach_port_mod_refs (__mach_task_self (),
                                            port, MACH_PORT_RIGHT_SEND,
                                            +1));
  return (*_hurd_ports_getters[which]) (result);
}

Here is the call graph for this function:

Here is the caller graph for this function:

error_t _hurd_ports_set ( unsigned int  which,
mach_port_t  newport 
)

Definition at line 43 of file ports-set.c.

{
  error_t err;
  if (which >= _hurd_nports)
    return EINVAL;
  if (err = __mach_port_mod_refs (__mach_task_self (), newport,
                              MACH_PORT_RIGHT_SEND, 1))
    return err;
  if (which >= INIT_PORT_MAX || _hurd_ports_setters[which] == NULL)
    {
      _hurd_port_set (&_hurd_ports[which], newport);
      return 0;
    }
  return (*_hurd_ports_setters[which]) (newport);
}

Here is the call graph for this function:

Here is the caller graph for this function:

error_t _hurd_ports_use ( int  which,
error_t(*)(mach_port_t)  operate 
)

Definition at line 41 of file hurdinit.c.

{
  if (__builtin_expect (_hurd_ports == NULL, 0))
    /* 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));
}

Here is the caller graph for this function:

void _hurd_proc_init ( char **  argv,
const int intarray,
size_t  intarraysize 
)
int _hurd_set_brk ( vm_address_t  newbrk)

Here is the caller graph for this function:

error_t _hurd_sig_post ( pid_t  pid,
int  sig,
mach_port_t  refport 
)

Definition at line 32 of file hurdkill.c.

{
  int delivered = 0;        /* Set when we deliver any signal.  */
  error_t err;
  mach_port_t proc;
  struct hurd_userlink ulink;

  inline void kill_pid (pid_t pid) /* Kill one PID.  */
    {
      err = HURD_MSGPORT_RPC (__proc_getmsgport (proc, pid, &msgport),
                           (refport = arg_refport, 0), 0,
                           /* If no message port we cannot send signals.  */
                           msgport == MACH_PORT_NULL ? EPERM :
                           __msg_sig_post (msgport, sig, 0, refport));
      if (! err)
       delivered = 1;
    }

  proc = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink);

  if (pid <= 0)
    {
      /* Send SIG to each process in pgrp (- PID).  */
      mach_msg_type_number_t npids = 10, i;
      pid_t pidsbuf[10], *pids = pidsbuf;

      err = __proc_getpgrppids (proc, - pid, &pids, &npids);
      if (!err)
       {
         int self = 0;
         for (i = 0; i < npids; ++i)
           if (pids[i] == _hurd_pid)
             /* We must do ourselves last so we are not suspended
               and fail to suspend the other processes in the pgrp.  */
             self = 1;
           else
             {
              kill_pid (pids[i]);
              if (err == ESRCH)
                /* The process died already.  Ignore it.  */
                err = 0;
             }
         if (pids != pidsbuf)
           __vm_deallocate (__mach_task_self (),
                          (vm_address_t) pids, npids * sizeof (pids[0]));

         if (self)
           kill_pid (_hurd_pid);
       }
    }
  else
    kill_pid (pid);

  _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, proc);

  /* If we delivered no signals, but ERR is clear, this must mean that
     every kill_pid call failed with ESRCH, meaning all the processes in
     the pgrp died between proc_getpgrppids and kill_pid; in that case we
     fail with ESRCH.  */
  return delivered ? 0 : err ?: ESRCH;
}

Here is the call graph for this function:

Here is the caller graph for this function:

socket_t _hurd_socket_server ( int  domain,
int  dead 
)

Definition at line 46 of file hurdsock.c.

{
  socket_t server;

  HURD_CRITICAL_BEGIN;
  __mutex_lock (&lock);

  if (domain > max_domain)
    {
      error_t save = errno;
      file_t *new = realloc (servers, (domain + 1) * sizeof (file_t));
      if (new != NULL)
       {
         do
           new[++max_domain] = MACH_PORT_NULL;
         while (max_domain < domain);
         servers = new;
       }
      else
       /* No space to cache the port; we will just fetch it anew below.  */
       errno = save;
    }

  if (dead && domain <= max_domain)
    {
      /* The user says the port we returned earlier (now in SERVERS[DOMAIN])
        was dead.  Clear the cache and fetch a new one below.  */
      __mach_port_deallocate (__mach_task_self (), servers[domain]);
      servers[domain] = MACH_PORT_NULL;
    }

  if (domain > max_domain || servers[domain] == MACH_PORT_NULL)
    {
      char name[sizeof (_SERVERS_SOCKET) + 100];
      char *np = &name[sizeof (name)];
      *--np = '\0';
      np = _itoa (domain, np, 10, 0);
      *--np = '/';
      np -= sizeof (_SERVERS_SOCKET) - 1;
      memcpy (np, _SERVERS_SOCKET, sizeof (_SERVERS_SOCKET) - 1);
      server = __file_name_lookup (np, 0, 0);
      if (domain <= max_domain)
       servers[domain] = server;
    }
  else
    server = servers[domain];

  if (server == MACH_PORT_NULL && errno == ENOENT)
    /* If the server node is absent, we don't support that protocol.  */
    errno = EAFNOSUPPORT;

  __mutex_unlock (&lock);
  HURD_CRITICAL_END;

  return server;
}

Here is the call graph for this function:

Here is the caller graph for this function:

file_t directory_name_split ( const char *  file,
char **  name 
)
file_t file_name_lookup ( const char *  file,
int  flags,
mode_t  mode 
)
file_t file_name_lookup_under ( file_t  startdir,
const char *  file,
int  flags,
mode_t  mode 
)
file_t file_name_path_lookup ( const char *  file_name,
const char *  path,
int  flags,
mode_t  mode,
char **  prefixed_name 
)

Definition at line 112 of file path-lookup.c.

{
  error_t err;
  file_t result;

  err = hurd_file_name_path_lookup (&_hurd_ports_use, &__getdport, 0,
                                file_name, path, flags, mode,
                                &result, prefixed_name);

  return err ? (__hurd_fail (err), MACH_PORT_NULL) : result;
}

Here is the call graph for this function:

file_t file_name_split ( const char *  file,
char **  name 
)
FILE* fopenport ( io_t  port,
const char *  mode 
)
kern_return_t get_privileged_ports ( mach_port_t *  host_priv_ptr,
device_t *  device_master_ptr 
)
auth_t getauth ( void  )
file_t getcrdir ( void  )
mach_port_t getcttyid ( void  )
file_t getcwdir ( void  )
io_t getdport ( int  fd)
int geteuids ( int  __n,
uid_t __uidset 
)

Definition at line 24 of file geteuids.c.

{
  error_t err;
  int nuids;
  void *crit;

  crit = _hurd_critical_section_lock ();
  __mutex_lock (&_hurd_id.lock);

  if (err = _hurd_check_ids ())
    {
      __mutex_unlock (&_hurd_id.lock);
      _hurd_critical_section_unlock (crit);
      return __hurd_fail (err);
    }

  nuids = _hurd_id.gen.nuids;

  if (n != 0)
    {
      /* Copy the uids onto stack storage and then release the idlock.  */
      uid_t uids[nuids];
      memcpy (uids, _hurd_id.gen.uids, sizeof (uids));
      __mutex_unlock (&_hurd_id.lock);
      _hurd_critical_section_unlock (crit);

      /* Now that the lock is released, we can safely copy the
        uid set into the user's array, which might fault.  */
      if (nuids > n)
       nuids = n;
      memcpy (uidset, uids, nuids * sizeof (uid_t));
    }
  else
    {
      __mutex_unlock (&_hurd_id.lock);
      _hurd_critical_section_unlock (crit);
    }

  return nuids;
}

Here is the call graph for this function:

process_t getproc ( void  )
int hurd_check_cancel ( void  )

Definition at line 89 of file thread-cancel.c.

{
  struct hurd_sigstate *ss = _hurd_self_sigstate ();
  int cancel;

  __spin_lock (&ss->lock);
  assert (! __spin_lock_locked (&ss->critical_section_lock));
  cancel = ss->cancel;
  ss->cancel = 0;
  __spin_unlock (&ss->lock);

  return cancel;
}

Here is the call graph for this function:

error_t hurd_sig_post ( pid_t  pid,
int  sig,
mach_port_t  refport 
)

Definition at line 36 of file thread-cancel.c.

{
  struct hurd_sigstate *ss = _hurd_thread_sigstate (thread);
  struct machine_thread_all_state state;
  int state_change;
  error_t err;

  if (! ss)
    return EINVAL;
  if (ss == _hurd_self_sigstate ())
    {
      /* We are cancelling ourselves, so it is easy to succeed
        quickly.  Since this function is not a cancellation point, we
        just leave the flag set pending the next cancellation point
        (hurd_check_cancel or RPC) and return success.  */
      ss->cancel = 1;
      return 0;
    }

  assert (! __spin_lock_locked (&ss->critical_section_lock));
  __spin_lock (&ss->critical_section_lock);
  __spin_lock (&ss->lock);
  err = __thread_suspend (thread);
  __spin_unlock (&ss->lock);

  if (! err)
    {
      /* Set the flag telling the thread its operation is being cancelled.  */
      ss->cancel = 1;

      /* Interrupt any interruptible RPC now in progress.  */
      state.set = 0;
      _hurdsig_abort_rpcs (ss, 0, 0, &state, &state_change, NULL, 0, 0);
      if (state_change)
       err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
                              (natural_t *) &state.basic,
                              MACHINE_THREAD_STATE_COUNT);

      if (ss->cancel_hook)
       /* The code being cancelled has a special wakeup function.
          Calling this should make the thread wake up and check the
          cancellation flag.  */
       (*ss->cancel_hook) ();

      __thread_resume (thread);
    }

  _hurd_critical_section_unlock (ss);
  return err;
}

Here is the call graph for this function:

Definition at line 23 of file thread-self.c.

{
  return _hurd_self_sigstate ()->thread;
}

Here is the call graph for this function:

int openport ( io_t  port,
int  flags 
)

Definition at line 26 of file openport.c.

{
  return _hurd_intern_fd (port, flags, 0);
}

Here is the call graph for this function:

task_t pid2task ( pid_t  pid)
int setauth ( auth_t  )
int setcrdir ( file_t  )
int setcttyid ( mach_port_t  )
int setcwdir ( file_t  )
int seteuids ( int  __n,
const uid_t __uidset 
)

Definition at line 24 of file seteuids.c.

{
  error_t err;
  auth_t newauth;
  int i;
  gid_t new[n];

  /* Fault before taking locks.  */
  for (i = 0; i < n; ++i)
    new[i] = uids[i];

  HURD_CRITICAL_BEGIN;
  __mutex_lock (&_hurd_id.lock);
  err = _hurd_check_ids ();
  if (! err)
    {
      /* Get a new auth port using those IDs.  */
      err = __USEPORT (AUTH,
                     __auth_makeauth (port, NULL, 0, 0,
                                   new, n,
                                   _hurd_id.aux.uids, _hurd_id.aux.nuids,
                                   _hurd_id.gen.gids, _hurd_id.gen.ngids,
                                   _hurd_id.aux.gids, _hurd_id.aux.ngids,
                                   &newauth));
    }
  __mutex_unlock (&_hurd_id.lock);
  HURD_CRITICAL_END;

  if (err)
    return __hurd_fail (err);

  /* Install the new auth port and reauthenticate everything.  */
  err = __setauth (newauth);
  __mach_port_deallocate (__mach_task_self (), newauth);
  return err;
}

Here is the call graph for this function:

int setproc ( process_t  )
pid_t task2pid ( task_t  task)
int vpprintf ( io_t  port,
const char *  format,
va_list  arg 
)

Definition at line 41 of file vpprintf.c.

{
  int done;

#ifdef USE_IN_LIBIO

  struct locked_FILE
  {
    struct _IO_cookie_file cfile;
#ifdef _IO_MTSAFE_IO
    _IO_lock_t lock;
#endif
  } temp_f;
#ifdef _IO_MTSAFE_IO
  temp_f.cfile.__fp.file._lock = &temp_f.lock;
#endif

  _IO_cookie_init (&temp_f.cfile, _IO_NO_READS,
                 (void *) port, (cookie_io_functions_t) { write: do_write });

  done = _IO_vfprintf (&temp_f.cfile.__fp.file, format, arg);

#else

  FILE f;

  /* Create an unbuffered stream talking to PORT on the stack.  */
  memset ((void *) &f, 0, sizeof (f));
  f.__magic = _IOMAGIC;
  f.__mode.__write = 1;
  f.__cookie = (void *) port;
  f.__room_funcs = __default_room_functions;
  f.__io_funcs.__write = do_write;
  f.__seen = 1;
  f.__userbuf = 1;

  /* vfprintf will use a buffer on the stack for the life of the call.  */
  done = vfprintf (&f, format, arg);

#endif

  return done;
}

Here is the call graph for this function:


Variable Documentation

vm_address_t _hurd_brk

Definition at line 34 of file brk.c.

vm_address_t _hurd_data_end

Definition at line 30 of file brk.c.

mach_port_t _hurd_device_master

Definition at line 24 of file privports.c.

Definition at line 30 of file hurdinit.c.

mach_port_t _hurd_host_priv

Definition at line 24 of file privports.c.

mach_port_t* _hurd_init_dtable

Definition at line 34 of file hurdstartup.c.

mach_msg_type_number_t _hurd_init_dtablesize

Definition at line 35 of file hurdstartup.c.

unsigned int _hurd_nports

Definition at line 32 of file hurdinit.c.

Definition at line 21 of file hurdpid.c.

Definition at line 20 of file hurdpid.c.

Definition at line 20 of file hurdpid.c.

Definition at line 44 of file hurdpid.c.

Definition at line 31 of file hurdinit.c.

Definition at line 20 of file hurdpid.c.

vm_address_t _hurd_stack_base
vm_size_t _hurd_stack_size

Definition at line 33 of file hurdinit.c.

Definition at line 34 of file hurdinit.c.