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 */
32 /* --- functions --- */
34 fetch_dlerror (gboolean replace_null
)
36 gchar
*msg
= dlerror ();
38 /* make sure we always return an error message != NULL, if
39 * expected to do so. */
41 if (!msg
&& replace_null
)
42 return "unknown dl-error";
47 static gchar
* _g_module_get_member(const gchar
* file_name
)
50 struct fl_hdr file_header
;
51 struct ar_hdr ar_header
;
56 fd
= open(file_name
, O_RDONLY
);
60 if (read(fd
, (void*)&file_header
, FL_HSZ
) != FL_HSZ
)
63 if (strncmp(file_header
.fl_magic
, AIAMAGBIG
, SAIAMAG
) != 0)
66 /* read first archive file member header */
68 first_member
= atol(file_header
.fl_fstmoff
);
70 if (lseek(fd
, first_member
, SEEK_SET
) != first_member
)
73 if (read(fd
, (void*)&ar_header
, AR_HSZ
- 2) != AR_HSZ
- 2)
76 /* read member name */
78 name_len
= atol(ar_header
.ar_namlen
);
80 member
= g_malloc(name_len
+1);
84 if (read(fd
, (void*)member
, name_len
) != name_len
)
100 _g_module_open (const gchar
*file_name
,
108 /* extract name of first member of archive */
110 member
= _g_module_get_member (file_name
);
113 full_name
= g_strconcat (file_name
, "(", member
, ")", NULL
);
117 full_name
= g_strdup (file_name
);
119 handle
= dlopen (full_name
,
120 (bind_local
? RTLD_LOCAL
: RTLD_GLOBAL
) | RTLD_MEMBER
| (bind_lazy
? RTLD_LAZY
: RTLD_NOW
));
125 g_module_set_error (fetch_dlerror (TRUE
));
131 _g_module_self (void)
135 handle
= dlopen (NULL
, RTLD_GLOBAL
| RTLD_LAZY
);
137 g_module_set_error (fetch_dlerror (TRUE
));
143 _g_module_close (gpointer handle
,
146 /* are there any systems out there that have dlopen()/dlclose()
147 * without a reference count implementation?
153 if (dlclose (handle
) != 0)
154 g_module_set_error (fetch_dlerror (TRUE
));
159 _g_module_symbol (gpointer handle
,
160 const gchar
*symbol_name
)
164 p
= dlsym (handle
, symbol_name
);
166 g_module_set_error (fetch_dlerror (FALSE
));
172 _g_module_build_path (const gchar
*directory
,
173 const gchar
*module_name
)
175 if (directory
&& *directory
) {
176 if (strncmp (module_name
, "lib", 3) == 0)
177 return g_strconcat (directory
, "/", module_name
, NULL
);
179 return g_strconcat (directory
, "/lib", module_name
, "." G_MODULE_SUFFIX
, NULL
);
180 } else if (strncmp (module_name
, "lib", 3) == 0)
181 return g_strdup (module_name
);
183 return g_strconcat ("lib", module_name
, "." G_MODULE_SUFFIX
, NULL
);