1 /* @(#)dlfcn.c 1.3 18/03/21 Copyright 2014-2018 J. Schilling */
2 /*
3 * Functions to support POSIX shared library handling
4 *
5 * Copyright (c) 2014-2018 J. Schilling
6 */
7 /*
8 * The contents of this file are subject to the terms of the
9 * Common Development and Distribution License, Version 1.0 only
10 * (the "License"). You may not use this file except in compliance
11 * with the License.
12 *
13 * See the file CDDL.Schily.txt in this distribution for details.
14 * A copy of the CDDL is also available via the Internet at
15 * http://www.opensource.org/licenses/cddl1.txt
16 *
17 * When distributing Covered Code, include this CDDL HEADER in each
18 * file and include the License file CDDL.Schily.txt from this distribution.
19 */
20
21 #include <schily/standard.h>
22 #include <schily/dlfcn.h>
23 #include <schily/errno.h>
24
25 #ifndef HAVE_DLOPEN
26
27 #if !defined(DID_DLOPEN) && defined(HAVE_LOADLIBRARY) /* Win-DOS */
28 #define DID_DLOPEN
29
30 #include <schily/windows.h>
31
32 LOCAL int _dl_lasterror;
33
34 EXPORT void *
dlopen(pathname,mode)35 dlopen(pathname, mode)
36 const char *pathname;
37 int mode;
38 {
39 void *ret = NULL;
40
41 /*
42 * Nur eine Directory, kein PATH:
43 *
44 * BOOL SetDllDirectory(char *pathname)
45 * DWORD GetDllDirectory(DWORD nBufferLength, LPTSTR lpBuffer) -> len
46 */
47 ret = LoadLibrary(pathname);
48 if (ret == NULL)
49 _dl_lasterror = GetLastError();
50
51 return (ret);
52 }
53
54 EXPORT int
dlclose(handle)55 dlclose(handle)
56 void *handle;
57 {
58 int ret = 0;
59
60 if (!FreeLibrary(handle)) {
61 _dl_lasterror = GetLastError();
62 ret = -1;
63 }
64
65 return (ret);
66 }
67
68 EXPORT void *
dlsym(handle,name)69 dlsym(handle, name)
70 void *handle;
71 const char *name;
72 {
73 void *ret = NULL;
74
75 ret = GetProcAddress(handle, name);
76 if (ret == NULL)
77 _dl_lasterror = GetLastError();
78
79 return (ret);
80 }
81
82 #define ERROR_BUFFER_SIZE 1024
83 EXPORT char *
dlerror()84 dlerror()
85 {
86 char *ret = NULL;
87 DWORD dwMsgLen;
88 static char buff[ERROR_BUFFER_SIZE + 1];
89
90 if (_dl_lasterror == 0)
91 return (ret);
92
93 buff[0] = 0;
94 dwMsgLen = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
95 |FORMAT_MESSAGE_IGNORE_INSERTS
96 |FORMAT_MESSAGE_MAX_WIDTH_MASK,
97 NULL,
98 _dl_lasterror,
99 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
100 (LPSTR)buff,
101 ERROR_BUFFER_SIZE,
102 NULL);
103 _dl_lasterror = 0;
104 ret = buff;
105
106 return (ret);
107 }
108
109 #endif /* HAVE_LOADLOBRARY */
110
111 #if !defined(DID_DLOPEN) && defined(HAVE_SHL_LOAD) /* HP-UX */
112 #define DID_DLOPEN
113
114 #include <schily/string.h> /* for sterror() */
115
116 LOCAL int _dl_lasterror;
117
118 EXPORT void *
dlopen(pathname,mode)119 dlopen(pathname, mode)
120 const char *pathname;
121 int mode;
122 {
123 void *ret;
124 int flags = BIND_IMMEDIATE;
125
126 if (mode == RTLD_LAZY)
127 flags = BIND_DEFERRED;
128
129 ret = shl_load(pathname, flags, 0L);
130 if (ret == NULL)
131 _dl_lasterror = errno;
132
133 return (ret);
134 }
135
136 EXPORT int
dlclose(handle)137 dlclose(handle)
138 void *handle;
139 {
140 return (shl_unload(handle));
141 }
142
143 EXPORT void *
dlsym(handle,name)144 dlsym(handle, name)
145 void *handle;
146 const char *name;
147 {
148 void *ret = NULL;
149
150 if (shl_findsym(handle, name, TYPE_UNDEFINED, &ret) != 0)
151 _dl_lasterror = errno;
152
153 return (ret);
154 }
155
156 EXPORT char *
dlerror()157 dlerror()
158 {
159 char *ret = NULL;
160
161 if (_dl_lasterror == 0)
162 return (ret);
163 ret = strerror(_dl_lasterror);
164 _dl_lasterror = 0;
165
166 return (ret);
167 }
168
169 #endif /* HAVE_SHL_LOAD */
170
171 #if !defined(DID_DLOPEN) /* unknown OS */
172 #define DID_DLOPEN
173
174 /*
175 * If we do not have dlopen(), we at least need to define a
176 * dummy function of that name.
177 */
178
179 EXPORT void *
dlopen(pathname,mode)180 dlopen(pathname, mode)
181 const char *pathname;
182 int mode;
183 {
184 void *ret = NULL;
185
186 return (ret);
187 }
188
189 EXPORT int
dlclose(handle)190 dlclose(handle)
191 void *handle;
192 {
193 int ret = 0;
194
195 return (ret);
196 }
197
198 EXPORT void *
dlsym(handle,name)199 dlsym(handle, name)
200 void *handle;
201 const char *name;
202 {
203 void *ret = NULL;
204
205 return (ret);
206 }
207
208 EXPORT char *
dlerror()209 dlerror()
210 {
211 char *ret = NULL;
212
213 return (ret);
214 }
215
216 #endif /* HAVE_SHL_LOAD */
217
218
219 #else /* HAVE_DLOPEN */
220 #endif /* HAVE_DLOPEN */
221