]>
Commit | Line | Data |
---|---|---|
d66e34cd | 1 | /* Error handling for runtime dynamic linker. |
0200214b | 2 | Copyright (C) 1995, 1996 Free Software Foundation, Inc. |
d66e34cd RM |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Library General Public License as | |
7 | published by the Free Software Foundation; either version 2 of the | |
8 | License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Library General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Library General Public | |
16 | License along with the GNU C Library; see the file COPYING.LIB. If | |
17 | not, write to the Free Software Foundation, Inc., 675 Mass Ave, | |
18 | Cambridge, MA 02139, USA. */ | |
19 | ||
20 | #include <stddef.h> | |
21 | #include <link.h> | |
22 | #include <setjmp.h> | |
0200214b RM |
23 | #include <string.h> |
24 | ||
25 | /* This structure communicates state between _dl_catch_error and | |
26 | _dl_signal_error. */ | |
27 | struct catch | |
28 | { | |
29 | const char *errstring, *objname; /* Error detail filled in here. */ | |
30 | jmp_buf env; /* longjmp here on error. */ | |
31 | }; | |
32 | ||
33 | /* This points to such a structure during a call to _dl_catch_error. | |
34 | During implicit startup and run-time work for needed shared libraries, | |
35 | this is null. */ | |
36 | static struct catch *catch; | |
d66e34cd | 37 | |
d66e34cd RM |
38 | |
39 | void | |
421f82e5 RM |
40 | _dl_signal_error (int errcode, |
41 | const char *objname, | |
42 | const char *errstring) | |
d66e34cd | 43 | { |
0200214b RM |
44 | if (! errstring) |
45 | errstring = "DYNAMIC LINKER BUG!!!"; | |
46 | ||
47 | if (catch) | |
48 | { | |
dcf0671d UD |
49 | /* We are inside _dl_catch_error. Return to it. We have to |
50 | duplicate the error string since it might be allocated on the | |
51 | stack. */ | |
52 | size_t len = strlen (errstring) + 1; | |
53 | catch->errstring = malloc (len); | |
54 | if (catch->errstring != NULL) | |
55 | memcpy (catch->errstring, errstring, len); | |
0200214b RM |
56 | catch->objname = objname; |
57 | longjmp (catch->env, errcode ?: -1); | |
58 | } | |
59 | else | |
60 | { | |
61 | /* Lossage while resolving the program's own symbols is always fatal. */ | |
62 | extern char **_dl_argv; /* Set in rtld.c at startup. */ | |
63 | _dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>", | |
64 | ": error in loading shared libraries\n", | |
65 | objname ?: "", objname ? ": " : "", | |
66 | errstring, errcode ? ": " : "", | |
67 | errcode ? strerror (errcode) : "", "\n", NULL); | |
68 | } | |
d66e34cd RM |
69 | } |
70 | ||
71 | int | |
421f82e5 RM |
72 | _dl_catch_error (const char **errstring, |
73 | const char **objname, | |
74 | void (*operate) (void)) | |
d66e34cd RM |
75 | { |
76 | int errcode; | |
0200214b | 77 | struct catch c = { errstring: NULL, objname: NULL }; |
d66e34cd | 78 | |
0200214b | 79 | errcode = setjmp (c.env); |
a1a9d215 RM |
80 | if (errcode == 0) |
81 | { | |
0200214b | 82 | catch = &c; |
a1a9d215 | 83 | (*operate) (); |
0200214b | 84 | catch = NULL; |
5bf62f2d | 85 | *errstring = *objname = NULL; |
a1a9d215 RM |
86 | return 0; |
87 | } | |
88 | ||
89 | /* We get here only if we longjmp'd out of OPERATE. */ | |
0200214b RM |
90 | *errstring = c.errstring; |
91 | *objname = c.objname; | |
a1a9d215 | 92 | return errcode == -1 ? 0 : errcode; |
d66e34cd | 93 | } |