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