1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19: #include <hurd.h>
20: #include <hurd/term.h>
21: #include <hurd/fd.h>
22: #include <stdlib.h>
23: #include <stdio.h>
24: #include <fcntl.h>
25: #include <limits.h>
26: #include <cthreads.h>
27: #include "set-hooks.h"
28: #include "hurdmalloc.h"
29:
30:
31: struct mutex _hurd_dtable_lock = MUTEX_INITIALIZER;
32: struct hurd_fd **_hurd_dtable;
33: int _hurd_dtablesize;
34:
35:
36: DEFINE_HOOK (_hurd_fd_subinit, (void));
37:
38:
39:
40: static void
41: init_dtable (void)
42: {
43: int i;
44:
45: __mutex_init (&_hurd_dtable_lock);
46:
47:
48:
49: _hurd_dtablesize = _hurd_init_dtablesize;
50:
51:
52: _hurd_dtable = malloc (_hurd_dtablesize * sizeof (*_hurd_dtable));
53: if (_hurd_dtablesize != 0 && _hurd_dtable == NULL)
54: __libc_fatal ("hurd: Can't allocate file descriptor table\n");
55:
56:
57: for (i = 0; (unsigned int) i < _hurd_init_dtablesize; ++i)
58: {
59: if (_hurd_init_dtable[i] == MACH_PORT_NULL)
60:
61: _hurd_dtable[i] = NULL;
62: else
63: {
64:
65: struct hurd_fd *new = malloc (sizeof (struct hurd_fd));
66: if (new == NULL)
67: __libc_fatal ("hurd: Can't allocate initial file descriptors\n");
68:
69:
70: _hurd_port_init (&new->port, MACH_PORT_NULL);
71: _hurd_port_init (&new->ctty, MACH_PORT_NULL);
72:
73:
74:
75: _hurd_port2fd (new, _hurd_init_dtable[i], 0);
76:
77: _hurd_dtable[i] = new;
78: }
79: }
80:
81:
82:
83: __vm_deallocate (__mach_task_self (),
84: (vm_address_t) _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: for (; i < _hurd_dtablesize; ++i)
91: _hurd_dtable[i] = NULL;
92:
93:
94:
95: RUN_HOOK (_hurd_fd_subinit, ());
96:
97: (void) &init_dtable;
98: }
99:
100: text_set_element (_hurd_subinit, init_dtable);
101:
102:
103:
104: ^L
105:
106:
107: static file_t
108: get_dtable_port (int fd)
109: {
110: struct hurd_fd *d = _hurd_fd_get (fd);
111: file_t dport;
112:
113: if (!d)
114: return __hurd_fail (EBADF), MACH_PORT_NULL;
115:
116: HURD_CRITICAL_BEGIN;
117:
118: dport = HURD_PORT_USE (&d->port,
119: ({
120: error_t err;
121: mach_port_t outport;
122: err = __mach_port_mod_refs (__mach_task_self (),
123: port,
124: MACH_PORT_RIGHT_SEND,
125: 1);
126: if (err)
127: {
128: errno = err;
129: outport = MACH_PORT_NULL;
130: }
131: else
132: outport = port;
133: outport;
134: }));
135:
136: HURD_CRITICAL_END;
137:
138: return dport;
139: }
140:
141: file_t (*_hurd_getdport_fn) (int fd) = get_dtable_port;
142: ^L
143: #include <hurd/signal.h>
144:
145:
146:
147:
148: static error_t
149: fork_child_dtable (void)
150: {
151: error_t err;
152: int i;
153:
154: err = 0;
155:
156: for (i = 0; !err && i < _hurd_dtablesize; ++i)
157: {
158: struct hurd_fd *d = _hurd_dtable[i];
159: if (d == NULL)
160: continue;
161:
162:
163: d->port.users = d->ctty.users = NULL;
164:
165: if (d->ctty.port != MACH_PORT_NULL)
166: {
167:
168:
169: __mach_port_deallocate (__mach_task_self (), d->ctty.port);
170: err = __term_open_ctty (d->port.port, _hurd_pid, _hurd_pgrp,
171: &d->ctty.port);
172: if (err)
173: d->ctty.port = MACH_PORT_NULL;
174: }
175:
176:
177: }
178: return err;
179:
180: (void) &fork_child_dtable;
181: }
182:
183: data_set_element (_hurd_fork_locks, _hurd_dtable_lock);
184: text_set_element (_hurd_fork_child_hook, fork_child_dtable);
185: ^L
186:
187:
188: static void
189: ctty_new_pgrp (void)
190: {
191: int i;
192:
193: HURD_CRITICAL_BEGIN;
194: __mutex_lock (&_hurd_dtable_lock);
195:
196: if (__USEPORT (CTTYID, port == MACH_PORT_NULL))
197: {
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208: }
209: else
210: for (i = 0; i < _hurd_dtablesize; ++i)
211: {
212: struct hurd_fd *const d = _hurd_dtable[i];
213: struct hurd_userlink ulink, ctty_ulink;
214: io_t port, ctty;
215:
216: if (d == NULL)
217:
218: continue;
219:
220: port = _hurd_port_get (&d->port, &ulink);
221: ctty = _hurd_port_get (&d->ctty, &ctty_ulink);
222:
223: if (ctty != MACH_PORT_NULL)
224: {
225:
226:
227: io_t new;
228: if (__term_open_ctty (port, _hurd_pid, _hurd_pgrp, &new))
229: new = MACH_PORT_NULL;
230: _hurd_port_set (&d->ctty, new);
231: }
232:
233: _hurd_port_free (&d->port, &ulink, port);
234: _hurd_port_free (&d->ctty, &ctty_ulink, ctty);
235: }
236:
237: __mutex_unlock (&_hurd_dtable_lock);
238: HURD_CRITICAL_END;
239:
240: (void) &ctty_new_pgrp;
241: }
242:
243: text_set_element (_hurd_pgrp_changed_hook, ctty_new_pgrp);
244: ^L
245:
246:
247: static void
248: reauth_dtable (void)
249: {
250: int i;
251:
252: HURD_CRITICAL_BEGIN;
253: __mutex_lock (&_hurd_dtable_lock);
254:
255: for (i = 0; i < _hurd_dtablesize; ++i)
256: {
257: struct hurd_fd *const d = _hurd_dtable[i];
258: mach_port_t new, newctty, ref;
259:
260: if (d == NULL)
261:
262: continue;
263:
264: ref = __mach_reply_port ();
265:
266:
267: __spin_lock (&d->port.lock);
268:
269:
270: if (d->port.port != MACH_PORT_NULL &&
271: ! __io_reauthenticate (d->port.port,
272: ref, MACH_MSG_TYPE_MAKE_SEND) &&
273: ! __USEPORT (AUTH, __auth_user_authenticate
274: (port,
275: ref, MACH_MSG_TYPE_MAKE_SEND,
276: &new)))
277: {
278:
279:
280:
281: if (d->ctty.port != MACH_PORT_NULL &&
282: ! __io_reauthenticate (d->ctty.port,
283: ref, MACH_MSG_TYPE_MAKE_SEND) &&
284: ! __USEPORT (AUTH, __auth_user_authenticate
285: (port,
286: ref, MACH_MSG_TYPE_MAKE_SEND,
287: &newctty)))
288: _hurd_port_set (&d->ctty, newctty);
289:
290: _hurd_port_locked_set (&d->port, new);
291: }
292: else
293:
294: __spin_unlock (&d->port.lock);
295:
296: __mach_port_destroy (__mach_task_self (), ref);
297: }
298:
299: __mutex_unlock (&_hurd_dtable_lock);
300: HURD_CRITICAL_END;
301:
302: (void) &reauth_dtable;
303: }
304:
305: text_set_element (_hurd_reauth_hook, reauth_dtable);