1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc.  All rights reserved.
3  * Copyright (c) 2016      IBM Corporation.  All rights reserved.
4  * $COPYRIGHT$
5  *
6  * Additional copyrights may follow
7  *
8  * $HEADER$
9  */
10 
11 #include "opal_config.h"
12 
13 #include "opal/constants.h"
14 #include "opal/mca/dl/dl.h"
15 
16 #include "dl_libltdl.h"
17 
18 
libltdl_open(const char * fname,bool use_ext,bool private_namespace,opal_dl_handle_t ** handle,char ** err_msg)19 static int libltdl_open(const char *fname, bool use_ext, bool private_namespace,
20                        opal_dl_handle_t **handle, char **err_msg)
21 {
22     assert(handle);
23 
24     *handle = NULL;
25     if (NULL != err_msg) {
26         *err_msg = NULL;
27     }
28 
29     lt_dlhandle local_handle;
30 
31 #if OPAL_DL_LIBLTDL_HAVE_LT_DLADVISE
32     opal_dl_libltdl_component_t *c = &mca_dl_libltdl_component;
33 
34     if (use_ext && private_namespace) {
35         local_handle = lt_dlopenadvise(fname, c->advise_private_ext);
36     } else if (use_ext && !private_namespace) {
37         local_handle = lt_dlopenadvise(fname, c->advise_public_ext);
38     } else if (!use_ext && private_namespace) {
39         local_handle = lt_dlopenadvise(fname, c->advise_private_noext);
40     } else if (!use_ext && !private_namespace) {
41         local_handle = lt_dlopenadvise(fname, c->advise_public_noext);
42     }
43 #else
44     if (use_ext) {
45         local_handle = lt_dlopenext(fname);
46     } else {
47         local_handle = lt_dlopen(fname);
48     }
49 #endif
50 
51     if (NULL != local_handle) {
52         *handle = calloc(1, sizeof(opal_dl_handle_t));
53         (*handle)->ltdl_handle = local_handle;
54 
55 #if OPAL_ENABLE_DEBUG
56         if( NULL != fname ) {
57             (*handle)->filename = strdup(fname);
58         }
59         else {
60             (*handle)->filename = strdup("(null)");
61         }
62 #endif
63 
64         return OPAL_SUCCESS;
65     }
66 
67     if (NULL != err_msg) {
68         *err_msg = (char*) lt_dlerror();
69     }
70     return OPAL_ERROR;
71 }
72 
73 
libltdl_lookup(opal_dl_handle_t * handle,const char * symbol,void ** ptr,char ** err_msg)74 static int libltdl_lookup(opal_dl_handle_t *handle, const char *symbol,
75                          void **ptr, char **err_msg)
76 {
77     assert(handle);
78     assert(handle->ltdl_handle);
79     assert(symbol);
80     assert(ptr);
81 
82     if (NULL != err_msg) {
83         *err_msg = NULL;
84     }
85 
86     *ptr = lt_dlsym(handle->ltdl_handle, symbol);
87     if (NULL != *ptr) {
88         return OPAL_SUCCESS;
89     }
90 
91     if (NULL != err_msg) {
92         *err_msg = (char*) lt_dlerror();
93     }
94     return OPAL_ERROR;
95 }
96 
97 
libltdl_close(opal_dl_handle_t * handle)98 static int libltdl_close(opal_dl_handle_t *handle)
99 {
100     assert(handle);
101 
102     int ret;
103     ret = lt_dlclose(handle->ltdl_handle);
104 
105 #if OPAL_ENABLE_DEBUG
106     free(handle->filename);
107 #endif
108     free(handle);
109 
110     return ret;
111 }
112 
libltdl_foreachfile(const char * search_path,int (* func)(const char * filename,void * data),void * data)113 static int libltdl_foreachfile(const char *search_path,
114                                int (*func)(const char *filename, void *data),
115                                void *data)
116 {
117     assert(search_path);
118     assert(func);
119 
120     int ret = lt_dlforeachfile(search_path, func, data);
121     return (0 == ret) ? OPAL_SUCCESS : OPAL_ERROR;
122 }
123 
124 
125 /*
126  * Module definition
127  */
128 opal_dl_base_module_t opal_dl_libltdl_module = {
129     .open = libltdl_open,
130     .lookup = libltdl_lookup,
131     .close = libltdl_close,
132     .foreachfile = libltdl_foreachfile
133 };
134