]>
Commit | Line | Data |
---|---|---|
f7a9f785 | 1 | /* Copyright (C) 1992-2016 Free Software Foundation, Inc. |
c84142e8 UD |
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 | |
41bdb6e2 AJ |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
c84142e8 UD |
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 | |
41bdb6e2 | 12 | Lesser General Public License for more details. |
c84142e8 | 13 | |
41bdb6e2 | 14 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
15 | License along with the GNU C Library; if not, see |
16 | <http://www.gnu.org/licenses/>. */ | |
28f540f4 RM |
17 | |
18 | #include <sys/stat.h> | |
19 | #include <stdlib.h> | |
20 | #include <stdio.h> | |
21 | #include <unistd.h> | |
22 | #include <hurd.h> | |
23 | #include <hurd/port.h> | |
24 | #include "set-hooks.h" | |
25 | #include "hurdmalloc.h" /* XXX */ | |
26 | ||
27 | ||
28 | int _hurd_exec_flags; | |
29 | struct hurd_port *_hurd_ports; | |
30 | unsigned int _hurd_nports; | |
31 | mode_t _hurd_umask; | |
8f0c527e | 32 | sigset_t _hurdsig_traced; |
6bac11d9 | 33 | |
8a080f40 | 34 | char **__libc_argv; |
6bac11d9 | 35 | int __libc_argc; |
8a080f40 | 36 | |
28f540f4 | 37 | |
8f5ca04b RM |
38 | error_t |
39 | _hurd_ports_use (int which, error_t (*operate) (mach_port_t)) | |
40 | { | |
a1ffb40e | 41 | if (__glibc_unlikely (_hurd_ports == NULL)) |
7595ddb8 RM |
42 | /* This means that _hurd_init has not been called yet, which is |
43 | normally only the case in the bootstrap filesystem, and there | |
44 | only in the early phases of booting. */ | |
45 | return EGRATUITOUS; | |
46 | ||
8f5ca04b RM |
47 | return HURD_PORT_USE (&_hurd_ports[which], (*operate) (port)); |
48 | } | |
49 | ||
28f540f4 RM |
50 | DEFINE_HOOK (_hurd_subinit, (void)); |
51 | ||
0c981d96 RM |
52 | __typeof (_hurd_proc_init) _hurd_new_proc_init; /* below */ |
53 | ||
28f540f4 RM |
54 | /* Initialize the library data structures from the |
55 | ints and ports passed to us by the exec server. | |
56 | ||
57 | PORTARRAY and INTARRAY are vm_deallocate'd. */ | |
58 | ||
59 | void | |
60 | _hurd_init (int flags, char **argv, | |
61 | mach_port_t *portarray, size_t portarraysize, | |
62 | int *intarray, size_t intarraysize) | |
63 | { | |
1e9dc039 | 64 | size_t i; |
28f540f4 RM |
65 | |
66 | _hurd_exec_flags = flags; | |
67 | ||
68 | _hurd_ports = malloc (portarraysize * sizeof (*_hurd_ports)); | |
69 | if (_hurd_ports == NULL) | |
70 | __libc_fatal ("Can't allocate _hurd_ports\n"); | |
71 | _hurd_nports = portarraysize; | |
72 | ||
73 | /* See what ports we were passed. */ | |
74 | for (i = 0; i < portarraysize; ++i) | |
75 | _hurd_port_init (&_hurd_ports[i], portarray[i]); | |
76 | ||
77 | /* When the user asks for the bootstrap port, | |
78 | he will get the one the exec server passed us. */ | |
79 | __task_set_special_port (__mach_task_self (), TASK_BOOTSTRAP_PORT, | |
80 | portarray[INIT_PORT_BOOTSTRAP]); | |
81 | ||
28f540f4 RM |
82 | if (intarraysize > INIT_UMASK) |
83 | _hurd_umask = intarray[INIT_UMASK] & 0777; | |
84 | else | |
85 | _hurd_umask = CMASK; | |
86 | ||
8f0c527e RM |
87 | if (intarraysize > INIT_TRACEMASK) |
88 | _hurdsig_traced = intarray[INIT_TRACEMASK]; | |
89 | ||
d545ee47 MB |
90 | /* Tell the proc server we exist, if it does. */ |
91 | if (portarray[INIT_PORT_PROC] != MACH_PORT_NULL) | |
0c981d96 | 92 | _hurd_new_proc_init (argv, intarray, intarraysize); |
d545ee47 | 93 | |
28f540f4 RM |
94 | /* All done with init ints and ports. */ |
95 | __vm_deallocate (__mach_task_self (), | |
96 | (vm_address_t) intarray, | |
97 | intarraysize * sizeof (int)); | |
98 | __vm_deallocate (__mach_task_self (), | |
99 | (vm_address_t) portarray, | |
100 | portarraysize * sizeof (mach_port_t)); | |
101 | ||
102 | if (flags & EXEC_SECURE) | |
103 | /* XXX if secure exec, elide environment variables | |
104 | which the library uses and could be security holes. | |
105 | CORESERVER, COREFILE | |
106 | */ ; | |
107 | ||
108 | /* Call other things which want to do some initialization. These are not | |
109 | on the __libc_subinit hook because things there like to be able to | |
110 | assume the availability of the POSIX.1 services we provide. */ | |
111 | RUN_HOOK (_hurd_subinit, ()); | |
112 | } | |
113 | \f | |
114 | #include <hurd/signal.h> | |
115 | ||
116 | /* The user can do "int _hide_arguments = 1;" to make | |
117 | sure the arguments are never visible with `ps'. */ | |
118 | int _hide_arguments, _hide_environment; | |
119 | ||
120 | /* Hook for things which should be initialized as soon as the proc | |
121 | server is available. */ | |
122 | DEFINE_HOOK (_hurd_proc_subinit, (void)); | |
123 | ||
124 | /* Do startup handshaking with the proc server just installed in _hurd_ports. | |
125 | Call _hurdsig_init to set up signal processing. */ | |
126 | ||
127 | void | |
aab217f3 RM |
128 | _hurd_new_proc_init (char **argv, |
129 | const int *intarray, size_t intarraysize) | |
28f540f4 RM |
130 | { |
131 | mach_port_t oldmsg; | |
132 | struct hurd_userlink ulink; | |
133 | process_t procserver; | |
134 | ||
135 | /* Initialize the signal code; Mach exceptions will become signals. */ | |
62495816 | 136 | _hurdsig_init (intarray, intarraysize); |
28f540f4 RM |
137 | |
138 | /* The signal thread is now prepared to receive messages. | |
139 | It is safe to give the port to the proc server. */ | |
140 | ||
141 | procserver = _hurd_port_get (&_hurd_ports[INIT_PORT_PROC], &ulink); | |
142 | ||
143 | /* Give the proc server our message port. */ | |
144 | __proc_setmsgport (procserver, _hurd_msgport, &oldmsg); | |
145 | if (oldmsg != MACH_PORT_NULL) | |
146 | /* Deallocate the old msg port we replaced. */ | |
147 | __mach_port_deallocate (__mach_task_self (), oldmsg); | |
148 | ||
149 | /* Tell the proc server where our args and environment are. */ | |
150 | __proc_set_arg_locations (procserver, | |
151 | _hide_arguments ? 0 : (vm_address_t) argv, | |
152 | _hide_environment ? 0 : (vm_address_t) __environ); | |
153 | ||
154 | _hurd_port_free (&_hurd_ports[INIT_PORT_PROC], &ulink, procserver); | |
155 | ||
156 | /* Initialize proc server-assisted fault recovery for the signal thread. */ | |
157 | _hurdsig_fault_init (); | |
158 | ||
159 | /* Call other things which want to do some initialization. These are not | |
160 | on the _hurd_subinit hook because things there assume that things done | |
161 | here, like _hurd_pid, are already initialized. */ | |
162 | RUN_HOOK (_hurd_proc_subinit, ()); | |
163 | ||
deb83464 RM |
164 | /* XXX This code should probably be removed entirely at some point. This |
165 | conditional should make it reasonably usable with old gdb's for a | |
166 | while. Eventually it probably makes most sense for the exec server to | |
167 | mask out EXEC_SIGTRAP so the debugged program is closer to not being | |
168 | able to tell it's being debugged. */ | |
05dea6d1 | 169 | if (!__sigisemptyset (&_hurdsig_traced) |
deb83464 RM |
170 | #ifdef EXEC_SIGTRAP |
171 | && !(_hurd_exec_flags & EXEC_SIGTRAP) | |
172 | #endif | |
173 | ) | |
28f540f4 RM |
174 | /* This process is "traced", meaning it should stop on signals or exec. |
175 | We are all set up now to handle signals. Stop ourselves, to inform | |
176 | our parent (presumably a debugger) that the exec has completed. */ | |
8f0c527e | 177 | __msg_sig_post (_hurd_msgport, SIGTRAP, 0, __mach_task_self ()); |
28f540f4 | 178 | } |
aab217f3 | 179 | |
16710d58 RM |
180 | #include <shlib-compat.h> |
181 | versioned_symbol (libc, _hurd_new_proc_init, _hurd_proc_init, GLIBC_2_1); | |
28f540f4 RM |
182 | \f |
183 | /* Called when we get a message telling us to change our proc server port. */ | |
184 | ||
185 | error_t | |
186 | _hurd_setproc (process_t procserver) | |
187 | { | |
188 | error_t err; | |
189 | mach_port_t oldmsg; | |
190 | ||
191 | /* Give the proc server our message port. */ | |
192 | if (err = __proc_setmsgport (procserver, _hurd_msgport, &oldmsg)) | |
193 | return err; | |
194 | if (oldmsg != MACH_PORT_NULL) | |
195 | /* Deallocate the old msg port we replaced. */ | |
196 | __mach_port_deallocate (__mach_task_self (), oldmsg); | |
197 | ||
198 | /* Tell the proc server where our args and environment are. */ | |
199 | if (err = __proc_set_arg_locations (procserver, | |
acf51e02 TBB |
200 | _hide_arguments ? 0 : |
201 | (vm_address_t) __libc_argv, | |
28f540f4 RM |
202 | _hide_environment ? 0 : |
203 | (vm_address_t) __environ)) | |
204 | return err; | |
205 | ||
206 | /* Those calls worked, so the port looks good. */ | |
207 | _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], procserver); | |
208 | ||
209 | { | |
210 | pid_t oldpgrp = _hurd_pgrp; | |
211 | ||
212 | /* Call these functions again so they can fetch the | |
213 | new information from the new proc server. */ | |
214 | RUN_HOOK (_hurd_proc_subinit, ()); | |
215 | ||
216 | if (_hurd_pgrp != oldpgrp) | |
217 | { | |
218 | /* Run things that want notification of a pgrp change. */ | |
219 | DECLARE_HOOK (_hurd_pgrp_changed_hook, (pid_t)); | |
220 | RUN_HOOK (_hurd_pgrp_changed_hook, (_hurd_pgrp)); | |
221 | } | |
222 | } | |
223 | ||
224 | return 0; | |
225 | } |