Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libdll/dll_lib.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1997-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Glenn Fowler
23
* AT&T Research
24
*/
25
26
#include "dlllib.h"
27
28
typedef void* (*Dll_lib_f)(const char*, void*, const char*);
29
30
typedef struct Dll_lib_s
31
{
32
struct Dll_lib_s* next;
33
Dll_lib_f libf;
34
char* path;
35
char base[1];
36
} Dll_lib_t;
37
38
/*
39
* split <name,base,type,opts> from name into names
40
*/
41
42
Dllnames_t*
43
dllnames(const char* id, const char* name, Dllnames_t* names)
44
{
45
char* s;
46
char* t;
47
char* b;
48
char* e;
49
size_t n;
50
51
n = strlen(id);
52
if (strneq(name, id, n) && (streq(name + n, "_s") || streq(name + n, "_t")))
53
return 0;
54
if (!names)
55
{
56
s = fmtbuf(sizeof(Dllnames_t*) + sizeof(names) - 1);
57
if (n = (s - (char*)0) % sizeof(names))
58
s += sizeof(names) - n;
59
names = (Dllnames_t*)s;
60
}
61
62
/*
63
* determine the base name
64
*/
65
66
if ((s = strrchr(name, '/')) || (s = strrchr(name, '\\')))
67
s++;
68
else
69
s = (char*)name;
70
if (strneq(s, "lib", 3))
71
s += 3;
72
b = names->base = names->data;
73
e = b + sizeof(names->data) - 1;
74
t = s;
75
while (b < e && *t && *t != '.' && *t != '-' && *t != ':')
76
*b++ = *t++;
77
*b++ = 0;
78
79
/*
80
* determine the optional type
81
*/
82
83
if (t = strrchr(s, ':'))
84
{
85
names->name = b;
86
while (b < e && s < t)
87
*b++ = *s++;
88
*b++ = 0;
89
names->type = b;
90
while (b < e && *++t)
91
*b++ = *t;
92
*b++ = 0;
93
}
94
else
95
{
96
names->name = (char*)name;
97
names->type = 0;
98
}
99
*(names->path = b) = 0;
100
names->opts = 0;
101
names->id = (char*)id;
102
return names;
103
}
104
105
/*
106
* return method pointer for <id,version> in names
107
*/
108
109
void*
110
dll_lib(Dllnames_t* names, unsigned long version, Dllerror_f dllerrorf, void* disc)
111
{
112
void* dll;
113
Dll_lib_t* lib;
114
Dll_lib_f libf;
115
ssize_t n;
116
char sym[64];
117
118
static Dll_lib_t* loaded;
119
120
if (!names)
121
return 0;
122
123
/*
124
* check if plugin already loaded
125
*/
126
127
for (lib = loaded; lib; lib = lib->next)
128
if (streq(names->base, lib->base))
129
{
130
libf = lib->libf;
131
goto init;
132
}
133
134
/*
135
* load
136
*/
137
138
if (!(dll = dllplugin(names->id, names->name, NiL, version, NiL, RTLD_LAZY, names->path, names->data + sizeof(names->data) - names->path)) && (streq(names->name, names->base) || !(dll = dllplugin(names->id, names->base, NiL, version, NiL, RTLD_LAZY, names->path, names->data + sizeof(names->data) - names->path))))
139
{
140
if (dllerrorf)
141
(*dllerrorf)(NiL, disc, 2, "%s: library not found", names->name);
142
else
143
errorf("dll", NiL, -1, "dll_lib: %s version %lu library not found", names->name, version);
144
return 0;
145
}
146
147
/*
148
* init
149
*/
150
151
sfsprintf(sym, sizeof(sym), "%s_lib", names->id);
152
if (!(libf = (Dll_lib_f)dlllook(dll, sym)))
153
{
154
if (dllerrorf)
155
(*dllerrorf)(NiL, disc, 2, "%s: %s: initialization function not found in library", names->path, sym);
156
else
157
errorf("dll", NiL, -1, "dll_lib: %s version %lu initialization function %s not found in library", names->name, version, sym);
158
return 0;
159
}
160
161
/*
162
* add to the loaded list
163
*/
164
165
if (lib = newof(0, Dll_lib_t, 1, (n = strlen(names->base)) + strlen(names->path) + 1))
166
{
167
lib->libf = libf;
168
strcpy(lib->base, names->base);
169
strcpy(lib->path = lib->base + n + 1, names->path);
170
lib->next = loaded;
171
loaded = lib;
172
errorf("dll", NiL, -1, "dll_lib: %s version %lu loaded from %s", names->name, version, lib->path);
173
}
174
init:
175
return (*libf)(names->path, disc, names->type);
176
}
177
178
/*
179
* return method pointer for <id,name,version>
180
*/
181
182
void*
183
dllmeth(const char* id, const char* name, unsigned long version)
184
{
185
Dllnames_t names;
186
187
return dll_lib(dllnames(id, name, &names), version, 0, 0);
188
}
189
190