ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/libltdl/lt_dlloader.c
Revision: 1028
Committed: Sun Nov 8 13:03:38 2009 UTC (15 years, 9 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/libltdl/lt_dlloader.c
File size: 6046 byte(s)
Log Message:
- move ircd-hybrid-7.2 to trunk

File Contents

# User Rev Content
1 michael 945 /* lt_dlloader.c -- dynamic library loader interface
2    
3     Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc.
4     Written by Gary V. Vaughan, 2004
5    
6     NOTE: The canonical source of this file is maintained with the
7     GNU Libtool package. Report bugs to bug-libtool@gnu.org.
8    
9     GNU Libltdl is free software; you can redistribute it and/or
10     modify it under the terms of the GNU Lesser General Public
11     License as published by the Free Software Foundation; either
12     version 2 of the License, or (at your option) any later version.
13    
14     As a special exception to the GNU Lesser General Public License,
15     if you distribute this file as part of a program or library that
16     is built using GNU Libtool, you may include this file under the
17     same distribution terms that you use for the rest of that program.
18    
19     GNU Libltdl is distributed in the hope that it will be useful,
20     but WITHOUT ANY WARRANTY; without even the implied warranty of
21     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22     GNU Lesser General Public License for more details.
23    
24     You should have received a copy of the GNU Lesser General Public
25     License along with GNU Libltdl; see the file COPYING.LIB. If not, a
26     copy can be downloaded from http://www.gnu.org/licenses/lgpl.html,
27     or obtained by writing to the Free Software Foundation, Inc.,
28     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29     */
30    
31     #include "lt__private.h"
32     #include "lt_dlloader.h"
33    
34     #define RETURN_SUCCESS 0
35     #define RETURN_FAILURE 1
36    
37     static void * loader_callback (SList *item, void *userdata);
38    
39     /* A list of all the dlloaders we know about, each stored as a boxed
40     SList item: */
41     static SList *loaders = 0;
42    
43    
44     /* Return NULL, unless the loader in this ITEM has a matching name,
45     in which case we return the matching item so that its address is
46     passed back out (for possible freeing) by slist_remove. */
47     static void *
48     loader_callback (SList *item, void *userdata)
49     {
50     const lt_dlvtable *vtable = (const lt_dlvtable *) item->userdata;
51     const char * name = (const char *) userdata;
52    
53     assert (vtable);
54    
55     return streq (vtable->name, name) ? (void *) item : NULL;
56     }
57    
58    
59     /* Hook VTABLE into our global LOADERS list according to its own
60     PRIORITY field value. */
61     int
62     lt_dlloader_add (const lt_dlvtable *vtable)
63     {
64     SList *item;
65    
66     if ((vtable == 0) /* diagnose invalid vtable fields */
67     || (vtable->module_open == 0)
68     || (vtable->module_close == 0)
69     || (vtable->find_sym == 0)
70     || ((vtable->priority != LT_DLLOADER_PREPEND) &&
71     (vtable->priority != LT_DLLOADER_APPEND)))
72     {
73     LT__SETERROR (INVALID_LOADER);
74     return RETURN_FAILURE;
75     }
76    
77     item = slist_box (vtable);
78     if (!item)
79     {
80     (*lt__alloc_die) ();
81    
82     /* Let the caller know something went wrong if lt__alloc_die
83     doesn't abort. */
84     return RETURN_FAILURE;
85     }
86    
87     if (vtable->priority == LT_DLLOADER_PREPEND)
88     {
89     loaders = slist_cons (item, loaders);
90     }
91     else
92     {
93     assert (vtable->priority == LT_DLLOADER_APPEND);
94     loaders = slist_concat (loaders, item);
95     }
96    
97     return RETURN_SUCCESS;
98     }
99    
100     #ifdef LT_DEBUG_LOADERS
101     static void *
102     loader_dump_callback (SList *item, void *userdata)
103     {
104     const lt_dlvtable *vtable = (const lt_dlvtable *) item->userdata;
105     fprintf (stderr, ", %s", (vtable && vtable->name) ? vtable->name : "(null)");
106     return 0;
107     }
108    
109     void
110     lt_dlloader_dump (void)
111     {
112     fprintf (stderr, "loaders: ");
113     if (!loaders)
114     {
115     fprintf (stderr, "(empty)");
116     }
117     else
118     {
119     const lt_dlvtable *head = (const lt_dlvtable *) loaders->userdata;
120     fprintf (stderr, "%s", (head && head->name) ? head->name : "(null)");
121     if (slist_tail (loaders))
122     slist_foreach (slist_tail (loaders), loader_dump_callback, NULL);
123     }
124     fprintf (stderr, "\n");
125     }
126     #endif
127    
128     /* An iterator for the global loader list: if LOADER is NULL, then
129     return the first element, otherwise the following element. */
130     lt_dlloader
131     lt_dlloader_next (lt_dlloader loader)
132     {
133     SList *item = (SList *) loader;
134     return (lt_dlloader) (item ? item->next : loaders);
135     }
136    
137    
138     /* Non-destructive unboxing of a loader. */
139     const lt_dlvtable *
140     lt_dlloader_get (lt_dlloader loader)
141     {
142     return (const lt_dlvtable *) (loader ? ((SList *) loader)->userdata : NULL);
143     }
144    
145    
146     /* Return the contents of the first item in the global loader list
147     with a matching NAME after removing it from that list. If there
148     was no match, return NULL; if there is an error, return NULL and
149     set an error for lt_dlerror; do not set an error if only resident
150     modules need this loader; in either case, the loader list is not
151     changed if NULL is returned. */
152     lt_dlvtable *
153     lt_dlloader_remove (char *name)
154     {
155     const lt_dlvtable * vtable = lt_dlloader_find (name);
156     static const char id_string[] = "lt_dlloader_remove";
157     lt_dlinterface_id iface;
158     lt_dlhandle handle = 0;
159     int in_use = 0;
160     int in_use_by_resident = 0;
161    
162     if (!vtable)
163     {
164     LT__SETERROR (INVALID_LOADER);
165     return 0;
166     }
167    
168     /* Fail if there are any open modules which use this loader. */
169     iface = lt_dlinterface_register (id_string, NULL);
170     while ((handle = lt_dlhandle_iterate (iface, handle)))
171     {
172     lt_dlhandle cur = handle;
173     if (cur->vtable == vtable)
174     {
175     in_use = 1;
176     if (lt_dlisresident (handle))
177     in_use_by_resident = 1;
178     }
179     }
180     lt_dlinterface_free (iface);
181     if (in_use)
182     {
183     if (!in_use_by_resident)
184     LT__SETERROR (REMOVE_LOADER);
185     return 0;
186     }
187    
188     /* Call the loader finalisation function. */
189     if (vtable && vtable->dlloader_exit)
190     {
191     if ((*vtable->dlloader_exit) (vtable->dlloader_data) != 0)
192     {
193     /* If there is an exit function, and it returns non-zero
194     then it must set an error, and we will not remove it
195     from the list. */
196     return 0;
197     }
198     }
199    
200     /* If we got this far, remove the loader from our global list. */
201     return (lt_dlvtable *)
202     slist_unbox ((SList *) slist_remove (&loaders, loader_callback, name));
203     }
204    
205    
206     const lt_dlvtable *
207     lt_dlloader_find (char *name)
208     {
209     return lt_dlloader_get (slist_find (loaders, loader_callback, name));
210     }

Properties

Name Value
svn:eol-style native