RTS API Documentation  1.10.11
switch_dso.c
Go to the documentation of this file.
1 /*
2  * Cross Platform dso/dll load abstraction
3  * Copyright(C) 2008 Michael Jerris
4  *
5  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
6  * copies of the Software, and permit persons to whom the Software is
7  * furnished to do so.
8  *
9  * This work is provided under this license on an "as is" basis, without warranty of any kind,
10  * either expressed or implied, including, without limitation, warranties that the covered code
11  * is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire
12  * risk as to the quality and performance of the covered code is with you. Should any covered
13  * code prove defective in any respect, you (not the initial developer or any other contributor)
14  * assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty
15  * constitutes an essential part of this license. No use of any covered code is authorized hereunder
16  * except under this disclaimer.
17  *
18  */
19 
20 #include <switch.h>
21 #include "switch_dso.h"
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #ifdef WIN32
26 
28 {
29  if (lib && *lib) {
30  FreeLibrary(*lib);
31  *lib = NULL;
32  }
33 }
34 
35 SWITCH_DECLARE(switch_dso_lib_t) switch_dso_open(const char *path, int global, char **err)
36 {
37  HINSTANCE lib;
38 
39  lib = LoadLibraryEx(path, NULL, 0);
40 
41  if (!lib) {
42  lib = LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
43  }
44 
45  if (!lib) {
46  lib = LoadLibraryEx(path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
47  }
48 
49  if (!lib) {
50  DWORD error = GetLastError();
51  *err = switch_mprintf("dll open error [%ul]\n", error);
52  }
53 
54  return lib;
55 }
56 
58 {
59  FARPROC func = GetProcAddress(lib, sym);
60  if (!func) {
61  DWORD error = GetLastError();
62  *err = switch_mprintf("dll sym error [%ul]\n", error);
63  }
64  return (switch_dso_func_t) func;
65 }
66 
67 SWITCH_DECLARE(void *) switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err)
68 {
69  FARPROC addr = GetProcAddress(lib, sym);
70  if (!addr) {
71  DWORD error = GetLastError();
72  *err = switch_mprintf("dll sym error [%ul]\n", error);
73  }
74  return (void *) (intptr_t) addr;
75 }
76 
77 
78 #else
79 /*
80 ** {========================================================================
81 ** This is an implementation of loadlib based on the dlfcn interface.
82 ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
83 ** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
84 ** as an emulation layer on top of native functions.
85 ** =========================================================================
86 */
87 
88 
89 #include <dlfcn.h>
90 
92 {
93  if (lib && *lib) {
94 #ifndef HAVE_FAKE_DLCLOSE
95  dlclose(*lib);
96 #endif
97  *lib = NULL;
98  }
99 }
100 
101 switch_dso_lib_t switch_dso_open(const char *path, int global, char **err)
102 {
103  void *lib;
104 
105  if (global) {
106  lib = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
107  } else {
108  lib = dlopen(path, RTLD_NOW | RTLD_LOCAL);
109  }
110 
111  if (lib == NULL) {
112  const char *dlerr = dlerror();
113  /* Work around broken uclibc returning NULL on both dlopen() and dlerror() */
114  if (dlerr) {
115  *err = strdup(dlerr);
116  } else {
117  *err = strdup("Unknown error");
118  }
119  }
120  return lib;
121 }
122 
123 switch_dso_func_t switch_dso_func_sym(switch_dso_lib_t lib, const char *sym, char **err)
124 {
125  void *func = dlsym(lib, sym);
126  if (!func) {
127  *err = strdup(dlerror());
128  }
129  return (switch_dso_func_t) (intptr_t) func;
130 }
131 
132 void *switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err)
133 {
134  void *addr = dlsym(lib, sym);
135  if (!addr) {
136  char *err_str = NULL;
137  dlerror();
138 
139  if (!(addr = dlsym(lib, sym))) {
140  err_str = (char *)dlerror();
141  }
142 
143  if (err_str) {
144  *err = strdup(err_str);
145  }
146  }
147  return addr;
148 }
149 
150 #endif
151 /* }====================================================== */
152 
153 /* For Emacs:
154  * Local Variables:
155  * mode:c
156  * indent-tabs-mode:t
157  * tab-width:4
158  * c-basic-offset:4
159  * End:
160  * For VIM:
161  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet
162  */
switch_dso_lib_t switch_dso_open(const char *path, int global, char **err)
Definition: switch_dso.c:101
void switch_dso_destroy(switch_dso_lib_t *lib)
Definition: switch_dso.c:91
switch_dso_func_t switch_dso_func_sym(switch_dso_lib_t lib, const char *sym, char **err)
Definition: switch_dso.c:123
void * switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err)
Definition: switch_dso.c:132
Definition: cJSON.c:68
SWITCH_BEGIN_EXTERN_C typedef int(* switch_dso_func_t)(void)
Definition: switch_dso.h:26
const char *const const char *const path
Main Library Header.
#define SWITCH_DECLARE(type)
void * switch_dso_lib_t
Definition: switch_dso.h:30
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)