1 /* GMODULE - GLIB wrapper code for dynamic module loading
2 * Copyright (C) 1998, 2000 Tim Janik
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 /* because we are compatible with archive format only since AIX 4.3 */
33 /* --- functions --- */
35 fetch_dlerror (gboolean replace_null
)
37 gchar
*msg
= dlerror ();
39 /* make sure we always return an error message != NULL, if
40 * expected to do so. */
42 if (!msg
&& replace_null
)
43 return "unknown dl-error";
48 static gchar
* _g_module_get_member(const gchar
* file_name
)
51 struct fl_hdr file_header
;
52 struct ar_hdr ar_header
;
57 fd
= open(file_name
, O_RDONLY
);
61 if (read(fd
, (void*)&file_header
, FL_HSZ
) != FL_HSZ
)
64 if (strncmp(file_header
.fl_magic
, AIAMAGBIG
, SAIAMAG
) != 0)
67 /* read first archive file member header */
69 first_member
= atol(file_header
.fl_fstmoff
);
71 if (lseek(fd
, first_member
, SEEK_SET
) != first_member
)
74 if (read(fd
, (void*)&ar_header
, AR_HSZ
- 2) != AR_HSZ
- 2)
77 /* read member name */
79 name_len
= atol(ar_header
.ar_namlen
);
81 member
= g_malloc(name_len
+1);
85 if (read(fd
, (void*)member
, name_len
) != name_len
)
101 _g_module_open (const gchar
*file_name
,
109 /* extract name of first member of archive */
111 member
= _g_module_get_member (file_name
);
114 full_name
= g_strconcat (file_name
, "(", member
, ")", NULL
);
118 full_name
= g_strdup (file_name
);
120 handle
= dlopen (full_name
,
121 (bind_local
? RTLD_LOCAL
: RTLD_GLOBAL
) | RTLD_MEMBER
| (bind_lazy
? RTLD_LAZY
: RTLD_NOW
));
126 g_module_set_error (fetch_dlerror (TRUE
));
132 _g_module_self (void)
136 handle
= dlopen (NULL
, RTLD_GLOBAL
| RTLD_LAZY
);
138 g_module_set_error (fetch_dlerror (TRUE
));
144 _g_module_close (gpointer handle
,
147 /* are there any systems out there that have dlopen()/dlclose()
148 * without a reference count implementation?
154 if (dlclose (handle
) != 0)
155 g_module_set_error (fetch_dlerror (TRUE
));
160 _g_module_symbol (gpointer handle
,
161 const gchar
*symbol_name
)
165 p
= dlsym (handle
, symbol_name
);
167 g_module_set_error (fetch_dlerror (FALSE
));
173 _g_module_build_path (const gchar
*directory
,
174 const gchar
*module_name
)
176 if (directory
&& *directory
) {
177 if (strncmp (module_name
, "lib", 3) == 0)
178 return g_strconcat (directory
, "/", module_name
, NULL
);
180 return g_strconcat (directory
, "/lib", module_name
, "." G_MODULE_SUFFIX
, NULL
);
181 } else if (strncmp (module_name
, "lib", 3) == 0)
182 return g_strdup (module_name
);
184 return g_strconcat ("lib", module_name
, "." G_MODULE_SUFFIX
, NULL
);