Mercurial > pub > dyncall > dyncall
comparison dynload/dynload_unix.c @ 248:ab23f9f2934a
- BeOS impl for dlGetLibraryPath
- more dynload doc clarifications
author | Tassilo Philipp |
---|---|
date | Fri, 05 May 2017 13:13:43 +0200 |
parents | 06a354b2e120 |
children | 5cfe4322c500 |
comparison
equal
deleted
inserted
replaced
247:446d2220bc49 | 248:ab23f9f2934a |
---|---|
112 } | 112 } |
113 | 113 |
114 return l+1; /* strlen + '\0' */ | 114 return l+1; /* strlen + '\0' */ |
115 } | 115 } |
116 | 116 |
117 #else /* non-Darwin --> */ | 117 #elif defined(OS_OpenBSD) /* doesn't have dlinfo() but dl_iterate_phdr() --> */ |
118 | |
119 #if defined(OS_OpenBSD) /* doesn't have dlinfo() but dl_iterate_phdr() --> */ | |
120 | 118 |
121 /* @@@ dl_iterate_phdr() only exists on OpenBSD >= 3.7 */ | 119 /* @@@ dl_iterate_phdr() only exists on OpenBSD >= 3.7 */ |
122 | 120 |
123 #include <sys/types.h> | 121 #include <sys/types.h> |
124 #include <link.h> | 122 #include <link.h> |
152 { | 150 { |
153 iter_phdr_data d = { pLib, sOut, bufSize }; | 151 iter_phdr_data d = { pLib, sOut, bufSize }; |
154 return dl_iterate_phdr(iter_phdr_cb, &d); | 152 return dl_iterate_phdr(iter_phdr_cb, &d); |
155 } | 153 } |
156 | 154 |
155 #elif defined(OS_BeOS) /* neither dlinfo(), nor dl_iterate_phdr(), but ltdl stuff*/ | |
156 | |
157 #if 0 | |
158 #include <ltdl.h> | |
159 | |
160 typedef struct { // @@@share | |
161 DLLib* pLib; | |
162 char* sOut; | |
163 int bufSize; | |
164 } iter_phdr_data; | |
165 | |
166 static int handle_map_cb(lt_dlhandle h, void* data) | |
167 { | |
168 int l = -1; | |
169 iter_phdr_data* d = (iter_phdr_data*)data; | |
170 /* same idea as with dl_iterate_phdr, see above */ | |
171 const lt_dlinfo* dli = lt_dlgetinfo(h); | |
172 if(dli) { | |
173 void* lib = dlopen(dli->filename, RTLD_LIGHTEST); | |
174 if(lib) { | |
175 dlclose(lib); | |
176 if(lib == (void*)d->pLib) { | |
177 l = strlen(dli->filename); | |
178 if(l < d->bufSize) /* l+'\0' <= bufSize */ | |
179 strcpy(d->sOut, dli->filename); | |
180 } | |
181 } | |
182 } | |
183 return l+1; /* strlen + '\0'; is 0 if lib not found, which continues iter */ | |
184 } | |
185 | |
186 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) | |
187 { | |
188 iter_phdr_data d = { pLib, sOut, bufSize }; | |
189 lt_dlinterface_id ii = lt_dlinterface_register("not_sure_here...", NULL); | |
190 int l = lt_dlhandle_map(ii, handle_map_cb, &d); | |
191 lt_dlinterface_free(ii); | |
192 return l; | |
193 } | |
194 #endif | |
195 | |
196 /* we have lt_dlgetinfo on BeOS, which requires iterating over ltdl stuff, */ | |
197 /* but was unable to get that to work (would also have introduced a link */ | |
198 /* dependency on libltdl); so do a hacky dladdr() based attempt, instead, */ | |
199 /* which might not always work, but probably is ok for nearly all libs */ | |
200 | |
201 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) | |
202 { | |
203 /* BeOS uses ELF, cross fingers that .so is standard and look for _fini */ | |
204 int l = -1; | |
205 void* s = dlsym((void*)pLib, "_fini"); | |
206 if(s) { | |
207 Dl_info i; | |
208 if(dladdr(s, &i) != 0) { | |
209 l = strlen(i.dli_fname); | |
210 if(l < bufSize) /* l+'\0' <= bufSize */ | |
211 strcpy(sOut, i.dli_fname); | |
212 } | |
213 } | |
214 return l+1; /* strlen + '\0' */ | |
215 } | |
216 | |
157 #else /* use dlinfo() --> */ | 217 #else /* use dlinfo() --> */ |
158 | 218 |
159 #include <link.h> | 219 #include <link.h> |
160 | 220 |
161 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) | 221 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) |
170 return l+1; /* strlen + '\0' */ | 230 return l+1; /* strlen + '\0' */ |
171 } | 231 } |
172 | 232 |
173 #endif | 233 #endif |
174 | 234 |
175 #endif | |
176 |