Formerly ../hurd/dtable.c.~8~
[kopensolaris-gnu/glibc.git] / hurd / dtable.c
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 <hurd.h>
20 #include <gnu-stabs.h>
21 #include <stdlib.h>
22 #include <limits.h>
23
24
25 /* Initialize the file descriptor table at startup.  */
26
27 static void
28 init_dtable (void)
29 {
30   register size_t i;
31
32   __mutex_init (&_hurd_dtable_lock);
33
34   /* The initial size of the descriptor table is that of the passed-in
35      table, rounded up to a multiple of OPEN_MAX descriptors.  */
36   _hurd_dtable.size
37     = (_hurd_init_dtablesize + OPEN_MAX - 1) / OPEN_MAX * OPEN_MAX;
38
39   _hurd_dtable.d = malloc (_hurd_dtable.size * sizeof (*_hurd_dtable.d));
40   if (_hurd_dtable.d == NULL)
41     __libc_fatal ("hurd: Can't allocate file descriptor table\n");
42
43   for (i = 0; i < _hurd_init_dtablesize; ++i)
44     {
45       __typeof (_hurd_dtable.d[i]) *const d = &_hurd_dtable.d[i];
46       io_statbuf_t stb;
47       io_t fg_port;
48
49       _hurd_port_init (&d->port, _hurd_init_dtable[i]);
50       d->flags = 0;
51
52       if (_hurd_ctty_fstype != 0 &&
53           /* We have a controlling tty.  Is this it?  */
54           ! __io_stat (d->port.port, &stb) &&
55           stb.stb_fstype == _hurd_ctty_fstype &&
56           stb.stb_fsid == _hurd_ctty_fsid &&
57           stb.stb_fileid == _hurd_ctty_fileid &&
58           /* This is a descriptor to our controlling tty.  */
59           ! __term_become_ctty (d->port.port, _hurd_pid, _hurd_pgrp,
60                                 _hurd_sigport, &fg_port))
61         {
62           /* Operations on FG_PORT return EBACKGROUND when we are not a
63              foreground user of the tty.  Operations on D->ctty never
64              return EBACKGROUND.  */
65           d->ctty = d->port.port;
66           d->port.port = fg_port;
67         }
68       else
69         /* No ctty magic happening here.  */
70         d->ctty = MACH_PORT_NULL;
71     }
72
73   /* Initialize the remaining empty slots in the table.  */
74   for (; i < _hurd_dtable.size; ++i)
75     {
76       _hurd_port_init (&_hurd_dtable.d[i].port, MACH_PORT_NULL);
77       _hurd_dtable.d[i].ctty = MACH_PORT_NULL;
78       _hurd_dtable.d[i].flags = 0;
79     }
80
81   /* Clear out the initial descriptor table.
82      Everything must use _hurd_dtable now.  */
83   __vm_deallocate (__mach_task_self (),
84                    _hurd_init_dtable,
85                    _hurd_init_dtablesize * sizeof (_hurd_init_dtable[0]));
86   _hurd_init_dtable = NULL;
87   _hurd_init_dtablesize = 0;
88 }
89
90 text_set_element (__libc_subinit, init_dtable);
91 \f
92 /* Called on fork to install the dtable in NEWTASK.  */
93
94 static error_t
95 fork_dtable (task_t newtask)
96 {
97   int i;
98   __mutex_lock (&_hurd_dtable_lock);
99   for (i = 0; i < _hurd_dtable.size; ++i)
100     if (err = _HURD_PORT_USE (&_hurd_dtable.d[i],
101                               __mach_port_insert_right (newtask, port, port,
102                                                         MACH_PORT_COPY_SEND)))
103       {
104         /* XXX for each fd with a cntlmap, reauth and re-map_cntl.  */
105         __mutex_unlock (&_hurd_dtable.lock);
106         return err;
107       }
108   __mutex_unlock (&_hurd_dtable_lock);
109   return 0;
110 }
111
112 text_set_element (_hurd_fork_hook, fork_dtable);