home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / glibc-1.06 / hurd / dtable.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-16  |  5.7 KB  |  209 lines

  1. /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <hurd.h>
  21. #include <gnu-stabs.h>
  22. #include <stdlib.h>
  23. #include <limits.h>
  24.  
  25.  
  26. struct _hurd_dtable _hurd_dtable;
  27. struct mutex _hurd_dtable_lock;
  28. int _hurd_dtable_rlimit;
  29. int *_hurd_dtable_user_dealloc;
  30.  
  31. const struct _hurd_dtable_resizes _hurd_dtable_resizes;
  32.  
  33.  
  34. /* Initialize the file descriptor table at startup.  */
  35.  
  36. static void
  37. init_dtable (void)
  38. {
  39.   register size_t i;
  40.  
  41.   __mutex_init (&_hurd_dtable_lock);
  42.  
  43.   _hurd_dtable_user_dealloc = NULL;
  44.  
  45.   /* The initial size of the descriptor table is that of the passed-in
  46.      table, rounded up to a multiple of OPEN_MAX descriptors.  */
  47.   _hurd_dtable.size
  48.     = (_hurd_init_dtablesize + OPEN_MAX - 1) / OPEN_MAX * OPEN_MAX;
  49.   _hurd_dtable_rlimit = _hurd_dtable.size;
  50.  
  51.   _hurd_dtable.d = malloc (_hurd_dtable.size * sizeof (*_hurd_dtable.d));
  52.   if (_hurd_dtable.d == NULL)
  53.     __libc_fatal ("hurd: Can't allocate file descriptor table\n");
  54.  
  55.   for (i = 0; i < _hurd_init_dtablesize; ++i)
  56.     {
  57.       struct _hurd_fd *const d = &_hurd_dtable.d[i];
  58.       io_statbuf_t stb;
  59.       io_t ctty;
  60.  
  61.       _hurd_port_init (&d->port, _hurd_init_dtable[i]);
  62.       d->flags = 0;
  63.  
  64.       if (_hurd_ctty_fstype != 0 &&
  65.       /* We have a controlling tty.  Is this it?  */
  66.       ! __io_stat (d->port.port, &stb) &&
  67.       stb.stb_fstype == _hurd_ctty_fstype &&
  68.       stb.stb_fsid == _hurd_ctty_fsid &&
  69.       stb.stb_fileid == _hurd_ctty_fileid &&
  70.       /* This is a descriptor to our controlling tty.  */
  71.       ! __term_become_ctty (d->port.port, _hurd_pid, _hurd_pgrp,
  72.                 _hurd_sigport, &ctty))
  73.     {
  74.       /* Operations on CTTY return EBACKGROUND when we are not a
  75.          foreground user of the tty.  */
  76.       d->port.port = ctty;
  77.       ctty = _hurd_init_dtable[i];
  78.     }
  79.       else
  80.     /* No ctty magic happening here.  */
  81.     ctty = MACH_PORT_NULL;
  82.  
  83.       _hurd_port_init (&d->ctty, ctty);
  84.     }
  85.  
  86.   /* Initialize the remaining empty slots in the table.  */
  87.   for (; i < _hurd_dtable.size; ++i)
  88.     {
  89.       _hurd_port_init (&_hurd_dtable.d[i].port, MACH_PORT_NULL);
  90.       _hurd_port_init (&_hurd_dtable.d[i].ctty, MACH_PORT_NULL);
  91.       _hurd_dtable.d[i].flags = 0;
  92.     }
  93.  
  94.   /* Clear out the initial descriptor table.
  95.      Everything must use _hurd_dtable now.  */
  96.   __vm_deallocate (__mach_task_self (),
  97.            _hurd_init_dtable,
  98.            _hurd_init_dtablesize * sizeof (_hurd_init_dtable[0]));
  99.   _hurd_init_dtable = NULL;
  100.   _hurd_init_dtablesize = 0;
  101. }
  102.  
  103. text_set_element (__libc_subinit, init_dtable);
  104.  
  105. /* Called by `getdport' to do its work.  */
  106.  
  107. static file_t
  108. get_dtable_port (int fd)
  109. {
  110.   file_t dport;
  111.   int err = _HURD_DPORT_USE (fd,
  112.                  __mach_port_mod_refs (__mach_task_self (),
  113.                            (dport = port),
  114.                            MACH_PORT_RIGHT_SEND,
  115.                            1));
  116.   if (err)
  117.     {
  118.       errno = err;
  119.       return MACH_PORT_NULL;
  120.     }
  121.   else
  122.     return dport;
  123. }
  124.  
  125. text_set_element (_hurd_getdport_fn, get_dtable_port);
  126.  
  127. /* Called on fork to install the dtable in NEWTASK.
  128.    The dtable lock is held.  */
  129.  
  130. static error_t
  131. fork_dtable (task_t newtask)
  132. {
  133.   error_t err;
  134.   int i;
  135.  
  136.   err = 0;
  137.  
  138.   for (i = 0; !err && i < _hurd_dtable.size; ++i)
  139.     {
  140.       int dealloc, dealloc_ctty;
  141.       io_t port = _HURD_PORT_USE (&_hurd_dtable.d[i].port, &dealloc);
  142.       io_t ctty = _HURD_PORT_USE (&_hurd_dtable.d[i].ctty, &dealloc_ctty);
  143.  
  144.       if (port != MACH_PORT_NULL)
  145.     err = __mach_port_insert_right (newtask, port, port,
  146.                     MACH_PORT_COPY_SEND);
  147.       if (!err && ctty != MACH_PORT_NULL)
  148.     err = __mach_port_insert_right (newtask, ctty, ctty,
  149.                     MACH_PORT_COPY_SEND);
  150.  
  151.       _hurd_port_free (port, &dealloc);
  152.       _hurd_port_free (ctty, &dealloc_ctty);
  153.  
  154.       /* XXX for each fd with a cntlmap, reauth and re-map_cntl.  */
  155.     }
  156.   __mutex_unlock (&_hurd_dtable_lock);
  157.   return err;
  158. }
  159.  
  160. text_set_element (_hurd_fork_hook, fork_dtable);
  161. text_set_element (_hurd_fork_locks, _hurd_dtable_lock);
  162.  
  163. /* Called to reauthenticate the dtable when the auth port changes.  */
  164.  
  165. static void
  166. reauth_dtable (void)
  167. {
  168.   int d;
  169.  
  170.   __mutex_lock (&_hurd_dtable_lock);
  171.  
  172.   for (d = 0; d < _hurd_dtable.size; ++d)
  173.     {
  174.       struct _hurd_fd *const d = &hurd_dtable.d[d];
  175.       mach_port_t new, newctty;
  176.       
  177.       /* Take the descriptor cell's lock.  */
  178.       __spin_lock (&cell->port.lock);
  179.       
  180.       /* Reauthenticate the descriptor's port.  */
  181.       if (cell->port.port != MACH_PORT_NULL &&
  182.       ! __io_reauthenticate (cell->port.port) &&
  183.       ! _HURD_PORT_USE (&_hurd_auth,
  184.                 __auth_user_authenticate (port,
  185.                               cell->port.port, &new)))
  186.     {
  187.       /* Replace the port in the descriptor cell
  188.          with the newly reauthenticated port.  */
  189.  
  190.       if (cell->ctty.port != MACH_PORT_NULL &&
  191.           ! __io_reauthenticate (cell->ctty.port) &&
  192.           ! _HURD_PORT_USE (&_hurd_auth,
  193.                 __auth_user_authenticate (port,
  194.                               cell->ctty.port,
  195.                               &newctty)))
  196.         _hurd_port_set (&cell->ctty, newctty);
  197.  
  198.       _hurd_port_locked_set (&cell->port, new);
  199.     }
  200.       else
  201.     /* Lost.  Leave this descriptor cell alone.  */
  202.     __spin_unlock (&cell->port.lock);
  203.     }
  204.  
  205.   __mutex_unlock (&_hurd_dtable_lock);
  206. }
  207.  
  208. text_set_element (_hurd_reauth_hook, reauth_dtable);
  209.