ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/libltdl/lt_dlloader.c
Revision: 10082
Committed: Sat Jun 11 11:40:12 2022 UTC (22 months ago) by michael
Content type: text/x-csrc
File size: 6171 byte(s)
Log Message:
- autoreconf

File Contents

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

Properties

Name Value
svn:eol-style native