(__select): Don't fault when some fdmask is 0.
[glibc.git] / hurd / hurdinit.c
blobe7558c3ef726449cb6d2cd39e99a86bf7889257e
1 /* Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
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.
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.
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. */
19 #include <sys/stat.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <hurd.h>
24 #include <hurd/port.h>
25 #include "set-hooks.h"
26 #include "hurdmalloc.h" /* XXX */
29 int _hurd_exec_flags;
30 struct hurd_port *_hurd_ports;
31 unsigned int _hurd_nports;
32 mode_t _hurd_umask;
34 error_t
35 _hurd_ports_use (int which, error_t (*operate) (mach_port_t))
37 return HURD_PORT_USE (&_hurd_ports[which], (*operate) (port));
40 void _hurd_proc_init (char **argv);
42 DEFINE_HOOK (_hurd_subinit, (void));
44 /* Initialize the library data structures from the
45 ints and ports passed to us by the exec server.
47 PORTARRAY and INTARRAY are vm_deallocate'd. */
49 void
50 _hurd_init (int flags, char **argv,
51 mach_port_t *portarray, size_t portarraysize,
52 int *intarray, size_t intarraysize)
54 size_t i;
56 _hurd_exec_flags = flags;
58 _hurd_ports = malloc (portarraysize * sizeof (*_hurd_ports));
59 if (_hurd_ports == NULL)
60 __libc_fatal ("Can't allocate _hurd_ports\n");
61 _hurd_nports = portarraysize;
63 /* See what ports we were passed. */
64 for (i = 0; i < portarraysize; ++i)
65 _hurd_port_init (&_hurd_ports[i], portarray[i]);
67 /* When the user asks for the bootstrap port,
68 he will get the one the exec server passed us. */
69 __task_set_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT,
70 portarray[INIT_PORT_BOOTSTRAP]);
72 /* Tell the proc server we exist, if it does. */
73 if (portarray[INIT_PORT_PROC] != MACH_PORT_NULL)
74 _hurd_proc_init (argv);
76 if (intarraysize > INIT_UMASK)
77 _hurd_umask = intarray[INIT_UMASK] & 0777;
78 else
79 _hurd_umask = CMASK;
81 /* All done with init ints and ports. */
82 __vm_deallocate (__mach_task_self (),
83 (vm_address_t) intarray,
84 intarraysize * sizeof (int));
85 __vm_deallocate (__mach_task_self (),
86 (vm_address_t) portarray,
87 portarraysize * sizeof (mach_port_t));
89 if (flags & EXEC_SECURE)
90 /* XXX if secure exec, elide environment variables
91 which the library uses and could be security holes.
92 CORESERVER, COREFILE
93 */ ;
95 /* Call other things which want to do some initialization. These are not
96 on the __libc_subinit hook because things there like to be able to
97 assume the availability of the POSIX.1 services we provide. */
98 RUN_HOOK (_hurd_subinit, ());
101 #include <hurd/signal.h>
103 /* The user can do "int _hide_arguments = 1;" to make
104 sure the arguments are never visible with `ps'. */
105 int _hide_arguments, _hide_environment;
107 /* Hook for things which should be initialized as soon as the proc
108 server is available. */
109 DEFINE_HOOK (_hurd_proc_subinit, (void));
111 /* Do startup handshaking with the proc server just installed in _hurd_ports.
112 Call _hurdsig_init to set up signal processing. */
114 void
115 _hurd_proc_init (char **argv)
117 mach_port_t oldmsg;
118 struct hurd_userlink ulink;
119 process_t procserver;
121 /* Initialize the signal code; Mach exceptions will become signals. */
122 _hurdsig_init ();
124 /* The signal thread is now prepared to receive messages.
125 It is safe to give the port to the proc server. */
127 procserver = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink);
129 /* Give the proc server our message port. */
130 __proc_setmsgport (procserver, _hurd_msgport, &oldmsg);
131 if (oldmsg != MACH_PORT_NULL)
132 /* Deallocate the old msg port we replaced. */
133 __mach_port_deallocate (__mach_task_self (), oldmsg);
135 /* Tell the proc server where our args and environment are. */
136 __proc_set_arg_locations (procserver,
137 _hide_arguments ? 0 : (vm_address_t) argv,
138 _hide_environment ? 0 : (vm_address_t) __environ);
140 _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, procserver);
142 /* Initialize proc server-assisted fault recovery for the signal thread. */
143 _hurdsig_fault_init ();
145 /* Call other things which want to do some initialization. These are not
146 on the _hurd_subinit hook because things there assume that things done
147 here, like _hurd_pid, are already initialized. */
148 RUN_HOOK (_hurd_proc_subinit, ());
150 if (_hurd_exec_flags & EXEC_TRACED)
151 /* This process is "traced", meaning it should stop on signals or exec.
152 We are all set up now to handle signals. Stop ourselves, to inform
153 our parent (presumably a debugger) that the exec has completed. */
154 __msg_sig_post (_hurd_msgport, SIGTRAP, __mach_task_self ());
157 /* Called when we get a message telling us to change our proc server port. */
159 error_t
160 _hurd_setproc (process_t procserver)
162 error_t err;
163 mach_port_t oldmsg;
165 /* Give the proc server our message port. */
166 if (err = __proc_setmsgport (procserver, _hurd_msgport, &oldmsg))
167 return err;
168 if (oldmsg != MACH_PORT_NULL)
169 /* Deallocate the old msg port we replaced. */
170 __mach_port_deallocate (__mach_task_self (), oldmsg);
172 /* Tell the proc server where our args and environment are. */
173 if (err = __proc_set_arg_locations (procserver,
174 /* We don't know the ARGV location. */
175 (vm_address_t) 0,
176 _hide_environment ? 0 :
177 (vm_address_t) __environ))
178 return err;
180 /* Those calls worked, so the port looks good. */
181 _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], procserver);
184 pid_t oldpgrp = _hurd_pgrp;
186 /* Call these functions again so they can fetch the
187 new information from the new proc server. */
188 RUN_HOOK (_hurd_proc_subinit, ());
190 if (_hurd_pgrp != oldpgrp)
192 /* Run things that want notification of a pgrp change. */
193 DECLARE_HOOK (_hurd_pgrp_changed_hook, (pid_t));
194 RUN_HOOK (_hurd_pgrp_changed_hook, (_hurd_pgrp));
198 return 0;
201 #ifndef PIC
203 /* Map the page at address zero with no access allowed, so
204 dereferencing NULL will fault and no "anywhere" allocations
205 (e.g. the out of line memory containing the argument strings)
206 can be assigned address zero, which C says is not a valid pointer.
208 When dynamically linked, this will be done by the dynamic linker
209 before we run. */
211 static void map0 (void) __attribute__ ((unused));
212 text_set_element (_hurd_preinit_hook, map0);
214 static void
215 map0 (void)
217 vm_address_t addr = 0;
218 __vm_map (__mach_task_self (),
219 &addr, __vm_page_size, 0, 0, MACH_PORT_NULL, 0, 1,
220 VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY);
223 #endif