Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/bash/src/builtins/enable.def |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | This file is enable.def, from which is created enable.c. | - | ||||||||||||
2 | It implements the builtin "enable" in Bash. | - | ||||||||||||
3 | - | |||||||||||||
4 | Copyright (C) 1987-2016 Free Software Foundation, Inc. | - | ||||||||||||
5 | - | |||||||||||||
6 | This file is part of GNU Bash, the Bourne Again SHell. | - | ||||||||||||
7 | - | |||||||||||||
8 | Bash is free software: you can redistribute it and/or modify | - | ||||||||||||
9 | it under the terms of the GNU General Public License as published by | - | ||||||||||||
10 | the Free Software Foundation, either version 3 of the License, or | - | ||||||||||||
11 | (at your option) any later version. | - | ||||||||||||
12 | - | |||||||||||||
13 | Bash is distributed in the hope that it will be useful, | - | ||||||||||||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | ||||||||||||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | ||||||||||||
16 | GNU General Public License for more details. | - | ||||||||||||
17 | - | |||||||||||||
18 | You should have received a copy of the GNU General Public License | - | ||||||||||||
19 | along with Bash. If not, see <http://www.gnu.org/licenses/>. | - | ||||||||||||
20 | - | |||||||||||||
21 | $PRODUCES enable.c | - | ||||||||||||
22 | - | |||||||||||||
23 | $BUILTIN enable | - | ||||||||||||
24 | $FUNCTION enable_builtin | - | ||||||||||||
25 | $SHORT_DOC enable [-a] [-dnps] [-f filename] [name ...] | - | ||||||||||||
26 | Enable and disable shell builtins. | - | ||||||||||||
27 | - | |||||||||||||
28 | Enables and disables builtin shell commands. Disabling allows you to | - | ||||||||||||
29 | execute a disk command which has the same name as a shell builtin | - | ||||||||||||
30 | without using a full pathname. | - | ||||||||||||
31 | - | |||||||||||||
32 | Options: | - | ||||||||||||
33 | -a print a list of builtins showing whether or not each is enabled | - | ||||||||||||
34 | -n disable each NAME or display a list of disabled builtins | - | ||||||||||||
35 | -p print the list of builtins in a reusable format | - | ||||||||||||
36 | -s print only the names of Posix `special' builtins | - | ||||||||||||
37 | - | |||||||||||||
38 | Options controlling dynamic loading: | - | ||||||||||||
39 | -f Load builtin NAME from shared object FILENAME | - | ||||||||||||
40 | -d Remove a builtin loaded with -f | - | ||||||||||||
41 | - | |||||||||||||
42 | Without options, each NAME is enabled. | - | ||||||||||||
43 | - | |||||||||||||
44 | To use the `test' found in $PATH instead of the shell builtin | - | ||||||||||||
45 | version, type `enable -n test'. | - | ||||||||||||
46 | - | |||||||||||||
47 | Exit Status: | - | ||||||||||||
48 | Returns success unless NAME is not a shell builtin or an error occurs. | - | ||||||||||||
49 | $END | - | ||||||||||||
50 | - | |||||||||||||
51 | #include <config.h> | - | ||||||||||||
52 | - | |||||||||||||
53 | #if defined (HAVE_UNISTD_H) | - | ||||||||||||
54 | # ifdef _MINIX | - | ||||||||||||
55 | # include <sys/types.h> | - | ||||||||||||
56 | # endif | - | ||||||||||||
57 | # include <unistd.h> | - | ||||||||||||
58 | #endif | - | ||||||||||||
59 | - | |||||||||||||
60 | #include <stdio.h> | - | ||||||||||||
61 | #include "../bashansi.h" | - | ||||||||||||
62 | #include "../bashintl.h" | - | ||||||||||||
63 | - | |||||||||||||
64 | #include "../shell.h" | - | ||||||||||||
65 | #include "../builtins.h" | - | ||||||||||||
66 | #include "../flags.h" | - | ||||||||||||
67 | #include "common.h" | - | ||||||||||||
68 | #include "bashgetopt.h" | - | ||||||||||||
69 | #include "findcmd.h" | - | ||||||||||||
70 | - | |||||||||||||
71 | #if defined (PROGRAMMABLE_COMPLETION) | - | ||||||||||||
72 | # include "../pcomplete.h" | - | ||||||||||||
73 | #endif | - | ||||||||||||
74 | - | |||||||||||||
75 | #define ENABLED 1 | - | ||||||||||||
76 | #define DISABLED 2 | - | ||||||||||||
77 | #define SPECIAL 4 | - | ||||||||||||
78 | - | |||||||||||||
79 | #define AFLAG 0x01 | - | ||||||||||||
80 | #define DFLAG 0x02 | - | ||||||||||||
81 | #define FFLAG 0x04 | - | ||||||||||||
82 | #define NFLAG 0x08 | - | ||||||||||||
83 | #define PFLAG 0x10 | - | ||||||||||||
84 | #define SFLAG 0x20 | - | ||||||||||||
85 | - | |||||||||||||
86 | #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) | - | ||||||||||||
87 | static int dyn_load_builtin __P((WORD_LIST *, int, char *)); | - | ||||||||||||
88 | #endif | - | ||||||||||||
89 | - | |||||||||||||
90 | #if defined (HAVE_DLCLOSE) | - | ||||||||||||
91 | static int dyn_unload_builtin __P((char *)); | - | ||||||||||||
92 | static void delete_builtin __P((struct builtin *)); | - | ||||||||||||
93 | static int local_dlclose __P((void *)); | - | ||||||||||||
94 | #endif | - | ||||||||||||
95 | - | |||||||||||||
96 | #define STRUCT_SUFFIX "_struct" | - | ||||||||||||
97 | /* for now */ | - | ||||||||||||
98 | #define LOAD_SUFFIX "_builtin_load" | - | ||||||||||||
99 | #define UNLOAD_SUFFIX "_builtin_unload" | - | ||||||||||||
100 | - | |||||||||||||
101 | static void list_some_builtins __P((int)); | - | ||||||||||||
102 | static int enable_shell_command __P((char *, int)); | - | ||||||||||||
103 | - | |||||||||||||
104 | /* Enable/disable shell commands present in LIST. If list is not specified, | - | ||||||||||||
105 | then print out a list of shell commands showing which are enabled and | - | ||||||||||||
106 | which are disabled. */ | - | ||||||||||||
107 | int | - | ||||||||||||
108 | enable_builtin (list) | - | ||||||||||||
109 | WORD_LIST *list; | - | ||||||||||||
110 | { | - | ||||||||||||
111 | int result, flags; | - | ||||||||||||
112 | int opt, filter; | - | ||||||||||||
113 | #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) | - | ||||||||||||
114 | char *filename; | - | ||||||||||||
115 | #endif | - | ||||||||||||
116 | - | |||||||||||||
117 | result = EXECUTION_SUCCESS; | - | ||||||||||||
118 | flags = 0; | - | ||||||||||||
119 | - | |||||||||||||
120 | reset_internal_getopt (); | - | ||||||||||||
121 | while ((opt = internal_getopt (list, "adnpsf:")) != -1)
| 45-81 | ||||||||||||
122 | { | - | ||||||||||||
123 | switch (opt) | - | ||||||||||||
124 | { | - | ||||||||||||
125 | case 'a': executed 9 times by 1 test: case 'a': Executed by:
| 9 | ||||||||||||
126 | flags |= AFLAG; | - | ||||||||||||
127 | break; executed 9 times by 1 test: break; Executed by:
| 9 | ||||||||||||
128 | case 'n': executed 18 times by 1 test: case 'n': Executed by:
| 18 | ||||||||||||
129 | flags |= NFLAG; | - | ||||||||||||
130 | break; executed 18 times by 1 test: break; Executed by:
| 18 | ||||||||||||
131 | case 'p': executed 27 times by 1 test: case 'p': Executed by:
| 27 | ||||||||||||
132 | flags |= PFLAG; | - | ||||||||||||
133 | break; executed 27 times by 1 test: break; Executed by:
| 27 | ||||||||||||
134 | case 's': executed 27 times by 1 test: case 's': Executed by:
| 27 | ||||||||||||
135 | flags |= SFLAG; | - | ||||||||||||
136 | break; executed 27 times by 1 test: break; Executed by:
| 27 | ||||||||||||
137 | case 'f': never executed: case 'f': | 0 | ||||||||||||
138 | #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) | - | ||||||||||||
139 | flags |= FFLAG; | - | ||||||||||||
140 | filename = list_optarg; | - | ||||||||||||
141 | break; never executed: break; | 0 | ||||||||||||
142 | #else | - | ||||||||||||
143 | builtin_error (_("dynamic loading not available")); | - | ||||||||||||
144 | return (EX_USAGE); | - | ||||||||||||
145 | #endif | - | ||||||||||||
146 | #if defined (HAVE_DLCLOSE) | - | ||||||||||||
147 | case 'd': never executed: case 'd': | 0 | ||||||||||||
148 | flags |= DFLAG; | - | ||||||||||||
149 | break; never executed: break; | 0 | ||||||||||||
150 | #else | - | ||||||||||||
151 | builtin_error (_("dynamic loading not available")); | - | ||||||||||||
152 | return (EX_USAGE); | - | ||||||||||||
153 | #endif /* HAVE_DLCLOSE */ | - | ||||||||||||
154 | CASE_HELPOPT; never executed: return (258); never executed: case -99: | 0 | ||||||||||||
155 | default: never executed: default: | 0 | ||||||||||||
156 | builtin_usage (); | - | ||||||||||||
157 | return (EX_USAGE); never executed: return (258); | 0 | ||||||||||||
158 | } | - | ||||||||||||
159 | } | - | ||||||||||||
160 | - | |||||||||||||
161 | list = loptend; | - | ||||||||||||
162 | - | |||||||||||||
163 | #if defined (RESTRICTED_SHELL) | - | ||||||||||||
164 | /* Restricted shells cannot load new builtins. */ | - | ||||||||||||
165 | if (restricted && (flags & (FFLAG|DFLAG)))
| 0-45 | ||||||||||||
166 | { | - | ||||||||||||
167 | sh_restricted ((char *)NULL); | - | ||||||||||||
168 | return (EXECUTION_FAILURE); never executed: return (1); | 0 | ||||||||||||
169 | } | - | ||||||||||||
170 | #endif | - | ||||||||||||
171 | - | |||||||||||||
172 | if (list == 0 || (flags & PFLAG))
| 0-27 | ||||||||||||
173 | { | - | ||||||||||||
174 | filter = (flags & AFLAG) ? (ENABLED | DISABLED)
| 9-18 | ||||||||||||
175 | : (flags & NFLAG) ? DISABLED : ENABLED;
| 9 | ||||||||||||
176 | - | |||||||||||||
177 | if (flags & SFLAG)
| 0-27 | ||||||||||||
178 | filter |= SPECIAL; executed 27 times by 1 test: filter |= 4; Executed by:
| 27 | ||||||||||||
179 | - | |||||||||||||
180 | list_some_builtins (filter); | - | ||||||||||||
181 | } executed 27 times by 1 test: end of block Executed by:
| 27 | ||||||||||||
182 | #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) | - | ||||||||||||
183 | else if (flags & FFLAG)
| 0-18 | ||||||||||||
184 | { | - | ||||||||||||
185 | filter = (flags & NFLAG) ? DISABLED : ENABLED;
| 0 | ||||||||||||
186 | if (flags & SFLAG)
| 0 | ||||||||||||
187 | filter |= SPECIAL; never executed: filter |= 4; | 0 | ||||||||||||
188 | - | |||||||||||||
189 | result = dyn_load_builtin (list, filter, filename); | - | ||||||||||||
190 | #if defined (PROGRAMMABLE_COMPLETION) | - | ||||||||||||
191 | set_itemlist_dirty (&it_builtins); | - | ||||||||||||
192 | #endif | - | ||||||||||||
193 | } never executed: end of block | 0 | ||||||||||||
194 | #endif | - | ||||||||||||
195 | #if defined (HAVE_DLCLOSE) | - | ||||||||||||
196 | else if (flags & DFLAG)
| 0-18 | ||||||||||||
197 | { | - | ||||||||||||
198 | while (list)
| 0 | ||||||||||||
199 | { | - | ||||||||||||
200 | opt = dyn_unload_builtin (list->word->word); | - | ||||||||||||
201 | if (opt == EXECUTION_FAILURE)
| 0 | ||||||||||||
202 | result = EXECUTION_FAILURE; never executed: result = 1; | 0 | ||||||||||||
203 | list = list->next; | - | ||||||||||||
204 | } never executed: end of block | 0 | ||||||||||||
205 | #if defined (PROGRAMMABLE_COMPLETION) | - | ||||||||||||
206 | set_itemlist_dirty (&it_builtins); | - | ||||||||||||
207 | #endif | - | ||||||||||||
208 | } never executed: end of block | 0 | ||||||||||||
209 | #endif | - | ||||||||||||
210 | else | - | ||||||||||||
211 | { | - | ||||||||||||
212 | while (list)
| 18-19 | ||||||||||||
213 | { | - | ||||||||||||
214 | opt = enable_shell_command (list->word->word, flags & NFLAG); | - | ||||||||||||
215 | - | |||||||||||||
216 | if (opt == EXECUTION_FAILURE)
| 2-17 | ||||||||||||
217 | { | - | ||||||||||||
218 | sh_notbuiltin (list->word->word); | - | ||||||||||||
219 | result = EXECUTION_FAILURE; | - | ||||||||||||
220 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||
221 | list = list->next; | - | ||||||||||||
222 | } executed 19 times by 1 test: end of block Executed by:
| 19 | ||||||||||||
223 | } executed 18 times by 1 test: end of block Executed by:
| 18 | ||||||||||||
224 | return (result); executed 45 times by 1 test: return (result); Executed by:
| 45 | ||||||||||||
225 | } | - | ||||||||||||
226 | - | |||||||||||||
227 | /* List some builtins. | - | ||||||||||||
228 | FILTER is a mask with two slots: ENABLED and DISABLED. */ | - | ||||||||||||
229 | static void | - | ||||||||||||
230 | list_some_builtins (filter) | - | ||||||||||||
231 | int filter; | - | ||||||||||||
232 | { | - | ||||||||||||
233 | register int i; | - | ||||||||||||
234 | - | |||||||||||||
235 | for (i = 0; i < num_shell_builtins; i++)
| 27-2052 | ||||||||||||
236 | { | - | ||||||||||||
237 | if (shell_builtins[i].function == 0 || (shell_builtins[i].flags & BUILTIN_DELETED))
| 0-1647 | ||||||||||||
238 | continue; executed 405 times by 1 test: continue; Executed by:
| 405 | ||||||||||||
239 | - | |||||||||||||
240 | if ((filter & SPECIAL) &&
| 0-1647 | ||||||||||||
241 | (shell_builtins[i].flags & SPECIAL_BUILTIN) == 0)
| 432-1215 | ||||||||||||
242 | continue; executed 1215 times by 1 test: continue; Executed by:
| 1215 | ||||||||||||
243 | - | |||||||||||||
244 | if ((filter & ENABLED) && (shell_builtins[i].flags & BUILTIN_ENABLED))
| 0-288 | ||||||||||||
245 | printf ("enable %s\n", shell_builtins[i].name); executed 288 times by 1 test: printf ("enable %s\n", shell_builtins[i].name); Executed by:
| 288 | ||||||||||||
246 | else if ((filter & DISABLED) &&
| 0-144 | ||||||||||||
247 | ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0))
| 0-144 | ||||||||||||
248 | printf ("enable -n %s\n", shell_builtins[i].name); never executed: printf ("enable -n %s\n", shell_builtins[i].name); | 0 | ||||||||||||
249 | } executed 432 times by 1 test: end of block Executed by:
| 432 | ||||||||||||
250 | } executed 27 times by 1 test: end of block Executed by:
| 27 | ||||||||||||
251 | - | |||||||||||||
252 | /* Enable the shell command NAME. If DISABLE_P is non-zero, then | - | ||||||||||||
253 | disable NAME instead. */ | - | ||||||||||||
254 | static int | - | ||||||||||||
255 | enable_shell_command (name, disable_p) | - | ||||||||||||
256 | char *name; | - | ||||||||||||
257 | int disable_p; | - | ||||||||||||
258 | { | - | ||||||||||||
259 | struct builtin *b; | - | ||||||||||||
260 | - | |||||||||||||
261 | b = builtin_address_internal (name, 1); | - | ||||||||||||
262 | if (b == 0)
| 2-17 | ||||||||||||
263 | return (EXECUTION_FAILURE); executed 2 times by 1 test: return (1); Executed by:
| 2 | ||||||||||||
264 | - | |||||||||||||
265 | if (disable_p)
| 8-9 | ||||||||||||
266 | b->flags &= ~BUILTIN_ENABLED; executed 9 times by 1 test: b->flags &= ~0x01; Executed by:
| 9 | ||||||||||||
267 | #if defined (RESTRICTED_SHELL) | - | ||||||||||||
268 | else if (restricted && ((b->flags & BUILTIN_ENABLED) == 0))
| 0-8 | ||||||||||||
269 | { | - | ||||||||||||
270 | sh_restricted ((char *)NULL); | - | ||||||||||||
271 | return (EXECUTION_FAILURE); never executed: return (1); | 0 | ||||||||||||
272 | } | - | ||||||||||||
273 | #endif | - | ||||||||||||
274 | else | - | ||||||||||||
275 | b->flags |= BUILTIN_ENABLED; executed 8 times by 1 test: b->flags |= 0x01; Executed by:
| 8 | ||||||||||||
276 | - | |||||||||||||
277 | #if defined (PROGRAMMABLE_COMPLETION) | - | ||||||||||||
278 | set_itemlist_dirty (&it_enabled); | - | ||||||||||||
279 | set_itemlist_dirty (&it_disabled); | - | ||||||||||||
280 | #endif | - | ||||||||||||
281 | - | |||||||||||||
282 | return (EXECUTION_SUCCESS); executed 17 times by 1 test: return (0); Executed by:
| 17 | ||||||||||||
283 | } | - | ||||||||||||
284 | - | |||||||||||||
285 | #if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) | - | ||||||||||||
286 | - | |||||||||||||
287 | #if defined (HAVE_DLFCN_H) | - | ||||||||||||
288 | # include <dlfcn.h> | - | ||||||||||||
289 | #endif | - | ||||||||||||
290 | - | |||||||||||||
291 | static int | - | ||||||||||||
292 | dyn_load_builtin (list, flags, filename) | - | ||||||||||||
293 | WORD_LIST *list; | - | ||||||||||||
294 | int flags; | - | ||||||||||||
295 | char *filename; | - | ||||||||||||
296 | { | - | ||||||||||||
297 | WORD_LIST *l; | - | ||||||||||||
298 | void *handle; | - | ||||||||||||
299 | - | |||||||||||||
300 | int total, size, new, replaced, r; | - | ||||||||||||
301 | char *struct_name, *name, *funcname; | - | ||||||||||||
302 | sh_load_func_t *loadfunc; | - | ||||||||||||
303 | struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin; | - | ||||||||||||
304 | char *loadables_path, *load_path; | - | ||||||||||||
305 | - | |||||||||||||
306 | if (list == 0)
| 0 | ||||||||||||
307 | return (EXECUTION_FAILURE); never executed: return (1); | 0 | ||||||||||||
308 | - | |||||||||||||
309 | #ifndef RTLD_LAZY | - | ||||||||||||
310 | #define RTLD_LAZY 1 | - | ||||||||||||
311 | #endif | - | ||||||||||||
312 | - | |||||||||||||
313 | handle = 0; | - | ||||||||||||
314 | if (absolute_program (filename) == 0)
| 0 | ||||||||||||
315 | { | - | ||||||||||||
316 | loadables_path = get_string_value ("BASH_LOADABLES_PATH"); | - | ||||||||||||
317 | if (loadables_path)
| 0 | ||||||||||||
318 | { | - | ||||||||||||
319 | load_path = find_in_path (filename, loadables_path, FS_NODIRS|FS_EXEC_PREFERRED); | - | ||||||||||||
320 | if (load_path)
| 0 | ||||||||||||
321 | { | - | ||||||||||||
322 | #if defined (_AIX) | - | ||||||||||||
323 | handle = dlopen (load_path, RTLD_NOW|RTLD_GLOBAL); | - | ||||||||||||
324 | #else | - | ||||||||||||
325 | handle = dlopen (load_path, RTLD_LAZY); | - | ||||||||||||
326 | #endif /* !_AIX */ | - | ||||||||||||
327 | free (load_path); | - | ||||||||||||
328 | } never executed: end of block | 0 | ||||||||||||
329 | } never executed: end of block | 0 | ||||||||||||
330 | } never executed: end of block | 0 | ||||||||||||
331 | - | |||||||||||||
332 | /* Fall back to current directory for now */ | - | ||||||||||||
333 | if (handle == 0)
| 0 | ||||||||||||
334 | #if defined (_AIX) | - | ||||||||||||
335 | handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL); | - | ||||||||||||
336 | #else | - | ||||||||||||
337 | handle = dlopen (filename, RTLD_LAZY); never executed: handle = dlopen (filename, 0x00001 ); | 0 | ||||||||||||
338 | #endif /* !_AIX */ | - | ||||||||||||
339 | - | |||||||||||||
340 | if (handle == 0)
| 0 | ||||||||||||
341 | { | - | ||||||||||||
342 | name = printable_filename (filename, 0); | - | ||||||||||||
343 | builtin_error (_("cannot open shared object %s: %s"), name, dlerror ()); | - | ||||||||||||
344 | if (name != filename)
| 0 | ||||||||||||
345 | free (name); never executed: sh_xfree((name), "./enable.def", 345); | 0 | ||||||||||||
346 | return (EXECUTION_FAILURE); never executed: return (1); | 0 | ||||||||||||
347 | } | - | ||||||||||||
348 | - | |||||||||||||
349 | for (new = 0, l = list; l; l = l->next, new++)
| 0 | ||||||||||||
350 | ; never executed: ; | 0 | ||||||||||||
351 | new_builtins = (struct builtin **)xmalloc (new * sizeof (struct builtin *)); | - | ||||||||||||
352 | - | |||||||||||||
353 | /* For each new builtin in the shared object, find it and its describing | - | ||||||||||||
354 | structure. If this is overwriting an existing builtin, do so, otherwise | - | ||||||||||||
355 | save the loaded struct for creating the new list of builtins. */ | - | ||||||||||||
356 | for (replaced = new = 0; list; list = list->next)
| 0 | ||||||||||||
357 | { | - | ||||||||||||
358 | name = list->word->word; | - | ||||||||||||
359 | - | |||||||||||||
360 | size = strlen (name); | - | ||||||||||||
361 | struct_name = (char *)xmalloc (size + 8); | - | ||||||||||||
362 | strcpy (struct_name, name); | - | ||||||||||||
363 | strcpy (struct_name + size, STRUCT_SUFFIX); | - | ||||||||||||
364 | - | |||||||||||||
365 | b = (struct builtin *)dlsym (handle, struct_name); | - | ||||||||||||
366 | if (b == 0)
| 0 | ||||||||||||
367 | { | - | ||||||||||||
368 | name = printable_filename (filename, 0); | - | ||||||||||||
369 | builtin_error (_("cannot find %s in shared object %s: %s"), | - | ||||||||||||
370 | struct_name, name, dlerror ()); | - | ||||||||||||
371 | if (name != filename)
| 0 | ||||||||||||
372 | free (name); never executed: sh_xfree((name), "./enable.def", 372); | 0 | ||||||||||||
373 | free (struct_name); | - | ||||||||||||
374 | continue; never executed: continue; | 0 | ||||||||||||
375 | } | - | ||||||||||||
376 | - | |||||||||||||
377 | funcname = xrealloc (struct_name, size + sizeof (LOAD_SUFFIX) + 1); | - | ||||||||||||
378 | strcpy (funcname, name); | - | ||||||||||||
379 | strcpy (funcname + size, LOAD_SUFFIX); | - | ||||||||||||
380 | - | |||||||||||||
381 | loadfunc = (sh_load_func_t *)dlsym (handle, funcname); | - | ||||||||||||
382 | if (loadfunc)
| 0 | ||||||||||||
383 | { | - | ||||||||||||
384 | r = (*loadfunc) (name); | - | ||||||||||||
385 | if (r == 0)
| 0 | ||||||||||||
386 | { | - | ||||||||||||
387 | builtin_error (_("load function for %s returns failure (%d): not loaded"), name, r); | - | ||||||||||||
388 | free (funcname); | - | ||||||||||||
389 | continue; never executed: continue; | 0 | ||||||||||||
390 | } | - | ||||||||||||
391 | } never executed: end of block | 0 | ||||||||||||
392 | free (funcname); | - | ||||||||||||
393 | - | |||||||||||||
394 | b->flags &= ~STATIC_BUILTIN; | - | ||||||||||||
395 | if (flags & SPECIAL)
| 0 | ||||||||||||
396 | b->flags |= SPECIAL_BUILTIN; never executed: b->flags |= 0x08; | 0 | ||||||||||||
397 | b->handle = handle; | - | ||||||||||||
398 | - | |||||||||||||
399 | if (old_builtin = builtin_address_internal (name, 1))
| 0 | ||||||||||||
400 | { | - | ||||||||||||
401 | replaced++; | - | ||||||||||||
402 | FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin)); | - | ||||||||||||
403 | } never executed: end of block | 0 | ||||||||||||
404 | else | - | ||||||||||||
405 | new_builtins[new++] = b; never executed: new_builtins[new++] = b; | 0 | ||||||||||||
406 | } | - | ||||||||||||
407 | - | |||||||||||||
408 | if (replaced == 0 && new == 0)
| 0 | ||||||||||||
409 | { | - | ||||||||||||
410 | free (new_builtins); | - | ||||||||||||
411 | dlclose (handle); | - | ||||||||||||
412 | return (EXECUTION_FAILURE); never executed: return (1); | 0 | ||||||||||||
413 | } | - | ||||||||||||
414 | - | |||||||||||||
415 | if (new)
| 0 | ||||||||||||
416 | { | - | ||||||||||||
417 | total = num_shell_builtins + new; | - | ||||||||||||
418 | size = (total + 1) * sizeof (struct builtin); | - | ||||||||||||
419 | - | |||||||||||||
420 | new_shell_builtins = (struct builtin *)xmalloc (size); | - | ||||||||||||
421 | FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins, | - | ||||||||||||
422 | num_shell_builtins * sizeof (struct builtin)); | - | ||||||||||||
423 | for (replaced = 0; replaced < new; replaced++)
| 0 | ||||||||||||
424 | FASTCOPY ((char *)new_builtins[replaced], never executed: __builtin_memcpy (((char *)&new_shell_builtins[num_shell_builtins + replaced]), ((char *)new_builtins[replaced]), (sizeof (struct builtin))) ; | 0 | ||||||||||||
425 | (char *)&new_shell_builtins[num_shell_builtins + replaced], never executed: __builtin_memcpy (((char *)&new_shell_builtins[num_shell_builtins + replaced]), ((char *)new_builtins[replaced]), (sizeof (struct builtin))) ; | 0 | ||||||||||||
426 | sizeof (struct builtin)); never executed: __builtin_memcpy (((char *)&new_shell_builtins[num_shell_builtins + replaced]), ((char *)new_builtins[replaced]), (sizeof (struct builtin))) ; | 0 | ||||||||||||
427 | - | |||||||||||||
428 | new_shell_builtins[total].name = (char *)0; | - | ||||||||||||
429 | new_shell_builtins[total].function = (sh_builtin_func_t *)0; | - | ||||||||||||
430 | new_shell_builtins[total].flags = 0; | - | ||||||||||||
431 | - | |||||||||||||
432 | if (shell_builtins != static_shell_builtins)
| 0 | ||||||||||||
433 | free (shell_builtins); never executed: sh_xfree((shell_builtins), "./enable.def", 433); | 0 | ||||||||||||
434 | - | |||||||||||||
435 | shell_builtins = new_shell_builtins; | - | ||||||||||||
436 | num_shell_builtins = total; | - | ||||||||||||
437 | initialize_shell_builtins (); | - | ||||||||||||
438 | } never executed: end of block | 0 | ||||||||||||
439 | - | |||||||||||||
440 | free (new_builtins); | - | ||||||||||||
441 | return (EXECUTION_SUCCESS); never executed: return (0); | 0 | ||||||||||||
442 | } | - | ||||||||||||
443 | #endif | - | ||||||||||||
444 | - | |||||||||||||
445 | #if defined (HAVE_DLCLOSE) | - | ||||||||||||
446 | static void | - | ||||||||||||
447 | delete_builtin (b) | - | ||||||||||||
448 | struct builtin *b; | - | ||||||||||||
449 | { | - | ||||||||||||
450 | int ind, size; | - | ||||||||||||
451 | struct builtin *new_shell_builtins; | - | ||||||||||||
452 | - | |||||||||||||
453 | /* XXX - funky pointer arithmetic - XXX */ | - | ||||||||||||
454 | #ifdef __STDC__ | - | ||||||||||||
455 | ind = b - shell_builtins; | - | ||||||||||||
456 | #else | - | ||||||||||||
457 | ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin); | - | ||||||||||||
458 | #endif | - | ||||||||||||
459 | size = num_shell_builtins * sizeof (struct builtin); | - | ||||||||||||
460 | new_shell_builtins = (struct builtin *)xmalloc (size); | - | ||||||||||||
461 | - | |||||||||||||
462 | /* Copy shell_builtins[0]...shell_builtins[ind - 1] to new_shell_builtins */ | - | ||||||||||||
463 | if (ind)
| 0 | ||||||||||||
464 | FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins, never executed: __builtin_memcpy (((char *)new_shell_builtins), ((char *)shell_builtins), (ind * sizeof (struct builtin))) ; | 0 | ||||||||||||
465 | ind * sizeof (struct builtin)); never executed: __builtin_memcpy (((char *)new_shell_builtins), ((char *)shell_builtins), (ind * sizeof (struct builtin))) ; | 0 | ||||||||||||
466 | /* Copy shell_builtins[ind+1]...shell_builtins[num_shell_builtins to | - | ||||||||||||
467 | new_shell_builtins, starting at ind. */ | - | ||||||||||||
468 | FASTCOPY ((char *)(&shell_builtins[ind+1]), | - | ||||||||||||
469 | (char *)(&new_shell_builtins[ind]), | - | ||||||||||||
470 | (num_shell_builtins - ind) * sizeof (struct builtin)); | - | ||||||||||||
471 | - | |||||||||||||
472 | if (shell_builtins != static_shell_builtins)
| 0 | ||||||||||||
473 | free (shell_builtins); never executed: sh_xfree((shell_builtins), "./enable.def", 473); | 0 | ||||||||||||
474 | - | |||||||||||||
475 | /* The result is still sorted. */ | - | ||||||||||||
476 | num_shell_builtins--; | - | ||||||||||||
477 | shell_builtins = new_shell_builtins; | - | ||||||||||||
478 | } never executed: end of block | 0 | ||||||||||||
479 | - | |||||||||||||
480 | /* Tenon's MachTen has a dlclose that doesn't return a value, so we | - | ||||||||||||
481 | finesse it with a local wrapper. */ | - | ||||||||||||
482 | static int | - | ||||||||||||
483 | local_dlclose (handle) | - | ||||||||||||
484 | void *handle; | - | ||||||||||||
485 | { | - | ||||||||||||
486 | #if !defined (__MACHTEN__) | - | ||||||||||||
487 | return (dlclose (handle)); never executed: return (dlclose (handle)); | 0 | ||||||||||||
488 | #else /* __MACHTEN__ */ | - | ||||||||||||
489 | dlclose (handle); | - | ||||||||||||
490 | return ((dlerror () != NULL) ? -1 : 0); | - | ||||||||||||
491 | #endif /* __MACHTEN__ */ | - | ||||||||||||
492 | } | - | ||||||||||||
493 | - | |||||||||||||
494 | static int | - | ||||||||||||
495 | dyn_unload_builtin (name) | - | ||||||||||||
496 | char *name; | - | ||||||||||||
497 | { | - | ||||||||||||
498 | struct builtin *b; | - | ||||||||||||
499 | void *handle; | - | ||||||||||||
500 | char *funcname; | - | ||||||||||||
501 | sh_unload_func_t *unloadfunc; | - | ||||||||||||
502 | int ref, i, size; | - | ||||||||||||
503 | - | |||||||||||||
504 | b = builtin_address_internal (name, 1); | - | ||||||||||||
505 | if (b == 0)
| 0 | ||||||||||||
506 | { | - | ||||||||||||
507 | sh_notbuiltin (name); | - | ||||||||||||
508 | return (EXECUTION_FAILURE); never executed: return (1); | 0 | ||||||||||||
509 | } | - | ||||||||||||
510 | if (b->flags & STATIC_BUILTIN)
| 0 | ||||||||||||
511 | { | - | ||||||||||||
512 | builtin_error (_("%s: not dynamically loaded"), name); | - | ||||||||||||
513 | return (EXECUTION_FAILURE); never executed: return (1); | 0 | ||||||||||||
514 | } | - | ||||||||||||
515 | - | |||||||||||||
516 | handle = (void *)b->handle; | - | ||||||||||||
517 | for (ref = i = 0; i < num_shell_builtins; i++)
| 0 | ||||||||||||
518 | { | - | ||||||||||||
519 | if (shell_builtins[i].handle == b->handle)
| 0 | ||||||||||||
520 | ref++; never executed: ref++; | 0 | ||||||||||||
521 | } never executed: end of block | 0 | ||||||||||||
522 | - | |||||||||||||
523 | /* Call any unload function */ | - | ||||||||||||
524 | size = strlen (name); | - | ||||||||||||
525 | funcname = xmalloc (size + sizeof (UNLOAD_SUFFIX) + 1); | - | ||||||||||||
526 | strcpy (funcname, name); | - | ||||||||||||
527 | strcpy (funcname + size, UNLOAD_SUFFIX); | - | ||||||||||||
528 | - | |||||||||||||
529 | unloadfunc = (sh_unload_func_t *)dlsym (handle, funcname); | - | ||||||||||||
530 | if (unloadfunc)
| 0 | ||||||||||||
531 | (*unloadfunc) (name); /* void function */ never executed: (*unloadfunc) (name); | 0 | ||||||||||||
532 | free (funcname); | - | ||||||||||||
533 | - | |||||||||||||
534 | /* Don't remove the shared object unless the reference count of builtins | - | ||||||||||||
535 | using it drops to zero. */ | - | ||||||||||||
536 | if (ref == 1 && local_dlclose (handle) != 0)
| 0 | ||||||||||||
537 | { | - | ||||||||||||
538 | builtin_error (_("%s: cannot delete: %s"), name, dlerror ()); | - | ||||||||||||
539 | return (EXECUTION_FAILURE); never executed: return (1); | 0 | ||||||||||||
540 | } | - | ||||||||||||
541 | - | |||||||||||||
542 | /* Now remove this entry from the builtin table and reinitialize. */ | - | ||||||||||||
543 | delete_builtin (b); | - | ||||||||||||
544 | - | |||||||||||||
545 | return (EXECUTION_SUCCESS); never executed: return (0); | 0 | ||||||||||||
546 | } | - | ||||||||||||
547 | #endif | - | ||||||||||||
Source code | Switch to Preprocessed file |