]>
Commit | Line | Data |
---|---|---|
1 | /* Error handling for runtime dynamic linker. | |
2 | Copyright (C) 1995, 1996 Free Software Foundation, Inc. | |
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> | |
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; | |
37 | ||
38 | ||
39 | void | |
40 | _dl_signal_error (int errcode, | |
41 | const char *objname, | |
42 | const char *errstring) | |
43 | { | |
44 | if (! errstring) | |
45 | errstring = "DYNAMIC LINKER BUG!!!"; | |
46 | ||
47 | if (catch) | |
48 | { | |
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); | |
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 | } | |
69 | } | |
70 | ||
71 | int | |
72 | _dl_catch_error (const char **errstring, | |
73 | const char **objname, | |
74 | void (*operate) (void)) | |
75 | { | |
76 | int errcode; | |
77 | struct catch c = { errstring: NULL, objname: NULL }; | |
78 | ||
79 | errcode = setjmp (c.env); | |
80 | if (errcode == 0) | |
81 | { | |
82 | catch = &c; | |
83 | (*operate) (); | |
84 | catch = NULL; | |
85 | *errstring = *objname = NULL; | |
86 | return 0; | |
87 | } | |
88 | ||
89 | /* We get here only if we longjmp'd out of OPERATE. */ | |
90 | *errstring = c.errstring; | |
91 | *objname = c.objname; | |
92 | return errcode == -1 ? 0 : errcode; | |
93 | } |