/src/gnutls/lib/dlwrap/zlib.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copying and distribution of this file, with or without modification, |
3 | | * are permitted in any medium without royalty provided the copyright |
4 | | * notice and this notice are preserved. This file is offered as-is, |
5 | | * without any warranty. |
6 | | */ |
7 | | |
8 | | #ifdef HAVE_CONFIG_H |
9 | | #include "config.h" |
10 | | #endif |
11 | | |
12 | | #include "zlib.h" |
13 | | |
14 | | #if defined(GNUTLS_ZLIB_ENABLE_DLOPEN) && GNUTLS_ZLIB_ENABLE_DLOPEN |
15 | | |
16 | | #include <assert.h> |
17 | | #include <dlfcn.h> |
18 | | #include <errno.h> |
19 | | #include <stdlib.h> |
20 | | |
21 | | /* If Z_LIBRARY_SONAME_UNUSED is defined, dlopen handle can be automatically |
22 | | * set; otherwise, the caller needs to call |
23 | | * gnutls_zlib_ensure_library with soname determined at run time. |
24 | | */ |
25 | | #ifdef Z_LIBRARY_SONAME_UNUSED |
26 | | |
27 | | static void |
28 | | ensure_library (void) |
29 | | { |
30 | | if (gnutls_zlib_ensure_library (Z_LIBRARY_SONAME_UNUSED, RTLD_LAZY | RTLD_LOCAL) < 0) |
31 | | abort (); |
32 | | } |
33 | | |
34 | | #if defined(GNUTLS_ZLIB_ENABLE_PTHREAD) && GNUTLS_ZLIB_ENABLE_PTHREAD |
35 | | #include <pthread.h> |
36 | | |
37 | | static pthread_once_t dlopen_once = PTHREAD_ONCE_INIT; |
38 | | |
39 | | #define ENSURE_LIBRARY pthread_once(&dlopen_once, ensure_library) |
40 | | |
41 | | #else /* GNUTLS_ZLIB_ENABLE_PTHREAD */ |
42 | | |
43 | | #define ENSURE_LIBRARY do { \ |
44 | | if (!gnutls_zlib_dlhandle) \ |
45 | | ensure_library(); \ |
46 | | } while (0) |
47 | | |
48 | | #endif /* !GNUTLS_ZLIB_ENABLE_PTHREAD */ |
49 | | |
50 | | #else /* Z_LIBRARY_SONAME_UNUSED */ |
51 | | |
52 | 0 | #define ENSURE_LIBRARY do {} while (0) |
53 | | |
54 | | #endif /* !Z_LIBRARY_SONAME_UNUSED */ |
55 | | |
56 | | static void *gnutls_zlib_dlhandle; |
57 | | |
58 | | /* Define redirection symbols */ |
59 | | #pragma GCC diagnostic push |
60 | | #pragma GCC diagnostic ignored "-Wunused-macros" |
61 | | |
62 | | #if (2 <= __GNUC__ || (4 <= __clang_major__)) |
63 | | #define FUNC(ret, name, args, cargs) \ |
64 | | static __typeof__(name)(*gnutls_zlib_sym_##name); |
65 | | #else |
66 | | #define FUNC(ret, name, args, cargs) \ |
67 | | static ret(*gnutls_zlib_sym_##name)args; |
68 | | #endif |
69 | | #define VOID_FUNC FUNC |
70 | | #include "zlibfuncs.h" |
71 | | #undef VOID_FUNC |
72 | | #undef FUNC |
73 | | |
74 | | #pragma GCC diagnostic pop |
75 | | |
76 | | /* Define redirection wrapper functions */ |
77 | | #pragma GCC diagnostic push |
78 | | #pragma GCC diagnostic ignored "-Wunused-macros" |
79 | | |
80 | | #define FUNC(ret, name, args, cargs) \ |
81 | 0 | ret gnutls_zlib_func_##name args \ |
82 | 0 | { \ |
83 | 0 | ENSURE_LIBRARY; \ |
84 | 0 | assert (gnutls_zlib_sym_##name); \ |
85 | 0 | return gnutls_zlib_sym_##name cargs; \ |
86 | 0 | } Unexecuted instantiation: gnutls_zlib_func_compress Unexecuted instantiation: gnutls_zlib_func_compressBound Unexecuted instantiation: gnutls_zlib_func_uncompress |
87 | | #define VOID_FUNC(ret, name, args, cargs) \ |
88 | | ret gnutls_zlib_func_##name args \ |
89 | | { \ |
90 | | ENSURE_LIBRARY; \ |
91 | | assert (gnutls_zlib_sym_##name); \ |
92 | | gnutls_zlib_sym_##name cargs; \ |
93 | | } |
94 | | #include "zlibfuncs.h" |
95 | | #undef VOID_FUNC |
96 | | #undef FUNC |
97 | | |
98 | | #pragma GCC diagnostic pop |
99 | | |
100 | | static int |
101 | | ensure_symbol (const char *name, void **symp) |
102 | 0 | { |
103 | 0 | if (!*symp) |
104 | 0 | { |
105 | 0 | void *sym = dlsym (gnutls_zlib_dlhandle, name); |
106 | 0 | if (!sym) |
107 | 0 | return -EINVAL; |
108 | 0 | *symp = sym; |
109 | 0 | } |
110 | 0 | return 0; |
111 | 0 | } |
112 | | |
113 | | int |
114 | | gnutls_zlib_ensure_library (const char *soname, int flags) |
115 | 0 | { |
116 | 0 | int err; |
117 | |
|
118 | 0 | if (!gnutls_zlib_dlhandle) |
119 | 0 | { |
120 | 0 | gnutls_zlib_dlhandle = dlopen (soname, flags); |
121 | 0 | if (!gnutls_zlib_dlhandle) |
122 | 0 | return -EINVAL; |
123 | 0 | } |
124 | | |
125 | 0 | #define ENSURE_SYMBOL(name) \ |
126 | 0 | ensure_symbol(#name, (void **)&gnutls_zlib_sym_##name) |
127 | | |
128 | 0 | #pragma GCC diagnostic push |
129 | 0 | #pragma GCC diagnostic ignored "-Wunused-macros" |
130 | | |
131 | 0 | #define FUNC(ret, name, args, cargs) \ |
132 | 0 | err = ENSURE_SYMBOL(name); \ |
133 | 0 | if (err < 0) \ |
134 | 0 | { \ |
135 | 0 | dlclose (gnutls_zlib_dlhandle); \ |
136 | 0 | gnutls_zlib_dlhandle = NULL; \ |
137 | 0 | return err; \ |
138 | 0 | } |
139 | 0 | #define VOID_FUNC FUNC |
140 | 0 | #include "zlibfuncs.h" |
141 | 0 | #undef VOID_FUNC |
142 | 0 | #undef FUNC |
143 | | |
144 | 0 | #pragma GCC diagnostic pop |
145 | | |
146 | 0 | #undef ENSURE_SYMBOL |
147 | 0 | return 0; |
148 | 0 | } |
149 | | |
150 | | void |
151 | | gnutls_zlib_unload_library (void) |
152 | 0 | { |
153 | 0 | if (gnutls_zlib_dlhandle) |
154 | 0 | { |
155 | 0 | dlclose (gnutls_zlib_dlhandle); |
156 | 0 | gnutls_zlib_dlhandle = NULL; |
157 | 0 | } |
158 | |
|
159 | 0 | #pragma GCC diagnostic push |
160 | 0 | #pragma GCC diagnostic ignored "-Wunused-macros" |
161 | |
|
162 | 0 | #define FUNC(ret, name, args, cargs) \ |
163 | 0 | gnutls_zlib_sym_##name = NULL; |
164 | 0 | #define VOID_FUNC FUNC |
165 | 0 | #include "zlibfuncs.h" |
166 | 0 | #undef VOID_FUNC |
167 | 0 | #undef FUNC |
168 | |
|
169 | 0 | #pragma GCC diagnostic pop |
170 | 0 | } |
171 | | |
172 | | unsigned |
173 | | gnutls_zlib_is_usable (void) |
174 | 0 | { |
175 | 0 | return gnutls_zlib_dlhandle != NULL; |
176 | 0 | } |
177 | | |
178 | | #else /* GNUTLS_ZLIB_ENABLE_DLOPEN */ |
179 | | |
180 | | int |
181 | | gnutls_zlib_ensure_library (const char *soname, int flags) |
182 | | { |
183 | | (void) soname; |
184 | | (void) flags; |
185 | | return 0; |
186 | | } |
187 | | |
188 | | void |
189 | | gnutls_zlib_unload_library (void) |
190 | | { |
191 | | } |
192 | | |
193 | | unsigned |
194 | | gnutls_zlib_is_usable (void) |
195 | | { |
196 | | /* The library is linked at build time, thus always usable */ |
197 | | return 1; |
198 | | } |
199 | | |
200 | | #endif /* !GNUTLS_ZLIB_ENABLE_DLOPEN */ |