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