This source file includes following definitions.
- do_dlopen
- dlopen_open
- dlopen_lookup
- dlopen_close
- dlopen_foreachfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include "opal_config.h"
16
17 #include <stdlib.h>
18 #include <dlfcn.h>
19 #include <sys/types.h>
20 #include <dirent.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23
24 #include "opal/constants.h"
25 #include "opal/mca/dl/dl.h"
26 #include "opal/util/argv.h"
27 #include "opal/util/printf.h"
28
29 #include "dl_dlopen.h"
30
31
32
33
34
35 static void do_dlopen(const char *fname, int flags,
36 void **handle, char **err_msg)
37 {
38 assert(handle);
39
40 *handle = dlopen(fname, flags);
41
42 if (NULL != err_msg) {
43 if (NULL != *handle) {
44 *err_msg = NULL;
45 } else {
46 *err_msg = dlerror();
47 }
48 }
49 }
50
51
52 static int dlopen_open(const char *fname, bool use_ext, bool private_namespace,
53 opal_dl_handle_t **handle, char **err_msg)
54 {
55 assert(handle);
56
57 *handle = NULL;
58
59
60 int flags = RTLD_LAZY;
61 if (private_namespace) {
62 flags |= RTLD_LOCAL;
63 } else {
64 flags |= RTLD_GLOBAL;
65 }
66
67
68
69 void *local_handle = NULL;
70 if (use_ext && NULL != fname) {
71 int i;
72 char *ext;
73
74 for (i = 0, ext = mca_dl_dlopen_component.filename_suffixes[i];
75 NULL != ext;
76 ext = mca_dl_dlopen_component.filename_suffixes[++i]) {
77 char *name;
78
79 opal_asprintf(&name, "%s%s", fname, ext);
80 if (NULL == name) {
81 return OPAL_ERR_IN_ERRNO;
82 }
83
84
85 struct stat buf;
86 if (stat(name, &buf) < 0) {
87 free(name);
88 if (NULL != err_msg) {
89 *err_msg = "File not found";
90 }
91 continue;
92 }
93
94
95
96 do_dlopen(name, flags, &local_handle, err_msg);
97 free(name);
98 break;
99 }
100 }
101
102
103
104 else {
105 do_dlopen(fname, flags, &local_handle, err_msg);
106 }
107
108 if (NULL != local_handle) {
109 *handle = calloc(1, sizeof(opal_dl_handle_t));
110 (*handle)->dlopen_handle = local_handle;
111
112 #if OPAL_ENABLE_DEBUG
113 if( NULL != fname ) {
114 (*handle)->filename = strdup(fname);
115 }
116 else {
117 (*handle)->filename = strdup("(null)");
118 }
119 #endif
120 }
121 return (NULL != local_handle) ? OPAL_SUCCESS : OPAL_ERROR;
122 }
123
124
125 static int dlopen_lookup(opal_dl_handle_t *handle, const char *symbol,
126 void **ptr, char **err_msg)
127 {
128 assert(handle);
129 assert(handle->dlopen_handle);
130 assert(symbol);
131 assert(ptr);
132
133 *ptr = dlsym(handle->dlopen_handle, symbol);
134 if (NULL != *ptr) {
135 return OPAL_SUCCESS;
136 }
137
138 if (NULL != err_msg) {
139 *err_msg = dlerror();
140 }
141 return OPAL_ERROR;
142 }
143
144
145 static int dlopen_close(opal_dl_handle_t *handle)
146 {
147 assert(handle);
148
149 int ret;
150 ret = dlclose(handle->dlopen_handle);
151
152 #if OPAL_ENABLE_DEBUG
153 free(handle->filename);
154 #endif
155 free(handle);
156
157 return ret;
158 }
159
160
161
162
163
164 static int dlopen_foreachfile(const char *search_path,
165 int (*func)(const char *filename, void *data),
166 void *data)
167 {
168 int ret;
169 DIR *dp = NULL;
170 char **dirs = NULL;
171 char **good_files = NULL;
172
173 dirs = opal_argv_split(search_path, OPAL_ENV_SEP);
174 for (int i = 0; NULL != dirs && NULL != dirs[i]; ++i) {
175
176 dp = opendir(dirs[i]);
177 if (NULL == dp) {
178 ret = OPAL_ERR_IN_ERRNO;
179 goto error;
180 }
181
182 struct dirent *de;
183 while (NULL != (de = readdir(dp))) {
184
185
186 char *abs_name = NULL;
187 opal_asprintf(&abs_name, "%s/%s", dirs[i], de->d_name);
188 if (NULL == abs_name) {
189 ret = OPAL_ERR_IN_ERRNO;
190 goto error;
191 }
192
193
194 struct stat buf;
195 if (stat(abs_name, &buf) < 0) {
196 free(abs_name);
197 ret = OPAL_ERR_IN_ERRNO;
198 goto error;
199 }
200
201
202 if (!S_ISREG(buf.st_mode)) {
203 free(abs_name);
204 continue;
205 }
206
207
208 char *ptr = strrchr(abs_name, '.');
209 if (NULL != ptr) {
210
211
212 if (strcmp(ptr, ".la") == 0 ||
213 strcmp(ptr, ".lo") == 0) {
214 free (abs_name);
215 continue;
216 }
217
218 *ptr = '\0';
219 }
220
221
222
223 bool found = false;
224 for (int j = 0; NULL != good_files &&
225 NULL != good_files[j]; ++j) {
226 if (strcmp(good_files[j], abs_name) == 0) {
227 found = true;
228 break;
229 }
230 }
231
232 if (!found) {
233 opal_argv_append_nosize(&good_files, abs_name);
234 }
235 free(abs_name);
236 }
237 closedir(dp);
238 }
239 dp = NULL;
240
241
242 if (NULL != good_files) {
243 for (int i = 0; NULL != good_files[i]; ++i) {
244 ret = func(good_files[i], data);
245 if (OPAL_SUCCESS != ret) {
246 goto error;
247 }
248 }
249 }
250
251 ret = OPAL_SUCCESS;
252
253 error:
254 if (NULL != dp) {
255 closedir(dp);
256 }
257 if (NULL != dirs) {
258 opal_argv_free(dirs);
259 }
260 if (NULL != good_files) {
261 opal_argv_free(good_files);
262 }
263
264 return ret;
265 }
266
267
268
269
270
271 opal_dl_base_module_t opal_dl_dlopen_module = {
272 .open = dlopen_open,
273 .lookup = dlopen_lookup,
274 .close = dlopen_close,
275 .foreachfile = dlopen_foreachfile
276 };