Back to index

glibc  2.9
Functions | Variables
dtable.c File Reference
#include <hurd.h>
#include <hurd/term.h>
#include <hurd/fd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <limits.h>
#include <cthreads.h>
#include "set-hooks.h"
#include "hurdmalloc.h"
#include <hurd/signal.h>

Go to the source code of this file.

Functions

 DEFINE_HOOK (_hurd_fd_subinit,(void))
static void init_dtable (void)
 text_set_element (_hurd_subinit, init_dtable)
static file_t get_dtable_port (int fd)
static error_t fork_child_dtable (void)
 data_set_element (_hurd_fork_locks, _hurd_dtable_lock)
 text_set_element (_hurd_fork_child_hook, fork_child_dtable)
static void ctty_new_pgrp (void)
 text_set_element (_hurd_pgrp_changed_hook, ctty_new_pgrp)
static void reauth_dtable (void)
 text_set_element (_hurd_reauth_hook, reauth_dtable)

Variables

struct hurd_fd ** _hurd_dtable
int _hurd_dtablesize
file_t(* _hurd_getdport_fn )(int fd) = get_dtable_port

Function Documentation

static void ctty_new_pgrp ( void  ) [static]

Definition at line 189 of file dtable.c.

{
  int i;

  HURD_CRITICAL_BEGIN;
  __mutex_lock (&_hurd_dtable_lock);

  if (__USEPORT (CTTYID, port == MACH_PORT_NULL))
    {
      /* We have no controlling terminal.  If we haven't had one recently,
        but our pgrp is being pointlessly diddled anyway, then we will
        have nothing to do in the loop below because no fd will have a
        ctty port at all.

        More likely, a setsid call is responsible both for the change
        in pgrp and for clearing the cttyid port.  In that case, setsid
        held the dtable lock while updating the dtable to clear all the
        ctty ports, and ergo must have finished doing so before we run here.
        So we can be sure, again, that the loop below has no work to do.  */
    }
  else
    for (i = 0; i < _hurd_dtablesize; ++i)
      {
       struct hurd_fd *const d = _hurd_dtable[i];
       struct hurd_userlink ulink, ctty_ulink;
       io_t port, ctty;

       if (d == NULL)
         /* Nothing to do for an unused descriptor cell.  */
         continue;

       port = _hurd_port_get (&d->port, &ulink);
       ctty = _hurd_port_get (&d->ctty, &ctty_ulink);

       if (ctty != MACH_PORT_NULL)
         {
           /* This fd has a ctty-special port.  We need a new one, to tell
              the io server of our different process group.  */
           io_t new;
           if (__term_open_ctty (port, _hurd_pid, _hurd_pgrp, &new))
             new = MACH_PORT_NULL;
           _hurd_port_set (&d->ctty, new);
         }

       _hurd_port_free (&d->port, &ulink, port);
       _hurd_port_free (&d->ctty, &ctty_ulink, ctty);
      }

  __mutex_unlock (&_hurd_dtable_lock);
  HURD_CRITICAL_END;

  (void) &ctty_new_pgrp;    /* Avoid "defined but not used" warning.  */
}

Here is the call graph for this function:

data_set_element ( _hurd_fork_locks  ,
_hurd_dtable_lock   
)
DEFINE_HOOK ( _hurd_fd_subinit  ,
(void)   
)
static error_t fork_child_dtable ( void  ) [static]

Definition at line 149 of file dtable.c.

{
  error_t err;
  int i;

  err = 0;

  for (i = 0; !err && i < _hurd_dtablesize; ++i)
    {
      struct hurd_fd *d = _hurd_dtable[i];
      if (d == NULL)
       continue;

      /* No other thread is using the send rights in the child task.  */
      d->port.users = d->ctty.users = NULL;

      if (d->ctty.port != MACH_PORT_NULL)
       {
         /* There was a ctty-special port in the parent.
            We need to get one for ourselves too.  */
         __mach_port_deallocate (__mach_task_self (), d->ctty.port);
         err = __term_open_ctty (d->port.port, _hurd_pid, _hurd_pgrp,
                              &d->ctty.port);
         if (err)
           d->ctty.port = MACH_PORT_NULL;
       }

      /* XXX for each fd with a cntlmap, reauth and re-map_cntl.  */
    }
  return err;

  (void) &fork_child_dtable;       /* Avoid "defined but not used" warning.  */
}

Here is the call graph for this function:

static file_t get_dtable_port ( int  fd) [static]

Definition at line 108 of file dtable.c.

{
  struct hurd_fd *d = _hurd_fd_get (fd);
  file_t dport;

  if (!d)
    return __hurd_fail (EBADF), MACH_PORT_NULL;

  HURD_CRITICAL_BEGIN;

  dport = HURD_PORT_USE (&d->port,
                      ({
                        error_t err;
                        mach_port_t outport;
                        err = __mach_port_mod_refs (__mach_task_self (),
                                                 port,
                                                 MACH_PORT_RIGHT_SEND,
                                                 1);
                        if (err)
                          {
                            errno = err;
                            outport = MACH_PORT_NULL;
                          }
                        else
                          outport = port;
                        outport;
                      }));

  HURD_CRITICAL_END;

  return dport;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init_dtable ( void  ) [static]

Definition at line 41 of file dtable.c.

{
  int i;

  __mutex_init (&_hurd_dtable_lock);

  /* The initial size of the descriptor table is that of the passed-in
     table.  It will be expanded as necessary up to _hurd_dtable_rlimit.  */
  _hurd_dtablesize = _hurd_init_dtablesize;

  /* Allocate the vector of pointers.  */
  _hurd_dtable = malloc (_hurd_dtablesize * sizeof (*_hurd_dtable));
  if (_hurd_dtablesize != 0 && _hurd_dtable == NULL)
    __libc_fatal ("hurd: Can't allocate file descriptor table\n");

  /* Initialize the descriptor table.  */
  for (i = 0; (unsigned int) i < _hurd_init_dtablesize; ++i)
    {
      if (_hurd_init_dtable[i] == MACH_PORT_NULL)
       /* An unused descriptor is marked by a null pointer.  */
       _hurd_dtable[i] = NULL;
      else
       {
         /* Allocate a new file descriptor structure.  */
         struct hurd_fd *new = malloc (sizeof (struct hurd_fd));
         if (new == NULL)
           __libc_fatal ("hurd: Can't allocate initial file descriptors\n");

         /* Initialize the port cells.  */
         _hurd_port_init (&new->port, MACH_PORT_NULL);
         _hurd_port_init (&new->ctty, MACH_PORT_NULL);

         /* Install the port in the descriptor.
            This sets up all the ctty magic.  */
         _hurd_port2fd (new, _hurd_init_dtable[i], 0);

         _hurd_dtable[i] = new;
       }
    }

  /* Clear out the initial descriptor table.
     Everything must use _hurd_dtable now.  */
  __vm_deallocate (__mach_task_self (),
                 (vm_address_t) _hurd_init_dtable,
                 _hurd_init_dtablesize * sizeof (_hurd_init_dtable[0]));
  _hurd_init_dtable = NULL;
  _hurd_init_dtablesize = 0;

  /* Initialize the remaining empty slots in the table.  */
  for (; i < _hurd_dtablesize; ++i)
    _hurd_dtable[i] = NULL;

  /* Run things that want to run after the file descriptor table
     is initialized.  */
  RUN_HOOK (_hurd_fd_subinit, ());

  (void) &init_dtable;             /* Avoid "defined but not used" warning.  */
}

Here is the call graph for this function:

static void reauth_dtable ( void  ) [static]

Definition at line 248 of file dtable.c.

{
  int i;

  HURD_CRITICAL_BEGIN;
  __mutex_lock (&_hurd_dtable_lock);

  for (i = 0; i < _hurd_dtablesize; ++i)
    {
      struct hurd_fd *const d = _hurd_dtable[i];
      mach_port_t new, newctty, ref;

      if (d == NULL)
       /* Nothing to do for an unused descriptor cell.  */
       continue;

      ref = __mach_reply_port ();

      /* Take the descriptor cell's lock.  */
      __spin_lock (&d->port.lock);

      /* Reauthenticate the descriptor's port.  */
      if (d->port.port != MACH_PORT_NULL &&
         ! __io_reauthenticate (d->port.port,
                             ref, MACH_MSG_TYPE_MAKE_SEND) &&
         ! __USEPORT (AUTH, __auth_user_authenticate
                     (port,
                     ref, MACH_MSG_TYPE_MAKE_SEND,
                     &new)))
       {
         /* Replace the port in the descriptor cell
            with the newly reauthenticated port.  */

         if (d->ctty.port != MACH_PORT_NULL &&
             ! __io_reauthenticate (d->ctty.port,
                                 ref, MACH_MSG_TYPE_MAKE_SEND) &&
             ! __USEPORT (AUTH, __auth_user_authenticate
                        (port,
                         ref, MACH_MSG_TYPE_MAKE_SEND,
                         &newctty)))
           _hurd_port_set (&d->ctty, newctty);

         _hurd_port_locked_set (&d->port, new);
       }
      else
       /* Lost.  Leave this descriptor cell alone.  */
       __spin_unlock (&d->port.lock);

      __mach_port_destroy (__mach_task_self (), ref);
    }

  __mutex_unlock (&_hurd_dtable_lock);
  HURD_CRITICAL_END;

  (void) &reauth_dtable;    /* Avoid "defined but not used" warning.  */
}

Here is the call graph for this function:

text_set_element ( _hurd_subinit  ,
init_dtable   
)
text_set_element ( _hurd_fork_child_hook  ,
fork_child_dtable   
)
text_set_element ( _hurd_pgrp_changed_hook  ,
ctty_new_pgrp   
)
text_set_element ( _hurd_reauth_hook  ,
reauth_dtable   
)

Variable Documentation

Definition at line 32 of file dtable.c.

Definition at line 33 of file dtable.c.

Definition at line 141 of file dtable.c.