]> git.ipfire.org Git - thirdparty/glibc.git/blame - hurd/dtable.c
Fri May 3 13:32:08 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
[thirdparty/glibc.git] / hurd / dtable.c
CommitLineData
28f540f4
RM
1/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
2This file is part of the GNU C Library.
3
4The GNU C Library is free software; you can redistribute it and/or
5modify it under the terms of the GNU Library General Public License as
6published by the Free Software Foundation; either version 2 of the
7License, or (at your option) any later version.
8
9The GNU C Library is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12Library General Public License for more details.
13
14You should have received a copy of the GNU Library General Public
15License along with the GNU C Library; see the file COPYING.LIB. If
16not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17Cambridge, MA 02139, USA. */
18
19#include <ansidecl.h>
20#include <hurd.h>
21#include <hurd/term.h>
22#include <hurd/fd.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <fcntl.h>
26#include <limits.h>
27#include <cthreads.h> /* For `struct mutex'. */
28#include "set-hooks.h"
29#include "hurdmalloc.h" /* XXX */
30
31
32struct mutex _hurd_dtable_lock = MUTEX_INITIALIZER; /* XXX ld bug; must init */
33struct hurd_fd **_hurd_dtable;
34int _hurd_dtablesize;
35
36
37DEFINE_HOOK (_hurd_fd_subinit, (void));
38
39/* Initialize the file descriptor table at startup. */
40
41static void
42init_dtable (void)
43{
1e9dc039 44 int i;
28f540f4
RM
45
46 __mutex_init (&_hurd_dtable_lock);
47
48 /* The initial size of the descriptor table is that of the passed-in
49 table. It will be expanded as necessary up to _hurd_dtable_rlimit. */
50 _hurd_dtablesize = _hurd_init_dtablesize;
51
52 /* Allocate the vector of pointers. */
53 _hurd_dtable = malloc (_hurd_dtablesize * sizeof (*_hurd_dtable));
54 if (_hurd_dtablesize != 0 && _hurd_dtable == NULL)
55 __libc_fatal ("hurd: Can't allocate file descriptor table\n");
56
57 /* Initialize the descriptor table. */
1e9dc039 58 for (i = 0; (unsigned int) i < _hurd_init_dtablesize; ++i)
28f540f4
RM
59 {
60 if (_hurd_init_dtable[i] == MACH_PORT_NULL)
61 /* An unused descriptor is marked by a null pointer. */
62 _hurd_dtable[i] = NULL;
63 else
64 {
65 /* Allocate a new file descriptor structure. */
66 struct hurd_fd *new = malloc (sizeof (struct hurd_fd));
67 if (new == NULL)
68 __libc_fatal ("hurd: Can't allocate initial file descriptors\n");
69
70 /* Initialize the port cells. */
71 _hurd_port_init (&new->port, MACH_PORT_NULL);
72 _hurd_port_init (&new->ctty, MACH_PORT_NULL);
73
74 /* Install the port in the descriptor.
75 This sets up all the ctty magic. */
76 _hurd_port2fd (new, _hurd_init_dtable[i], 0);
77
78 _hurd_dtable[i] = new;
79 }
80 }
81
82 /* Clear out the initial descriptor table.
83 Everything must use _hurd_dtable now. */
84 __vm_deallocate (__mach_task_self (),
85 (vm_address_t) _hurd_init_dtable,
86 _hurd_init_dtablesize * sizeof (_hurd_init_dtable[0]));
87 _hurd_init_dtable = NULL;
88 _hurd_init_dtablesize = 0;
89
90 /* Initialize the remaining empty slots in the table. */
91 for (; i < _hurd_dtablesize; ++i)
92 _hurd_dtable[i] = NULL;
93
94 /* Run things that want to run after the file descriptor table
95 is initialized. */
96 RUN_HOOK (_hurd_fd_subinit, ());
97
98 (void) &init_dtable; /* Avoid "defined but not used" warning. */
99}
100
101text_set_element (_hurd_subinit, init_dtable);
102
103/* XXX when the linker supports it, the following functions should all be
104 elsewhere and just have text_set_elements here. */
105\f
106/* Called by `getdport' to do its work. */
107
108static file_t
109get_dtable_port (int fd)
110{
111 file_t dport;
112 int err = HURD_DPORT_USE (fd, __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
125file_t (*_hurd_getdport_fn) (int fd) = get_dtable_port;
126\f
127#include <hurd/signal.h>
128
129/* We are in the child fork; the dtable lock is still held.
130 The parent has inserted send rights for all the normal io ports,
131 but we must recover ctty-special ports for ourselves. */
132static error_t
133fork_child_dtable (void)
134{
135 error_t err;
136 int i;
137
138 err = 0;
139
140 for (i = 0; !err && i < _hurd_dtablesize; ++i)
141 {
142 struct hurd_fd *d = _hurd_dtable[i];
143 if (d == NULL)
144 continue;
145
146 /* No other thread is using the send rights in the child task. */
147 d->port.users = d->ctty.users = NULL;
148
149 if (d->ctty.port != MACH_PORT_NULL)
150 {
151 /* There was a ctty-special port in the parent.
152 We need to get one for ourselves too. */
153 __mach_port_deallocate (__mach_task_self (), d->ctty.port);
154 err = __term_open_ctty (d->port.port, _hurd_pid, _hurd_pgrp,
155 &d->ctty.port);
156 if (err)
157 d->ctty.port = MACH_PORT_NULL;
158 }
159
160 /* XXX for each fd with a cntlmap, reauth and re-map_cntl. */
161 }
162 return err;
163
164 (void) &fork_child_dtable; /* Avoid "defined but not used" warning. */
165}
166
167data_set_element (_hurd_fork_locks, _hurd_dtable_lock); /* XXX ld bug: bss */
168text_set_element (_hurd_fork_child_hook, fork_child_dtable);
169\f
170/* Called when our process group has changed. */
171
172static void
173ctty_new_pgrp (void)
174{
175 int i;
176
177 HURD_CRITICAL_BEGIN;
178 __mutex_lock (&_hurd_dtable_lock);
179
180 for (i = 0; i < _hurd_dtablesize; ++i)
181 {
182 struct hurd_fd *const d = _hurd_dtable[i];
183 struct hurd_userlink ulink, ctty_ulink;
184 io_t port, ctty;
185
186 if (d == NULL)
187 /* Nothing to do for an unused descriptor cell. */
188 continue;
189
190 port = _hurd_port_get (&d->port, &ulink);
191 ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
192
193 if (ctty != MACH_PORT_NULL)
194 {
195 /* This fd has a ctty-special port. We need a new one, to tell
196 the io server of our different process group. */
197 io_t new;
198 if (__term_open_ctty (port, _hurd_pid, _hurd_pgrp, &new))
199 new = MACH_PORT_NULL;
200 _hurd_port_set (&d->ctty, new);
201 }
202
203 _hurd_port_free (&d->port, &ulink, port);
204 _hurd_port_free (&d->ctty, &ctty_ulink, ctty);
205 }
206
207 __mutex_unlock (&_hurd_dtable_lock);
208 HURD_CRITICAL_END;
209
210 (void) &ctty_new_pgrp; /* Avoid "defined but not used" warning. */
211}
212
213text_set_element (_hurd_pgrp_changed_hook, ctty_new_pgrp);
214\f
215/* Called to reauthenticate the dtable when the auth port changes. */
216
217static void
218reauth_dtable (void)
219{
220 int i;
221
222 HURD_CRITICAL_BEGIN;
223 __mutex_lock (&_hurd_dtable_lock);
224
225 for (i = 0; i < _hurd_dtablesize; ++i)
226 {
227 struct hurd_fd *const d = _hurd_dtable[i];
228 mach_port_t new, newctty, ref;
229
230 if (d == NULL)
231 /* Nothing to do for an unused descriptor cell. */
232 continue;
233
234 ref = __mach_reply_port ();
235
236 /* Take the descriptor cell's lock. */
237 __spin_lock (&d->port.lock);
238
239 /* Reauthenticate the descriptor's port. */
240 if (d->port.port != MACH_PORT_NULL &&
241 ! __io_reauthenticate (d->port.port,
242 ref, MACH_MSG_TYPE_MAKE_SEND) &&
243 ! __USEPORT (AUTH, __auth_user_authenticate
244 (port,
245 d->port.port,
246 ref, MACH_MSG_TYPE_MAKE_SEND,
247 &new)))
248 {
249 /* Replace the port in the descriptor cell
250 with the newly reauthenticated port. */
251
252 if (d->ctty.port != MACH_PORT_NULL &&
253 ! __io_reauthenticate (d->ctty.port,
254 ref, MACH_MSG_TYPE_MAKE_SEND) &&
255 ! __USEPORT (AUTH, __auth_user_authenticate
256 (port,
257 d->ctty.port,
258 ref, MACH_MSG_TYPE_MAKE_SEND,
259 &newctty)))
260 _hurd_port_set (&d->ctty, newctty);
261
262 _hurd_port_locked_set (&d->port, new);
263 }
264 else
265 /* Lost. Leave this descriptor cell alone. */
266 __spin_unlock (&d->port.lock);
267
268 __mach_port_destroy (__mach_task_self (), ref);
269 }
270
271 __mutex_unlock (&_hurd_dtable_lock);
272 HURD_CRITICAL_END;
273
274 (void) &reauth_dtable; /* Avoid "defined but not used" warning. */
275}
276
277text_set_element (_hurd_reauth_hook, reauth_dtable);