Mercurial > hg > vamp-plugin-load-checker
comparison src/helper.cpp @ 8:25e00373f597
Much renaming to ease inclusion into another project
author | Chris Cannam |
---|---|
date | Thu, 14 Apr 2016 16:52:19 +0100 |
parents | helper.cpp@61dbb18f2369 |
children | c7baebf68fac |
comparison
equal
deleted
inserted
replaced
7:846464771d06 | 8:25e00373f597 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /** | |
4 * Plugin Load Checker Helper | |
5 * | |
6 * This program accepts the name of a descriptor symbol as its only | |
7 * command-line argument. It then reads a list of plugin library paths | |
8 * from stdin, one per line. For each path read, it attempts to load | |
9 * that library and retrieve the named descriptor symbol, printing a | |
10 * line to stdout reporting whether this was successful or not and | |
11 * then flushing stdout. The output line format is described | |
12 * below. The program exits with code 0 if all libraries were loaded | |
13 * successfully and non-zero otherwise. | |
14 * | |
15 * Note that library paths must be ready to pass to dlopen() or | |
16 * equivalent; this usually means they should be absolute paths. | |
17 * | |
18 * Output line for successful load of library libname.so: | |
19 * SUCCESS|/path/to/libname.so| | |
20 * | |
21 * Output line for failed load of library libname.so: | |
22 * FAILURE|/path/to/libname.so|Reason for failure if available | |
23 * | |
24 * Sometimes plugins will crash completely on load, bringing down this | |
25 * program with them. If the program exits before all listed plugins | |
26 * have been checked, this means that the plugin following the last | |
27 * reported one has crashed. Typically the caller may want to run it | |
28 * again, omitting that plugin. | |
29 */ | |
30 | |
31 /* | |
32 Copyright (c) 2016 Queen Mary, University of London | |
33 | |
34 Permission is hereby granted, free of charge, to any person | |
35 obtaining a copy of this software and associated documentation | |
36 files (the "Software"), to deal in the Software without | |
37 restriction, including without limitation the rights to use, copy, | |
38 modify, merge, publish, distribute, sublicense, and/or sell copies | |
39 of the Software, and to permit persons to whom the Software is | |
40 furnished to do so, subject to the following conditions: | |
41 | |
42 The above copyright notice and this permission notice shall be | |
43 included in all copies or substantial portions of the Software. | |
44 | |
45 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
46 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
47 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
48 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
49 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
50 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
51 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
52 | |
53 Except as contained in this notice, the names of the Centre for | |
54 Digital Music and Queen Mary, University of London shall not be | |
55 used in advertising or otherwise to promote the sale, use or other | |
56 dealings in this Software without prior written authorization. | |
57 */ | |
58 | |
59 #ifdef _WIN32 | |
60 #include <windows.h> | |
61 #include <process.h> | |
62 #define DLOPEN(a,b) LoadLibrary((a).toStdWString().c_str()) | |
63 #define DLSYM(a,b) GetProcAddress((HINSTANCE)(a),(b)) | |
64 #define DLCLOSE(a) (!FreeLibrary((HINSTANCE)(a))) | |
65 #define DLERROR() "" | |
66 #else | |
67 #include <dlfcn.h> | |
68 #define DLOPEN(a,b) dlopen((a).c_str(),(b)) | |
69 #define DLSYM(a,b) dlsym((a),(b).c_str()) | |
70 #define DLCLOSE(a) dlclose((a)) | |
71 #define DLERROR() dlerror() | |
72 #endif | |
73 | |
74 #include <string> | |
75 #include <iostream> | |
76 | |
77 #include <unistd.h> | |
78 | |
79 using namespace std; | |
80 | |
81 string error() | |
82 { | |
83 string e = dlerror(); | |
84 if (e == "") return "(unknown error)"; | |
85 else return e; | |
86 } | |
87 | |
88 string check(string soname, string descriptor) | |
89 { | |
90 void *handle = DLOPEN(soname, RTLD_NOW | RTLD_LOCAL); | |
91 if (!handle) { | |
92 return "Unable to open plugin library: " + error(); | |
93 } | |
94 | |
95 void *fn = DLSYM(handle, descriptor); | |
96 if (!fn) { | |
97 return "Failed to find plugin descriptor " + descriptor + | |
98 " in library: " + error(); | |
99 } | |
100 | |
101 return ""; | |
102 } | |
103 | |
104 int main(int argc, char **argv) | |
105 { | |
106 bool allGood = true; | |
107 string soname; | |
108 | |
109 if (argc != 2) { | |
110 cerr << "\nUsage:\n " << argv[0] << " descriptorname\n" | |
111 "\nwhere descriptorname is the name of a plugin descriptor symbol to be sought\n" | |
112 "in each library (e.g. vampGetPluginDescriptor for Vamp plugins). The list of\n" | |
113 "candidate plugin library filenames is read from stdin.\n" << endl; | |
114 return 2; | |
115 } | |
116 | |
117 string descriptor = argv[1]; | |
118 | |
119 while (getline(cin, soname)) { | |
120 string report = check(soname, descriptor); | |
121 if (report != "") { | |
122 cout << "FAILURE|" << soname << "|" << report << endl; | |
123 allGood = false; | |
124 } else { | |
125 cout << "SUCCESS|" << soname << "|" << endl; | |
126 } | |
127 } | |
128 | |
129 return allGood ? 0 : 1; | |
130 } |