Add braces to eliminate an ambiguous else warning.
[platform/upstream/glib.git] / gmodule / gmodule-dl.c
1 /* GMODULE - GLIB wrapper code for dynamic module loading
2  * Copyright (C) 1998 Tim Janik
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library 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.
8  *
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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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.
18  */
19
20 /* 
21  * MT safe
22  */
23
24 #include <dlfcn.h>
25
26 /* Perl includes <nlist.h> and <link.h> instead of <dlfcn.h> on some systmes? */
27
28
29 /* dlerror() is not implemented on all systems
30  */
31 #ifndef G_MODULE_HAVE_DLERROR
32 #  ifdef __NetBSD__
33 #    define dlerror()   g_strerror (errno)
34 #  else /* !__NetBSD__ */
35 /* could we rely on errno's state here? */
36 #    define dlerror()   "unknown dl-error"
37 #  endif /* !__NetBSD__ */
38 #endif  /* G_MODULE_HAVE_DLERROR */
39
40 /* some flags are missing on some systems, so we provide
41  * harmless defaults.
42  * The Perl sources say, RTLD_LAZY needs to be defined as (1),
43  * at least for Solaris 1.
44  *
45  * Mandatory:
46  * RTLD_LAZY   - resolve undefined symbols as code from the dynamic library
47  *               is executed.
48  * RTLD_NOW    - resolve all undefined symbols before dlopen returns, and fail
49  *               if this cannot be done.
50  * Optionally:
51  * RTLD_GLOBAL - the external symbols defined in the library will be made
52  *               available to subsequently loaded libraries.
53  */
54 #ifndef RTLD_GLOBAL
55 #define RTLD_GLOBAL     0
56 #endif  /* RTLD_GLOBAL */
57 #ifndef RTLD_LAZY
58 #define RTLD_LAZY       1
59 #endif  /* RTLD_LAZY */
60 #ifndef RTLD_NOW
61 #define RTLD_NOW        0
62 #endif  /* RTLD_NOW */
63
64
65 /* --- functions --- */
66 static gpointer
67 _g_module_open (const gchar    *file_name,
68                 gboolean        bind_lazy)
69 {
70   gpointer handle;
71   
72   handle = dlopen (file_name, RTLD_GLOBAL | (bind_lazy ? RTLD_LAZY : RTLD_NOW));
73   if (!handle)
74     g_module_set_error (dlerror ());
75   
76   return handle;
77 }
78
79 static gpointer
80 _g_module_self (void)
81 {
82   gpointer handle;
83   
84   /* to query symbols from the program itself, special link options
85    * are required on some systems.
86    */
87   
88   handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY);
89   if (!handle)
90     g_module_set_error (dlerror ());
91   
92   return handle;
93 }
94
95 static void
96 _g_module_close (gpointer         handle,
97                  gboolean         is_unref)
98 {
99   /* are there any systems out there that have dlopen()/dlclose()
100    * without a reference count implementation?
101    */
102   is_unref |= 1;
103   
104   if (is_unref)
105     {
106       if (dlclose (handle) != 0)
107         g_module_set_error (dlerror ());
108     }
109 }
110
111 static gpointer
112 _g_module_symbol (gpointer        handle,
113                   const gchar    *symbol_name)
114 {
115   gpointer p;
116   
117   p = dlsym (handle, symbol_name);
118   if (!p)
119     g_module_set_error (dlerror ());
120   
121   return p;
122 }
123
124 static gchar*
125 _g_module_build_path (const gchar *directory,
126                       const gchar *module_name)
127 {
128   if (directory && *directory) {
129     if (strncmp (module_name, "lib", 3) == 0)
130       return g_strconcat (directory, "/", module_name, NULL);
131     else
132       return g_strconcat (directory, "/lib", module_name, ".so", NULL);
133   } else if (strncmp (module_name, "lib", 3) == 0)
134     return g_strdup (module_name);
135   else
136     return g_strconcat ("lib", module_name, ".so", NULL);
137 }