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