home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, write to the Free Software Foundation, Inc., 675 Mass Ave,
- Cambridge, MA 02139, USA. */
-
- #include <ansidecl.h>
- #include <hurd.h>
- #include <gnu-stabs.h>
- #include <stdlib.h>
- #include <limits.h>
-
-
- struct _hurd_dtable _hurd_dtable;
- struct mutex _hurd_dtable_lock;
- int _hurd_dtable_rlimit;
- int *_hurd_dtable_user_dealloc;
-
- const struct _hurd_dtable_resizes _hurd_dtable_resizes;
-
-
- /* Initialize the file descriptor table at startup. */
-
- static void
- init_dtable (void)
- {
- register size_t i;
-
- __mutex_init (&_hurd_dtable_lock);
-
- _hurd_dtable_user_dealloc = NULL;
-
- /* The initial size of the descriptor table is that of the passed-in
- table, rounded up to a multiple of OPEN_MAX descriptors. */
- _hurd_dtable.size
- = (_hurd_init_dtablesize + OPEN_MAX - 1) / OPEN_MAX * OPEN_MAX;
- _hurd_dtable_rlimit = _hurd_dtable.size;
-
- _hurd_dtable.d = malloc (_hurd_dtable.size * sizeof (*_hurd_dtable.d));
- if (_hurd_dtable.d == NULL)
- __libc_fatal ("hurd: Can't allocate file descriptor table\n");
-
- for (i = 0; i < _hurd_init_dtablesize; ++i)
- {
- struct _hurd_fd *const d = &_hurd_dtable.d[i];
- io_statbuf_t stb;
- io_t ctty;
-
- _hurd_port_init (&d->port, _hurd_init_dtable[i]);
- d->flags = 0;
-
- if (_hurd_ctty_fstype != 0 &&
- /* We have a controlling tty. Is this it? */
- ! __io_stat (d->port.port, &stb) &&
- stb.stb_fstype == _hurd_ctty_fstype &&
- stb.stb_fsid == _hurd_ctty_fsid &&
- stb.stb_fileid == _hurd_ctty_fileid &&
- /* This is a descriptor to our controlling tty. */
- ! __term_become_ctty (d->port.port, _hurd_pid, _hurd_pgrp,
- _hurd_sigport, &ctty))
- {
- /* Operations on CTTY return EBACKGROUND when we are not a
- foreground user of the tty. */
- d->port.port = ctty;
- ctty = _hurd_init_dtable[i];
- }
- else
- /* No ctty magic happening here. */
- ctty = MACH_PORT_NULL;
-
- _hurd_port_init (&d->ctty, ctty);
- }
-
- /* Initialize the remaining empty slots in the table. */
- for (; i < _hurd_dtable.size; ++i)
- {
- _hurd_port_init (&_hurd_dtable.d[i].port, MACH_PORT_NULL);
- _hurd_port_init (&_hurd_dtable.d[i].ctty, MACH_PORT_NULL);
- _hurd_dtable.d[i].flags = 0;
- }
-
- /* Clear out the initial descriptor table.
- Everything must use _hurd_dtable now. */
- __vm_deallocate (__mach_task_self (),
- _hurd_init_dtable,
- _hurd_init_dtablesize * sizeof (_hurd_init_dtable[0]));
- _hurd_init_dtable = NULL;
- _hurd_init_dtablesize = 0;
- }
-
- text_set_element (__libc_subinit, init_dtable);
-
- /* Called by `getdport' to do its work. */
-
- static file_t
- get_dtable_port (int fd)
- {
- file_t dport;
- int err = _HURD_DPORT_USE (fd,
- __mach_port_mod_refs (__mach_task_self (),
- (dport = port),
- MACH_PORT_RIGHT_SEND,
- 1));
- if (err)
- {
- errno = err;
- return MACH_PORT_NULL;
- }
- else
- return dport;
- }
-
- text_set_element (_hurd_getdport_fn, get_dtable_port);
-
- /* Called on fork to install the dtable in NEWTASK.
- The dtable lock is held. */
-
- static error_t
- fork_dtable (task_t newtask)
- {
- error_t err;
- int i;
-
- err = 0;
-
- for (i = 0; !err && i < _hurd_dtable.size; ++i)
- {
- int dealloc, dealloc_ctty;
- io_t port = _HURD_PORT_USE (&_hurd_dtable.d[i].port, &dealloc);
- io_t ctty = _HURD_PORT_USE (&_hurd_dtable.d[i].ctty, &dealloc_ctty);
-
- if (port != MACH_PORT_NULL)
- err = __mach_port_insert_right (newtask, port, port,
- MACH_PORT_COPY_SEND);
- if (!err && ctty != MACH_PORT_NULL)
- err = __mach_port_insert_right (newtask, ctty, ctty,
- MACH_PORT_COPY_SEND);
-
- _hurd_port_free (port, &dealloc);
- _hurd_port_free (ctty, &dealloc_ctty);
-
- /* XXX for each fd with a cntlmap, reauth and re-map_cntl. */
- }
- __mutex_unlock (&_hurd_dtable_lock);
- return err;
- }
-
- text_set_element (_hurd_fork_hook, fork_dtable);
- text_set_element (_hurd_fork_locks, _hurd_dtable_lock);
-
- /* Called to reauthenticate the dtable when the auth port changes. */
-
- static void
- reauth_dtable (void)
- {
- int d;
-
- __mutex_lock (&_hurd_dtable_lock);
-
- for (d = 0; d < _hurd_dtable.size; ++d)
- {
- struct _hurd_fd *const d = &hurd_dtable.d[d];
- mach_port_t new, newctty;
-
- /* Take the descriptor cell's lock. */
- __spin_lock (&cell->port.lock);
-
- /* Reauthenticate the descriptor's port. */
- if (cell->port.port != MACH_PORT_NULL &&
- ! __io_reauthenticate (cell->port.port) &&
- ! _HURD_PORT_USE (&_hurd_auth,
- __auth_user_authenticate (port,
- cell->port.port, &new)))
- {
- /* Replace the port in the descriptor cell
- with the newly reauthenticated port. */
-
- if (cell->ctty.port != MACH_PORT_NULL &&
- ! __io_reauthenticate (cell->ctty.port) &&
- ! _HURD_PORT_USE (&_hurd_auth,
- __auth_user_authenticate (port,
- cell->ctty.port,
- &newctty)))
- _hurd_port_set (&cell->ctty, newctty);
-
- _hurd_port_locked_set (&cell->port, new);
- }
- else
- /* Lost. Leave this descriptor cell alone. */
- __spin_unlock (&cell->port.lock);
- }
-
- __mutex_unlock (&_hurd_dtable_lock);
- }
-
- text_set_element (_hurd_reauth_hook, reauth_dtable);
-