XEmacs 21.2.13
[chise/xemacs-chise.git.1] / src / sysdll.c
1 /* sysdll.c --- system dependent support for dynamic linked libraries
2    Copyright (C) 1998 Free Software Foundation, Inc.
3    Author:  William Perry <wmperry@aventail.com>
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING.  If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "sysdll.h"
27
28 /* This whole file is conditional upon HAVE_SHLIB */
29 #ifdef HAVE_SHLIB
30
31 /* Thankfully, most systems follow the ELFish dlopen() method.
32 ** HAVE__DLOPEN is lame, but SCO has their dl* functions as _dl*, and
33 ** unless you include dlfcn.h you don't get the macros to mask them, and
34 ** autoconf fails to find them. No longer true as of 5.0.5.
35 **
36 ** Anybody who wants to use this on SCO needs to have their configure.in
37 ** look for _dlopen() as well as dlopen()
38 */
39 #if defined(HAVE_DLOPEN) || defined(HAVE__DLOPEN) || defined(HAVE_DLFCN_H)
40 #include <dlfcn.h>
41
42 #ifndef RTLD_LAZY
43 # define RTLD_LAZY 1
44 #endif /* RTLD_LAZY isn't defined under FreeBSD - ick */
45
46 #ifndef RTLD_GLOBAL
47 # define RTLD_GLOBAL 0
48 #endif
49
50 int
51 dll_init (CONST char *arg)
52 {
53   return 0;
54 }
55
56 dll_handle
57 dll_open (CONST char *fname)
58 {
59   return (dll_handle)dlopen (fname, RTLD_LAZY | RTLD_GLOBAL);
60 }
61
62 int
63 dll_close (dll_handle h)
64 {
65   return dlclose((void *)h);
66 }
67
68 dll_func
69 dll_function (dll_handle h, CONST char *n)
70 {
71 #ifdef DLSYM_NEEDS_UNDERSCORE
72   char *buf = alloca_array (char, strlen (n) + 2);
73   *buf = '_';
74   (void)strcpy(buf + 1, n);
75   n = buf;
76 #endif
77   return (dll_func)dlsym ((void *)h, n);
78 }
79
80 dll_var
81 dll_variable (dll_handle h, CONST char *n)
82 {
83 #ifdef DLSYM_NEEDS_UNDERSCORE
84   char *buf = alloca_array (char, strlen (n) + 2);
85   *buf = '_';
86   (void)strcpy(buf + 1, n);
87   n = buf;
88 #endif
89   return (dll_var)dlsym ((void *)h, n);
90 }
91
92 CONST char *
93 dll_error (dll_handle h)
94 {
95 #if defined(HAVE_DLERROR) || defined(dlerror)
96   return (CONST char *)dlerror ();
97 #elif defined(HAVE__DLERROR)
98   return (const char *)_dlerror();
99 #else
100   return "Shared library error";
101 #endif
102 }
103
104 #elif defined(HAVE_SHL_LOAD)
105 /* This is the HP/UX version */
106 #include <dl.h>
107 int
108 dll_init (CONST char *arg)
109 {
110   return 0;
111 }
112
113 dll_handle
114 dll_open (CONST char *fname)
115 {
116   shl_t h = shl_load (fname, BIND_DEFERRED,0L);
117   shl_t *hp = NULL;
118
119   if (h)
120     {
121       hp = (shl_t *)malloc (sizeof (shl_t));
122       if (!hp)
123         shl_unload(h);
124       else
125         *hp = h;
126     }
127   return (dll_handle)hp;
128 }
129
130 int
131 dll_close (dll_handle h)
132 {
133   shl_t hp = *((shl_t *)h);
134   free (hp);
135   return shl_unload(h);
136 }
137
138 dll_func
139 dll_function (dll_handle h, CONST char *n)
140 {
141   long handle = 0L;
142
143   if (shl_findsym ((shl_t *)h, n, TYPE_PROCEDURE, &handle))
144     return NULL;
145
146   return (dll_func)handle;
147 }
148
149 dll_var
150 dll_variable (dll_handle h, CONST char *n)
151 {
152   long handle = 0L;
153
154   if (shl_findsym ((shl_t *)h, n, TYPE_DATA, &handle))
155     return NULL;
156
157   return (dll_var)handle;
158 }
159
160 CONST char *
161 dll_error (dll_handle h)
162 {
163   /* #### WTF?!  Shouldn't this at least attempt to get strerror or
164      something?  --hniksic */
165   return "Generic shared library error";
166 }
167
168 #elif defined(HAVE_INIT_DLD)
169 #include <dld.h>
170 int
171 dll_init (CONST char *arg)
172 {
173   char *real_exe = dld_find_executable (arg);
174   int rc;
175
176   rc = dld_init (real_exe);
177   if (rc)
178     {
179       dld_perror (exe);
180       return -1;
181     }
182   return 0;
183 }
184
185 dll_handle
186 dll_open (CONST char *fname)
187 {
188   rc = dld_link (fname);
189   if (rc)
190     return NULL;
191
192   return (dll_handle)1;
193 }
194
195 int
196 dll_close (dll_handle h)
197 {
198   /* *sigh* DLD is pretty lame and doesn't return a handle that you can use
199   ** later on to free the file - you have to remember the filename and
200   ** use that as the unlinker.  We should eventually keep a linked list
201   ** of loaded modules and then use the node pointer as the unique id
202   ** for the shared library.  Wheeee.  But not now.
203   */
204   return 1;
205 }
206
207 DLL_FUNC
208 dll_function (dll_handle h, CONST char *n)
209 {
210   return dld_get_func(n);
211 }
212
213 DLL_FUNC
214 dll_variable (dll_handle h, CONST char *n)
215 {
216   return dld_get_symbol(n);
217 }
218 #elif defined(_WINDOWS) || defined(WIN32)
219 int
220 dll_init (CONST char *arg)
221 {
222   return 0;
223 }
224
225 dll_handle
226 dll_open (CONST char *fname)
227 {
228   return (dll_handle)LoadLibrary (fname);
229 }
230
231 int
232 dll_close (dll_handle h)
233 {
234   return FreeLibrary (h);
235 }
236
237 dll_func
238 dll_function (dll_handle h, CONST char *n)
239 {
240   return (dll_func)GetProcAddress (h,n);
241 }
242
243 dll_func
244 dll_variable (dll_handle h, CONST char *n)
245 {
246   return (dll_func)GetProcAddress (h,n);
247 }
248
249 CONST char *
250 dll_error (dll_handle h)
251 {
252   return "Windows DLL Error";
253 }
254 #else
255 /* Catchall if we don't know about this systems method of dynamic loading */
256 int
257 dll_init (CONST char *arg)
258 {
259   return -1;
260 }
261
262 dll_handle
263 dll_open (CONST char *fname)
264 {
265   return NULL;
266 }
267
268 int
269 dll_close (dll_handle h)
270 {
271   return 0;
272 }
273
274 dll_func
275 dll_function (dll_handle h, CONST char *n)
276 {
277   return NULL;
278 }
279
280 dll_func
281 dll_variable (dll_handle h, CONST char *n)
282 {
283   return NULL;
284 }
285
286 CONST char *
287 dll_error (dll_handle h)
288 {
289   return "Shared libraries not implemented on this system";
290 }
291 #endif /* System conditionals */
292
293 #endif /* HAVE_SHLIB */