Merge r21-4-13-chise-b1.
[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 <stdlib.h>
27 #include "lisp.h"
28 #include "sysdll.h"
29
30 /* This whole file is conditional upon HAVE_SHLIB */
31 #ifdef HAVE_SHLIB
32
33 /* Thankfully, most systems follow the ELFish dlopen() method.
34 */
35 #if defined(HAVE_DLOPEN)
36 #include <dlfcn.h>
37
38 #ifndef RTLD_LAZY
39 # define RTLD_LAZY 1
40 #endif /* RTLD_LAZY isn't defined under FreeBSD - ick */
41
42 #ifndef RTLD_NOW
43 # define RTLD_NOW 2
44 #endif
45
46 int
47 dll_init (const char *arg)
48 {
49   return 0;
50 }
51
52 dll_handle
53 dll_open (const char *fname)
54 {
55   return (dll_handle) dlopen (fname, RTLD_NOW);
56 }
57
58 int
59 dll_close (dll_handle h)
60 {
61   return dlclose ((void *) h);
62 }
63
64 dll_func
65 dll_function (dll_handle h, const char *n)
66 {
67 #ifdef DLSYM_NEEDS_UNDERSCORE
68   char *buf = alloca_array (char, strlen (n) + 2);
69   *buf = '_';
70   strcpy (buf + 1, n);
71   n = buf;
72 #endif
73   return (dll_func) dlsym ((void *) h, n);
74 }
75
76 dll_var
77 dll_variable (dll_handle h, const char *n)
78 {
79 #ifdef DLSYM_NEEDS_UNDERSCORE
80   char *buf = alloca_array (char, strlen (n) + 2);
81   *buf = '_';
82   strcpy (buf + 1, n);
83   n = buf;
84 #endif
85   return (dll_var)dlsym ((void *)h, n);
86 }
87
88 const char *
89 dll_error (dll_handle h)
90 {
91 #if defined(HAVE_DLERROR) || defined(dlerror)
92   return (const char *) dlerror ();
93 #elif defined(HAVE__DLERROR)
94   return (const char *) _dlerror();
95 #else
96   return "Shared library error";
97 #endif
98 }
99
100 #elif defined(HAVE_SHL_LOAD)
101 /* This is the HP/UX version */
102 #include <dl.h>
103 int
104 dll_init (const char *arg)
105 {
106   return 0;
107 }
108
109 dll_handle
110 dll_open (const char *fname)
111 {
112   /* shl_load will hang hard if passed a NULL fname. */
113   if (fname == NULL) return NULL;
114
115   return (dll_handle) shl_load (fname, BIND_DEFERRED,0L);
116 }
117
118 int
119 dll_close (dll_handle h)
120 {
121   return shl_unload ((shl_t) h);
122 }
123
124 dll_func
125 dll_function (dll_handle h, const char *n)
126 {
127   long handle = 0L;
128
129   if (shl_findsym ((shl_t *) &h, n, TYPE_PROCEDURE, &handle))
130     return NULL;
131
132   return (dll_func) handle;
133 }
134
135 dll_var
136 dll_variable (dll_handle h, const char *n)
137 {
138   long handle = 0L;
139
140   if (shl_findsym ((shl_t *) &h, n, TYPE_DATA, &handle))
141     return NULL;
142
143   return (dll_var) handle;
144 }
145
146 const char *
147 dll_error (dll_handle h)
148 {
149   /* #### WTF?!  Shouldn't this at least attempt to get strerror or
150      something?  --hniksic */
151   return "Generic shared library error";
152 }
153
154 #elif defined(HAVE_INIT_DLD)
155 #include <dld.h>
156 int
157 dll_init (const char *arg)
158 {
159   char *real_exe = dld_find_executable (arg);
160   int rc;
161
162   rc = dld_init (real_exe);
163   if (rc)
164     {
165       dld_perror (exe);
166       return -1;
167     }
168   return 0;
169 }
170
171 dll_handle
172 dll_open (const char *fname)
173 {
174   rc = dld_link (fname);
175   if (rc)
176     return NULL;
177
178   return (dll_handle) 1;
179 }
180
181 int
182 dll_close (dll_handle h)
183 {
184   /* *sigh* DLD is pretty lame and doesn't return a handle that you can use
185   ** later on to free the file - you have to remember the filename and
186   ** use that as the unlinker.  We should eventually keep a linked list
187   ** of loaded modules and then use the node pointer as the unique id
188   ** for the shared library.  Wheeee.  But not now.
189   */
190   return 1;
191 }
192
193 DLL_FUNC
194 dll_function (dll_handle h, const char *n)
195 {
196   return dld_get_func (n);
197 }
198
199 DLL_FUNC
200 dll_variable (dll_handle h, const char *n)
201 {
202   return dld_get_symbol (n);
203 }
204 #elif defined (WIN32_NATIVE)
205
206 #define WIN32_LEAN_AND_MEAN
207 #include <windows.h>
208 #undef WIN32_LEAN_AND_MEAN
209
210 int
211 dll_init (const char *arg)
212 {
213   return 0;
214 }
215
216 dll_handle
217 dll_open (const char *fname)
218 {
219   return (dll_handle) LoadLibrary (fname);
220 }
221
222 int
223 dll_close (dll_handle h)
224 {
225   return FreeLibrary (h);
226 }
227
228 dll_func
229 dll_function (dll_handle h, const char *n)
230 {
231   return (dll_func) GetProcAddress (h, n);
232 }
233
234 dll_func
235 dll_variable (dll_handle h, const char *n)
236 {
237   return (dll_func) GetProcAddress (h, n);
238 }
239
240 const char *
241 dll_error (dll_handle h)
242 {
243   return "Windows DLL Error";
244 }
245 #else
246 /* Catchall if we don't know about this systems method of dynamic loading */
247 int
248 dll_init (const char *arg)
249 {
250   return -1;
251 }
252
253 dll_handle
254 dll_open (const char *fname)
255 {
256   return NULL;
257 }
258
259 int
260 dll_close (dll_handle h)
261 {
262   return 0;
263 }
264
265 dll_func
266 dll_function (dll_handle h, const char *n)
267 {
268   return NULL;
269 }
270
271 dll_func
272 dll_variable (dll_handle h, const char *n)
273 {
274   return NULL;
275 }
276
277 const char *
278 dll_error (dll_handle h)
279 {
280   return "Shared libraries not implemented on this system";
281 }
282 #endif /* System conditionals */
283
284 #endif /* HAVE_SHLIB */