📄 dtable.c
字号:
/* Copyright (C) 1991, 1992, 1993, 1994 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/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with the GNU C Library; see the file COPYING.LIB. Ifnot, write to the Free Software Foundation, Inc., 675 Mass Ave,Cambridge, MA 02139, USA. */#include <ansidecl.h>#include <hurd.h>#include <hurd/term.h>#include <hurd/fd.h>#include <gnu-stabs.h>#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <limits.h>#include <cthreads.h> /* For `struct mutex'. */#include "set-hooks.h"#include "hurdmalloc.h" /* XXX */struct mutex _hurd_dtable_lock = MUTEX_INITIALIZER; /* XXX ld bug; must init */struct hurd_fd **_hurd_dtable;int _hurd_dtablesize;DEFINE_HOOK (_hurd_fd_subinit, (void));/* Initialize the file descriptor table at startup. */static voidinit_dtable (void){ register size_t 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; 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. */}text_set_element (_hurd_subinit, init_dtable);/* XXX when the linker supports it, the following functions should all be elsewhere and just have text_set_elements here. *//* Called by `getdport' to do its work. */static file_tget_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;}file_t (*_hurd_getdport_fn) (int fd) = get_dtable_port;#include <hurd/signal.h>/* We are in the child fork; the dtable lock is still held. The parent has inserted send rights for all the normal io ports, but we must recover ctty-special ports for ourselves. */static error_tfork_child_dtable (void){ 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. */}data_set_element (_hurd_fork_locks, _hurd_dtable_lock); /* XXX ld bug: bss */text_set_element (_hurd_fork_child_hook, fork_child_dtable);/* Called when our process group has changed. */static voidctty_new_pgrp (void){ 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]; 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. */}text_set_element (_hurd_pgrp_changed_hook, ctty_new_pgrp);/* Called to reauthenticate the dtable when the auth port changes. */static voidreauth_dtable (void){ 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, d->port.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, d->ctty.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. */}text_set_element (_hurd_reauth_hook, reauth_dtable);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -