source: roaraudio/libroar/roardl.c @ 3367:c20f7b4fbd0f

Last change on this file since 3367:c20f7b4fbd0f was 3367:c20f7b4fbd0f, checked in by phi, 14 years ago

we try our self RTLD_NEXT if we do not find one

File size: 4.4 KB
Line 
1//roardl.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *  NOTE for everyone want's to change something and send patches:
24 *  read README and HACKING! There a addition information on
25 *  the license of this document you need to read before you send
26 *  any patches.
27 *
28 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
29 *  or libpulse*:
30 *  The libs libroaresd, libroararts and libroarpulse link this lib
31 *  and are therefore GPL. Because of this it may be illigal to use
32 *  them with any software that uses libesd, libartsc or libpulse*.
33 */
34
35#include "libroar.h"
36
37#if defined(ROAR_HAVE_LIBDL) && !defined(RTLD_NEXT)
38#define RTLD_NEXT ((void *) -1L)
39#endif
40
41#if defined(ROAR_HAVE_LIBDL)
42static void * _roardl2ldl (struct roar_dl_lhandle * lhandle) {
43 if ( lhandle == ROAR_DL_HANDLE_DEFAULT )
44  return RTLD_DEFAULT;
45
46 if ( lhandle == ROAR_DL_HANDLE_NEXT )
47  return RTLD_NEXT;
48
49 return lhandle->handle;
50}
51#endif
52
53struct roar_dl_lhandle * roar_dl_open(const char * filename, int flags, int ra_init) {
54 struct roar_dl_lhandle * ret = NULL;
55
56 // early errors just return.
57
58 if ( flags != ROAR_DL_FLAG_DEFAUTS )
59  return NULL;
60
61 if ( (ret = roar_mm_malloc(sizeof(struct roar_dl_lhandle))) == NULL )
62  return NULL;
63
64 memset(ret, 0, sizeof(struct roar_dl_lhandle));
65
66#if defined(ROAR_HAVE_LIBDL)
67 flags  = RTLD_NOW;
68
69#ifdef RTLD_DEEPBIND
70 flags |= RTLD_DEEPBIND;
71#endif
72
73 ret->handle = dlopen(filename, flags);
74
75 if ( ret->handle == NULL ) {
76  roar_mm_free(ret);
77  return NULL;
78 }
79#else
80 roar_mm_free(ret);
81 return NULL;
82#endif
83
84 if ( ret == NULL )
85  return NULL;
86
87 if ( ra_init ) {
88  roar_dl_ra_init(ret, NULL);
89 }
90
91 return ret;
92}
93
94int                      roar_dl_close(struct roar_dl_lhandle * lhandle) {
95 int ret = -1;
96
97 if ( lhandle == ROAR_DL_HANDLE_DEFAULT )
98  return -1;
99 if ( lhandle == ROAR_DL_HANDLE_NEXT )
100  return -1;
101
102 if ( lhandle->lib != NULL && lhandle->lib->unload != NULL )
103  lhandle->lib->unload(lhandle->para, lhandle->lib);
104
105#if defined(ROAR_HAVE_LIBDL)
106 ret = dlclose(_roardl2ldl(lhandle));
107#else
108 ret = -1;
109#endif
110
111 roar_mm_free(lhandle);
112
113 return ret;
114}
115
116void                   * roar_dl_getsym(struct roar_dl_lhandle * lhandle, const char * sym, int type) {
117#if defined(ROAR_HAVE_LIBDL)
118 return dlsym(_roardl2ldl(lhandle), sym);
119#else
120 return NULL;
121#endif
122}
123
124int                      roar_dl_ra_init(struct roar_dl_lhandle * lhandle, const char * prefix) {
125#define _SUFFIX "_roaraudio_library_init"
126 char name[80] = _SUFFIX;
127 struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para);
128 struct roar_dl_libraryinst * lib;
129 struct roar_dl_librarypara * para = NULL;
130 int i;
131
132 if ( (void*)lhandle < (void*)128 ) {
133  if ( prefix == NULL )
134   return -1;
135 } else {
136  para = lhandle->para;
137 }
138
139
140 if ( prefix != NULL ) {
141  strcpy(name, "_");
142  strcat(name, prefix);
143  strcat(name, _SUFFIX);
144 }
145
146 ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s'): name='%s'", lhandle, prefix, name);
147
148 if ( (func = roar_dl_getsym(lhandle, name, -1)) == NULL )
149  return -1;
150
151 ROAR_DBG("roar_dl_ra_init(lhandle=%p, prefix='%s'): func=%p", lhandle, prefix, func);
152
153 lib = func(para);
154
155 if ( lib == NULL )
156  return -1;
157
158 if ( lib->version != ROAR_DL_LIBINST_VERSION )
159  return -1;
160
161 if ( sizeof(struct roar_dl_libraryinst) > lib->len )
162  return -1;
163
164 if ( !((void*)lhandle < (void*)128) ) {
165  lhandle->lib = lib;
166 }
167
168 for (i = 0; i < ROAR_DL_FN_MAX; i++) {
169  if ( lib->func[i] != NULL )
170   lib->func[i](para, lib);
171 }
172
173 return 0;
174}
175
176char *                   roar_dl_errstr(struct roar_dl_lhandle * lhandle) {
177#if defined(ROAR_HAVE_LIBDL)
178 return dlerror();
179#else
180 return NULL;
181#endif
182}
183
184//ll
Note: See TracBrowser for help on using the repository browser.