This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl5.000 patch.0i: fix glaring mistakes in patches a-h
[perl5.git] / ext / DynaLoader / dl_next.xs
CommitLineData
a0d0e21e
LW
1/* dl_next.xs
2 *
3 * Platform: NeXT NS 3.2
4 * Author: Anno Siegel (siegel@zrz.TU-Berlin.DE)
5 * Based on: dl_dlopen.xs by Paul Marquess
6 * Created: Aug 15th, 1994
7 *
8 */
9
10/*
11 And Gandalf said: 'Many folk like to know beforehand what is to
12 be set on the table; but those who have laboured to prepare the
13 feast like to keep their secret; for wonder makes the words of
14 praise louder.'
15*/
16
17/* Porting notes:
18
19dl_next.xs is itself a port from dl_dlopen.xs by Paul Marquess. It
20should not be used as a base for further ports though it may be used
21as an example for how dl_dlopen.xs can be ported to other platforms.
22
23The method used here is just to supply the sun style dlopen etc.
24functions in terms of NeXTs rld_*. The xs code proper is unchanged
25from Paul's original.
26
27The port could use some streamlining. For one, error handling could
28be simplified.
29
30Anno Siegel
31
32*/
33
34#include "EXTERN.h"
35#include "perl.h"
36#include "XSUB.h"
37
38#include "dlutils.c" /* SaveError() etc */
39
40
41#include <mach-o/rld.h>
42#include <streams/streams.h>
43
44static char * dl_last_error = (char *) 0;
45
46NXStream *
47OpenError()
48{
49 return NXOpenMemory( (char *) 0, 0, NX_WRITEONLY);
50}
51
52void
53TransferError( s)
54NXStream *s;
55{
56 char *buffer;
57 int len, maxlen;
58
59 if ( dl_last_error ) {
60 safefree(dl_last_error);
61 }
62 NXGetMemoryBuffer(s, &buffer, &len, &maxlen);
63 dl_last_error = safemalloc(len);
64 strcpy(dl_last_error, buffer);
65}
66
67void
68CloseError( s)
69NXStream *s;
70{
71 if ( s ) {
72 NXCloseMemory( s, NX_FREEBUFFER);
73 }
74}
75
76char *dlerror()
77{
78 return dl_last_error;
79}
80
81char *
82dlopen(path, mode)
83char * path;
84int mode; /* mode is ignored */
85{
86 int rld_success;
87 NXStream *nxerr = OpenError();
88 AV * av_resolve;
89 I32 i, psize;
90 char *result;
91 char **p;
92
93 av_resolve = GvAVn(gv_fetchpv(
94 "DynaLoader::dl_resolve_using", FALSE, SVt_PVAV));
95 psize = AvFILL(av_resolve) + 3;
96 p = (char **) safemalloc(psize * sizeof(char*));
97 p[0] = path;
98 for(i=1; i<psize-1; i++) {
99 p[i] = SvPVx(*av_fetch(av_resolve, i-1, TRUE), na);
100 }
101 p[psize-1] = 0;
102 rld_success = rld_load(nxerr, (struct mach_header **)0, p,
103 (const char *) 0);
104 safefree((char*) p);
105 if (rld_success) {
106 result = path;
107 } else {
108 TransferError(nxerr);
109 result = (char*) 0;
110 }
111 CloseError(nxerr);
112 return result;
113}
114
115int
116dlclose(handle) /* stub only */
117void *handle;
118{
119 return 0;
120}
121
122void *
123dlsym(handle, symbol)
124void *handle;
125char *symbol;
126{
127 NXStream *nxerr = OpenError();
128 char symbuf[1024];
129 unsigned long symref = 0;
130
131 sprintf(symbuf, "_%s", symbol);
132 if (!rld_lookup(nxerr, symbuf, &symref)) {
133 TransferError(nxerr);
134 }
135 CloseError(nxerr);
136 return (void*) symref;
137}
138
139
140/* ----- code from dl_dlopen.xs below here ----- */
141
142
143static void
144dl_private_init()
145{
146 (void)dl_generic_private_init();
147}
148
149MODULE = DynaLoader PACKAGE = DynaLoader
150
151BOOT:
152 (void)dl_private_init();
153
154
155
156void *
157dl_load_file(filename)
158 char * filename
159 CODE:
160 int mode = 1;
161 DLDEBUG(1,fprintf(stderr,"dl_load_file(%s):\n", filename));
162 RETVAL = dlopen(filename, mode) ;
163 DLDEBUG(2,fprintf(stderr," libref=%x\n", RETVAL));
164 ST(0) = sv_newmortal() ;
165 if (RETVAL == NULL)
166 SaveError("%s",dlerror()) ;
167 else
168 sv_setiv( ST(0), (IV)RETVAL);
169
170
171void *
172dl_find_symbol(libhandle, symbolname)
173 void * libhandle
174 char * symbolname
175 CODE:
176 DLDEBUG(2,fprintf(stderr,"dl_find_symbol(handle=%x, symbol=%s)\n",
177 libhandle, symbolname));
178 RETVAL = dlsym(libhandle, symbolname);
179 DLDEBUG(2,fprintf(stderr," symbolref = %x\n", RETVAL));
180 ST(0) = sv_newmortal() ;
181 if (RETVAL == NULL)
182 SaveError("%s",dlerror()) ;
183 else
184 sv_setiv( ST(0), (IV)RETVAL);
185
186
187void
188dl_undef_symbols()
189 PPCODE:
190
191
192
193# These functions should not need changing on any platform:
194
195void
196dl_install_xsub(perl_name, symref, filename="$Package")
197 char * perl_name
198 void * symref
199 char * filename
200 CODE:
201 DLDEBUG(2,fprintf(stderr,"dl_install_xsub(name=%s, symref=%x)\n",
202 perl_name, symref));
203 ST(0)=sv_2mortal(newRV((SV*)newXS(perl_name, (void(*)())symref, filename)));
204
205
206char *
207dl_error()
208 CODE:
209 RETVAL = LastError ;
210 OUTPUT:
211 RETVAL
212
213# end.