FreeSWITCH API Documentation  1.7.0
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  LoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
43  }
44 
45  if (!lib) {
46  DWORD error = GetLastError();
47  *err = switch_mprintf("dll open error [%ul]\n", error);
48  }
49 
50  return lib;
51 }
52 
54 {
55  FARPROC func = GetProcAddress(lib, sym);
56  if (!func) {
57  DWORD error = GetLastError();
58  *err = switch_mprintf("dll sym error [%ul]\n", error);
59  }
60  return (switch_dso_func_t) func;
61 }
62 
63 SWITCH_DECLARE(void *) switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err)
64 {
65  FARPROC addr = GetProcAddress(lib, sym);
66  if (!addr) {
67  DWORD error = GetLastError();
68  *err = switch_mprintf("dll sym error [%ul]\n", error);
69  }
70  return (void *) (intptr_t) addr;
71 }
72 
73 
74 #else
75 /*
76 ** {========================================================================
77 ** This is an implementation of loadlib based on the dlfcn interface.
78 ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
79 ** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
80 ** as an emulation layer on top of native functions.
81 ** =========================================================================
82 */
83 
84 
85 #include <dlfcn.h>
86 
88 {
89  if (lib && *lib) {
90  dlclose(*lib);
91  *lib = NULL;
92  }
93 }
94 
95 switch_dso_lib_t switch_dso_open(const char *path, int global, char **err)
96 {
97  void *lib;
98 
99  if (global) {
100  lib = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
101  } else {
102  lib = dlopen(path, RTLD_NOW | RTLD_LOCAL);
103  }
104 
105  if (lib == NULL) {
106  const char *dlerr = dlerror();
107  /* Work around broken uclibc returning NULL on both dlopen() and dlerror() */
108  if (dlerr) {
109  *err = strdup(dlerr);
110  } else {
111  *err = strdup("Unknown error");
112  }
113  }
114  return lib;
115 }
116 
117 switch_dso_func_t switch_dso_func_sym(switch_dso_lib_t lib, const char *sym, char **err)
118 {
119  void *func = dlsym(lib, sym);
120  if (!func) {
121  *err = strdup(dlerror());
122  }
123  return (switch_dso_func_t) (intptr_t) func;
124 }
125 
126 void *switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err)
127 {
128  void *addr = dlsym(lib, sym);
129  if (!addr) {
130  char *err_str = NULL;
131  dlerror();
132 
133  if (!(addr = dlsym(lib, sym))) {
134  err_str = (char *)dlerror();
135  }
136 
137  if (err_str) {
138  *err = strdup(err_str);
139  }
140  }
141  return addr;
142 }
143 
144 #endif
145 /* }====================================================== */
146 
147 /* For Emacs:
148  * Local Variables:
149  * mode:c
150  * indent-tabs-mode:t
151  * tab-width:4
152  * c-basic-offset:4
153  * End:
154  * For VIM:
155  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet
156  */
switch_dso_lib_t switch_dso_open(const char *path, int global, char **err)
Definition: switch_dso.c:95
void switch_dso_destroy(switch_dso_lib_t *lib)
Definition: switch_dso.c:87
switch_dso_func_t switch_dso_func_sym(switch_dso_lib_t lib, const char *sym, char **err)
Definition: switch_dso.c:117
SWITCH_BEGIN_EXTERN_C typedef int(* switch_dso_func_t)(void)
Definition: switch_dso.h:26
void * switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err)
Definition: switch_dso.c:126
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,...)