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 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, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
24 /* because we are compatible with archive format only since AIX 4.3 */
35 /* --- functions --- */
37 fetch_dlerror (gboolean replace_null
)
39 gchar
*msg
= dlerror ();
41 /* make sure we always return an error message != NULL, if
42 * expected to do so. */
44 if (!msg
&& replace_null
)
45 return "unknown dl-error";
50 static gchar
* _g_module_get_member(const gchar
* file_name
)
53 struct fl_hdr file_header
;
54 struct ar_hdr ar_header
;
59 fd
= open(file_name
, O_RDONLY
);
63 if (read(fd
, (void*)&file_header
, FL_HSZ
) != FL_HSZ
)
66 if (strncmp(file_header
.fl_magic
, AIAMAGBIG
, SAIAMAG
) != 0)
69 /* read first archive file member header */
71 first_member
= atol(file_header
.fl_fstmoff
);
73 if (lseek(fd
, first_member
, SEEK_SET
) != first_member
)
76 if (read(fd
, (void*)&ar_header
, AR_HSZ
- 2) != AR_HSZ
- 2)
79 /* read member name */
81 name_len
= atol(ar_header
.ar_namlen
);
83 member
= g_malloc(name_len
+1);
87 if (read(fd
, (void*)member
, name_len
) != name_len
)
103 _g_module_open (const gchar
*file_name
,
111 /* extract name of first member of archive */
113 member
= _g_module_get_member (file_name
);
116 full_name
= g_strconcat (file_name
, "(", member
, ")", NULL
);
120 full_name
= g_strdup (file_name
);
122 handle
= dlopen (full_name
,
123 (bind_local
? RTLD_LOCAL
: RTLD_GLOBAL
) | RTLD_MEMBER
| (bind_lazy
? RTLD_LAZY
: RTLD_NOW
));
128 g_module_set_error (fetch_dlerror (TRUE
));
134 _g_module_self (void)
138 handle
= dlopen (NULL
, RTLD_GLOBAL
| RTLD_LAZY
);
140 g_module_set_error (fetch_dlerror (TRUE
));
146 _g_module_close (gpointer handle
,
149 /* are there any systems out there that have dlopen()/dlclose()
150 * without a reference count implementation?
156 if (dlclose (handle
) != 0)
157 g_module_set_error (fetch_dlerror (TRUE
));
162 _g_module_symbol (gpointer handle
,
163 const gchar
*symbol_name
)
167 p
= dlsym (handle
, symbol_name
);
169 g_module_set_error (fetch_dlerror (FALSE
));
175 _g_module_build_path (const gchar
*directory
,
176 const gchar
*module_name
)
178 if (directory
&& *directory
) {
179 if (strncmp (module_name
, "lib", 3) == 0)
180 return g_strconcat (directory
, "/", module_name
, NULL
);
182 return g_strconcat (directory
, "/lib", module_name
, "." G_MODULE_SUFFIX
, NULL
);
183 } else if (strncmp (module_name
, "lib", 3) == 0)
184 return g_strdup (module_name
);
186 return g_strconcat ("lib", module_name
, "." G_MODULE_SUFFIX
, NULL
);