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